public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed() { $positivePrice = 1; $skipValidation = true; $item = $this->getPreparedItem(); $couponCode = 111; $ruleId = 1; $appliedRuleIds = [$ruleId => $ruleId]; /** * @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleWithStopFurtherProcessing */ $ruleWithStopFurtherProcessing = $this->getMock('Magento\\SalesRule\\Model\\Rule', ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup'], [], '', false); /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleThatShouldNotBeRun */ $ruleThatShouldNotBeRun = $this->getMock('Magento\\SalesRule\\Model\\Rule', ['getStopRulesProcessing', '__wakeup'], [], '', false); $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing'); $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun'); $rules = [$ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun]; $item->setDiscountCalculationPrice($positivePrice); $item->setData('calculation_price', $positivePrice); $this->validatorUtility->expects($this->atLeastOnce())->method('canProcessRule')->will($this->returnValue(true)); $ruleWithStopFurtherProcessing->expects($this->any())->method('getRuleId')->will($this->returnValue($ruleId)); $this->applyRule($item, $ruleWithStopFurtherProcessing); $ruleWithStopFurtherProcessing->setStopRulesProcessing(true); $ruleThatShouldNotBeRun->expects($this->never())->method('getStopRulesProcessing'); $result = $this->rulesApplier->applyRules($item, $rules, $skipValidation, $couponCode); $this->assertEquals($appliedRuleIds, $result); }
/** * @param bool $isChildren * @param bool $isContinue * * @dataProvider dataProviderChildren */ public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed($isChildren, $isContinue) { $positivePrice = 1; $skipValidation = false; $item = $this->getPreparedItem(); $couponCode = 111; $ruleId = 1; $appliedRuleIds = [$ruleId => $ruleId]; /** * @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleWithStopFurtherProcessing */ $ruleWithStopFurtherProcessing = $this->getMock('Magento\\SalesRule\\Model\\Rule', ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup', 'getActions'], [], '', false); /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleThatShouldNotBeRun */ $ruleThatShouldNotBeRun = $this->getMock('Magento\\SalesRule\\Model\\Rule', ['getStopRulesProcessing', '__wakeup'], [], '', false); $actionMock = $this->getMock('Magento\\Rule\\Model\\Action\\Collection', ['validate'], [], '', false); $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing'); $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun'); $rules = [$ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun]; $item->setDiscountCalculationPrice($positivePrice); $item->setData('calculation_price', $positivePrice); $this->validatorUtility->expects($this->atLeastOnce())->method('canProcessRule')->will($this->returnValue(true)); $ruleWithStopFurtherProcessing->expects($this->atLeastOnce())->method('getActions')->willReturn($actionMock); $actionMock->expects($this->at(0))->method('validate')->with($item)->willReturn(!$isChildren); // if there are child elements, check them if ($isChildren) { $item->expects($this->atLeastOnce())->method('getChildren')->willReturn([$item]); $actionMock->expects($this->at(1))->method('validate')->with($item)->willReturn(!$isContinue); } // if (!$isContinue || !$isChildren) { $ruleWithStopFurtherProcessing->expects($this->any())->method('getRuleId')->will($this->returnValue($ruleId)); $this->applyRule($item, $ruleWithStopFurtherProcessing); $ruleWithStopFurtherProcessing->setStopRulesProcessing(true); $ruleThatShouldNotBeRun->expects($this->never())->method('getStopRulesProcessing'); } $result = $this->rulesApplier->applyRules($item, $rules, $skipValidation, $couponCode); $this->assertEquals($appliedRuleIds, $result); }
public function testApplyRulesThatAppliedRuleIdsAreCollected() { $positivePrice = 1; $ruleId1 = 123; $ruleId2 = 234; $expectedRuleIds = [$ruleId1 => $ruleId1, $ruleId2 => $ruleId2]; $this->model->init($this->model->getWebsiteId(), $this->model->getCustomerGroupId(), $this->model->getCouponCode()); $this->item->setDiscountCalculationPrice($positivePrice); $this->item->setData('calculation_price', $positivePrice); $this->model->setSkipActionsValidation(true); $this->rulesApplier->expects($this->once())->method('applyRules')->with($this->equalTo($this->item), $this->equalTo($this->ruleCollection), $this->anything(), $this->anything())->will($this->returnValue($expectedRuleIds)); $this->rulesApplier->expects($this->once())->method('setAppliedRuleIds')->with($this->anything(), $expectedRuleIds); $this->model->process($this->item); }
/** * Apply discounts to shipping amount * * @param Address $address * @return $this */ public function processShippingAmount(Address $address) { $shippingAmount = $address->getShippingAmountForDiscount(); if ($shippingAmount !== null) { $baseShippingAmount = $address->getBaseShippingAmountForDiscount(); } else { $shippingAmount = $address->getShippingAmount(); $baseShippingAmount = $address->getBaseShippingAmount(); } $quote = $address->getQuote(); $appliedRuleIds = array(); foreach ($this->_getRules() as $rule) { /* @var \Magento\SalesRule\Model\Rule $rule */ if (!$rule->getApplyToShipping() || !$this->validatorUtility->canProcessRule($rule, $address)) { continue; } $discountAmount = 0; $baseDiscountAmount = 0; $rulePercent = min(100, $rule->getDiscountAmount()); switch ($rule->getSimpleAction()) { case \Magento\SalesRule\Model\Rule::TO_PERCENT_ACTION: $rulePercent = max(0, 100 - $rule->getDiscountAmount()); // break is intentionally omitted // break is intentionally omitted case \Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION: $discountAmount = ($shippingAmount - $address->getShippingDiscountAmount()) * $rulePercent / 100; $baseDiscountAmount = ($baseShippingAmount - $address->getBaseShippingDiscountAmount()) * $rulePercent / 100; $discountPercent = min(100, $address->getShippingDiscountPercent() + $rulePercent); $address->setShippingDiscountPercent($discountPercent); break; case \Magento\SalesRule\Model\Rule::TO_FIXED_ACTION: $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $shippingAmount - $quoteAmount; $baseDiscountAmount = $baseShippingAmount - $rule->getDiscountAmount(); break; case \Magento\SalesRule\Model\Rule::BY_FIXED_ACTION: $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $quoteAmount; $baseDiscountAmount = $rule->getDiscountAmount(); break; case \Magento\SalesRule\Model\Rule::CART_FIXED_ACTION: $cartRules = $address->getCartFixedRules(); if (!isset($cartRules[$rule->getId()])) { $cartRules[$rule->getId()] = $rule->getDiscountAmount(); } if ($cartRules[$rule->getId()] > 0) { $quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]); $discountAmount = min($shippingAmount - $address->getShippingDiscountAmount(), $quoteAmount); $baseDiscountAmount = min($baseShippingAmount - $address->getBaseShippingDiscountAmount(), $cartRules[$rule->getId()]); $cartRules[$rule->getId()] -= $baseDiscountAmount; } $address->setCartFixedRules($cartRules); break; } $discountAmount = min($address->getShippingDiscountAmount() + $discountAmount, $shippingAmount); $baseDiscountAmount = min($address->getBaseShippingDiscountAmount() + $baseDiscountAmount, $baseShippingAmount); $address->setShippingDiscountAmount($discountAmount); $address->setBaseShippingDiscountAmount($baseDiscountAmount); $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); $this->rulesApplier->maintainAddressCouponCode($address, $rule, $this->getCouponCode()); $this->rulesApplier->addDiscountDescription($address, $rule); if ($rule->getStopRulesProcessing()) { break; } } $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); return $this; }