Skip to content

Commit d75d305

Browse files
committed
Merge remote-tracking branch 'origin/MC-24043' into 2.4-develop-pr27
2 parents 331ec09 + fbd9c58 commit d75d305

File tree

7 files changed

+688
-151
lines changed

7 files changed

+688
-151
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
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\Helper;
9+
10+
use Magento\Framework\Pricing\PriceCurrencyInterface;
11+
use Magento\Quote\Api\Data\AddressInterface;
12+
use Magento\Quote\Model\Quote;
13+
use Magento\SalesRule\Model\DeltaPriceRound;
14+
use Magento\SalesRule\Model\Rule;
15+
16+
/**
17+
* Helper for CartFixed Available Discount and Quote Totals
18+
*/
19+
class CartFixedDiscount
20+
{
21+
/**
22+
* @var DeltaPriceRound
23+
*/
24+
private $deltaPriceRound;
25+
26+
/**
27+
* @var PriceCurrencyInterface
28+
*/
29+
private $priceCurrency;
30+
31+
/**
32+
* @param DeltaPriceRound $deltaPriceRound
33+
* @param PriceCurrencyInterface $priceCurrency
34+
*/
35+
public function __construct(
36+
DeltaPriceRound $deltaPriceRound,
37+
PriceCurrencyInterface $priceCurrency
38+
) {
39+
$this->deltaPriceRound = $deltaPriceRound;
40+
$this->priceCurrency = $priceCurrency;
41+
}
42+
43+
/**
44+
* Retrieve shipping amount by quote address and shipping method
45+
*
46+
* @param AddressInterface $address
47+
* @return float
48+
*/
49+
public function calculateShippingAmountWhenAppliedToShipping(
50+
AddressInterface $address
51+
): float {
52+
$shippingAmount = (float) $address->getShippingAmount();
53+
if ($shippingAmount == 0.0) {
54+
$address->setCollectShippingRates(true);
55+
$address->collectShippingRates();
56+
$shippingRates = $address->getAllShippingRates();
57+
foreach ($shippingRates as $shippingRate) {
58+
if ($shippingRate->getCode() === $address->getShippingMethod()
59+
) {
60+
$shippingAmount = (float) $shippingRate->getPrice();
61+
break;
62+
}
63+
}
64+
}
65+
return $shippingAmount;
66+
}
67+
68+
/**
69+
* Get the available discount amount calculated from the ration
70+
*
71+
* @param float $ruleDiscount
72+
* @param float $qty
73+
* @param float $baseItemPrice
74+
* @param float $baseRuleTotals
75+
* @param string $discountType
76+
* @return float
77+
*/
78+
public function getDiscountAmount(
79+
float $ruleDiscount,
80+
float $qty,
81+
float $baseItemPrice,
82+
float $baseRuleTotals,
83+
string $discountType
84+
): float {
85+
$ratio = $baseItemPrice * $qty / $baseRuleTotals;
86+
return $this->deltaPriceRound->round(
87+
$ruleDiscount * $ratio,
88+
$discountType
89+
);
90+
}
91+
92+
/**
93+
* Get shipping discount amount
94+
*
95+
* @param Rule $rule
96+
* @param float $shippingAmount
97+
* @param float $quoteBaseSubtotal
98+
* @return float
99+
*/
100+
public function getShippingDiscountAmount(
101+
Rule $rule,
102+
float $shippingAmount,
103+
float $quoteBaseSubtotal
104+
): float {
105+
$ratio = $shippingAmount / $quoteBaseSubtotal;
106+
return $this->priceCurrency
107+
->roundPrice(
108+
$rule->getDiscountAmount() * $ratio
109+
);
110+
}
111+
112+
/**
113+
* Check if the current quote is multi shipping or not
114+
*
115+
* @param Quote $quote
116+
* @return bool
117+
*/
118+
public function checkMultiShippingQuote(Quote $quote): bool
119+
{
120+
$isMultiShipping = false;
121+
$extensionAttributes = $quote->getExtensionAttributes();
122+
if (!$quote->isVirtual() &&
123+
$extensionAttributes &&
124+
$extensionAttributes->getShippingAssignments()) {
125+
$shippingAssignments = $extensionAttributes->getShippingAssignments();
126+
if (count($shippingAssignments) > 1) {
127+
$isMultiShipping = true;
128+
}
129+
}
130+
return $isMultiShipping;
131+
}
132+
133+
/**
134+
* Get base rule totals for multi shipping addresses
135+
*
136+
* @param Quote $quote
137+
* @return float
138+
*/
139+
public function getQuoteTotalsForMultiShipping(Quote $quote): float
140+
{
141+
$quoteTotal = $quote->getBaseSubtotal();
142+
$extensionAttributes = $quote->getExtensionAttributes();
143+
$shippingAssignments = $extensionAttributes->getShippingAssignments();
144+
$totalShippingPrice = 0.0;
145+
foreach ($shippingAssignments as $assignment) {
146+
$totalShippingPrice += $assignment->getShipping()->getAddress()->getBaseShippingInclTax();
147+
}
148+
return $quoteTotal + $totalShippingPrice;
149+
}
150+
151+
/**
152+
* Get base rule totals for regular shipping address
153+
*
154+
* @param Quote\Address $address
155+
* @param float $baseRuleTotals
156+
* @return float
157+
*/
158+
public function getQuoteTotalsForRegularShipping(
159+
Quote\Address $address,
160+
float $baseRuleTotals
161+
): float {
162+
$baseRuleTotals += $this->calculateShippingAmountWhenAppliedToShipping(
163+
$address
164+
);
165+
return $baseRuleTotals;
166+
}
167+
168+
/**
169+
* Get base rule totals
170+
*
171+
* @param int $isAppliedToShipping
172+
* @param Quote $quote
173+
* @param bool $isMultiShipping
174+
* @param Quote\Address $address
175+
* @param float $baseRuleTotals
176+
* @return float
177+
*/
178+
public function getBaseRuleTotals(
179+
int $isAppliedToShipping,
180+
Quote $quote,
181+
bool $isMultiShipping,
182+
Quote\Address $address,
183+
float $baseRuleTotals
184+
): float {
185+
if ($isAppliedToShipping) {
186+
$baseRuleTotals = ($quote->getIsMultiShipping() && $isMultiShipping) ?
187+
$this->getQuoteTotalsForMultiShipping($quote) :
188+
$this->getQuoteTotalsForRegularShipping($address, $baseRuleTotals);
189+
} else {
190+
if ($quote->getIsMultiShipping() && $isMultiShipping) {
191+
$baseRuleTotals = $quote->getBaseSubtotal();
192+
}
193+
}
194+
return (float) $baseRuleTotals;
195+
}
196+
197+
/**
198+
* Get available discount amount
199+
*
200+
* @param Rule $rule
201+
* @param Quote $quote
202+
* @param bool $isMultiShipping
203+
* @param array $cartRules
204+
* @param float $baseDiscountAmount
205+
* @param float $availableDiscountAmount
206+
* @return float
207+
*/
208+
public function getAvailableDiscountAmount(
209+
Rule $rule,
210+
Quote $quote,
211+
bool $isMultiShipping,
212+
array $cartRules,
213+
float $baseDiscountAmount,
214+
float $availableDiscountAmount
215+
): float {
216+
if ($quote->getIsMultiShipping() && $isMultiShipping) {
217+
$availableDiscountAmount = (float)$cartRules[$rule->getId()] - $baseDiscountAmount;
218+
} else {
219+
$availableDiscountAmount -= $baseDiscountAmount;
220+
}
221+
return $availableDiscountAmount;
222+
}
223+
}

0 commit comments

Comments
 (0)