Tax.php 6.5 KB

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