= /* @escapeNotVerified */ __('Ordered') ?> | @@ -116,7 +125,7 @@- canShowPriceInfo($_item)): ?> + canShowPriceInfo($_item) || $shipTogether): ?> canEditQty()) : ?> getItem(); +$items = array_merge([$parentItem], $parentItem->getChildrenItems()); +$index = 0; +$prevOptionId = ''; ?> -getItem() ?> -getChildrenItems()); ?> - - + - - - getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?> - + getItemOptions() + || $parentItem->getDescription() + || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) + && $parentItem->getGiftMessageId()): ?> + - + - getParentItem()): ?> - getSelectionAttributes($_item) ?> - + getParentItem()): ?> + getSelectionAttributes($item) ?> + | ||||||||
---|---|---|---|---|---|---|---|---|---|
= /* @escapeNotVerified */ $attributes['option_label'] ?> | += $block->escapeHtml($attributes['option_label']); ?> | ||||||||
- = $block->escapeHtml($_item->getName()) ?> + | |||||||||
+ = $block->escapeHtml($item->getName()); ?> | -= $block->getValueHtml($_item) ?> | ++ = $block->getValueHtml($item); ?> + | -= /* @escapeNotVerified */ $block->prepareSku($_item->getSku()) ?> | -- getParentItem()): ?> - = $block->getItemPriceHtml() ?> + | + = /* @noEscape */ $block->prepareSku($item->getSku()); ?> + | ++ getParentItem()): ?> + = /* @noEscape */ $block->getItemPriceHtml(); ?> | -+ |
getParentItem() && $block->isChildCalculated()) ||
- (!$_item->getParentItem() && !$block->isChildCalculated()) || ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $block->isShipmentSeparately())):?>
+ ($item->getParentItem() && $block->isChildCalculated()) ||
+ (!$item->getParentItem() && !$block->isChildCalculated()) ||
+ ($item->getQtyShipped() > 0 && $item->getParentItem() && $block->isShipmentSeparately())): ?>
|
- getParentItem()): ?> - = $block->getItemRowTotalHtml() ?> + getParentItem()): ?> + = /* @noEscape */ $block->getItemRowTotalHtml(); ?> @@ -103,33 +119,38 @@ |
- getItemOptions()): ?> + getItemOptions()): ?> | - = $block->escapeHtml($_item->getDescription()) ?> + = $block->escapeHtml($item->getDescription()); ?>
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html b/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html index bc7c079d7f21b..b7411d80d2ba6 100644 --- a/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html @@ -10,7 +10,7 @@ "var creditmemo.increment_id":"Credit Memo Id", "var billing.getName()":"Guest Customer Name", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_update.html b/app/code/Magento/Sales/view/frontend/email/invoice_update.html index cafdd65ff5208..4043e59f9d7d6 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_update.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_update.html @@ -11,7 +11,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html b/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html index fafb533301efb..40cdec7fb4cab 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html @@ -10,7 +10,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/order_update.html b/app/code/Magento/Sales/view/frontend/email/order_update.html index a709a9ed8a7f1..a8f0068b70e87 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_update.html +++ b/app/code/Magento/Sales/view/frontend/email/order_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/order_update_guest.html b/app/code/Magento/Sales/view/frontend/email/order_update_guest.html index 5a39b01810c18..749fa3b60ad59 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/order_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -22,7 +22,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_update.html b/app/code/Magento/Sales/view/frontend/email/shipment_update.html index 6d9efc37004bc..9d1c93287549a 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_update.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html b/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html index 4896a00b7bc5a..0d2dccd3377d2 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml index 1c02a5c31ea6b..b9a032212352b 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Sales\Block\Order\History $block */ + ?> getOrders(); ?> = $block->getChildHtml('info') ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 9b3633fde60b4..a2ab3d02b13ea 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -57,7 +57,7 @@
diff --git a/app/code/Magento/SalesAnalytics/README.md b/app/code/Magento/SalesAnalytics/README.md index 70f456c97d4b3..0b1f804b278fe 100644 --- a/app/code/Magento/SalesAnalytics/README.md +++ b/app/code/Magento/SalesAnalytics/README.md @@ -1,3 +1,3 @@ # Magento_SalesAnalytics module -The Magento_SalesAnalytics module configures data definitions for a data collection related to the Sales module entities to be used in [Advanced Reporting](http://devdocs.magento.com/guides/v2.2/advanced-reporting/modules.html). +The Magento_SalesAnalytics module configures data definitions for a data collection related to the Sales module entities to be used in [Advanced Reporting](https://devdocs.magento.com/guides/v2.2/advanced-reporting/modules.html). diff --git a/app/code/Magento/SalesRule/Api/CouponRepositoryInterface.php b/app/code/Magento/SalesRule/Api/CouponRepositoryInterface.php index d4cce37fd15fd..1a631886f1a9b 100644 --- a/app/code/Magento/SalesRule/Api/CouponRepositoryInterface.php +++ b/app/code/Magento/SalesRule/Api/CouponRepositoryInterface.php @@ -38,7 +38,7 @@ public function getById($couponId); * Retrieve a coupon using the specified search criteria. * * This call returns an array of objects, but detailed information about each object’s attributes might not be - * included. See http://devdocs.magento.com/codelinks/attributes.html#CouponRepositoryInterface to + * included. See https://devdocs.magento.com/codelinks/attributes.html#CouponRepositoryInterface to * determine which call to use to get detailed information about all attributes for an object. * * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria diff --git a/app/code/Magento/SalesRule/Api/RuleRepositoryInterface.php b/app/code/Magento/SalesRule/Api/RuleRepositoryInterface.php index d0d275de63a00..963edf5483e43 100644 --- a/app/code/Magento/SalesRule/Api/RuleRepositoryInterface.php +++ b/app/code/Magento/SalesRule/Api/RuleRepositoryInterface.php @@ -38,7 +38,7 @@ public function getById($ruleId); * Retrieve sales rules that match te specified criteria. * * This call returns an array of objects, but detailed information about each object’s attributes might not be - * included. See http://devdocs.magento.com/codelinks/attributes.html#RuleRepositoryInterface to + * included. See https://devdocs.magento.com/codelinks/attributes.html#RuleRepositoryInterface to * determine which call to use to get detailed information about all attributes for an object. * * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php index da05fd98e609b..cfafe110df22b 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php @@ -7,9 +7,13 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\SalesRule\Model\CouponGenerator; +use Magento\Framework\MessageQueue\PublisherInterface; +use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory; /** * Generate promo quote + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpPostActionInterface { @@ -18,6 +22,16 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote imple */ private $couponGenerator; + /** + * @var PublisherInterface + */ + private $messagePublisher; + + /** + * @var CouponGenerationSpecInterfaceFactory + */ + private $generationSpecFactory; + /** * Generate constructor. * @param \Magento\Backend\App\Action\Context $context @@ -25,17 +39,27 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote imple * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter * @param CouponGenerator|null $couponGenerator + * @param PublisherInterface|null $publisher + * @param CouponGenerationSpecInterfaceFactory|null $generationSpecFactory */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter, - CouponGenerator $couponGenerator = null + CouponGenerator $couponGenerator = null, + PublisherInterface $publisher = null, + CouponGenerationSpecInterfaceFactory $generationSpecFactory = null ) { parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter); $this->couponGenerator = $couponGenerator ?: $this->_objectManager->get(CouponGenerator::class); + $this->messagePublisher = $publisher ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(PublisherInterface::class); + $this->generationSpecFactory = $generationSpecFactory ?: + \Magento\Framework\App\ObjectManager::getInstance()->get( + CouponGenerationSpecInterfaceFactory::class + ); } /** @@ -64,9 +88,14 @@ public function execute() $data = $inputFilter->getUnescaped(); } - $couponCodes = $this->couponGenerator->generateCodes($data); - $generated = count($couponCodes); - $this->messageManager->addSuccessMessage(__('%1 coupon(s) have been generated.', $generated)); + $data['quantity'] = isset($data['qty']) ? $data['qty'] : null; + + $couponSpec = $this->generationSpecFactory->create(['data' => $data]); + + $this->messagePublisher->publish('sales_rule.codegenerator', $couponSpec); + $this->messageManager->addSuccessMessage( + __('Message is added to queue, wait to get your coupons soon') + ); $this->_view->getLayout()->initMessages(); $result['messages'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml(); } catch (\Magento\Framework\Exception\InputException $inputException) { diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php index 388679e6d9eff..7d55d18b770e2 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php @@ -7,6 +7,7 @@ namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** @@ -20,6 +21,11 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implement * @var TimezoneInterface */ private $timezone; + + /** + * @var DataPersistorInterface + */ + private $dataPersistor; /** * @param \Magento\Backend\App\Action\Context $context @@ -27,18 +33,23 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implement * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter * @param TimezoneInterface $timezone + * @param DataPersistorInterface $dataPersistor */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter, - TimezoneInterface $timezone = null + TimezoneInterface $timezone = null, + DataPersistorInterface $dataPersistor = null ) { parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter); $this->timezone = $timezone ?? \Magento\Framework\App\ObjectManager::getInstance()->get( TimezoneInterface::class ); + $this->dataPersistor = $dataPersistor ?? \Magento\Framework\App\ObjectManager::getInstance()->get( + DataPersistorInterface::class + ); } /** @@ -73,12 +84,8 @@ public function execute() $data ); $data = $inputFilter->getUnescaped(); - $id = $this->getRequest()->getParam('rule_id'); - if ($id) { - $model->load($id); - if ($id != $model->getId()) { - throw new \Magento\Framework\Exception\LocalizedException(__('The wrong rule is specified.')); - } + if (!$this->checkRuleExists($model)) { + throw new \Magento\Framework\Exception\LocalizedException(__('The wrong rule is specified.')); } $session = $this->_objectManager->get(\Magento\Backend\Model\Session::class); @@ -89,6 +96,7 @@ public function execute() $this->messageManager->addErrorMessage($errorMessage); } $session->setPageData($data); + $this->dataPersistor->set('sale_rule', $data); $this->_redirect('sales_rule/*/edit', ['id' => $model->getId()]); return; } @@ -147,4 +155,22 @@ public function execute() } $this->_redirect('sales_rule/*/'); } + + /** + * Check if Cart Price Rule with provided id exists. + * + * @param \Magento\SalesRule\Model\Rule $model + * @return bool + */ + private function checkRuleExists(\Magento\SalesRule\Model\Rule $model): bool + { + $id = $this->getRequest()->getParam('rule_id'); + if ($id) { + $model->load($id); + if ($model->getId() != $id) { + return false; + } + } + return true; + } } diff --git a/app/code/Magento/SalesRule/Model/Coupon/Consumer.php b/app/code/Magento/SalesRule/Model/Coupon/Consumer.php new file mode 100644 index 0000000000000..2354c72a3e293 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/Coupon/Consumer.php @@ -0,0 +1,85 @@ +logger = $logger; + $this->couponManager = $couponManager; + $this->filesystem = $filesystem; + $this->notifier = $notifier; + } + + /** + * Consumer logic. + * + * @param CouponGenerationSpecInterface $exportInfo + * @return void + */ + public function process(CouponGenerationSpecInterface $exportInfo) + { + try { + $this->couponManager->generate($exportInfo); + + $this->notifier->addMajor( + __('Your coupons are ready'), + __('You can check your coupons at sales rule page') + ); + } catch (LocalizedException $exception) { + $this->notifier->addCritical( + __('Error during coupons generator process occurred'), + __('Error during coupons generator process occurred. Please check logs for detail') + ); + $this->logger->critical( + 'Something went wrong while coupons generator process. ' . $exception->getMessage() + ); + } + } +} diff --git a/app/code/Magento/SalesRule/Model/Quote/Address/Total/ShippingDiscount.php b/app/code/Magento/SalesRule/Model/Quote/Address/Total/ShippingDiscount.php new file mode 100644 index 0000000000000..c37ca276e0ee2 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/Quote/Address/Total/ShippingDiscount.php @@ -0,0 +1,101 @@ +calculator = $calculator; + } + + /** + * @inheritdoc + * + * @param Quote $quote + * @param ShippingAssignment $shippingAssignment + * @param Total $total + * @return ShippingDiscount + */ + public function collect(Quote $quote, ShippingAssignment $shippingAssignment, Total $total): self + { + parent::collect($quote, $shippingAssignment, $total); + + $address = $shippingAssignment->getShipping()->getAddress(); + $this->calculator->reset($address); + + $items = $shippingAssignment->getItems(); + if (!count($items)) { + return $this; + } + + $address->setShippingDiscountAmount(0); + $address->setBaseShippingDiscountAmount(0); + if ($address->getShippingAmount()) { + $this->calculator->processShippingAmount($address); + $total->addTotalAmount(DiscountCollector::COLLECTOR_TYPE_CODE, -$address->getShippingDiscountAmount()); + $total->addBaseTotalAmount( + DiscountCollector::COLLECTOR_TYPE_CODE, + -$address->getBaseShippingDiscountAmount() + ); + $total->setShippingDiscountAmount($address->getShippingDiscountAmount()); + $total->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount()); + + $this->calculator->prepareDescription($address); + $total->setDiscountDescription($address->getDiscountDescription()); + $total->setSubtotalWithDiscount($total->getSubtotal() + $total->getDiscountAmount()); + $total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $total->getBaseDiscountAmount()); + + $address->setDiscountAmount($total->getDiscountAmount()); + $address->setBaseDiscountAmount($total->getBaseDiscountAmount()); + } + + return $this; + } + + /** + * @inheritdoc + * + * @param \Magento\Quote\Model\Quote $quote + * @param \Magento\Quote\Model\Quote\Address\Total $total + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function fetch(Quote $quote, Total $total): array + { + $result = []; + $amount = $total->getDiscountAmount(); + + if ($amount != 0) { + $description = $total->getDiscountDescription() ?: ''; + $result = [ + 'code' => DiscountCollector::COLLECTOR_TYPE_CODE, + 'title' => strlen($description) ? __('Discount (%1)', $description) : __('Discount'), + 'value' => $amount + ]; + } + return $result; + } +} diff --git a/app/code/Magento/SalesRule/Model/Quote/Discount.php b/app/code/Magento/SalesRule/Model/Quote/Discount.php index 693a61b272f66..315ce874513a3 100644 --- a/app/code/Magento/SalesRule/Model/Quote/Discount.php +++ b/app/code/Magento/SalesRule/Model/Quote/Discount.php @@ -5,8 +5,13 @@ */ namespace Magento\SalesRule\Model\Quote; +/** + * Discount totals calculation model. + */ class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal { + const COLLECTOR_TYPE_CODE = 'discount'; + /** * Discount calculation object * @@ -43,7 +48,7 @@ public function __construct( \Magento\SalesRule\Model\Validator $validator, \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency ) { - $this->setCode('discount'); + $this->setCode(self::COLLECTOR_TYPE_CODE); $this->eventManager = $eventManager; $this->calculator = $validator; $this->storeManager = $storeManager; @@ -124,21 +129,14 @@ public function collect( } } - /** Process shipping amount discount */ - $address->setShippingDiscountAmount(0); - $address->setBaseShippingDiscountAmount(0); - if ($address->getShippingAmount()) { - $this->calculator->processShippingAmount($address); - $total->addTotalAmount($this->getCode(), -$address->getShippingDiscountAmount()); - $total->addBaseTotalAmount($this->getCode(), -$address->getBaseShippingDiscountAmount()); - $total->setShippingDiscountAmount($address->getShippingDiscountAmount()); - $total->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount()); - } - $this->calculator->prepareDescription($address); $total->setDiscountDescription($address->getDiscountDescription()); $total->setSubtotalWithDiscount($total->getSubtotal() + $total->getDiscountAmount()); $total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $total->getBaseDiscountAmount()); + + $address->setDiscountAmount($total->getDiscountAmount()); + $address->setBaseDiscountAmount($total->getBaseDiscountAmount()); + return $this; } diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 59f24fa8b6e03..5e6f3847c8e31 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -80,6 +80,8 @@ protected function _construct() } /** + * Map data for associated entities + * * @param string $entityType * @param string $objectField * @throws \Magento\Framework\Exception\LocalizedException @@ -114,6 +116,8 @@ protected function mapAssociatedEntities($entityType, $objectField) } /** + * Add website ids and customer group ids to rules data + * * @return $this * @throws \Exception * @since 100.1.0 @@ -158,60 +162,15 @@ public function setValidationFilter( $connection = $this->getConnection(); if (strlen($couponCode)) { - $select->joinLeft( - ['rule_coupons' => $this->getTable('salesrule_coupon')], - $connection->quoteInto( - 'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON - ), - ['code'] - ); - $noCouponWhereCondition = $connection->quoteInto( - 'main_table.coupon_type = ? ', + 'main_table.coupon_type = ?', \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON ); - - $autoGeneratedCouponCondition = [ - $connection->quoteInto( - "main_table.coupon_type = ?", - \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO - ), - $connection->quoteInto( - "rule_coupons.type = ?", - \Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED - ), - ]; - - $orWhereConditions = [ - "(" . implode($autoGeneratedCouponCondition, " AND ") . ")", - $connection->quoteInto( - '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC - ), - $connection->quoteInto( - '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC - ), - ]; - - $andWhereConditions = [ - $connection->quoteInto( - 'rule_coupons.code = ?', - $couponCode - ), - $connection->quoteInto( - '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)', - $this->_date->date()->format('Y-m-d') - ), - ]; - - $orWhereCondition = implode(' OR ', $orWhereConditions); - $andWhereCondition = implode(' AND ', $andWhereConditions); + $relatedRulesIds = $this->getCouponRelatedRuleIds($couponCode); $select->where( - $noCouponWhereCondition . ' OR ((' . $orWhereCondition . ') AND ' . $andWhereCondition . ')', - null, + $noCouponWhereCondition . ' OR main_table.rule_id IN (?)', + $relatedRulesIds, Select::TYPE_CONDITION ); } else { @@ -227,6 +186,75 @@ public function setValidationFilter( return $this; } + /** + * Get rules ids related to coupon code + * + * @param string $couponCode + * @return array + */ + private function getCouponRelatedRuleIds(string $couponCode): array + { + $connection = $this->getConnection(); + $select = $connection->select()->from( + ['main_table' => $this->getTable('salesrule')], + 'rule_id' + ); + $select->joinLeft( + ['rule_coupons' => $this->getTable('salesrule_coupon')], + $connection->quoteInto( + 'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?', + \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON, + null + ) + ); + + $autoGeneratedCouponCondition = [ + $connection->quoteInto( + "main_table.coupon_type = ?", + \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO + ), + $connection->quoteInto( + "rule_coupons.type = ?", + \Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED + ), + ]; + + $orWhereConditions = [ + "(" . implode($autoGeneratedCouponCondition, " AND ") . ")", + $connection->quoteInto( + '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)', + \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC + ), + $connection->quoteInto( + '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)', + \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC + ), + ]; + + $andWhereConditions = [ + $connection->quoteInto( + 'rule_coupons.code = ?', + $couponCode + ), + $connection->quoteInto( + '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)', + $this->_date->date()->format('Y-m-d') + ), + ]; + + $orWhereCondition = implode(' OR ', $orWhereConditions); + $andWhereCondition = implode(' AND ', $andWhereConditions); + + $select->where( + '(' . $orWhereCondition . ') AND ' . $andWhereCondition, + null, + Select::TYPE_CONDITION + ); + $select->group('main_table.rule_id'); + + return $connection->fetchCol($select); + } + /** * Filter collection by website(s), customer group(s) and date. * Filter collection to only active rules. @@ -366,6 +394,8 @@ public function addCustomerGroupFilter($customerGroupId) } /** + * Getter for _associatedEntitiesMap property + * * @return array * @deprecated 100.1.0 */ @@ -380,6 +410,8 @@ private function getAssociatedEntitiesMap() } /** + * Getter for dateApplier property + * * @return DateApplier * @deprecated 100.1.0 */ diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php index fd5953697c7db..89ec2b84572fc 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php @@ -5,6 +5,9 @@ */ namespace Magento\SalesRule\Model\Rule\Condition; +/** + * Address rule condition data model. + */ class Address extends \Magento\Rule\Model\Condition\AbstractCondition { /** @@ -61,6 +64,7 @@ public function loadAttributeOptions() 'base_subtotal' => __('Subtotal'), 'total_qty' => __('Total Items Quantity'), 'weight' => __('Total Weight'), + 'payment_method' => __('Payment Method'), 'shipping_method' => __('Shipping Method'), 'postcode' => __('Shipping Postcode'), 'region' => __('Shipping Region'), diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php index 9bda4793e8681..ff83bb1ee9129 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php @@ -35,12 +35,13 @@ protected function _addSpecialAttributes(array &$attributes) * * @return string */ - public function getAttribute() + public function getAttribute(): string { $attribute = $this->getData('attribute'); if (strpos($attribute, '::') !== false) { - list (, $attribute) = explode('::', $attribute); + list(, $attribute) = explode('::', $attribute); } + return $attribute; } @@ -53,6 +54,7 @@ public function getAttributeName() if ($this->getAttributeScope()) { $attribute = $this->getAttributeScope() . '::' . $attribute; } + return $this->getAttributeOption($attribute); } @@ -92,6 +94,7 @@ public function getAttributeElementHtml() { $html = parent::getAttributeElementHtml() . $this->getAttributeScopeElement()->getHtml(); + return $html; } @@ -100,7 +103,7 @@ public function getAttributeElementHtml() * * @return \Magento\Framework\Data\Form\Element\AbstractElement */ - private function getAttributeScopeElement() + private function getAttributeScopeElement(): \Magento\Framework\Data\Form\Element\AbstractElement { return $this->getForm()->addField( $this->getPrefix() . '__' . $this->getId() . '__attribute_scope', @@ -110,7 +113,7 @@ private function getAttributeScopeElement() 'value' => $this->getAttributeScope(), 'no_span' => true, 'class' => 'hidden', - 'data-form-part' => $this->getFormName() + 'data-form-part' => $this->getFormName(), ] ); } @@ -119,8 +122,9 @@ private function getAttributeScopeElement() * Set attribute value * * @param string $value + * @return void */ - public function setAttribute($value) + public function setAttribute(string $value) { if (strpos($value, '::') !== false) { list($scope, $attribute) = explode('::', $value); @@ -137,7 +141,8 @@ public function setAttribute($value) public function loadArray($arr) { parent::loadArray($arr); - $this->setAttributeScope(isset($arr['attribute_scope']) ? $arr['attribute_scope'] : null); + $this->setAttributeScope($arr['attribute_scope'] ?? null); + return $this; } @@ -148,6 +153,7 @@ public function asArray(array $arrAttributes = []) { $out = parent::asArray($arrAttributes); $out['attribute_scope'] = $this->getAttributeScope(); + return $out; } @@ -155,7 +161,9 @@ public function asArray(array $arrAttributes = []) * Validate Product Rule Condition * * @param \Magento\Framework\Model\AbstractModel $model + * * @return bool + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function validate(\Magento\Framework\Model\AbstractModel $model) { diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php index 1e8fbf43ec3bc..5b02d3c080938 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php @@ -5,6 +5,9 @@ */ namespace Magento\SalesRule\Model\Rule\Condition\Product; +/** + * Subselect conditions for product. + */ class Subselect extends \Magento\SalesRule\Model\Rule\Condition\Product\Combine { /** @@ -161,7 +164,9 @@ public function validate(\Magento\Framework\Model\AbstractModel $model) } } if ($hasValidChild || parent::validate($item)) { - $total += (($hasValidChild && $useChildrenTotal) ? $childrenAttrTotal : $item->getData($attr)); + $total += ($hasValidChild && $useChildrenTotal) + ? $childrenAttrTotal * $item->getQty() + : $item->getData($attr); } } return $this->validateAttribute($total); diff --git a/app/code/Magento/SalesRule/Model/Rule/DataProvider.php b/app/code/Magento/SalesRule/Model/Rule/DataProvider.php index 916825776373d..25f0ef91eae68 100644 --- a/app/code/Magento/SalesRule/Model/Rule/DataProvider.php +++ b/app/code/Magento/SalesRule/Model/Rule/DataProvider.php @@ -5,6 +5,7 @@ */ namespace Magento\SalesRule\Model\Rule; +use Magento\Framework\App\Request\DataPersistorInterface; use Magento\SalesRule\Model\ResourceModel\Rule\Collection; use Magento\SalesRule\Model\ResourceModel\Rule\CollectionFactory; use Magento\SalesRule\Model\Rule; @@ -36,6 +37,11 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider */ protected $metadataValueProvider; + /** + * @var DataPersistorInterface + */ + private $dataPersistor; + /** * Initialize dependencies. * @@ -47,6 +53,7 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider * @param Metadata\ValueProvider $metadataValueProvider * @param array $meta * @param array $data + * @param DataPersistorInterface $dataPersistor */ public function __construct( $name, @@ -56,12 +63,16 @@ public function __construct( \Magento\Framework\Registry $registry, \Magento\SalesRule\Model\Rule\Metadata\ValueProvider $metadataValueProvider, array $meta = [], - array $data = [] + array $data = [], + DataPersistorInterface $dataPersistor = null ) { $this->collection = $collectionFactory->create(); $this->coreRegistry = $registry; $this->metadataValueProvider = $metadataValueProvider; $meta = array_replace_recursive($this->getMetadataValues(), $meta); + $this->dataPersistor = $dataPersistor ?? \Magento\Framework\App\ObjectManager::getInstance()->get( + DataPersistorInterface::class + ); parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data); } @@ -77,7 +88,7 @@ protected function getMetadataValues() } /** - * {@inheritdoc} + * @inheritdoc */ public function getData() { @@ -93,6 +104,13 @@ public function getData() $this->loadedData[$rule->getId()] = $rule->getData(); } + $data = $this->dataPersistor->get('sale_rule'); + if (!empty($data)) { + $rule = $this->collection->getNewEmptyItem(); + $rule->setData($data); + $this->loadedData[$rule->getId()] = $rule->getData(); + $this->dataPersistor->clear('sale_rule'); + } return $this->loadedData; } diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml index a794c67e736fc..e5907e1e9c0f5 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml @@ -16,4 +16,26 @@For additional assistance, see - PHP settings check help .
@@ -392,7 +392,7 @@ @@ -413,7 +413,7 @@
The best way to resolve this is to install the correct missing extensions. The exact fix depends on our server, your host, and other system variables.
- Our PHP extension help can get you started.
+ Our PHP extension help can get you started.
For additional assistance, contact your hosting provider. @@ -477,7 +477,7 @@
@@ -500,7 +500,7 @@ The best way to resolve this is to allow write permissions for files in the following Magento directories and subdirectories. The exact fix depends on your server, your host, and other system variables.