55 */
66namespace Magento \Sales \Model \Order \Creditmemo \Total ;
77
8+ use Magento \Sales \Api \Data \CreditmemoInterface ;
9+ use Magento \Sales \Model \Order \Creditmemo ;
10+ use Magento \Sales \Model \Order \Invoice ;
11+ use Magento \Sales \Model \ResourceModel \Order \Invoice as ResourceInvoice ;
12+
813/**
914 * Collects credit memo taxes.
1015 */
1116class Tax extends AbstractTotal
1217{
1318 /**
14- * Collects credit memo taxes.
15- *
16- * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
17- * @return $this
18- *
19+ * @var ResourceInvoice
20+ */
21+ private $ resourceInvoice ;
22+
23+ /**
24+ * @param ResourceInvoice $resourceInvoice
25+ * @param array $data
26+ */
27+ public function __construct (ResourceInvoice $ resourceInvoice , array $ data = [])
28+ {
29+ $ this ->resourceInvoice = $ resourceInvoice ;
30+ parent ::__construct ($ data );
31+ }
32+
33+ /**
34+ * {@inheritdoc}
1935 * @SuppressWarnings(PHPMD.NPathComplexity)
2036 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
2137 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
2238 */
23- public function collect (\ Magento \ Sales \ Model \ Order \ Creditmemo $ creditmemo )
39+ public function collect (Creditmemo $ creditmemo )
2440 {
2541 $ shippingTaxAmount = 0 ;
2642 $ baseShippingTaxAmount = 0 ;
2743 $ totalTax = 0 ;
2844 $ baseTotalTax = 0 ;
2945 $ totalDiscountTaxCompensation = 0 ;
3046 $ baseTotalDiscountTaxCompensation = 0 ;
31-
3247 $ order = $ creditmemo ->getOrder ();
3348
34- /** @var $item \Magento\Sales\Model\Order\Creditmemo\Item */
3549 foreach ($ creditmemo ->getAllItems () as $ item ) {
3650 $ orderItem = $ item ->getOrderItem ();
3751 if ($ orderItem ->isDummy () || $ item ->getQty () <= 0 ) {
3852 continue ;
3953 }
54+
4055 $ orderItemTax = (double )$ orderItem ->getTaxInvoiced ();
4156 $ baseOrderItemTax = (double )$ orderItem ->getBaseTaxInvoiced ();
4257 $ orderItemQty = (double )$ orderItem ->getQtyInvoiced ();
4358
4459 if ($ orderItemQty ) {
45- /**
46- * Check item tax amount
47- */
48-
60+ /** Check item tax amount */
4961 $ tax = $ orderItemTax - $ orderItem ->getTaxRefunded ();
5062 $ baseTax = $ baseOrderItemTax - $ orderItem ->getBaseTaxRefunded ();
51- $ discountTaxCompensation = $ orderItem ->getDiscountTaxCompensationInvoiced () -
52- $ orderItem ->getDiscountTaxCompensationRefunded ();
53- $ baseDiscountTaxCompensation = $ orderItem ->getBaseDiscountTaxCompensationInvoiced () -
54- $ orderItem ->getBaseDiscountTaxCompensationRefunded ();
63+ $ discountTaxCompensation = $ orderItem ->getDiscountTaxCompensationInvoiced ()
64+ - $ orderItem ->getDiscountTaxCompensationRefunded ();
65+ $ baseDiscountTaxCompensation = $ orderItem ->getBaseDiscountTaxCompensationInvoiced ()
66+ - $ orderItem ->getBaseDiscountTaxCompensationRefunded ();
5567 if (!$ item ->isLast ()) {
5668 $ availableQty = $ orderItemQty - $ orderItem ->getQtyRefunded ();
5769 $ tax = $ creditmemo ->roundPrice ($ tax / $ availableQty * $ item ->getQty ());
58- $ baseTax = $ creditmemo ->roundPrice ($ baseTax / $ availableQty * $ item ->getQty (), 'base ' );
59- $ discountTaxCompensation =
60- $ creditmemo ->roundPrice ($ discountTaxCompensation / $ availableQty * $ item ->getQty ());
61- $ baseDiscountTaxCompensation =
62- $ creditmemo ->roundPrice ($ baseDiscountTaxCompensation / $ availableQty * $ item ->getQty (), 'base ' );
70+ $ baseTax = $ creditmemo ->roundPrice (($ baseTax / $ availableQty * $ item ->getQty ()), 'base ' );
71+ $ discountTaxCompensation = $ creditmemo ->roundPrice (
72+ $ discountTaxCompensation / $ availableQty * $ item ->getQty ()
73+ );
74+ $ baseDiscountTaxCompensation = $ creditmemo ->roundPrice (
75+ $ baseDiscountTaxCompensation / $ availableQty * $ item ->getQty (),
76+ 'base '
77+ );
6378 }
6479
6580 $ item ->setTaxAmount ($ tax );
@@ -77,14 +92,14 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
7792 $ isPartialShippingRefunded = false ;
7893 $ baseOrderShippingAmount = (float )$ order ->getBaseShippingAmount ();
7994 if ($ invoice = $ creditmemo ->getInvoice ()) {
80- //recalculate tax amounts in case if refund shipping value was changed
95+ // recalculate tax amounts in case if refund shipping value was changed
8196 if ($ baseOrderShippingAmount && $ creditmemo ->getBaseShippingAmount () !== null ) {
8297 $ taxFactor = $ creditmemo ->getBaseShippingAmount () / $ baseOrderShippingAmount ;
8398 $ shippingTaxAmount = $ invoice ->getShippingTaxAmount () * $ taxFactor ;
8499 $ baseShippingTaxAmount = $ invoice ->getBaseShippingTaxAmount () * $ taxFactor ;
85100 $ totalDiscountTaxCompensation += $ invoice ->getShippingDiscountTaxCompensationAmount () * $ taxFactor ;
86- $ baseTotalDiscountTaxCompensation +=
87- $ invoice -> getBaseShippingDiscountTaxCompensationAmnt () * $ taxFactor ;
101+ $ baseTotalDiscountTaxCompensation += $ invoice -> getBaseShippingDiscountTaxCompensationAmnt ()
102+ * $ taxFactor ;
88103 $ shippingTaxAmount = $ creditmemo ->roundPrice ($ shippingTaxAmount );
89104 $ baseShippingTaxAmount = $ creditmemo ->roundPrice ($ baseShippingTaxAmount , 'base ' );
90105 $ totalDiscountTaxCompensation = $ creditmemo ->roundPrice ($ totalDiscountTaxCompensation );
@@ -97,14 +112,11 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
97112 }
98113 } else {
99114 $ orderShippingAmount = $ order ->getShippingAmount ();
100-
101115 $ baseOrderShippingRefundedAmount = $ order ->getBaseShippingRefunded ();
102-
103116 $ shippingTaxAmount = 0 ;
104117 $ baseShippingTaxAmount = 0 ;
105118 $ shippingDiscountTaxCompensationAmount = 0 ;
106119 $ baseShippingDiscountTaxCompensationAmount = 0 ;
107-
108120 $ shippingDelta = $ baseOrderShippingAmount - $ baseOrderShippingRefundedAmount ;
109121
110122 if ($ shippingDelta > $ creditmemo ->getBaseShippingAmount ()) {
@@ -113,45 +125,39 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
113125 $ shippingTaxAmount = $ order ->getShippingTaxAmount () * $ part ;
114126 $ baseShippingTaxAmount = $ order ->getBaseShippingTaxAmount () * $ basePart ;
115127 $ shippingDiscountTaxCompensationAmount = $ order ->getShippingDiscountTaxCompensationAmount () * $ part ;
116- $ baseShippingDiscountTaxCompensationAmount =
117- $ order -> getBaseShippingDiscountTaxCompensationAmnt () * $ basePart ;
128+ $ baseShippingDiscountTaxCompensationAmount = $ order -> getBaseShippingDiscountTaxCompensationAmnt ()
129+ * $ basePart ;
118130 $ shippingTaxAmount = $ creditmemo ->roundPrice ($ shippingTaxAmount );
119131 $ baseShippingTaxAmount = $ creditmemo ->roundPrice ($ baseShippingTaxAmount , 'base ' );
120- $ shippingDiscountTaxCompensationAmount =
121- $ creditmemo ->roundPrice ($ shippingDiscountTaxCompensationAmount );
122- $ baseShippingDiscountTaxCompensationAmount =
123- $ creditmemo ->roundPrice ($ baseShippingDiscountTaxCompensationAmount , 'base ' );
132+ $ shippingDiscountTaxCompensationAmount = $ creditmemo ->roundPrice (
133+ $ shippingDiscountTaxCompensationAmount
134+ );
135+ $ baseShippingDiscountTaxCompensationAmount = $ creditmemo ->roundPrice (
136+ $ baseShippingDiscountTaxCompensationAmount ,
137+ 'base '
138+ );
124139 if ($ part < 1 && $ order ->getShippingTaxAmount () > 0 ) {
125140 $ isPartialShippingRefunded = true ;
126141 }
127142 } elseif ($ shippingDelta == $ creditmemo ->getBaseShippingAmount ()) {
128143 $ shippingTaxAmount = $ order ->getShippingTaxAmount () - $ order ->getShippingTaxRefunded ();
129144 $ baseShippingTaxAmount = $ order ->getBaseShippingTaxAmount () - $ order ->getBaseShippingTaxRefunded ();
130- $ shippingDiscountTaxCompensationAmount = $ order ->getShippingDiscountTaxCompensationAmount () -
131- $ order ->getShippingDiscountTaxCompensationRefunded ();
132- $ baseShippingDiscountTaxCompensationAmount = $ order ->getBaseShippingDiscountTaxCompensationAmnt () -
133- $ order ->getBaseShippingDiscountTaxCompensationRefunded ();
145+ $ shippingDiscountTaxCompensationAmount = $ order ->getShippingDiscountTaxCompensationAmount ()
146+ - $ order ->getShippingDiscountTaxCompensationRefunded ();
147+ $ baseShippingDiscountTaxCompensationAmount = $ order ->getBaseShippingDiscountTaxCompensationAmnt ()
148+ - $ order ->getBaseShippingDiscountTaxCompensationRefunded ();
134149 }
150+
135151 $ totalTax += $ shippingTaxAmount ;
136152 $ baseTotalTax += $ baseShippingTaxAmount ;
137153 $ totalDiscountTaxCompensation += $ shippingDiscountTaxCompensationAmount ;
138154 $ baseTotalDiscountTaxCompensation += $ baseShippingDiscountTaxCompensationAmount ;
139155 }
140156
141- $ allowedTax = $ order ->getTaxInvoiced () - $ order ->getTaxRefunded () - $ creditmemo ->getTaxAmount ();
142- $ allowedBaseTax = $ order ->getBaseTaxInvoiced () - $ order ->getBaseTaxRefunded () - $ creditmemo ->getBaseTaxAmount ();
143- $ allowedDiscountTaxCompensation = $ order ->getDiscountTaxCompensationInvoiced () +
144- $ order ->getShippingDiscountTaxCompensationAmount () -
145- $ order ->getDiscountTaxCompensationRefunded () -
146- $ order ->getShippingDiscountTaxCompensationRefunded () -
147- $ creditmemo ->getDiscountTaxCompensationAmount () -
148- $ creditmemo ->getShippingDiscountTaxCompensationAmount ();
149- $ allowedBaseDiscountTaxCompensation = $ order ->getBaseDiscountTaxCompensationInvoiced () +
150- $ order ->getBaseShippingDiscountTaxCompensationAmnt () -
151- $ order ->getBaseDiscountTaxCompensationRefunded () -
152- $ order ->getBaseShippingDiscountTaxCompensationRefunded () -
153- $ creditmemo ->getBaseShippingDiscountTaxCompensationAmnt () -
154- $ creditmemo ->getBaseDiscountTaxCompensationAmount ();
157+ $ allowedTax = $ this ->calculateAllowedTax ($ creditmemo );
158+ $ allowedBaseTax = $ this ->calculateAllowedBaseTax ($ creditmemo );
159+ $ allowedDiscountTaxCompensation = $ this ->calculateAllowedDiscountTaxCompensation ($ creditmemo );
160+ $ allowedBaseDiscountTaxCompensation = $ this ->calculateAllowedBaseDiscountTaxCompensation ($ creditmemo );
155161
156162 if ($ creditmemo ->isLast () && !$ isPartialShippingRefunded ) {
157163 $ totalTax = $ allowedTax ;
@@ -161,10 +167,11 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
161167 } else {
162168 $ totalTax = min ($ allowedTax , $ totalTax );
163169 $ baseTotalTax = min ($ allowedBaseTax , $ baseTotalTax );
164- $ totalDiscountTaxCompensation =
165- min ($ allowedDiscountTaxCompensation , $ totalDiscountTaxCompensation );
166- $ baseTotalDiscountTaxCompensation =
167- min ($ allowedBaseDiscountTaxCompensation , $ baseTotalDiscountTaxCompensation );
170+ $ totalDiscountTaxCompensation = min ($ allowedDiscountTaxCompensation , $ totalDiscountTaxCompensation );
171+ $ baseTotalDiscountTaxCompensation = min (
172+ $ allowedBaseDiscountTaxCompensation ,
173+ $ baseTotalDiscountTaxCompensation
174+ );
168175 }
169176
170177 $ creditmemo ->setTaxAmount ($ creditmemo ->getTaxAmount () + $ totalTax );
@@ -177,9 +184,132 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
177184
178185 $ creditmemo ->setGrandTotal ($ creditmemo ->getGrandTotal () + $ totalTax + $ totalDiscountTaxCompensation );
179186 $ creditmemo ->setBaseGrandTotal (
180- $ creditmemo ->getBaseGrandTotal () +
181- $ baseTotalTax + $ baseTotalDiscountTaxCompensation
187+ $ creditmemo ->getBaseGrandTotal () + $ baseTotalTax + $ baseTotalDiscountTaxCompensation
182188 );
183189 return $ this ;
190+
191+ }
192+
193+ /**
194+ * Calculate allowed to Credit Memo tax amount
195+ *
196+ * @param Creditmemo $creditMemo
197+ * @return float
198+ */
199+ private function calculateAllowedTax (Creditmemo $ creditMemo ): float
200+ {
201+ $ invoice = $ creditMemo ->getInvoice ();
202+ $ order = $ creditMemo ->getOrder ();
203+ if ($ invoice !== null ) {
204+ $ amount = $ invoice ->getTaxAmount ()
205+ - $ this ->calculateInvoiceRefundedAmount ($ invoice , CreditmemoInterface::TAX_AMOUNT );
206+ } else {
207+ $ amount = $ order ->getTaxInvoiced () - $ order ->getTaxRefunded ();
208+ }
209+
210+ return (float ) $ amount - $ creditMemo ->getTaxAmount ();
211+ }
212+
213+ /**
214+ * Calculate allowed to Credit Memo tax amount in the base currency
215+ *
216+ * @param Creditmemo $creditMemo
217+ * @return float
218+ */
219+ private function calculateAllowedBaseTax (Creditmemo $ creditMemo ): float
220+ {
221+ $ invoice = $ creditMemo ->getInvoice ();
222+ $ order = $ creditMemo ->getOrder ();
223+
224+ if ($ invoice !== null ) {
225+ $ amount = $ invoice ->getBaseTaxAmount ()
226+ - $ this ->calculateInvoiceRefundedAmount ($ invoice , CreditmemoInterface::BASE_TAX_AMOUNT );
227+ } else {
228+ $ amount = $ order ->getBaseTaxInvoiced () - $ order ->getBaseTaxRefunded ();
229+ }
230+
231+ return (float ) $ amount - $ creditMemo ->getBaseTaxAmount ();
232+ }
233+
234+ /**
235+ * Calculate allowed to Credit Memo discount tax compensation amount
236+ *
237+ * @param Creditmemo $creditMemo
238+ * @return float
239+ */
240+ private function calculateAllowedDiscountTaxCompensation (Creditmemo $ creditMemo ): float
241+ {
242+ $ invoice = $ creditMemo ->getInvoice ();
243+ $ order = $ creditMemo ->getOrder ();
244+
245+ if ($ invoice ) {
246+ $ amount = $ invoice ->getDiscountTaxCompensationAmount ()
247+ + $ invoice ->getShippingDiscountTaxCompensationAmount ()
248+ - $ this ->calculateInvoiceRefundedAmount (
249+ $ invoice ,
250+ CreditmemoInterface::DISCOUNT_TAX_COMPENSATION_AMOUNT
251+ ) - $ this ->calculateInvoiceRefundedAmount (
252+ $ invoice ,
253+ CreditmemoInterface::SHIPPING_DISCOUNT_TAX_COMPENSATION_AMOUNT
254+ );
255+ } else {
256+ $ amount = $ order ->getDiscountTaxCompensationInvoiced ()
257+ + $ order ->getShippingDiscountTaxCompensationAmount ()
258+ - $ order ->getDiscountTaxCompensationRefunded ()
259+ - $ order ->getShippingDiscountTaxCompensationRefunded ();
260+ }
261+
262+ return (float ) $ amount
263+ - $ creditMemo ->getDiscountTaxCompensationAmount ()
264+ - $ creditMemo ->getShippingDiscountTaxCompensationAmount ();
265+ }
266+
267+ /**
268+ * Calculate allowed to Credit Memo discount tax compensation amount in the base currency
269+ *
270+ * @param Creditmemo $creditMemo
271+ * @return float
272+ */
273+ private function calculateAllowedBaseDiscountTaxCompensation (Creditmemo $ creditMemo ): float
274+ {
275+ $ invoice = $ creditMemo ->getInvoice ();
276+ $ order = $ creditMemo ->getOrder ();
277+
278+ if ($ invoice ) {
279+ $ amount = $ invoice ->getBaseDiscountTaxCompensationAmount ()
280+ + $ invoice ->getBaseShippingDiscountTaxCompensationAmnt ()
281+ - $ this ->calculateInvoiceRefundedAmount (
282+ $ invoice ,
283+ CreditmemoInterface::BASE_DISCOUNT_TAX_COMPENSATION_AMOUNT
284+ ) - $ this ->calculateInvoiceRefundedAmount (
285+ $ invoice ,
286+ CreditmemoInterface::BASE_SHIPPING_DISCOUNT_TAX_COMPENSATION_AMNT
287+ );
288+ } else {
289+ $ amount = $ order ->getBaseDiscountTaxCompensationInvoiced ()
290+ + $ order ->getBaseShippingDiscountTaxCompensationAmnt ()
291+ - $ order ->getBaseDiscountTaxCompensationRefunded ()
292+ - $ order ->getBaseShippingDiscountTaxCompensationRefunded ();
293+ }
294+
295+ return (float ) $ amount
296+ - $ creditMemo ->getBaseShippingDiscountTaxCompensationAmnt ()
297+ - $ creditMemo ->getBaseDiscountTaxCompensationAmount ();
298+ }
299+
300+ /**
301+ * Calculate refunded amount for invoice
302+ *
303+ * @param Invoice $invoice
304+ * @param string $field
305+ * @return float
306+ */
307+ private function calculateInvoiceRefundedAmount (Invoice $ invoice , string $ field ): float
308+ {
309+ if (empty ($ invoice ->getId ())) {
310+ return 0 ;
311+ }
312+
313+ return $ this ->resourceInvoice ->calculateRefundedAmount ((int )$ invoice ->getId (), $ field );
184314 }
185315}
0 commit comments