Skip to content

Commit 827235f

Browse files
author
Yauhen_Lyskavets
committed
MAGETWO-95186: [2.3] Incorrect table rates shipping charge at check out with cart price rule
- Fix shipping discounts.
1 parent ac3ae89 commit 827235f

File tree

13 files changed

+245
-66
lines changed

13 files changed

+245
-66
lines changed

app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
1919
\Magento\Shipping\Model\Carrier\CarrierInterface
2020
{
21+
const CONDITION_CODE_PACKAGE_VALUE_WITH_DISCOUNT = 'package_value_with_discount';
22+
2123
/**
2224
* @var string
2325
*/
@@ -82,6 +84,8 @@ public function __construct(
8284
}
8385

8486
/**
87+
* Collect rates.
88+
*
8589
* @param RateRequest $request
8690
* @return \Magento\Shipping\Model\Rate\Result
8791
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -199,6 +203,8 @@ public function collectRates(RateRequest $request)
199203
}
200204

201205
/**
206+
* Get rate.
207+
*
202208
* @param \Magento\Quote\Model\Quote\Address\RateRequest $request
203209
* @return array|bool
204210
*/
@@ -208,6 +214,8 @@ public function getRate(\Magento\Quote\Model\Quote\Address\RateRequest $request)
208214
}
209215

210216
/**
217+
* Get code.
218+
*
211219
* @param string $type
212220
* @param string $code
213221
* @return array
@@ -218,12 +226,12 @@ public function getCode($type, $code = '')
218226
$codes = [
219227
'condition_name' => [
220228
'package_weight' => __('Weight vs. Destination'),
221-
'package_value' => __('Price vs. Destination'),
229+
self::CONDITION_CODE_PACKAGE_VALUE_WITH_DISCOUNT => __('Price vs. Destination'),
222230
'package_qty' => __('# of Items vs. Destination'),
223231
],
224232
'condition_name_short' => [
225233
'package_weight' => __('Weight (and above)'),
226-
'package_value' => __('Order Subtotal (and above)'),
234+
self::CONDITION_CODE_PACKAGE_VALUE_WITH_DISCOUNT => __('Order Subtotal (and above)'),
227235
'package_qty' => __('# of Items (and above)'),
228236
],
229237
];
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\OfflineShipping\Setup\Patch\Data;
9+
10+
use Magento\Framework\Setup\Patch\DataPatchInterface;
11+
use Magento\OfflineShipping\Model\Carrier\Tablerate;
12+
13+
/**
14+
* Update for shipping_tablerate table for using price with discount in condition.
15+
*/
16+
class UpdateShippingTablerate implements DataPatchInterface
17+
{
18+
/**
19+
* @var \Magento\Framework\Setup\ModuleDataSetupInterface
20+
*/
21+
private $moduleDataSetup;
22+
23+
/**
24+
* PatchInitial constructor.
25+
* @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
26+
*/
27+
public function __construct(
28+
\Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
29+
) {
30+
$this->moduleDataSetup = $moduleDataSetup;
31+
}
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
public function apply()
37+
{
38+
$this->moduleDataSetup->getConnection()->startSetup();
39+
$connection = $this->moduleDataSetup->getConnection();
40+
$connection->update(
41+
$this->moduleDataSetup->getTable('shipping_tablerate'),
42+
['condition_name' => Tablerate::CONDITION_CODE_PACKAGE_VALUE_WITH_DISCOUNT],
43+
[new \Zend_Db_Expr('condition_name = \'package_value\'')]
44+
);
45+
$connection->update(
46+
$this->moduleDataSetup->getTable('core_config_data'),
47+
['value' => Tablerate::CONDITION_CODE_PACKAGE_VALUE_WITH_DISCOUNT],
48+
[
49+
new \Zend_Db_Expr('value = \'package_value\''),
50+
new \Zend_Db_Expr('path = \'carriers/tablerate/condition_name\'')
51+
]
52+
);
53+
$this->moduleDataSetup->getConnection()->endSetup();
54+
55+
$connection->endSetup();
56+
}
57+
58+
/**
59+
* @inheritdoc
60+
*/
61+
public static function getDependencies()
62+
{
63+
return [];
64+
}
65+
66+
/**
67+
* @inheritdoc
68+
*/
69+
public function getAliases()
70+
{
71+
return [];
72+
}
73+
}

app/code/Magento/OfflineShipping/etc/db_schema.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
default="0" comment="Destination Region Id"/>
1919
<column xsi:type="varchar" name="dest_zip" nullable="false" length="10" default="*"
2020
comment="Destination Post Code (Zip)"/>
21-
<column xsi:type="varchar" name="condition_name" nullable="false" length="20" comment="Rate Condition name"/>
21+
<column xsi:type="varchar" name="condition_name" nullable="false" length="30" comment="Rate Condition name"/>
2222
<column xsi:type="decimal" name="condition_value" scale="4" precision="12" unsigned="false" nullable="false"
2323
default="0" comment="Rate condition value"/>
2424
<column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0"

app/code/Magento/Quote/Model/Cart/CartTotalRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function __construct(
7979
}
8080

8181
/**
82-
* {@inheritDoc}
82+
* @inheritdoc
8383
*
8484
* @param int $cartId The cart ID.
8585
* @return Totals Quote totals data.

app/code/Magento/Quote/Test/Unit/Model/Cart/CartTotalRepositoryTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ protected function setUp()
7777
'getAllVisibleItems',
7878
'getBaseCurrencyCode',
7979
'getQuoteCurrencyCode',
80-
'getItemsQty'
80+
'getItemsQty',
81+
'collectTotals'
8182
]);
8283
$this->quoteRepositoryMock = $this->createMock(\Magento\Quote\Api\CartRepositoryInterface::class);
8384
$this->addressMock = $this->createPartialMock(

app/code/Magento/Quote/etc/sales.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<section name="quote">
1010
<group name="totals">
1111
<item name="subtotal" instance="Magento\Quote\Model\Quote\Address\Total\Subtotal" sort_order="100"/>
12-
<item name="shipping" instance="Magento\Quote\Model\Quote\Address\Total\Shipping" sort_order="250"/>
12+
<item name="shipping" instance="Magento\Quote\Model\Quote\Address\Total\Shipping" sort_order="350"/>
1313
<item name="grand_total" instance="Magento\Quote\Model\Quote\Address\Total\Grand" sort_order="550"/>
1414
</group>
1515
</section>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Model\Quote\Address\Total;
9+
10+
use Magento\Quote\Api\Data\ShippingAssignmentInterface as ShippingAssignment;
11+
use Magento\Quote\Model\Quote;
12+
use Magento\Quote\Model\Quote\Address\Total;
13+
use Magento\SalesRule\Model\Quote\Discount as DiscountCollector;
14+
use Magento\SalesRule\Model\Validator;
15+
16+
/**
17+
* Total collector for shipping discounts.
18+
*/
19+
class ShippingDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
20+
{
21+
/**
22+
* @var Validator
23+
*/
24+
private $calculator;
25+
26+
/**
27+
* @param Validator $calculator
28+
*/
29+
public function __construct(Validator $calculator)
30+
{
31+
$this->calculator = $calculator;
32+
}
33+
34+
/**
35+
* @inheritdoc
36+
*
37+
* @param Quote $quote
38+
* @param ShippingAssignment $shippingAssignment
39+
* @param Total $total
40+
* @return ShippingDiscount
41+
*/
42+
public function collect(Quote $quote, ShippingAssignment $shippingAssignment, Total $total): self
43+
{
44+
parent::collect($quote, $shippingAssignment, $total);
45+
46+
$address = $shippingAssignment->getShipping()->getAddress();
47+
$this->calculator->reset($address);
48+
49+
$items = $shippingAssignment->getItems();
50+
if (!count($items)) {
51+
return $this;
52+
}
53+
54+
$address->setShippingDiscountAmount(0);
55+
$address->setBaseShippingDiscountAmount(0);
56+
if ($address->getShippingAmount()) {
57+
$this->calculator->processShippingAmount($address);
58+
$total->addTotalAmount(DiscountCollector::COLLECTOR_TYPE_CODE, -$address->getShippingDiscountAmount());
59+
$total->addBaseTotalAmount(
60+
DiscountCollector::COLLECTOR_TYPE_CODE,
61+
-$address->getBaseShippingDiscountAmount()
62+
);
63+
$total->setShippingDiscountAmount($address->getShippingDiscountAmount());
64+
$total->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount());
65+
66+
$this->calculator->prepareDescription($address);
67+
$total->setDiscountDescription($address->getDiscountDescription());
68+
$total->setSubtotalWithDiscount($total->getSubtotal() + $total->getDiscountAmount());
69+
$total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $total->getBaseDiscountAmount());
70+
71+
$address->setDiscountAmount($total->getDiscountAmount());
72+
$address->setBaseDiscountAmount($total->getBaseDiscountAmount());
73+
}
74+
75+
return $this;
76+
}
77+
78+
/**
79+
* @inheritdoc
80+
*
81+
* @param \Magento\Quote\Model\Quote $quote
82+
* @param \Magento\Quote\Model\Quote\Address\Total $total
83+
* @return array
84+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
85+
*/
86+
public function fetch(Quote $quote, Total $total): array
87+
{
88+
$result = [];
89+
$amount = $total->getDiscountAmount();
90+
91+
if ($amount != 0) {
92+
$description = $total->getDiscountDescription() ?: '';
93+
$result = [
94+
'code' => DiscountCollector::COLLECTOR_TYPE_CODE,
95+
'title' => strlen($description) ? __('Discount (%1)', $description) : __('Discount'),
96+
'value' => $amount
97+
];
98+
}
99+
return $result;
100+
}
101+
}

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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
*/
66
namespace Magento\SalesRule\Model\Quote;
77

8+
/**
9+
* Discount totals calculation model.
10+
*/
811
class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
912
{
13+
const COLLECTOR_TYPE_CODE = 'discount';
14+
1015
/**
1116
* Discount calculation object
1217
*
@@ -43,7 +48,7 @@ public function __construct(
4348
\Magento\SalesRule\Model\Validator $validator,
4449
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
4550
) {
46-
$this->setCode('discount');
51+
$this->setCode(self::COLLECTOR_TYPE_CODE);
4752
$this->eventManager = $eventManager;
4853
$this->calculator = $validator;
4954
$this->storeManager = $storeManager;
@@ -124,21 +129,14 @@ public function collect(
124129
}
125130
}
126131

127-
/** Process shipping amount discount */
128-
$address->setShippingDiscountAmount(0);
129-
$address->setBaseShippingDiscountAmount(0);
130-
if ($address->getShippingAmount()) {
131-
$this->calculator->processShippingAmount($address);
132-
$total->addTotalAmount($this->getCode(), -$address->getShippingDiscountAmount());
133-
$total->addBaseTotalAmount($this->getCode(), -$address->getBaseShippingDiscountAmount());
134-
$total->setShippingDiscountAmount($address->getShippingDiscountAmount());
135-
$total->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount());
136-
}
137-
138132
$this->calculator->prepareDescription($address);
139133
$total->setDiscountDescription($address->getDiscountDescription());
140134
$total->setSubtotalWithDiscount($total->getSubtotal() + $total->getDiscountAmount());
141135
$total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $total->getBaseDiscountAmount());
136+
137+
$address->setDiscountAmount($total->getDiscountAmount());
138+
$address->setBaseDiscountAmount($total->getBaseDiscountAmount());
139+
142140
return $this;
143141
}
144142

app/code/Magento/SalesRule/etc/sales.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
99
<section name="quote">
1010
<group name="totals">
11-
<item name="discount" instance="Magento\SalesRule\Model\Quote\Discount" sort_order="400"/>
11+
<item name="discount" instance="Magento\SalesRule\Model\Quote\Discount" sort_order="300"/>
12+
<item name="shipping_discount" instance="Magento\SalesRule\Model\Quote\Address\Total\ShippingDiscount" sort_order="400"/>
1213
</group>
1314
</section>
1415
</config>

app/code/Magento/Tax/etc/sales.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<section name="quote">
1010
<group name="totals">
1111
<item name="tax_subtotal" instance="Magento\Tax\Model\Sales\Total\Quote\Subtotal" sort_order="200"/>
12-
<item name="tax_shipping" instance="Magento\Tax\Model\Sales\Total\Quote\Shipping" sort_order="300"/>
12+
<item name="tax_shipping" instance="Magento\Tax\Model\Sales\Total\Quote\Shipping" sort_order="375"/>
1313
<item name="tax" instance="Magento\Tax\Model\Sales\Total\Quote\Tax" sort_order="450">
1414
<renderer name="adminhtml" instance="Magento\Sales\Block\Adminhtml\Order\Create\Totals\Tax"/>
1515
<renderer name="frontend" instance="Magento\Tax\Block\Checkout\Tax"/>

0 commit comments

Comments
 (0)