Skip to content

Commit 2b34987

Browse files
authored
LYNX-336: Multicoupon
1 parent 1cfd2cc commit 2b34987

File tree

17 files changed

+551
-201
lines changed

17 files changed

+551
-201
lines changed

app/code/Magento/OfflineShipping/Model/Quote/Address/FreeShipping.php

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,25 @@
1111
use Magento\OfflineShipping\Model\SalesRule\ExtendedCalculator;
1212
use Magento\Quote\Model\Quote\Address\FreeShippingInterface;
1313
use Magento\Quote\Model\Quote\Item\AbstractItem;
14-
use Magento\Store\Model\StoreManagerInterface;
1514

1615
class FreeShipping implements FreeShippingInterface
1716
{
1817
/**
19-
* @var ExtendedCalculator
18+
* @var Calculator
2019
*/
2120
protected $calculator;
2221

2322
/**
24-
* @var StoreManagerInterface
25-
*/
26-
protected $storeManager;
27-
28-
/**
29-
* @param StoreManagerInterface $storeManager
3023
* @param Calculator $calculator
3124
*/
3225
public function __construct(
33-
StoreManagerInterface $storeManager,
3426
Calculator $calculator
3527
) {
36-
$this->storeManager = $storeManager;
3728
$this->calculator = $calculator;
3829
}
3930

4031
/**
41-
* {@inheritDoc}
32+
* @inheritdoc
4233
*/
4334
public function isFreeShipping(\Magento\Quote\Model\Quote $quote, $items)
4435
{
@@ -49,12 +40,7 @@ public function isFreeShipping(\Magento\Quote\Model\Quote $quote, $items)
4940

5041
$result = false;
5142
$addressFreeShipping = true;
52-
$store = $this->storeManager->getStore($quote->getStoreId());
53-
$this->calculator->init(
54-
$store->getWebsiteId(),
55-
$quote->getCustomerGroupId(),
56-
$quote->getCouponCode()
57-
);
43+
$this->calculator->initFromQuote($quote);
5844
$shippingAddress = $quote->getShippingAddress();
5945
$shippingAddress->setFreeShipping(0);
6046
/** @var \Magento\Quote\Api\Data\CartItemInterface $item */
@@ -88,6 +74,8 @@ public function isFreeShipping(\Magento\Quote\Model\Quote $quote, $items)
8874
}
8975

9076
/**
77+
* Apply free shipping to quote item child items
78+
*
9179
* @param AbstractItem $item
9280
* @param bool $isFreeShipping
9381
* @return void

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

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

35-
foreach ($this->_getRules($address) as $rule) {
35+
foreach ($this->getRules($address) as $rule) {
3636
/* @var $rule \Magento\SalesRule\Model\Rule */
3737
if (!$this->validatorUtility->canProcessRule($rule, $address)) {
3838
continue;

app/code/Magento/OfflineShipping/Test/Unit/Model/Quote/Address/FreeShippingTest.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use Magento\Quote\Model\Quote\Address;
1414
use Magento\Quote\Model\Quote\Item;
1515
use Magento\Store\Api\Data\StoreInterface;
16-
use Magento\Store\Model\StoreManagerInterface;
1716
use PHPUnit\Framework\MockObject\MockObject;
1817
use PHPUnit\Framework\TestCase;
1918

@@ -22,36 +21,41 @@
2221
*/
2322
class FreeShippingTest extends TestCase
2423
{
24+
/**
25+
* @var int
26+
*/
2527
private static $websiteId = 1;
2628

29+
/**
30+
* @var int
31+
*/
2732
private static $customerGroupId = 2;
2833

34+
/**
35+
* @var int
36+
*/
2937
private static $couponCode = 3;
3038

39+
/**
40+
* @var int
41+
*/
3142
private static $storeId = 1;
3243

3344
/**
3445
* @var FreeShipping
3546
*/
3647
private $model;
3748

38-
/**
39-
* @var MockObject|StoreManagerInterface
40-
*/
41-
private $storeManager;
42-
4349
/**
4450
* @var MockObject|Calculator
4551
*/
4652
private $calculator;
4753

4854
protected function setUp(): void
4955
{
50-
$this->storeManager = $this->getMockForAbstractClass(StoreManagerInterface::class);
5156
$this->calculator = $this->createMock(Calculator::class);
5257

5358
$this->model = new FreeShipping(
54-
$this->storeManager,
5559
$this->calculator
5660
);
5761
}
@@ -74,8 +78,8 @@ public function testIsFreeShipping(int $addressFree, int $fItemFree, int $sItemF
7478
$sItem = $this->getItem($quote);
7579
$items = [$fItem, $sItem];
7680

77-
$this->calculator->method('init')
78-
->with(self::$websiteId, self::$customerGroupId, self::$couponCode);
81+
$this->calculator->method('initFromQuote')
82+
->with($this->getQuote($this->getShippingAddress()));
7983
$this->calculator->method('processFreeShipping')
8084
->withConsecutive(
8185
[$fItem],
@@ -118,9 +122,6 @@ private function withStore()
118122
$store = $this->getMockBuilder(StoreInterface::class)
119123
->disableOriginalConstructor()
120124
->getMockForAbstractClass();
121-
$this->storeManager->method('getStore')
122-
->with(self::$storeId)
123-
->willReturn($store);
124125

125126
$store->method('getWebsiteId')
126127
->willReturn(self::$websiteId);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ protected function setUp(): void
2424
{
2525
$this->_model = $this->createPartialMock(
2626
Calculator::class,
27-
['_getRules', '__wakeup']
27+
['getRules', '__wakeup']
2828
);
2929
}
3030

@@ -40,7 +40,7 @@ public function testProcessFreeShipping()
4040
$item->expects($this->once())->method('getAddress')->willReturn($addressMock);
4141

4242
$this->_model->expects($this->once())
43-
->method('_getRules')
43+
->method('getRules')
4444
->with($addressMock)
4545
->willReturn([]);
4646

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public function collect(
182182
}
183183
}
184184
}
185-
$this->calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());
185+
$this->calculator->initFromQuote($quote);
186186
$this->calculator->initTotals($items, $address);
187187
$items = $this->calculator->sortItemsByPriority($items, $address);
188188
$itemsToApplyRules = $items;

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

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ protected function _afterLoad()
164164
* @param string $couponCode
165165
* @param string|null $now
166166
* @param Address $address allow extensions to further filter out rules based on quote address
167+
* @param string[] $couponCodes
167168
* @throws \Zend_Db_Select_Exception
168169
* @use $this->addWebsiteGroupDateFilter()
169170
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -174,31 +175,38 @@ public function setValidationFilter(
174175
$customerGroupId,
175176
$couponCode = '',
176177
$now = null,
177-
Address $address = null
178+
Address $address = null,
179+
array $couponCodes = []
178180
) {
179-
if (!$this->getFlag('validation_filter')) {
180-
$this->prepareSelect($websiteId, $customerGroupId, $now);
181+
if ($this->getFlag('validation_filter')) {
182+
return $this;
183+
}
184+
185+
$this->prepareSelect($websiteId, $customerGroupId, $now);
181186

182-
$noCouponRules = $this->getNoCouponCodeSelect();
187+
$noCouponRules = $this->getNoCouponCodeSelect();
183188

184-
if ($couponCode) {
185-
$couponRules = $this->getCouponCodeSelect($couponCode);
189+
if ($couponCode && !in_array($couponCode, $couponCodes)) {
190+
$couponCodes[] = $couponCode;
191+
}
186192

187-
$allAllowedRules = $this->getConnection()->select();
188-
$allAllowedRules->union([$noCouponRules, $couponRules], Select::SQL_UNION_ALL);
193+
if (!empty($couponCodes)) {
194+
$couponRules = $this->getCouponCodeSelect($couponCodes);
189195

190-
$wrapper = $this->getConnection()->select();
191-
$wrapper->from($allAllowedRules);
196+
$allAllowedRules = $this->getConnection()->select();
197+
$allAllowedRules->union([$noCouponRules, $couponRules], Select::SQL_UNION_ALL);
192198

193-
$this->_select = $wrapper;
194-
} else {
195-
$this->_select = $noCouponRules;
196-
}
199+
$wrapper = $this->getConnection()->select();
200+
$wrapper->from($allAllowedRules);
197201

198-
$this->setOrder('sort_order', self::SORT_ORDER_ASC);
199-
$this->setFlag('validation_filter', true);
202+
$this->_select = $wrapper;
203+
} else {
204+
$this->_select = $noCouponRules;
200205
}
201206

207+
$this->setOrder('sort_order', self::SORT_ORDER_ASC);
208+
$this->setFlag('validation_filter', true);
209+
202210
return $this;
203211
}
204212

@@ -239,14 +247,14 @@ private function getNoCouponCodeSelect()
239247
/**
240248
* Determine all active rules that are valid for the given coupon code.
241249
*
242-
* @param string $couponCode
250+
* @param string[] $couponCodes
243251
* @return Select
244252
*/
245-
private function getCouponCodeSelect($couponCode)
253+
private function getCouponCodeSelect(array $couponCodes)
246254
{
247255
$couponSelect = clone $this->getSelect();
248256

249-
$this->joinCouponTable($couponCode, $couponSelect);
257+
$this->joinCouponTable($couponCodes, $couponSelect);
250258

251259
$isAutogenerated =
252260
$this->getConnection()->quoteInto('main_table.coupon_type = ?', Rule::COUPON_TYPE_AUTO)
@@ -271,19 +279,19 @@ private function getCouponCodeSelect($couponCode)
271279
}
272280

273281
/**
274-
* Join coupong table to select.
282+
* Join coupon table to select.
275283
*
276-
* @param string $couponCode
284+
* @param string[] $couponCodes
277285
* @param Select $couponSelect
278286
*/
279-
private function joinCouponTable($couponCode, Select $couponSelect)
287+
private function joinCouponTable(array $couponCodes, Select $couponSelect)
280288
{
281289
$couponJoinCondition =
282290
'main_table.rule_id = rule_coupons.rule_id'
283291
. ' AND ' .
284292
$this->getConnection()->quoteInto('main_table.coupon_type <> ?', Rule::COUPON_TYPE_NO_COUPON)
285293
. ' AND ' .
286-
$this->getConnection()->quoteInto('rule_coupons.code = ?', $couponCode);
294+
$this->getConnection()->quoteInto('rule_coupons.code IN(?)', $couponCodes);
287295

288296
$couponSelect->joinInner(
289297
['rule_coupons' => $this->getTable('salesrule_coupon')],

0 commit comments

Comments
 (0)