TaxCalculationPlugin.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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\Plugin;
  7. use Magento\Store\Model\StoreManagerInterface;
  8. use Magento\Tax\Api\Data\QuoteDetailsInterface;
  9. use Magento\Tax\Api\TaxCalculationInterface;
  10. use Vertex\Tax\Model\Calculator;
  11. use Vertex\Tax\Model\VertexUsageDeterminer;
  12. /**
  13. * Handle tax calculation through Vertex
  14. */
  15. class TaxCalculationPlugin
  16. {
  17. /** @var Calculator */
  18. private $calculator;
  19. /** @var StoreManagerInterface */
  20. private $storeManager;
  21. /** @var VertexUsageDeterminer */
  22. private $usageDeterminer;
  23. /**
  24. * @param StoreManagerInterface $storeManager
  25. * @param Calculator $calculator
  26. * @param VertexUsageDeterminer $usageDeterminer
  27. */
  28. public function __construct(
  29. StoreManagerInterface $storeManager,
  30. Calculator $calculator,
  31. VertexUsageDeterminer $usageDeterminer
  32. ) {
  33. $this->storeManager = $storeManager;
  34. $this->calculator = $calculator;
  35. $this->usageDeterminer = $usageDeterminer;
  36. }
  37. /**
  38. * Use Vertex to calculate tax if it can be used
  39. *
  40. * @see TaxCalculationInterface::calculateTax()
  41. * @param TaxCalculationInterface $subject
  42. * @param callable $super
  43. * @param QuoteDetailsInterface $quoteDetails
  44. * @param string|null $storeId
  45. * @param bool $round
  46. * @return \Magento\Tax\Api\Data\TaxDetailsInterface
  47. * @throws \Magento\Framework\Exception\NoSuchEntityException
  48. * @throws \InvalidArgumentException
  49. */
  50. public function aroundCalculateTax(
  51. TaxCalculationInterface $subject,
  52. callable $super,
  53. QuoteDetailsInterface $quoteDetails,
  54. $storeId = null,
  55. $round = true
  56. ) {
  57. $storeId = $this->getStoreId($storeId);
  58. if (!$this->useVertex($quoteDetails, $storeId, $this->isVirtual($quoteDetails), true)) {
  59. // Allows forward compatibility with argument additions
  60. $arguments = func_get_args();
  61. array_splice($arguments, 0, 2);
  62. return call_user_func_array($super, $arguments);
  63. }
  64. return $this->calculator->calculateTax($quoteDetails, $storeId, $round);
  65. }
  66. /**
  67. * Retrieve current Store ID
  68. *
  69. * @param string|null $storeId
  70. * @return string
  71. * @throws \Magento\Framework\Exception\NoSuchEntityException
  72. */
  73. private function getStoreId($storeId)
  74. {
  75. return $storeId ?: $this->storeManager->getStore()->getStoreId();
  76. }
  77. /**
  78. * Determine whether a quote is virtual or not
  79. *
  80. * This determination is made by whether or not the quote has a shipping
  81. * item
  82. *
  83. * @param QuoteDetailsInterface $quoteDetails
  84. * @return bool
  85. */
  86. private function isVirtual(QuoteDetailsInterface $quoteDetails)
  87. {
  88. $items = $quoteDetails->getItems();
  89. foreach ($items as $item) {
  90. if ($item->getType() === 'shipping') {
  91. return true;
  92. }
  93. }
  94. return false;
  95. }
  96. /**
  97. * Determine whether or not to use Vertex
  98. *
  99. * We make this determination based on the UsageDeterminer result as well as whether or not any items on the
  100. * quote actually have a price.
  101. *
  102. * @param QuoteDetailsInterface $quoteDetails
  103. * @param string|null $storeId
  104. * @param bool $isVirtual
  105. * @param bool $checkCalculation
  106. * @return bool
  107. */
  108. private function useVertex(QuoteDetailsInterface $quoteDetails, $storeId, $isVirtual, $checkCalculation = false)
  109. {
  110. $anItemHasPrice = false;
  111. foreach ($quoteDetails->getItems() as $item) {
  112. if ($item->getUnitPrice()) {
  113. $anItemHasPrice = true;
  114. }
  115. }
  116. return $anItemHasPrice
  117. && $this->usageDeterminer->shouldUseVertex(
  118. $storeId,
  119. $quoteDetails->getShippingAddress(),
  120. $quoteDetails->getCustomerId(),
  121. $isVirtual,
  122. $checkCalculation
  123. );
  124. }
  125. }