From 5656862d8a20d0017d18332bd1c3476f8863e999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 09:38:09 +0100 Subject: [PATCH 1/6] Trigger gift item removal before quote item count is calculated and update it when adding quote items. --- Observer/ResetGiftItems.php | 75 ++++++++++++++++++++++----------- SalesRule/Action/GiftAction.php | 17 +++++++- composer.json | 2 +- etc/events.xml | 7 ++- 4 files changed, 72 insertions(+), 29 deletions(-) diff --git a/Observer/ResetGiftItems.php b/Observer/ResetGiftItems.php index c856b72..b439acc 100644 --- a/Observer/ResetGiftItems.php +++ b/Observer/ResetGiftItems.php @@ -10,9 +10,12 @@ use Magento\Quote\Model\Quote; /** - * Observer for resetting gift cart items + * Observer for resetting gift cart items. + * When quote totals are collected, all gifts are removed and are later re-added by Discount total collector. + * It is triggered by two events: + * - quote collect before: for normal quote operations (adding items, changing qty, removing item) + * - address collect before: When shipping is estimated the above event is not triggered. * - * @category C4B * @package C4B_FreeProduct * @author Dominik Meglič * @copyright code4business Software GmbH @@ -21,45 +24,71 @@ class ResetGiftItems implements ObserverInterface { /** - * Delete all gift items. They will be re-added by SalesRule (If possible). - * + * @var bool + */ + private $areGiftItemsReset = false; + + /** + * @event sales_quote_collect_totals_before * @event sales_quote_address_collect_totals_before * @param Observer $observer * @return void + * @throws \Exception */ - public function execute(\Magento\Framework\Event\Observer $observer) + public function execute(Observer $observer) { - /** @var ShippingAssignmentInterface $shippingAssignment */ - $shippingAssignment = $observer->getEvent()->getData('shipping_assignment'); /** @var Quote $quote */ $quote = $observer->getEvent()->getData('quote'); - /** @var Quote\Address $address */ - $address = $shippingAssignment->getShipping()->getAddress(); + /** @var ShippingAssignmentInterface $shippingAssignment */ + $shippingAssignment = $observer->getEvent()->getData('shipping_assignment'); - if ($shippingAssignment->getItems() == null || $address->getAddressType() != Quote\Address::TYPE_SHIPPING) + if ($quote->getItems() == null || $this->areGiftItemsReset) { return; } - $newShippingAssignmentItems = $this->removeOldGiftQuoteItems($shippingAssignment); + if ($shippingAssignment instanceof ShippingAssignmentInterface) + { + $address = $shippingAssignment->getShipping()->getAddress(); + } + else + { + $address = $quote->getShippingAddress(); + } - $shippingAssignment->setItems($newShippingAssignmentItems); + $quote->setItems($this->removeOldGiftQuoteItems($quote->getItemsCollection())); + $this->areGiftItemsReset = true; $address->unsetData(GiftAction::APPLIED_FREEPRODUCT_RULE_IDS); $address->unsetData('cached_items_all'); - $this->updateExtensionAttributes($quote, $shippingAssignment); + if ($shippingAssignment instanceof ShippingAssignmentInterface) + { + $shippingAssignment->setItems($quote->getItems()); + $this->updateExtensionAttributes($quote, $shippingAssignment); + } } /** - * @param ShippingAssignmentInterface $shippingAssignment - * @return array + * A new gift item was added so if cart totals are collected again, all gift items will be reset. + * + * @return void + */ + public function reportGiftItemAdded() + { + $this->areGiftItemsReset = false; + } + + /** + * @param \Magento\Quote\Model\ResourceModel\Quote\Item\Collection|\Magento\Framework\Data\Collection $quoteItemsCollection + * @return Quote\Item[] + * @throws \Exception */ - protected function removeOldGiftQuoteItems($shippingAssignment): array + protected function removeOldGiftQuoteItems($quoteItemsCollection) { - $newShippingAssignment = []; + $realQuoteItems = []; /** @var Quote\Item $quoteItem */ - foreach ($shippingAssignment->getItems() as $quoteItem) + foreach ($quoteItemsCollection->getItems() as $key => $quoteItem) { if ($quoteItem->isDeleted()) { @@ -78,15 +107,11 @@ protected function removeOldGiftQuoteItems($shippingAssignment): array } } else { - /** - * Reset shipping assignment to prevent others from working on old items - * @see \Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector::processAppliedTaxes - * @see \Magento\Tax\Model\Plugin\OrderSave::saveOrderTax - */ - $newShippingAssignment[] = $quoteItem; + $realQuoteItems[$key] = $quoteItem; } } - return $newShippingAssignment; + + return $realQuoteItems; } /** diff --git a/SalesRule/Action/GiftAction.php b/SalesRule/Action/GiftAction.php index 5b56bc9..81fddcf 100644 --- a/SalesRule/Action/GiftAction.php +++ b/SalesRule/Action/GiftAction.php @@ -2,6 +2,8 @@ namespace C4B\FreeProduct\SalesRule\Action; +use C4B\FreeProduct\Observer\ResetGiftItems; + use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; @@ -15,7 +17,6 @@ /** * Handles applying a "Add a Gift" type SalesRule. * - * @category C4B * @package C4B_FreeProduct * @author Dominik Meglič * @copyright code4business Software GmbH @@ -29,7 +30,6 @@ class GiftAction implements Discount\DiscountInterface const RULE_DATA_KEY_SKU = 'gift_sku'; const PRODUCT_TYPE_FREEPRODUCT = 'freeproduct_gift'; const APPLIED_FREEPRODUCT_RULE_IDS = '_freeproduct_applied_rules'; - /** * @var Discount\DataFactory */ @@ -38,26 +38,36 @@ class GiftAction implements Discount\DiscountInterface * @var ProductRepositoryInterface */ private $productRepository; + /** + * @var ResetGiftItems + */ + private $resetGiftItems; /** * @var LoggerInterface */ private $logger; + /** * @param Discount\DataFactory $discountDataFactory * @param ProductRepositoryInterface $productRepository + * @param ResetGiftItems $resetGiftItems * @param LoggerInterface $logger */ public function __construct(Discount\DataFactory $discountDataFactory, ProductRepositoryInterface $productRepository, + ResetGiftItems $resetGiftItems, LoggerInterface $logger) { $this->discountDataFactory = $discountDataFactory; $this->productRepository = $productRepository; + $this->resetGiftItems = $resetGiftItems; $this->logger = $logger; } /** + * Add gift product to quote, if not yet added + * * @param \Magento\SalesRule\Model\Rule $rule * @param AbstractItem $item * @param float $qty @@ -78,6 +88,9 @@ public function calculate($rule, $item, $qty) try { $quoteItem = $item->getQuote()->addProduct($this->getGiftProduct($sku), $rule->getDiscountAmount()); + $item->getQuote()->setItemsCount($item->getQuote()->getItemsCount() + 1); + $item->getQuote()->setItemsQty((float)$item->getQuote()->getItemsQty() + $quoteItem->getQty()); + $this->resetGiftItems->reportGiftItemAdded(); if (is_string($quoteItem)) { diff --git a/composer.json b/composer.json index 1a57829..0756c27 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "phpunit/phpunit": "~6.2.0" }, "type": "magento2-module", - "version": "1.0.5", + "version": "1.0.7", "license": [ "OSL-3.0" ], diff --git a/etc/events.xml b/etc/events.xml index 3788e82..b205c76 100644 --- a/etc/events.xml +++ b/etc/events.xml @@ -1,9 +1,14 @@ + + + + + - + \ No newline at end of file From 862578b5b5cc198fa71ac2e1ac55234874cf0ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 09:42:41 +0100 Subject: [PATCH 2/6] Allow multiple gifts to be added by one rule. --- SalesRule/Action/GiftAction.php | 15 ++++++++++++--- composer.json | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/SalesRule/Action/GiftAction.php b/SalesRule/Action/GiftAction.php index 81fddcf..0bff474 100644 --- a/SalesRule/Action/GiftAction.php +++ b/SalesRule/Action/GiftAction.php @@ -83,8 +83,11 @@ public function calculate($rule, $item, $qty) return $this->getDiscountData($item); } - $sku = $rule->getData(static::RULE_DATA_KEY_SKU); + $skus = explode(',', $rule->getData(static::RULE_DATA_KEY_SKU)); + $isRuleAdded = false; + foreach ($skus as $sku) + { try { $quoteItem = $item->getQuote()->addProduct($this->getGiftProduct($sku), $rule->getDiscountAmount()); @@ -97,14 +100,20 @@ public function calculate($rule, $item, $qty) throw new \Exception($quoteItem); } - $this->addAppliedRuleId($rule->getRuleId(), $item->getAddress()); + $isRuleAdded = true; } catch (\Exception $e) { $this->logger->error( - sprintf('Exception occurred while adding gift product %s to cart. Rule: %d, Exception: %s', $sku, $rule->getId(), $e->getMessage()), + sprintf('Exception occurred while adding gift product %s to cart. Rule: %d, Exception: %s', implode(',', $skus), $rule->getId(), $e->getMessage()), [__METHOD__] ); } + } + + if ($isRuleAdded) + { + $this->addAppliedRuleId($rule->getRuleId(), $item->getAddress()); + } return $this->getDiscountData($item); } diff --git a/composer.json b/composer.json index 0756c27..c70badd 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "phpunit/phpunit": "~6.2.0" }, "type": "magento2-module", - "version": "1.0.7", + "version": "1.1.0", "license": [ "OSL-3.0" ], From e16ab48a6007a9d870fd0ff9075fed2d341ae948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 10:00:57 +0100 Subject: [PATCH 3/6] Allow gifts to be added for each specific cart item and based on their qty. --- Observer/ResetGiftItems.php | 2 + .../SalesRule/Model/MetadataValueProvider.php | 5 + README.md | 11 +- SalesRule/Action/ForeachGiftAction.php | 117 ++++++++++++++++++ composer.json | 2 +- etc/di.xml | 1 + i18n/en_US.csv | 3 +- i18n/sl_SI.csv | 3 +- 8 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 SalesRule/Action/ForeachGiftAction.php diff --git a/Observer/ResetGiftItems.php b/Observer/ResetGiftItems.php index b439acc..b80e1c7 100644 --- a/Observer/ResetGiftItems.php +++ b/Observer/ResetGiftItems.php @@ -2,6 +2,7 @@ namespace C4B\FreeProduct\Observer; +use C4B\Freeproduct\SalesRule\Action\ForeachGiftAction; use C4B\FreeProduct\SalesRule\Action\GiftAction; use Magento\Framework\Event\Observer; @@ -107,6 +108,7 @@ protected function removeOldGiftQuoteItems($quoteItemsCollection) } } else { + $quoteItem->unsetData(ForeachGiftAction::APPLIED_FREEPRODUCT_RULE_IDS); $realQuoteItems[$key] = $quoteItem; } } diff --git a/Plugin/SalesRule/Model/MetadataValueProvider.php b/Plugin/SalesRule/Model/MetadataValueProvider.php index d9244ac..f3cbf5b 100644 --- a/Plugin/SalesRule/Model/MetadataValueProvider.php +++ b/Plugin/SalesRule/Model/MetadataValueProvider.php @@ -3,6 +3,8 @@ namespace C4B\FreeProduct\Plugin\SalesRule\Model; use C4B\FreeProduct\SalesRule\Action\GiftAction; +use C4B\FreeProduct\SalesRule\Action\ForeachGiftAction; + use \Magento\SalesRule\Model\Rule\Metadata\ValueProvider as Source; /** @@ -28,6 +30,9 @@ public function afterGetMetadataValues(Source $subject, $resultMetadataValues) $resultMetadataValues['actions']['children']['simple_action']['arguments']['data']['config']['options'][] = [ 'label' => __('Add a Gift'), 'value' => GiftAction::ACTION ]; + $resultMetadataValues['actions']['children']['simple_action']['arguments']['data']['config']['options'][] = [ + 'label' => __('Add a Gift (For each cart item)'), 'value' => ForeachGiftAction::ACTION + ]; return $resultMetadataValues; } diff --git a/README.md b/README.md index 6b755c0..60e8c7d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The development and the function of the original Magento1 extension is described Requirements ------- -- PHP >= 7.0.0 +- PHP >= 7.1 - Magento >= 2.2 Supported Product Types @@ -35,8 +35,13 @@ Configuration ------- Sales rules for carts are configured in _Marketing->Cart Price Rules_: - In the Actions tab, the Apply field should be set to Add a Gift -- Gift SKU: Product that will be added. Only simple and virtual products without (required) custom options are supported -- Discount Amount: The qty of added gifts +- Gift SKU: Product that will be added. Only simple and virtual products without (required) custom options are supported. Multiple comma-separated SKUs can be specified +- Discount Amount: The qty of added gifts +- The gift item is added once for the whole cart + +Action **Add a Gift (for each cart item)** works similarly but will add the gift item for each product in cart. The qty of said product is also taken into consideration. + +This action usually needs conditions to match only specific items *(Apply the rule only to cart items matching the following conditions)*. Limitations: ------- diff --git a/SalesRule/Action/ForeachGiftAction.php b/SalesRule/Action/ForeachGiftAction.php new file mode 100644 index 0000000..3817734 --- /dev/null +++ b/SalesRule/Action/ForeachGiftAction.php @@ -0,0 +1,117 @@ + + * @copyright code4business Software GmbH + * @license http://opensource.org/licenses/osl-3.0.php + */ +class ForeachGiftAction extends GiftAction +{ + const ACTION = 'add_gift_foreach'; + /** + * @var ResetGiftItems + */ + private $resetGiftItems; + /** + * @var LoggerInterface + */ + private $logger; + + + /** + * @param Discount\DataFactory $discountDataFactory + * @param ProductRepositoryInterface $productRepository + * @param ResetGiftItems $resetGiftItems + * @param LoggerInterface $logger + */ + public function __construct(Discount\DataFactory $discountDataFactory, + ProductRepositoryInterface $productRepository, + ResetGiftItems $resetGiftItems, + LoggerInterface $logger) + { + parent::__construct($discountDataFactory, $productRepository, $logger); + $this->resetGiftItems = $resetGiftItems; + $this->logger = $logger; + } + + /** + * @param \Magento\SalesRule\Model\Rule $rule + * @param AbstractItem $item + * @param float $qty + * @return Discount\Data + */ + public function calculate($rule, $item, $qty) + { + $appliedRuleIds = $item->getData(static::APPLIED_FREEPRODUCT_RULE_IDS); + + if ($item->getAddress()->getAddressType() != Address::TYPE_SHIPPING + || ($appliedRuleIds != null && isset($appliedRuleIds[$rule->getId()]))) + { + return $this->getDiscountData($item); + } + + $skus = explode(',', $rule->getData(static::RULE_DATA_KEY_SKU)); + $isRuleAdded = false; + + foreach ($skus as $sku) + { + try + { + $quoteItem = $item->getQuote()->addProduct($this->getGiftProduct($sku), $rule->getDiscountAmount() * $qty); + $item->getQuote()->setItemsCount($item->getQuote()->getItemsCount() + 1); + $item->getQuote()->setItemsQty((float)$item->getQuote()->getItemsQty() + $quoteItem->getQty()); + $this->resetGiftItems->reportGiftItemAdded(); + + if (is_string($quoteItem)) + { + throw new \Exception($quoteItem); + } + + $isRuleAdded = true; + } catch (\Exception $e) + { + $this->logger->error( + sprintf('Exception occurred while adding gift product %s to cart. Rule: %d, Exception: %s', implode(',', $skus), $rule->getId(), $e->getMessage()), + [__METHOD__] + ); + } + } + if ($isRuleAdded) + { + $this->addAppliedRuleIdToItem($rule->getRuleId(), $item); + } + + return $this->getDiscountData($item); + } + + /** + * @param int $ruleId + * @param AbstractItem $quoteItem + */ + protected function addAppliedRuleIdToItem(int $ruleId, AbstractItem $quoteItem) + { + $appliedRules = $quoteItem->getData(static::APPLIED_FREEPRODUCT_RULE_IDS); + + if ($appliedRules == null) + { + $appliedRules = []; + } + + $appliedRules[$ruleId] = $ruleId; + + $quoteItem->setData(static::APPLIED_FREEPRODUCT_RULE_IDS, $appliedRules); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index c70badd..57cca86 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "phpunit/phpunit": "~6.2.0" }, "type": "magento2-module", - "version": "1.1.0", + "version": "1.2.0", "license": [ "OSL-3.0" ], diff --git a/etc/di.xml b/etc/di.xml index 882ecc5..883a6b2 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -4,6 +4,7 @@ C4B\FreeProduct\SalesRule\Action\GiftAction + C4B\FreeProduct\SalesRule\Action\ForeachGiftAction diff --git a/i18n/en_US.csv b/i18n/en_US.csv index bfb21a6..1368abc 100644 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -1,3 +1,4 @@ "Add a Gift","Add a Gift" +"Add a Gift (For each cart item)","Add a Gift (For each cart item)" "Gift SKU","Gift SKU" -"Only simple and virtual types are supported.","Only simple and virtual types are supported." \ No newline at end of file +"Only simple and virtual types are supported.","Only simple and virtual types are supported." diff --git a/i18n/sl_SI.csv b/i18n/sl_SI.csv index 30c2623..821663d 100644 --- a/i18n/sl_SI.csv +++ b/i18n/sl_SI.csv @@ -1,3 +1,4 @@ "Add a Gift","Dodaj darilo" +"Add a Gift (For each cart item)","Dodaj darilo (Za vsak artikel v košarici)" "Gift SKU","SKU darila" -"Only simple and virtual types are supported.","Podprta sta samo enostavni in virtualni tip artikla." \ No newline at end of file +"Only simple and virtual types are supported.","Podprta sta samo enostavni in virtualni tip artikla." From d12abee0b5d1ae3ddaefb22db98c0c063ce46437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 11:40:13 +0100 Subject: [PATCH 4/6] Correct class name case. --- Observer/ResetGiftItems.php | 2 +- etc/adminhtml/di.xml | 2 +- etc/events.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Observer/ResetGiftItems.php b/Observer/ResetGiftItems.php index b80e1c7..f28cb2b 100644 --- a/Observer/ResetGiftItems.php +++ b/Observer/ResetGiftItems.php @@ -2,7 +2,7 @@ namespace C4B\FreeProduct\Observer; -use C4B\Freeproduct\SalesRule\Action\ForeachGiftAction; +use C4B\FreeProduct\SalesRule\Action\ForeachGiftAction; use C4B\FreeProduct\SalesRule\Action\GiftAction; use Magento\Framework\Event\Observer; diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index d6726f3..2104586 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/etc/events.xml b/etc/events.xml index b205c76..6311900 100644 --- a/etc/events.xml +++ b/etc/events.xml @@ -1,11 +1,11 @@ - + - + From 51a35068dfd21b0dba48480a20ab116a8d492bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 11:41:48 +0100 Subject: [PATCH 5/6] Don't reset quote items, only collection. --- Observer/RemoveGiftItems.php | 2 +- Observer/ResetGiftItems.php | 11 +++++++-- SalesRule/Action/ForeachGiftAction.php | 4 ++-- SalesRule/Action/GiftAction.php | 32 +++++++++++++------------- composer.json | 2 +- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Observer/RemoveGiftItems.php b/Observer/RemoveGiftItems.php index 053a90b..cebb9ae 100644 --- a/Observer/RemoveGiftItems.php +++ b/Observer/RemoveGiftItems.php @@ -34,7 +34,7 @@ public function __construct(CheckoutSession $checkoutSession) /** * Delete all gift items. They will be re-added by SalesRule (If possible). * - * @event sales_quote_address_collect_totals_before + * @event sales_quote_remove_item * @param Observer $observer * @return void */ diff --git a/Observer/ResetGiftItems.php b/Observer/ResetGiftItems.php index f28cb2b..e682ab3 100644 --- a/Observer/ResetGiftItems.php +++ b/Observer/ResetGiftItems.php @@ -17,6 +17,13 @@ * - quote collect before: for normal quote operations (adding items, changing qty, removing item) * - address collect before: When shipping is estimated the above event is not triggered. * + * There is some weird handling of quote items. There are two ways to get them: getItems() and getItemsCollection() + * New quote items are added into the collection, but not into getItems. This is apparently how it should be because + * otherwise newly added quote items are added again since they don't have an item_id yet and in case of bundle items this would fail. + * So quote->setItems should not be used here: + * @see \Magento\Quote\Model\QuoteRepository\SaveHandler::save + * @see \Magento\Quote\Model\Quote\Item\CartItemPersister::save + * * @package C4B_FreeProduct * @author Dominik Meglič * @copyright code4business Software GmbH @@ -57,14 +64,14 @@ public function execute(Observer $observer) $address = $quote->getShippingAddress(); } - $quote->setItems($this->removeOldGiftQuoteItems($quote->getItemsCollection())); + $realQuoteItems = $this->removeOldGiftQuoteItems($quote->getItemsCollection()); $this->areGiftItemsReset = true; $address->unsetData(GiftAction::APPLIED_FREEPRODUCT_RULE_IDS); $address->unsetData('cached_items_all'); if ($shippingAssignment instanceof ShippingAssignmentInterface) { - $shippingAssignment->setItems($quote->getItems()); + $shippingAssignment->setItems($realQuoteItems); $this->updateExtensionAttributes($quote, $shippingAssignment); } } diff --git a/SalesRule/Action/ForeachGiftAction.php b/SalesRule/Action/ForeachGiftAction.php index 3817734..190aca5 100644 --- a/SalesRule/Action/ForeachGiftAction.php +++ b/SalesRule/Action/ForeachGiftAction.php @@ -42,7 +42,7 @@ public function __construct(Discount\DataFactory $discountDataFactory, ResetGiftItems $resetGiftItems, LoggerInterface $logger) { - parent::__construct($discountDataFactory, $productRepository, $logger); + parent::__construct($discountDataFactory, $productRepository, $resetGiftItems, $logger); $this->resetGiftItems = $resetGiftItems; $this->logger = $logger; } @@ -87,8 +87,8 @@ public function calculate($rule, $item, $qty) sprintf('Exception occurred while adding gift product %s to cart. Rule: %d, Exception: %s', implode(',', $skus), $rule->getId(), $e->getMessage()), [__METHOD__] ); - } } + } if ($isRuleAdded) { $this->addAppliedRuleIdToItem($rule->getRuleId(), $item); diff --git a/SalesRule/Action/GiftAction.php b/SalesRule/Action/GiftAction.php index 0bff474..bd3038c 100644 --- a/SalesRule/Action/GiftAction.php +++ b/SalesRule/Action/GiftAction.php @@ -88,26 +88,26 @@ public function calculate($rule, $item, $qty) foreach ($skus as $sku) { - try - { - $quoteItem = $item->getQuote()->addProduct($this->getGiftProduct($sku), $rule->getDiscountAmount()); - $item->getQuote()->setItemsCount($item->getQuote()->getItemsCount() + 1); - $item->getQuote()->setItemsQty((float)$item->getQuote()->getItemsQty() + $quoteItem->getQty()); - $this->resetGiftItems->reportGiftItemAdded(); - - if (is_string($quoteItem)) + try { - throw new \Exception($quoteItem); - } + $quoteItem = $item->getQuote()->addProduct($this->getGiftProduct($sku), $rule->getDiscountAmount()); + $item->getQuote()->setItemsCount($item->getQuote()->getItemsCount() + 1); + $item->getQuote()->setItemsQty((float)$item->getQuote()->getItemsQty() + $quoteItem->getQty()); + $this->resetGiftItems->reportGiftItemAdded(); + + if (is_string($quoteItem)) + { + throw new \Exception($quoteItem); + } $isRuleAdded = true; - } catch (\Exception $e) - { - $this->logger->error( + } catch (\Exception $e) + { + $this->logger->error( sprintf('Exception occurred while adding gift product %s to cart. Rule: %d, Exception: %s', implode(',', $skus), $rule->getId(), $e->getMessage()), - [__METHOD__] - ); - } + [__METHOD__] + ); + } } if ($isRuleAdded) diff --git a/composer.json b/composer.json index 57cca86..3b5407f 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "https://github.com/code4business/freeproduct2", "require": { "magento/module-sales-rule": ">=100.0.0", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "tddwizard/magento2-fixtures": "^0.1.0", From 04f46a1556ffc507e55f1523df89b3a4c5e35cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Megli=C4=8D?= Date: Thu, 31 Jan 2019 16:08:26 +0100 Subject: [PATCH 6/6] Only work on shipping address. --- Observer/ResetGiftItems.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Observer/ResetGiftItems.php b/Observer/ResetGiftItems.php index e682ab3..389026f 100644 --- a/Observer/ResetGiftItems.php +++ b/Observer/ResetGiftItems.php @@ -57,7 +57,13 @@ public function execute(Observer $observer) if ($shippingAssignment instanceof ShippingAssignmentInterface) { + /** @var Quote\Address $address */ $address = $shippingAssignment->getShipping()->getAddress(); + + if ($address->getAddressType() != Quote\Address::ADDRESS_TYPE_SHIPPING) + { + return; + } } else {