Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
RulesApplier.php
Go to the documentation of this file.
1 <?php
7 
12 
18 {
24  protected $_eventManager;
25 
29  protected $validatorUtility;
30 
34  private $childrenValidationLocator;
35 
39  private $calculatorFactory;
40 
47  public function __construct(
48  \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory,
49  \Magento\Framework\Event\ManagerInterface $eventManager,
50  \Magento\SalesRule\Model\Utility $utility,
51  ChildrenValidationLocator $childrenValidationLocator = null
52  ) {
53  $this->calculatorFactory = $calculatorFactory;
54  $this->validatorUtility = $utility;
55  $this->_eventManager = $eventManager;
56  $this->childrenValidationLocator = $childrenValidationLocator
57  ?: ObjectManager::getInstance()->get(ChildrenValidationLocator::class);
58  }
59 
70  public function applyRules($item, $rules, $skipValidation, $couponCode)
71  {
72  $address = $item->getAddress();
73  $appliedRuleIds = [];
74  /* @var $rule \Magento\SalesRule\Model\Rule */
75  foreach ($rules as $rule) {
76  if (!$this->validatorUtility->canProcessRule($rule, $address)) {
77  continue;
78  }
79 
80  if (!$skipValidation && !$rule->getActions()->validate($item)) {
81  if (!$this->childrenValidationLocator->isChildrenValidationRequired($item)) {
82  continue;
83  }
84  $childItems = $item->getChildren();
85  $isContinue = true;
86  if (!empty($childItems)) {
87  foreach ($childItems as $childItem) {
88  if ($rule->getActions()->validate($childItem)) {
89  $isContinue = false;
90  }
91  }
92  }
93  if ($isContinue) {
94  continue;
95  }
96  }
97 
98  $this->applyRule($item, $rule, $address, $couponCode);
99  $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
100 
101  if ($rule->getStopRulesProcessing()) {
102  break;
103  }
104  }
105 
106  return $appliedRuleIds;
107  }
108 
117  {
118  $description = $address->getDiscountDescriptionArray();
119  $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore());
120  $label = '';
121  if ($ruleLabel) {
122  $label = $ruleLabel;
123  } else {
124  if (strlen($address->getCouponCode())) {
125  $label = $address->getCouponCode();
126  }
127  }
128 
129  if (strlen($label)) {
130  $description[$rule->getId()] = $label;
131  }
132 
133  $address->setDiscountDescriptionArray($description);
134 
135  return $this;
136  }
137 
145  protected function applyRule($item, $rule, $address, $couponCode)
146  {
147  $discountData = $this->getDiscountData($item, $rule);
148  $this->setDiscountData($discountData, $item);
149 
152 
153  return $this;
154  }
155 
161  protected function getDiscountData($item, $rule)
162  {
163  $qty = $this->validatorUtility->getItemQty($item, $rule);
164 
165  $discountCalculator = $this->calculatorFactory->create($rule->getSimpleAction());
166  $qty = $discountCalculator->fixQuantity($qty, $rule);
167  $discountData = $discountCalculator->calculate($rule, $item, $qty);
168 
169  $this->eventFix($discountData, $item, $rule, $qty);
170  $this->validatorUtility->deltaRoundingFix($discountData, $item);
171 
177  $this->validatorUtility->minFix($discountData, $item, $qty);
178 
179  return $discountData;
180  }
181 
187  protected function setDiscountData($discountData, $item)
188  {
189  $item->setDiscountAmount($discountData->getAmount());
190  $item->setBaseDiscountAmount($discountData->getBaseAmount());
191  $item->setOriginalDiscountAmount($discountData->getOriginalAmount());
192  $item->setBaseOriginalDiscountAmount($discountData->getBaseOriginalAmount());
193 
194  return $this;
195  }
196 
206  {
207  /*
208  Rule is a part of rules collection, which includes only rules with 'No Coupon' type or with validated coupon.
209  As a result, if rule uses coupon code(s) ('Specific' or 'Auto' Coupon Type), it always contains validated coupon
210  */
212  $address->setCouponCode($couponCode);
213  }
214 
215  return $this;
216  }
217 
227  protected function eventFix(
228  \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData,
230  \Magento\SalesRule\Model\Rule $rule,
231  $qty
232  ) {
233  $quote = $item->getQuote();
234  $address = $item->getAddress();
235 
236  $this->_eventManager->dispatch(
237  'salesrule_validator_process',
238  [
239  'rule' => $rule,
240  'item' => $item,
241  'address' => $address,
242  'quote' => $quote,
243  'qty' => $qty,
244  'result' => $discountData
245  ]
246  );
247 
248  return $this;
249  }
250 
256  public function setAppliedRuleIds(\Magento\Quote\Model\Quote\Item\AbstractItem $item, array $appliedRuleIds)
257  {
258  $address = $item->getAddress();
259  $quote = $item->getQuote();
260 
261  $item->setAppliedRuleIds(join(',', $appliedRuleIds));
262  $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
263  $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
264 
265  return $this;
266  }
267 }
setAppliedRuleIds(\Magento\Quote\Model\Quote\Item\AbstractItem $item, array $appliedRuleIds)
$quote
$address
Definition: customer.php:38
eventFix(\Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, \Magento\Quote\Model\Quote\Item\AbstractItem $item, \Magento\SalesRule\Model\Rule $rule, $qty)
$label
Definition: details.phtml:21
maintainAddressCouponCode($address, $rule, $couponCode)
__construct(\Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\SalesRule\Model\Utility $utility, ChildrenValidationLocator $childrenValidationLocator=null)
applyRules($item, $rules, $skipValidation, $couponCode)
setDiscountData($discountData, $item)
applyRule($item, $rule, $address, $couponCode)