ItemCalculator.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. /**
  3. * @copyright Vertex. All rights reserved. https://www.vertexinc.com/
  4. * @author Mediotype https://www.mediotype.com/
  5. */
  6. namespace Vertex\Tax\Model\Calculation\VertexCalculator;
  7. use Magento\Directory\Model\PriceCurrency;
  8. use Magento\Framework\DataObject;
  9. use Magento\Framework\DataObjectFactory;
  10. use Magento\Framework\Pricing\PriceCurrencyInterface;
  11. use Magento\Tax\Api\Data\QuoteDetailsItemInterface;
  12. use Vertex\Tax\Model\Calculation\VertexCalculator;
  13. use Vertex\Tax\Model\ItemCode;
  14. use Vertex\Tax\Model\ItemType;
  15. use Vertex\Tax\Model\TaxRegistry;
  16. /**
  17. * Determines taxes for an Item
  18. */
  19. class ItemCalculator
  20. {
  21. /** @var TaxRegistry */
  22. private $taxRegistry;
  23. /** @var DataObjectFactory */
  24. private $objectFactory;
  25. /** @var GwItemKeyManager */
  26. private $gwItemKeyManager;
  27. /** @var ItemType */
  28. private $itemType;
  29. /** @var ItemCode */
  30. private $itemCode;
  31. /** @var ItemKeyManager */
  32. private $itemKeyManager;
  33. /** @var PriceCurrencyInterface */
  34. private $currency;
  35. /**
  36. * @param TaxRegistry $taxRegistry
  37. * @param DataObjectFactory $objectFactory
  38. * @param ItemType $itemType
  39. * @param ItemCode $itemCode
  40. * @param ItemKeyManager $itemKeyManager
  41. * @param GwItemKeyManager $gwItemKeyManager
  42. * @param PriceCurrencyInterface $currency
  43. */
  44. public function __construct(
  45. TaxRegistry $taxRegistry,
  46. DataObjectFactory $objectFactory,
  47. ItemType $itemType,
  48. ItemCode $itemCode,
  49. ItemKeyManager $itemKeyManager,
  50. GwItemKeyManager $gwItemKeyManager,
  51. PriceCurrencyInterface $currency
  52. ) {
  53. $this->taxRegistry = $taxRegistry;
  54. $this->objectFactory = $objectFactory;
  55. $this->itemType = $itemType;
  56. $this->itemCode = $itemCode;
  57. $this->itemKeyManager = $itemKeyManager;
  58. $this->gwItemKeyManager = $gwItemKeyManager;
  59. $this->currency = $currency;
  60. }
  61. /**
  62. * Retrieve an object containing the relevant taxes for the QuoteDetailsItem
  63. *
  64. * @param QuoteDetailsItemInterface $item
  65. * @param array $itemTaxes
  66. * @param bool $round
  67. * @return DataObject
  68. */
  69. public function calculateItemTax(
  70. QuoteDetailsItemInterface $item,
  71. array $itemTaxes,
  72. $round = true
  73. ) {
  74. /** @var DataObject $itemTax */
  75. $itemTax = $this->objectFactory->create();
  76. $type = $item->getType();
  77. switch ($type) {
  78. case $this->itemType->product():
  79. $this->updateItemTaxFromKey($itemTax, $itemTaxes, $this->itemKeyManager->get($item));
  80. break;
  81. case $this->itemType->giftWrap():
  82. $this->updateItemTaxFromKey($itemTax, $itemTaxes, $this->gwItemKeyManager->get($item));
  83. break;
  84. case $this->itemType->shipping():
  85. $this->updateItemTaxFromKey($itemTax, $itemTaxes, VertexCalculator::VERTEX_SHIPPING_LINE_ITEM_ID);
  86. break;
  87. case $this->itemType->orderPrintedCard():
  88. $this->updateItemTaxFromKey($itemTax, $itemTaxes, $this->itemCode->printedCard());
  89. break;
  90. case $this->itemType->orderGiftWrap():
  91. $this->updateItemTaxFromKey($itemTax, $itemTaxes, $this->itemCode->giftWrap());
  92. break;
  93. }
  94. $this->convertNonBaseCurrency($itemTax, $item, $round);
  95. return $itemTax;
  96. }
  97. /**
  98. * Given a string to search for, update the itemTax with the calculated taxes.
  99. *
  100. * @param DataObject $itemTax
  101. * @param array $itemTaxes
  102. * @param string $key
  103. */
  104. private function updateItemTaxFromKey(DataObject $itemTax, array $itemTaxes, $key)
  105. {
  106. if (isset($itemTaxes[$key])) {
  107. $itemTax->addData($itemTaxes[$key]->getData());
  108. }
  109. }
  110. /**
  111. * Re-calculate taxes if a currency is not in the base currency
  112. *
  113. * Magento_Tax runs through this function once for each currency. We've calculated and cached the rate for the base
  114. * currency. In this way, if the item's UnitPrice isn't equal to our UnitPrice from Vertex we know it's a different
  115. * currency and recalculate it.
  116. *
  117. * @param DataObject $itemTax
  118. * @param QuoteDetailsItemInterface $item
  119. * @param bool $round
  120. * @return void
  121. */
  122. private function convertNonBaseCurrency(DataObject $itemTax, QuoteDetailsItemInterface $item, $round = true)
  123. {
  124. if ($itemTax->hasUnitPrice() && $itemTax->getUnitPrice() !== $item->getUnitPrice()) {
  125. $rowAmount = ($item->getQuantity() * $item->getUnitPrice()) - $item->getDiscountAmount();
  126. $taxAmount = $rowAmount * $itemTax->getTaxRate();
  127. $itemTax->setTaxAmount($round ? $this->currency->round($taxAmount) : $taxAmount);
  128. }
  129. }
  130. /**
  131. * Retrieve Vertex Item Taxes
  132. *
  133. * @return mixed
  134. */
  135. public function getVertexItemTaxes()
  136. {
  137. return $this->taxRegistry->lookupTaxes();
  138. }
  139. /**
  140. * Create an empty item tax object
  141. *
  142. * @return DataObject
  143. */
  144. public function getEmptyItemTax()
  145. {
  146. return $this->objectFactory->create();
  147. }
  148. }