Skip to content

Commit

Permalink
MC-20648: Implement the changes
Browse files Browse the repository at this point in the history
- added plugins for loading quote object with discounts
- added additional metadata to be stored in db
  • Loading branch information
prabhuram93 committed Oct 7, 2019
1 parent 59ff709 commit 6900c38
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 7 deletions.
Expand Up @@ -94,7 +94,8 @@ private function getDiscountValues($cartItem, $currencyCode)
$discount = [];
$amount = [];
/* @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
$discountAmount = $value['discount'];
$discountData = $value['discount'];
$discountAmount = $discountData->getAmount();
/* @var \Magento\SalesRule\Model\Rule $rule */
$rule = $value['rule'];
$discount['label'] = $rule ?: __('Discount');
Expand Down
4 changes: 3 additions & 1 deletion app/code/Magento/QuoteGraphQl/Model/Resolver/Discounts.php
Expand Up @@ -49,7 +49,9 @@ private function getDiscountValues(Quote $quote)
/* @var \Magento\SalesRule\Model\Rule $rule*/
$rule = $value['rule'];
$discount['label'] = $rule ?: __('Discount');
$amount['value'] = $value['discount'];
/* @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
$discountData = $value['discount'];
$amount['value'] = $discountData->getAmount();
$amount['currency'] = $quote->getQuoteCurrencyCode();
$discount['amount'] = $amount;
$discountValues[] = $discount;
Expand Down
101 changes: 101 additions & 0 deletions app/code/Magento/SalesRule/Model/Plugin/Discount.php
@@ -0,0 +1,101 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\SalesRule\Model\Plugin;

use Magento\Framework\Serialize\Serializer\Json;
use Magento\SalesRule\Model\Rule\Action\Discount\DataFactory;
use Magento\Framework\App\ObjectManager;

/**
* Plugin for persisting discounts along with Quote Address
*/
class Discount
{
/**
* @var Json
*/
private $json;

/**
* @var \Magento\SalesRule\Model\Rule\Action\Discount\DataFactory
*/
protected $discountFactory;

/**
* @param Json $json
* @param DataFactory|null $discountDataFactory
*/
public function __construct(Json $json, DataFactory $discountDataFactory = null)
{
$this->json = $json;
$this->discountFactory = $discountDataFactory ?: ObjectManager::getInstance()->get(DataFactory::class);
}

/**
* Plugin for adding item discounts to extension attributes
*
* @param \Magento\Quote\Model\Quote $subject
* @param \Magento\Quote\Model\ResourceModel\Quote\Item\Collection $result
* @return \Magento\Quote\Model\ResourceModel\Quote\Item\Collection
*/
public function afterGetItemsCollection(
\Magento\Quote\Model\Quote $subject,
\Magento\Quote\Model\ResourceModel\Quote\Item\Collection $result
) {
foreach ($result as $item) {
if ($item->getDiscounts() && !$item->getExtensionAttributes()->getDiscounts()) {
$discounts = $this->json->unserialize($item->getDiscounts());
foreach ($discounts as $key => $value) {
$discounts[$key]['discount'] = $this->unserializeDiscountData($value['discount']);
}
$itemExtension = $item->getExtensionAttributes();
$itemExtension->setDiscounts($discounts);
}
}
return $result;
}

/**
* Plugin for adding address level discounts to extension attributes
*
* @param \Magento\Quote\Model\Quote $subject
* @param array $result
* @return array
*/
public function afterGetAllAddresses(
\Magento\Quote\Model\Quote $subject,
array $result
) {
foreach ($result as $address) {
if ($address->getDiscounts() && !$address->getExtensionAttributes()->getDiscounts()) {
$discounts = $this->json->unserialize($address->getDiscounts());
foreach ($discounts as $key => $value) {
$discounts[$key]['discount'] = $this->unserializeDiscountData($value['discount']);
}
$itemExtension = $address->getExtensionAttributes();
$itemExtension->setDiscounts($discounts);
}
}
return $result;
}

/**
* Unserialize discount object
*
* @param string $serializedDiscount
* @return \Magento\SalesRule\Model\Rule\Action\Discount\Data
*/
private function unserializeDiscountData(string $serializedDiscount)
{
$discountArray = $this->json->unserialize($serializedDiscount);
$discountData = $this->discountFactory->create();
$discountData->setBaseOriginalAmount($discountArray['baseOriginalAmount']);
$discountData->setOriginalAmount($discountArray['originalAmount']);
$discountData->setAmount($discountArray['amount']);
$discountData->setBaseAmount($discountArray['baseAmount']);
return $discountData;
}
}
10 changes: 10 additions & 0 deletions app/code/Magento/SalesRule/Model/Plugin/ResourceModel/Discount.php
Expand Up @@ -39,6 +39,16 @@ public function beforeSave(
foreach ($object->getAllAddresses() as $address) {
$discounts = $address->getExtensionAttributes()->getDiscounts();
if ($discounts) {
foreach ($discounts as $key => $value) {
$discount = $value['discount'];
$discountData = [
"amount" => $discount->getAmount(),
"baseAmount" => $discount->getBaseAmount(),
"originalAmount" => $discount->getOriginalAmount(),
"baseOriginalAmount" => $discount->getBaseOriginalAmount()
];
$discounts[$key]['discount'] = $this->json->serialize($discountData);
}
$address->setDiscounts($this->json->serialize($discounts));
}
}
Expand Down
32 changes: 29 additions & 3 deletions app/code/Magento/SalesRule/Model/Quote/Discount.php
Expand Up @@ -5,6 +5,9 @@
*/
namespace Magento\SalesRule\Model\Quote;

use Magento\SalesRule\Model\Rule\Action\Discount\DataFactory;
use Magento\Framework\App\ObjectManager;

/**
* Discount totals calculation model.
*/
Expand Down Expand Up @@ -37,22 +40,31 @@ class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
protected $priceCurrency;

/**
* @var \Magento\SalesRule\Model\Rule\Action\Discount\DataFactory
*/
private $discountFactory;

/**
* Discount constructor.
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\SalesRule\Model\Validator $validator
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
* @param DataFactory|null $discountDataFactory
*/
public function __construct(
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\SalesRule\Model\Validator $validator,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
DataFactory $discountDataFactory = null
) {
$this->setCode(self::COLLECTOR_TYPE_CODE);
$this->eventManager = $eventManager;
$this->calculator = $validator;
$this->storeManager = $storeManager;
$this->priceCurrency = $priceCurrency;
$this->discountFactory = $discountDataFactory ?: ObjectManager::getInstance()->get(DataFactory::class);
}

/**
Expand Down Expand Up @@ -91,12 +103,14 @@ public function collect(

$address->setDiscountDescription([]);
$items = $this->calculator->sortItemsByPriority($items, $address);
$address->getExtensionAttributes()->setDiscounts([]);

/** @var \Magento\Quote\Model\Quote\Item $item */
foreach ($items as $item) {
if ($item->getNoDiscount() || !$this->calculator->canApplyDiscount($item)) {
$item->setDiscountAmount(0);
$item->setBaseDiscountAmount(0);
$item->getExtensionAttributes()->setDiscounts([]);

// ensure my children are zeroed out
if ($item->getHasChildren() && $item->isChildrenCalculated()) {
Expand Down Expand Up @@ -233,14 +247,26 @@ private function aggregateDiscountPerRule(
$discountBreakdown = $item->getExtensionAttributes()->getDiscounts();
$discountPerRule = $address->getExtensionAttributes()->getDiscounts();
if ($discountBreakdown) {
/** @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
foreach ($discountBreakdown as $key => $value) {
/* @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discount */
$discount = $value['discount'];
$ruleLabel = $value['rule'];
if (isset($discountPerRule[$key])) {
$discountPerRule[$key]['discount'] += $discount;
$discountData = $discountPerRule[$key]['discount'];
$discountData->setBaseAmount($discountData->getBaseAmount()+$discount->getBaseAmount());
$discountData->setAmount($discountData->getAmount()+$discount->getAmount());
$discountData->setOriginalAmount($discountData->getOriginalAmount()+$discount->getOriginalAmount());
$discountData->setBaseOriginalAmount(
$discountData->getBaseOriginalAmount()+$discount->getBaseOriginalAmount()
);
} else {
$discountPerRule[$key]['discount'] = $discount;
$discountData = $this->discountFactory->create();
$discountData->setBaseAmount($discount->getBaseAmount());
$discountData->setAmount($discount->getAmount());
$discountData->setOriginalAmount($discount->getOriginalAmount());
$discountData->setBaseOriginalAmount($discount->getBaseOriginalAmount());
$discountPerRule[$key]['discount'] = $discountData;
}
$discountPerRule[$key]['rule'] = $ruleLabel;
}
Expand Down
15 changes: 14 additions & 1 deletion app/code/Magento/SalesRule/Model/Quote/Item/Plugin/Discount.php
Expand Up @@ -37,7 +37,20 @@ public function __construct(Json $json)
public function beforeSave(CartItemPersister $subject, CartInterface $quote, CartItemInterface $cartItem)
{
$cartExtension = $cartItem->getExtensionAttributes();
$cartItem->setDiscounts($this->json->serialize($cartExtension->getDiscounts()));
$discounts = $cartExtension->getDiscounts();
if ($discounts) {
foreach ($discounts as $key => $value) {
$discount = $value['discount'];
$discountData = [
"amount" => $discount->getAmount(),
"baseAmount" => $discount->getBaseAmount(),
"originalAmount" => $discount->getOriginalAmount(),
"baseOriginalAmount" => $discount->getBaseOriginalAmount(),
];
$discounts[$key]['discount'] = $this->json->serialize($discountData);
}
$cartItem->setDiscounts($this->json->serialize($discounts));
}
return [$quote, $cartItem];
}
}
2 changes: 1 addition & 1 deletion app/code/Magento/SalesRule/Model/RulesApplier.php
Expand Up @@ -211,7 +211,7 @@ private function setDiscountBreakdown($discountData, $item, $rule, $address)
$discount->setBaseAmount($discountData->getBaseAmount());
$discount->setOriginalAmount($discountData->getOriginalAmount());
$discountBreakdown = $item->getExtensionAttributes()->getDiscounts() ?? [];
$discountBreakdown[$rule->getId()]['discount'] = $discountData->getAmount();
$discountBreakdown[$rule->getId()]['discount'] = $discount;
$discountBreakdown[$rule->getId()]['rule'] = $rule->getStoreLabel($address->getQuote()->getStore()) ?: __('Discount');
$item->getExtensionAttributes()->setDiscounts($discountBreakdown);
}
Expand Down
6 changes: 6 additions & 0 deletions app/code/Magento/SalesRule/etc/di.xml
Expand Up @@ -46,6 +46,12 @@
<type name="Magento\Quote\Model\Quote\Config">
<plugin name="append_sales_rule_keys_to_quote" type="Magento\SalesRule\Model\Plugin\QuoteConfigProductAttributes"/>
</type>
<type name="Magento\Quote\Model\Quote">
<plugin name="append_discounts_to_items" type="Magento\SalesRule\Model\Plugin\Discount"/>
</type>
<type name="Magento\Quote\Model\Quote\Config">
<plugin name="append_sales_rule_keys_to_quote" type="Magento\SalesRule\Model\Plugin\QuoteConfigProductAttributes"/>
</type>
<type name="Magento\Framework\Module\Setup\Migration">
<arguments>
<argument name="compositeModules" xsi:type="array">
Expand Down

0 comments on commit 6900c38

Please sign in to comment.