Skip to content

Commit 4aa478f

Browse files
author
Cari Spruiell
committed
Merge remote-tracking branch 'mainline/develop' into api-sprint-61-pr
2 parents 20fed16 + 494e83f commit 4aa478f

File tree

26 files changed

+1801
-106
lines changed

26 files changed

+1801
-106
lines changed

app/code/Magento/OfflineShipping/Model/SalesRule/Calculator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function processFreeShipping(\Magento\Quote\Model\Quote\Item\AbstractItem
2828
$address = $item->getAddress();
2929
$item->setFreeShipping(false);
3030

31-
foreach ($this->_getRules() as $rule) {
31+
foreach ($this->_getRules($address) as $rule) {
3232
/* @var $rule \Magento\SalesRule\Model\Rule */
3333
if (!$this->validatorUtility->canProcessRule($rule, $address)) {
3434
continue;

app/code/Magento/OfflineShipping/Test/Unit/Model/SalesRule/CalculatorTest.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class CalculatorTest extends \PHPUnit_Framework_TestCase
99
{
1010
/**
11-
* @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject
11+
* @var \Magento\OfflineShipping\Model\SalesRule\Calculator|\PHPUnit_Framework_MockObject_MockObject
1212
*/
1313
protected $_model;
1414

@@ -21,13 +21,20 @@ protected function setUp()
2121
'',
2222
false
2323
);
24-
$this->_model->expects($this->any())->method('_getRules')->will($this->returnValue([]));
2524
}
2625

2726
public function testProcessFreeShipping()
2827
{
28+
$addressMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Address')
29+
->disableOriginalConstructor()
30+
->getMock();
2931
$item = $this->getMock('Magento\Quote\Model\Quote\Item', ['getAddress', '__wakeup'], [], '', false);
30-
$item->expects($this->once())->method('getAddress')->will($this->returnValue(true));
32+
$item->expects($this->once())->method('getAddress')->will($this->returnValue($addressMock));
33+
34+
$this->_model->expects($this->once())
35+
->method('_getRules')
36+
->with($addressMock)
37+
->will($this->returnValue([]));
3138

3239
$this->assertInstanceOf(
3340
'Magento\OfflineShipping\Model\SalesRule\Calculator',

app/code/Magento/SalesRule/Model/Quote/Discount.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function collect(
8585
$this->calculator->initTotals($items, $address);
8686

8787
$address->setDiscountDescription([]);
88-
$items = $this->calculator->sortItemsByPriority($items);
88+
$items = $this->calculator->sortItemsByPriority($items, $address);
8989

9090
/** @var \Magento\Quote\Model\Quote\Item $item */
9191
foreach ($items as $item) {
@@ -201,6 +201,7 @@ protected function distributeDiscount(\Magento\Quote\Model\Quote\Item\AbstractIt
201201
* @param \Magento\Quote\Model\Quote $quote
202202
* @param \Magento\Quote\Model\Quote\Address\Total $total
203203
* @return array|null
204+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
204205
*/
205206
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
206207
{

app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace Magento\SalesRule\Model\ResourceModel\Rule;
1010

11+
use Magento\Quote\Model\Quote\Address;
12+
1113
/**
1214
* Sales Rules resource collection model
1315
*
@@ -80,11 +82,18 @@ protected function _construct()
8082
* @param int $customerGroupId
8183
* @param string $couponCode
8284
* @param string|null $now
85+
* @param Address $address allow extensions to further filter out rules based on quote address
8386
* @use $this->addWebsiteGroupDateFilter()
87+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
8488
* @return $this
8589
*/
86-
public function setValidationFilter($websiteId, $customerGroupId, $couponCode = '', $now = null)
87-
{
90+
public function setValidationFilter(
91+
$websiteId,
92+
$customerGroupId,
93+
$couponCode = '',
94+
$now = null,
95+
Address $address = null
96+
) {
8897
if (!$this->getFlag('validation_filter')) {
8998
/* We need to overwrite joinLeft if coupon is applied */
9099
$this->getSelect()->reset();

app/code/Magento/SalesRule/Model/Validator.php

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ class Validator extends \Magento\Framework\Model\AbstractModel
9292
*/
9393
protected $messageManager;
9494

95+
/**
96+
* Counter is used for assigning temporary id to quote address
97+
*
98+
* @var int
99+
*/
100+
protected $counter = 0;
101+
95102
/**
96103
* @param \Magento\Framework\Model\Context $context
97104
* @param \Magento\Framework\Registry $registry
@@ -145,29 +152,56 @@ public function init($websiteId, $customerGroupId, $couponCode)
145152
{
146153
$this->setWebsiteId($websiteId)->setCustomerGroupId($customerGroupId)->setCouponCode($couponCode);
147154

148-
$key = $websiteId . '_' . $customerGroupId . '_' . $couponCode;
155+
return $this;
156+
}
157+
158+
/**
159+
* Get rules collection for current object state
160+
*
161+
* @param Address|null $address
162+
* @return \Magento\SalesRule\Model\ResourceModel\Rule\Collection
163+
*/
164+
protected function _getRules(Address $address = null)
165+
{
166+
$addressId = $this->getAddressId($address);
167+
$key = $this->getWebsiteId() . '_'
168+
. $this->getCustomerGroupId() . '_'
169+
. $this->getCouponCode() . '_'
170+
. $addressId;
149171
if (!isset($this->_rules[$key])) {
150172
$this->_rules[$key] = $this->_collectionFactory->create()
151173
->setValidationFilter(
152-
$websiteId,
153-
$customerGroupId,
154-
$couponCode
174+
$this->getWebsiteId(),
175+
$this->getCustomerGroupId(),
176+
$this->getCouponCode(),
177+
null,
178+
$address
155179
)
156180
->addFieldToFilter('is_active', 1)
157181
->load();
158182
}
159-
return $this;
183+
return $this->_rules[$key];
160184
}
161185

162186
/**
163-
* Get rules collection for current object state
164-
*
165-
* @return \Magento\SalesRule\Model\ResourceModel\Rule\Collection
187+
* @param Address $address
188+
* @return string
166189
*/
167-
protected function _getRules()
190+
protected function getAddressId(Address $address)
168191
{
169-
$key = $this->getWebsiteId() . '_' . $this->getCustomerGroupId() . '_' . $this->getCouponCode();
170-
return $this->_rules[$key];
192+
if ($address == null) {
193+
return '';
194+
}
195+
if (!$address->hasData('address_sales_rule_id')) {
196+
if ($address->hasData('address_id')) {
197+
$address->setData('address_sales_rule_id', $address->getData('address_id'));
198+
} else {
199+
$type = $address->getAddressType();
200+
$tempId = $type . $this->counter++;
201+
$address->setData('address_sales_rule_id', $tempId);
202+
}
203+
}
204+
return $address->getData('address_sales_rule_id');
171205
}
172206

173207
/**
@@ -191,7 +225,7 @@ public function setSkipActionsValidation($flag)
191225
public function canApplyRules(AbstractItem $item)
192226
{
193227
$address = $item->getAddress();
194-
foreach ($this->_getRules() as $rule) {
228+
foreach ($this->_getRules($address) as $rule) {
195229
if (!$this->validatorUtility->canProcessRule($rule, $address) || !$rule->getActions()->validate($item)) {
196230
return false;
197231
}
@@ -237,7 +271,7 @@ public function process(AbstractItem $item)
237271

238272
$appliedRuleIds = $this->rulesApplier->applyRules(
239273
$item,
240-
$this->_getRules(),
274+
$this->_getRules($item->getAddress()),
241275
$this->_skipActionsValidation,
242276
$this->getCouponCode()
243277
);
@@ -264,7 +298,7 @@ public function processShippingAmount(Address $address)
264298
}
265299
$quote = $address->getQuote();
266300
$appliedRuleIds = [];
267-
foreach ($this->_getRules() as $rule) {
301+
foreach ($this->_getRules($address) as $rule) {
268302
/* @var \Magento\SalesRule\Model\Rule $rule */
269303
if (!$rule->getApplyToShipping() || !$this->validatorUtility->canProcessRule($rule, $address)) {
270304
continue;
@@ -351,7 +385,7 @@ public function initTotals($items, Address $address)
351385
}
352386

353387
/** @var \Magento\SalesRule\Model\Rule $rule */
354-
foreach ($this->_getRules() as $rule) {
388+
foreach ($this->_getRules($address) as $rule) {
355389
if (\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION == $rule->getSimpleAction()
356390
&& $this->validatorUtility->canProcessRule($rule, $address)
357391
) {
@@ -463,13 +497,14 @@ public function prepareDescription($address, $separator = ', ')
463497
* Return items list sorted by possibility to apply prioritized rules
464498
*
465499
* @param array $items
500+
* @param Address $address
466501
* @return array $items
467502
*/
468-
public function sortItemsByPriority($items)
503+
public function sortItemsByPriority($items, Address $address = null)
469504
{
470505
$itemsSorted = [];
471506
/** @var $rule \Magento\SalesRule\Model\Rule */
472-
foreach ($this->_getRules() as $rule) {
507+
foreach ($this->_getRules($address) as $rule) {
473508
foreach ($items as $itemKey => $itemValue) {
474509
if ($rule->getActions()->validate($itemValue)) {
475510
unset($items[$itemKey]);

app/code/Magento/SalesRule/Test/Unit/Model/Quote/DiscountTest.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ public function testCollectItemNoDiscount()
116116
false
117117
);
118118
$itemNoDiscount->expects($this->once())->method('getNoDiscount')->willReturn(true);
119-
$this->validatorMock->expects($this->any())->method('sortItemsByPriority')->willReturnArgument(0);
119+
$this->validatorMock->expects($this->once())->method('sortItemsByPriority')
120+
->with([$itemNoDiscount], $this->addressMock)
121+
->willReturnArgument(0);
120122
$storeMock = $this->getMock('Magento\Store\Model\Store', ['getStore', '__wakeup'], [], '', false);
121123
$this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
122124
$quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
@@ -145,7 +147,9 @@ public function testCollectItemHasParent()
145147
$itemWithParentId->expects($this->once())->method('getParentItem')->willReturn(true);
146148

147149
$this->validatorMock->expects($this->any())->method('canApplyDiscount')->willReturn(true);
148-
$this->validatorMock->expects($this->any())->method('sortItemsByPriority')->willReturnArgument(0);
150+
$this->validatorMock->expects($this->any())->method('sortItemsByPriority')
151+
->with([$itemWithParentId], $this->addressMock)
152+
->willReturnArgument(0);
149153

150154
$storeMock = $this->getMock('\Magento\Store\Model\Store', ['getStore', '__wakeup'], [], '', false);
151155
$this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
@@ -197,7 +201,9 @@ public function testCollectItemHasChildren($childItemData, $parentData, $expecte
197201
}
198202

199203
$this->validatorMock->expects($this->any())->method('canApplyDiscount')->willReturn(true);
200-
$this->validatorMock->expects($this->any())->method('sortItemsByPriority')->willReturnArgument(0);
204+
$this->validatorMock->expects($this->once())->method('sortItemsByPriority')
205+
->with([$itemWithChildren], $this->addressMock)
206+
->willReturnArgument(0);
201207
$this->validatorMock->expects($this->any())->method('canApplyRules')->willReturn(true);
202208

203209
$storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
@@ -296,7 +302,9 @@ public function testCollectItemHasNoChildren()
296302
$itemWithChildren->expects($this->once())->method('getHasChildren')->willReturn(false);
297303

298304
$this->validatorMock->expects($this->any())->method('canApplyDiscount')->willReturn(true);
299-
$this->validatorMock->expects($this->any())->method('sortItemsByPriority')->willReturnArgument(0);
305+
$this->validatorMock->expects($this->once())->method('sortItemsByPriority')
306+
->with([$itemWithChildren], $this->addressMock)
307+
->willReturnArgument(0);
300308

301309
$storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
302310
->disableOriginalConstructor()

0 commit comments

Comments
 (0)