1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model\Order\Invoice\Total;
/**
* Collects invoice taxes.
*/
class Tax extends AbstractTotal
{
/**
* Collect invoice tax amount
*
* @param \Magento\Sales\Model\Order\Invoice $invoice
* @return $this
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function collect(\Magento\Sales\Model\Order\Invoice $invoice)
{
$totalTax = 0;
$baseTotalTax = 0;
$totalDiscountTaxCompensation = 0;
$baseTotalDiscountTaxCompensation = 0;
$order = $invoice->getOrder();
/** @var $item \Magento\Sales\Model\Order\Invoice\Item */
foreach ($invoice->getAllItems() as $item) {
$orderItem = $item->getOrderItem();
$orderItemQty = $orderItem->getQtyOrdered();
if (($orderItem->getTaxAmount() || $orderItem->getDiscountTaxCompensationAmount()) && $orderItemQty) {
if ($item->getOrderItem()->isDummy() || $item->getQty() <= 0) {
continue;
}
/**
* Resolve rounding problems
*/
$tax = $orderItem->getTaxAmount() - $orderItem->getTaxInvoiced();
$baseTax = $orderItem->getBaseTaxAmount() - $orderItem->getBaseTaxInvoiced();
$discountTaxCompensation = $orderItem->getDiscountTaxCompensationAmount() -
$orderItem->getDiscountTaxCompensationInvoiced();
$baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationAmount() -
$orderItem->getBaseDiscountTaxCompensationInvoiced();
if (!$item->isLast()) {
$availableQty = $orderItemQty - $orderItem->getQtyInvoiced();
$tax = $invoice->roundPrice($tax / $availableQty * $item->getQty());
$baseTax = $invoice->roundPrice($baseTax / $availableQty * $item->getQty(), 'base');
$discountTaxCompensation = $invoice->roundPrice(
$discountTaxCompensation / $availableQty * $item->getQty()
);
$baseDiscountTaxCompensation = $invoice->roundPrice(
$baseDiscountTaxCompensation /
$availableQty * $item->getQty(),
'base'
);
}
$item->setTaxAmount($tax);
$item->setBaseTaxAmount($baseTax);
$item->setDiscountTaxCompensationAmount($discountTaxCompensation);
$item->setBaseDiscountTaxCompensationAmount($baseDiscountTaxCompensation);
$totalTax += $tax;
$baseTotalTax += $baseTax;
$totalDiscountTaxCompensation += $discountTaxCompensation;
$baseTotalDiscountTaxCompensation += $baseDiscountTaxCompensation;
}
}
$taxDiscountCompensationAmt = $totalDiscountTaxCompensation;
$baseTaxDiscountCompensationAmt = $baseTotalDiscountTaxCompensation;
$allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationAmount() -
$order->getDiscountTaxCompensationInvoiced();
$allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationAmount() -
$order->getBaseDiscountTaxCompensationInvoiced();
if ($this->_canIncludeShipping($invoice)) {
$totalTax += $order->getShippingTaxAmount();
$baseTotalTax += $order->getBaseShippingTaxAmount();
$totalDiscountTaxCompensation += $order->getShippingDiscountTaxCompensationAmount();
$baseTotalDiscountTaxCompensation += $order->getBaseShippingDiscountTaxCompensationAmnt();
$allowedDiscountTaxCompensation += $order->getShippingDiscountTaxCompensationAmount() -
$order->getShippingDiscountTaxCompensationInvoiced();
$allowedBaseDiscountTaxCompensation += $order->getBaseShippingDiscountTaxCompensationAmnt() -
$order->getBaseShippingDiscountTaxCompensationInvoiced();
$invoice->setShippingTaxAmount($order->getShippingTaxAmount());
$invoice->setBaseShippingTaxAmount($order->getBaseShippingTaxAmount());
$invoice->setShippingDiscountTaxCompensationAmount($order->getShippingDiscountTaxCompensationAmount());
$invoice->setBaseShippingDiscountTaxCompensationAmnt($order->getBaseShippingDiscountTaxCompensationAmnt());
}
$allowedTax = $order->getTaxAmount() - $order->getTaxInvoiced();
$allowedBaseTax = $order->getBaseTaxAmount() - $order->getBaseTaxInvoiced();
if ($invoice->isLast()) {
$totalTax = $allowedTax;
$baseTotalTax = $allowedBaseTax;
$totalDiscountTaxCompensation = $allowedDiscountTaxCompensation;
$baseTotalDiscountTaxCompensation = $allowedBaseDiscountTaxCompensation;
} else {
$totalTax = min($allowedTax, $totalTax);
$baseTotalTax = min($allowedBaseTax, $baseTotalTax);
$totalDiscountTaxCompensation = min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation);
$baseTotalDiscountTaxCompensation = min(
$allowedBaseDiscountTaxCompensation,
$baseTotalDiscountTaxCompensation
);
}
$invoice->setTaxAmount($totalTax);
$invoice->setBaseTaxAmount($baseTotalTax);
$invoice->setDiscountTaxCompensationAmount($taxDiscountCompensationAmt);
$invoice->setBaseDiscountTaxCompensationAmount($baseTaxDiscountCompensationAmt);
$invoice->setGrandTotal($invoice->getGrandTotal() + $totalTax + $totalDiscountTaxCompensation);
$invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $baseTotalTax + $baseTotalDiscountTaxCompensation);
return $this;
}
/**
* Check if shipping tax calculation can be included to current invoice
*
* @param \Magento\Sales\Model\Order\Invoice $invoice
* @return bool
*/
protected function _canIncludeShipping($invoice)
{
$includeShippingTax = true;
/**
* Check shipping amount in previous invoices
*/
foreach ($invoice->getOrder()->getInvoiceCollection() as $previousInvoice) {
if ($previousInvoice->getShippingAmount() && !$previousInvoice->isCanceled()) {
$includeShippingTax = false;
}
}
return $includeShippingTax;
}
}