|
7 | 7 |
|
8 | 8 | namespace craft\commerce\helpers; |
9 | 9 |
|
| 10 | +use Craft; |
| 11 | +use craft\commerce\base\Purchasable; |
10 | 12 | use craft\commerce\elements\Order as OrderElement; |
| 13 | +use craft\commerce\elements\Variant; |
| 14 | +use craft\commerce\models\OrderNotice; |
| 15 | +use craft\commerce\Plugin; |
| 16 | +use yii\base\InvalidConfigException; |
11 | 17 |
|
12 | 18 | /** |
13 | 19 | * Order helper |
@@ -44,4 +50,54 @@ public static function mergeDuplicateLineItems(OrderElement $order): bool |
44 | 50 |
|
45 | 51 | return $lineItems > $lineItemsByKey; |
46 | 52 | } |
| 53 | + |
| 54 | + /** |
| 55 | + * Removes any line items from the cart that are no longer available. |
| 56 | + * If a line item is available but the quantity is more than the available stock, |
| 57 | + * the quantity will be reduced to the available stock. |
| 58 | + * A notice will be added to the cart for each change. |
| 59 | + * |
| 60 | + * @param OrderElement $order |
| 61 | + * @return void |
| 62 | + * @throws InvalidConfigException |
| 63 | + * @since 4.9.3 |
| 64 | + */ |
| 65 | + public static function normalizeLineItemPurchasableAvailability(OrderElement $order): void |
| 66 | + { |
| 67 | + if ($order->isCompleted) { |
| 68 | + return; |
| 69 | + } |
| 70 | + |
| 71 | + foreach ($order->getLineItems() as $lineItem) { |
| 72 | + /* @var $purchasable Purchasable */ |
| 73 | + $purchasable = $lineItem->getPurchasable(); |
| 74 | + if (!$purchasable || !Plugin::getInstance()->getPurchasables()->isPurchasableAvailable($purchasable, $order)) { |
| 75 | + $message = Craft::t('commerce', '{description} is no longer available.', ['description' => $lineItem->getDescription()]); |
| 76 | + /** @var OrderNotice $notice */ |
| 77 | + $notice = Craft::createObject([ |
| 78 | + 'class' => OrderNotice::class, |
| 79 | + 'attributes' => [ |
| 80 | + 'message' => $message, |
| 81 | + 'type' => 'lineItemRemoved', |
| 82 | + 'attribute' => 'lineItems', |
| 83 | + ], |
| 84 | + ]); |
| 85 | + $order->addNotice($notice); |
| 86 | + $order->removeLineItem($lineItem); |
| 87 | + } elseif ($purchasable instanceof Variant && ($lineItem->qty > $purchasable->stock) && !$purchasable->hasUnlimitedStock && $purchasable->stock > 0) { |
| 88 | + $message = Craft::t('commerce', '{description} only has {stock} in stock.', ['description' => $lineItem->getDescription(), 'stock' => $purchasable->stock]); |
| 89 | + /** @var OrderNotice $notice */ |
| 90 | + $notice = Craft::createObject([ |
| 91 | + 'class' => OrderNotice::class, |
| 92 | + 'attributes' => [ |
| 93 | + 'type' => 'lineItemSalePriceChanged', |
| 94 | + 'attribute' => "lineItems.$lineItem->id.qty", |
| 95 | + 'message' => $message, |
| 96 | + ], |
| 97 | + ]); |
| 98 | + $order->addNotice($notice); |
| 99 | + $lineItem->qty = $purchasable->stock; |
| 100 | + } |
| 101 | + } |
| 102 | + } |
47 | 103 | } |
0 commit comments