Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.7 #3629

Merged
merged 101 commits into from
Oct 16, 2024
Merged

4.7 #3629

Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
3314d53
Add warning alert if upgrade command not completed
lukeholder Jun 21, 2024
77a1a59
Code style
lukeholder Jun 21, 2024
8023870
Adjust language
AugustMiller Jun 21, 2024
0bccf5c
Start 4.7 WIP release notes
lukeholder Aug 15, 2024
9bd4047
performance improvements
lukeholder Sep 4, 2024
7137c70
#3132 Issue where it was impossible for store managers to remove all …
nfourtythree Sep 6, 2024
4489783
#3132 Add “Require Coupon Code” lightswitch to discounts
nfourtythree Sep 6, 2024
374ae56
Changelog
nfourtythree Sep 6, 2024
c08ce32
Run workflow for `4.7`
nfourtythree Sep 6, 2024
ef8b0c3
Merge branch '4.7' into feature/pt-1998-add-requires-coupon-code-ligh…
nfourtythree Sep 6, 2024
c717c1e
fix cs
nfourtythree Sep 6, 2024
9d91c3a
fix install typo
nfourtythree Sep 6, 2024
3ad5aa0
No need for extra logic
nfourtythree Sep 6, 2024
76f1a3f
Merge branch '4.x' into 4.7
nfourtythree Sep 6, 2024
70a8c36
Merge branch '4.7' into feature/pt-1998-add-requires-coupon-code-ligh…
nfourtythree Sep 6, 2024
46178fe
Fix tests
nfourtythree Sep 6, 2024
dc130f3
Merge branch '4.7' into feature/shipping-condition-performance
lukeholder Sep 10, 2024
dcd49a1
Reapply "Performance improvement order condition on shipping"
lukeholder Sep 10, 2024
165d875
Improve cart performance
lukeholder Sep 10, 2024
ba3e1f8
Release notes
lukeholder Sep 10, 2024
20323dc
Save if new in cart
lukeholder Sep 10, 2024
c9f40f2
no need to save if it was forced saved
lukeholder Sep 10, 2024
5daaf25
No need
lukeholder Sep 10, 2024
ddd7dd9
#3306 default new address creation on order edit to store’s country
nfourtythree Sep 10, 2024
f60ac89
fix cs
nfourtythree Sep 10, 2024
6dfad2b
Merge branch '4.x' into 4.7
nfourtythree Sep 11, 2024
d301a62
Add events
lukeholder Sep 16, 2024
50f3aab
Merge branch '4.7' into feature/upgrade-events
lukeholder Sep 16, 2024
fac56cf
Added “Variant Search” condition rule for product conditions #3689
nfourtythree Sep 24, 2024
76b8eaf
Merge pull request #3691 from craftcms/feature/pt-2164-4x5x-variant-s…
lukeholder Sep 24, 2024
74369f4
Merge branch '4.7' into feature/pt-2142-4x-new-address-in-order-entry…
nfourtythree Sep 24, 2024
98acbed
build JS
nfourtythree Sep 24, 2024
7962a62
Tidy changelog
nfourtythree Sep 24, 2024
cf23533
Merge pull request #3665 from craftcms/feature/pt-2142-4x-new-address…
nfourtythree Sep 24, 2024
69b8b21
Merge branch '4.7' into feature/pt-1998-add-requires-coupon-code-ligh…
nfourtythree Sep 24, 2024
3f434d6
Merge branch '4.x' into 4.7
nfourtythree Sep 24, 2024
c4818d2
Merge branch '4.7' into feature/pt-1998-add-requires-coupon-code-ligh…
nfourtythree Sep 24, 2024
cfe4ce3
fix cs
nfourtythree Sep 24, 2024
85c819d
Merge branch '4.7' into feature/pt-1998-add-requires-coupon-code-ligh…
nfourtythree Sep 24, 2024
1078f1e
Merge pull request #3660 from craftcms/feature/pt-1998-add-requires-c…
nfourtythree Sep 24, 2024
86c54b5
Merge branch '4.7' into feature/upgrade-events
nfourtythree Sep 25, 2024
89062bb
doc block tweak
nfourtythree Sep 25, 2024
640b31a
fix cs
nfourtythree Sep 25, 2024
4bc9cca
Merge pull request #3675 from craftcms/feature/upgrade-events
lukeholder Sep 25, 2024
895fb63
Merge branch '4.x' into feature/shipping-condition-performance
lukeholder Sep 30, 2024
f2d2c10
Fix php error
lukeholder Sep 30, 2024
94bcfc9
Merge branch '4.7' into feature/shipping-condition-performance
lukeholder Oct 1, 2024
de7653e
Merge branch '4.x' into 4.7
lukeholder Oct 1, 2024
d9f4239
Merge branch '4.7' into feature/shipping-condition-performance
lukeholder Oct 1, 2024
b33f689
Use teller class for order comparisons
lukeholder Oct 9, 2024
55efd3c
cleanup
lukeholder Oct 9, 2024
d2551dd
Use teller
lukeholder Oct 9, 2024
7261c91
release notes
lukeholder Oct 9, 2024
0a11a07
Merge pull request #3712 from craftcms/feature/teller-rounding
lukeholder Oct 9, 2024
9ce7778
Fix translation
lukeholder Oct 9, 2024
1ec7779
Merge branch '4.7' into feature/upgrade-warning
lukeholder Oct 9, 2024
e0739cc
More simple translations
lukeholder Oct 9, 2024
94d518d
Merge branch '4.7' into feature/shipping-condition-performance
lukeholder Oct 9, 2024
9bfe91a
Test
lukeholder Oct 9, 2024
72cd613
Merge pull request #3550 from craftcms/feature/upgrade-warning
lukeholder Oct 9, 2024
2540239
Add since tag
lukeholder Oct 9, 2024
a6efd8e
Merge pull request #3653 from craftcms/feature/shipping-condition-per…
lukeholder Oct 9, 2024
ebfe563
Merge branch '4.x' into 4.7
lukeholder Oct 9, 2024
91cf9a3
Release Notes
lukeholder Oct 9, 2024
fcc04a9
Tweak
brandonkelly Oct 11, 2024
3cb7de6
New translations commerce.php (French)
shinybrad Oct 11, 2024
353efc4
New translations commerce.php (German)
shinybrad Oct 11, 2024
cfcbdd8
New translations commerce.php (Italian)
shinybrad Oct 11, 2024
7f5043d
New translations commerce.php (Japanese)
shinybrad Oct 11, 2024
382e845
New translations commerce.php (Dutch)
shinybrad Oct 11, 2024
d52a0f1
New translations commerce.php (Portuguese)
shinybrad Oct 11, 2024
12ede84
New translations commerce.php (Slovak)
shinybrad Oct 11, 2024
dbd6316
New translations commerce.php (English, United Kingdom)
shinybrad Oct 11, 2024
8a8c823
New translations commerce.php (French, Canada)
shinybrad Oct 11, 2024
70aea9b
New translations commerce.php (Norwegian Bokmal)
shinybrad Oct 11, 2024
08a140e
New translations commerce.php (Dutch)
shinybrad Oct 14, 2024
36c0c94
New translations commerce.php (French)
shinybrad Oct 14, 2024
7e79884
New translations commerce.php (Slovak)
shinybrad Oct 14, 2024
01fbca5
New translations commerce.php (French, Canada)
shinybrad Oct 14, 2024
f5e15b9
New translations commerce.php (Italian)
shinybrad Oct 14, 2024
003f892
New translations commerce.php (French, Canada)
shinybrad Oct 14, 2024
7845a61
New translations commerce.php (Portuguese)
shinybrad Oct 14, 2024
4caaaae
Fixes duplicate carts created
lukeholder Oct 15, 2024
ab45d9d
oops
lukeholder Oct 15, 2024
768a211
Fix code style
lukeholder Oct 15, 2024
58b62a5
Merge branch '4.7' into feature/fix-extra-carts-created
lukeholder Oct 15, 2024
45d352d
New translations commerce.php (Japanese)
shinybrad Oct 15, 2024
8511332
Better way
lukeholder Oct 15, 2024
83488b6
Formatting
lukeholder Oct 15, 2024
4fea406
New translations commerce.php (Norwegian Bokmal)
shinybrad Oct 15, 2024
1d3bc08
cleanup
lukeholder Oct 16, 2024
7cb8d6f
Merge pull request #3723 from craftcms/feature/fix-extra-carts-created
lukeholder Oct 16, 2024
9c9af70
New translations commerce.php (German)
shinybrad Oct 16, 2024
d5e0d83
Revert "Merge pull request #3723 from craftcms/feature/fix-extra-cart…
lukeholder Oct 16, 2024
f102342
Duplicate code
lukeholder Oct 16, 2024
0225837
code style
lukeholder Oct 16, 2024
c8e7cdf
Merge branch '4.x' into 4.7
lukeholder Oct 16, 2024
21adfa0
Merge branch '4.x' into 4.7
lukeholder Oct 16, 2024
f7afc78
Merge pull request #3717 from craftcms/t9n/4.7
lukeholder Oct 16, 2024
3a84c04
Changelog tweaks
brandonkelly Oct 16, 2024
f863c39
Merge branch '4.x' into 4.7
lukeholder Oct 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ on:
push:
branches:
- '4.x'
- '4.7'
pull_request:
permissions:
contents: read
19 changes: 19 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Release Notes for Craft Commerce 4.7 (WIP)

### Store Management
- It’s now possible for discounts to explicitly require a coupon code. ([#3132](https://github.com/craftcms/commerce/issues/3132))
- New order addresses now default to the store’s country on Order Edit screens. ([#3306](https://github.com/craftcms/commerce/issues/3306))
- Product conditions can now have a “Variant Search” rule. ([#3689](https://github.com/craftcms/commerce/issues/3689))

### Extensibility
- Added `craft\commerce\console\controllers\UpgradeController::$v3droppableColumns`
- Added `craft\commerce\console\controllers\UpgradeController::EVENT_BEFORE_DROP_V3_DATABASE_ENTITIES`.
- Added `craft\commerce\elements\conditions\products\ProductVariantSearchConditionRule`.
- Added `craft\commerce\events\UpgradeEvent`.
- Added `craft\commerce\models\Discount::$requireCouponCode`.

### System
- Improved the performance of adding items to the cart.
- Improved the performance of shipping rule matching when an order condition formula is used. ([3653](https://github.com/craftcms/commerce/pull/3653))
- Craft Commerce now requires Money PHP 4.2 or later.
- Fixed a bug where outstanding order balances could be calculated incorrectly. ([#3403](https://github.com/craftcms/commerce/issues/3403))
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -25,7 +25,8 @@
"craftcms/cms": "^4.9.4",
"dompdf/dompdf": "^2.0.2",
"ibericode/vat": "^1.2.2",
"iio/libmergepdf": "^4.0"
"iio/libmergepdf": "^4.0",
"moneyphp/money": "^4.2.0"
},
"require-dev": {
"codeception/codeception": "^4.0.0",
33 changes: 32 additions & 1 deletion src/Plugin.php
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
use craft\commerce\behaviors\CustomerAddressBehavior;
use craft\commerce\behaviors\CustomerBehavior;
use craft\commerce\behaviors\ValidateOrganizationTaxIdBehavior;
use craft\commerce\console\controllers\UpgradeController as UpgradeController;
use craft\commerce\db\Table;
use craft\commerce\debug\CommercePanel;
use craft\commerce\elements\Donation;
@@ -116,8 +117,10 @@
use craft\fixfks\controllers\RestoreController;
use craft\gql\ElementQueryConditionBuilder;
use craft\helpers\Console;
use craft\helpers\Cp;
use craft\helpers\Db;
use craft\helpers\FileHelper;
use craft\helpers\Html;
use craft\helpers\UrlHelper;
use craft\models\FieldLayout;
use craft\redactor\events\RegisterLinkOptionsEvent;
@@ -207,7 +210,7 @@ public static function editions(): array
/**
* @inheritDoc
*/
public string $schemaVersion = '4.5.3';
public string $schemaVersion = '4.7.0.1';

/**
* @inheritdoc
@@ -270,12 +273,40 @@ public function init(): void
$this->_registerDebugPanels();

if ($request->getIsCpRequest()) {
$this->_checkUpgradeCommandHasFinished();
$this->_registerStoreAddressAuthHandlers();
}
});
Craft::setAlias('@commerceLib', Craft::getAlias('@craft/commerce/../lib'));
}

private function _checkUpgradeCommandHasFinished()
{
$v3Columns = UpgradeController::$v3droppableColumns;
// do any of the columns exist:
$columnsExist = false;
foreach ($v3Columns as $column) {
if (Craft::$app->getDb()->columnExists($column['table'], $column['column'])) {
$columnsExist = true;
break;
}
}

if ($columnsExist) {
Event::on(Cp::class, Cp::EVENT_REGISTER_ALERTS, static function($event) {
$event->alerts[] = [
'content' =>
Html::tag('strong', Craft::t('commerce', '{name} upgrade incomplete.', [
'name' => '<span lang="en">Craft Commerce 4</span>',
])) . ' ' .
Craft::t('commerce', 'Please ensure the <a href="{url}">upgrade command</a> has finished running.', [
'url' => 'https://craftcms.com/docs/commerce/4.x/upgrading.html#performing-the-upgrade',
]),
];
});
}
}

/**
* @inheritdoc
*/
19 changes: 17 additions & 2 deletions src/console/controllers/UpgradeController.php
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
use craft\commerce\console\Controller;
use craft\commerce\db\Table;
use craft\commerce\elements\conditions\addresses\PostalCodeFormulaConditionRule;
use craft\commerce\events\UpgradeEvent;
use craft\commerce\Plugin;
use craft\commerce\records\Store;
use craft\db\Connection;
@@ -51,6 +52,13 @@
*/
class UpgradeController extends Controller
{
/**
* @event UpgradeEvent The event that is triggered before the v3 columns and tables are dropped during upgrade.
* @see actionRun()
* @since 4.7.0
*/
public const EVENT_BEFORE_DROP_V3_DATABASE_ENTITIES = 'beforeDropV3DatabaseEntities';

/**
* @inheritdoc
*/
@@ -96,7 +104,7 @@ private function _getOrphanedCustomerIds(): array
*
* @var array<array{table: string, column: string}>
*/
private array $_v3droppableColumns = [
public static array $v3droppableColumns = [
['table' => '{{%commerce_taxzones}}', 'column' => 'v3isCountryBased'],
['table' => '{{%commerce_shippingzones}}', 'column' => 'v3isCountryBased'],
['table' => '{{%commerce_taxzones}}', 'column' => 'v3zipCodeConditionFormula'],
@@ -316,13 +324,20 @@ public function actionRun(): int
return ExitCode::UNSPECIFIED_ERROR;
}

$event = new UpgradeEvent();
$event->v3columnMap = self::$v3droppableColumns;
$event->v3tables = $this->_v3tables;
if ($this->hasEventHandlers(self::EVENT_BEFORE_DROP_V3_DATABASE_ENTITIES)) {
$this->trigger(self::EVENT_BEFORE_DROP_V3_DATABASE_ENTITIES, $event);
}

$this->stdout("Cleaning up tables…");
foreach ($this->_v3tables as $table) {
Db::dropAllForeignKeysToTable($table, $this->db);
$this->db->createCommand()->dropTableIfExists($table)->execute();
}

foreach ($this->_v3droppableColumns as ['table' => $table, 'column' => $column]) {
foreach (static::$v3droppableColumns as ['table' => $table, 'column' => $column]) {
if ($this->db->columnExists($table, $column)) {
Db::dropForeignKeyIfExists($table, $column, $this->db);
Db::dropIndexIfExists($table, $column, db: $this->db);
10 changes: 6 additions & 4 deletions src/controllers/CartController.php
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ public function actionUpdateCart(): ?Response

// Get the cart from the request or from the session.
// When we are about to update the cart, we consider it a real cart at this point, and want to actually create it in the DB.
$this->_cart = $this->_getCart(true);
$this->_cart = $this->_getCart();

// Can clear line items when updating the cart
$clearLineItems = $this->request->getParam('clearLineItems');
@@ -580,7 +580,7 @@ private function _getCart(bool $forceSave = false): Order
// Get the cart from the order number
$cart = Order::find()->number($orderNumber)->isCompleted(false)->one();

if (!$cart) {
if ($cart === null) {
throw new NotFoundHttpException('Cart not found');
}

@@ -590,7 +590,9 @@ private function _getCart(bool $forceSave = false): Order
$requestForceSave = (bool)$this->request->getBodyParam('forceSave');
$doForceSave = ($requestForceSave || $forceSave);

return Plugin::getInstance()->getCarts()->getCart($doForceSave);
$this->_cart = Plugin::getInstance()->getCarts()->getCart($doForceSave);

return $this->_cart;
}

/**
@@ -685,7 +687,7 @@ private function _setAddresses(): void
$this->_cart->sourceBillingAddressId = $billingAddressId;

/** @var Address $cartBillingAddress */
$cartBillingAddress = Craft::$app->getElements()->duplicateElement($userBillingAddress, [
$cartBillingAddress = Craft::$app->getElements()->duplicateElement($userBillingAddress, [
'owner' => $this->_cart,
]);
$this->_cart->setBillingAddress($cartBillingAddress);
9 changes: 4 additions & 5 deletions src/controllers/DiscountsController.php
Original file line number Diff line number Diff line change
@@ -96,12 +96,10 @@ public function actionTableData(): Response
'discounts.dateTo',
'discounts.totalDiscountUses',
'discounts.ignoreSales',
'discounts.requireCouponCode',
'discounts.stopProcessing',
'discounts.sortOrder',
'coupons.discountId',
])
->distinct()
->leftJoin(Table::COUPONS . ' coupons', '[[coupons.discountId]] = [[discounts.id]]')
->orderBy(['sortOrder' => SORT_ASC]);


@@ -146,8 +144,7 @@ public function actionTableData(): Response
'status' => (bool)$item['enabled'],
'duration' => $dateRange,
'timesUsed' => $item['totalDiscountUses'],
// If there is joined data then there are coupons
'hasCoupons' => (bool)$item['discountId'],
'requireCouponCode' => (bool)$item['requireCouponCode'],
'ignore' => (bool)$item['ignoreSales'],
'stop' => (bool)$item['stopProcessing'],
];
@@ -223,6 +220,7 @@ public function actionSave(): ?Response
$discount->setCustomerCondition($this->request->getBodyParam('customerCondition'));
$discount->setShippingAddressCondition($this->request->getBodyParam('shippingAddressCondition'));
$discount->setBillingAddressCondition($this->request->getBodyParam('billingAddressCondition'));
$discount->requireCouponCode = (bool)$this->request->getBodyParam('requireCouponCode');
$discount->stopProcessing = (bool)$this->request->getBodyParam('stopProcessing');
$discount->purchaseQty = $this->request->getBodyParam('purchaseQty');
$discount->maxPurchaseQty = $this->request->getBodyParam('maxPurchaseQty');
@@ -340,6 +338,7 @@ public function actionSave(): ?Response
private function _setCouponsOnDiscount(array $coupons, Discount $discount): void
{
if (empty($coupons)) {
$discount->setCoupons([]);
return;
}

3 changes: 3 additions & 0 deletions src/controllers/OrdersController.php
Original file line number Diff line number Diff line change
@@ -1259,6 +1259,9 @@ private function _registerJavascript(array $variables): void
$forceEdit = ($variables['order']->hasErrors() || !$variables['order']->isCompleted);

Craft::$app->getView()->registerJs('window.orderEdit.forceEdit = ' . Json::encode($forceEdit) . ';', View::POS_BEGIN);

$store = Plugin::getInstance()->getStore()->getStore();
Craft::$app->getView()->registerJs('window.orderEdit.store = ' . Json::encode($store->toArray([], ['locationAddress'])) . ';', View::POS_BEGIN);
}

/**
34 changes: 23 additions & 11 deletions src/elements/Order.php
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@
use craft\i18n\Locale;
use craft\models\Site;
use DateTime;
use Money\Teller;
use ReflectionClass;
use ReflectionMethod;
use ReflectionNamedType;
@@ -2441,15 +2442,18 @@ public function isPaymentAmountPartial(): bool
*/
public function getPaidStatus(): string
{
if ($this->getIsPaid() && $this->getTotalPrice() > 0 && $this->getTotalPaid() > $this->getTotalPrice()) {
if ($this->getIsPaid() &&
$this->_getTeller()->greaterThan($this->getTotalPrice(), 0) &&
$this->_getTeller()->greaterThan($this->getTotalPaid(), $this->getTotalPrice())
) {
return self::PAID_STATUS_OVERPAID;
}

if ($this->getIsPaid()) {
return self::PAID_STATUS_PAID;
}

if ($this->getTotalPaid() > 0) {
if ($this->_getTeller()->greaterThan($this->getTotalPaid(), 0)) {
return self::PAID_STATUS_PARTIAL;
}

@@ -2553,20 +2557,18 @@ public function hasShippableItems(): bool

/**
* Returns the difference between the order amount and amount paid.
*
*
*/
public function getOutstandingBalance(): float
{
$totalPaid = Currency::round($this->getTotalPaid());
$totalPrice = $this->getTotalPrice(); // Already rounded

return $totalPrice - $totalPaid;
return (float)$this->_getTeller()->subtract($this->getTotalPrice(), $this->getTotalPaid());
}

/**
* @return bool
*/
public function hasOutstandingBalance(): bool
{
return $this->getOutstandingBalance() > 0;
return $this->_getTeller()->greaterThan($this->getOutstandingBalance(), 0);
}

/**
@@ -2593,7 +2595,7 @@ public function getTotalPaid(): float
$paid = array_sum(ArrayHelper::getColumn($paidTransactions, 'amount', false));
$refunded = array_sum(ArrayHelper::getColumn($refundedTransactions, 'amount', false));

return $paid - $refunded;
return (float)$this->_getTeller()->subtract($paid, $refunded);
}

/**
@@ -2631,7 +2633,7 @@ public function getTotalAuthorized(): float
}
}

return $authorized - $captured;
return (float)$this->_getTeller()->subtract($authorized, $captured);
}

/**
@@ -3611,4 +3613,14 @@ private function _populateAddressNameAttributes(AddressElement $addressElement,
}
}
}

/**
* @return Teller
* @throws InvalidConfigException
* @since 4.7.0
*/
private function _getTeller(): Teller
{
return Plugin::getInstance()->getCurrencies()->getTeller($this->currency);
}
}
1 change: 1 addition & 0 deletions src/elements/conditions/products/ProductCondition.php
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ protected function conditionRuleTypes(): array
{
return array_merge(parent::conditionRuleTypes(), [
ProductTypeConditionRule::class,
ProductVariantSearchConditionRule::class,
ProductVariantSkuConditionRule::class,
ProductVariantStockConditionRule::class,
ProductVariantHasUnlimitedStockConditionRule::class,
Loading