OrderSave.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php
  2. /**
  3. *
  4. * Copyright © Magento, Inc. All rights reserved.
  5. * See COPYING.txt for license details.
  6. */
  7. namespace Magento\Tax\Model\Plugin;
  8. use Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtension;
  9. class OrderSave
  10. {
  11. /**
  12. * @var \Magento\Tax\Model\Sales\Order\TaxFactory
  13. */
  14. protected $orderTaxFactory;
  15. /**
  16. * @var \Magento\Sales\Model\Order\Tax\ItemFactory
  17. */
  18. protected $taxItemFactory;
  19. /**
  20. * @param \Magento\Tax\Model\Sales\Order\TaxFactory $orderTaxFactory
  21. * @param \Magento\Sales\Model\Order\Tax\ItemFactory $taxItemFactory
  22. */
  23. public function __construct(
  24. \Magento\Tax\Model\Sales\Order\TaxFactory $orderTaxFactory,
  25. \Magento\Sales\Model\Order\Tax\ItemFactory $taxItemFactory
  26. ) {
  27. $this->orderTaxFactory = $orderTaxFactory;
  28. $this->taxItemFactory = $taxItemFactory;
  29. }
  30. /**
  31. * Save order tax
  32. *
  33. * @param \Magento\Sales\Api\OrderRepositoryInterface $subject
  34. * @param \Magento\Sales\Api\Data\OrderInterface $order
  35. * @return \Magento\Sales\Api\Data\OrderInterface
  36. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  37. */
  38. public function afterSave(
  39. \Magento\Sales\Api\OrderRepositoryInterface $subject,
  40. \Magento\Sales\Api\Data\OrderInterface $order
  41. ) {
  42. $this->saveOrderTax($order);
  43. return $order;
  44. }
  45. /**
  46. * @param \Magento\Sales\Api\Data\OrderInterface $order
  47. * @return $this
  48. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  49. * @SuppressWarnings(PHPMD.NPathComplexity)
  50. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  51. */
  52. protected function saveOrderTax(\Magento\Sales\Api\Data\OrderInterface $order)
  53. {
  54. $extensionAttribute = $order->getExtensionAttributes();
  55. if (!$extensionAttribute ||
  56. !$extensionAttribute->getConvertingFromQuote() ||
  57. $order->getAppliedTaxIsSaved()) {
  58. return;
  59. }
  60. /** @var \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface[]|null $taxes */
  61. $taxes = $extensionAttribute->getAppliedTaxes();
  62. if ($taxes == null) {
  63. $taxes = [];
  64. }
  65. /** @var \Magento\Tax\Api\Data\OrderTaxDetailsItemInterface[]|null $taxesForItems */
  66. $taxesForItems = $extensionAttribute->getItemAppliedTaxes();
  67. if ($taxesForItems == null) {
  68. $taxesForItems = [];
  69. }
  70. $ratesIdQuoteItemId = [];
  71. foreach ($taxesForItems as $taxesArray) {
  72. foreach ($taxesArray['applied_taxes'] as $rates) {
  73. if (isset($rates['extension_attributes'])) {
  74. $taxRates = $rates['extension_attributes'] instanceof OrderTaxDetailsAppliedTaxExtension
  75. ? $rates['extension_attributes']->getRates()
  76. : $rates['extension_attributes']['rates'];
  77. if (is_array($taxRates)) {
  78. if (count($taxRates) == 1) {
  79. $ratesIdQuoteItemId[$rates['id']][] = [
  80. 'id' => $taxesArray['item_id'],
  81. 'percent' => $rates['percent'],
  82. 'code' => $taxRates[0]['code'],
  83. 'associated_item_id' => $taxesArray['associated_item_id'],
  84. 'item_type' => $taxesArray['type'],
  85. 'amount' => $rates['amount'],
  86. 'base_amount' => $rates['base_amount'],
  87. 'real_amount' => $rates['amount'],
  88. 'real_base_amount' => $rates['base_amount'],
  89. ];
  90. } else {
  91. $percentSum = 0;
  92. foreach ($taxRates as $rate) {
  93. $percentSum += $rate['percent'];
  94. }
  95. foreach ($taxRates as $rate) {
  96. $realAmount = $rates['amount'] * $rate['percent'] / $percentSum;
  97. $realBaseAmount = $rates['base_amount'] * $rate['percent'] / $percentSum;
  98. $ratesIdQuoteItemId[$rates['id']][] = [
  99. 'id' => $taxesArray['item_id'],
  100. 'percent' => $rate['percent'],
  101. 'code' => $rate['code'],
  102. 'associated_item_id' => $taxesArray['associated_item_id'],
  103. 'item_type' => $taxesArray['type'],
  104. 'amount' => $rates['amount'],
  105. 'base_amount' => $rates['base_amount'],
  106. 'real_amount' => $realAmount,
  107. 'real_base_amount' => $realBaseAmount,
  108. ];
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. foreach ($taxes as $row) {
  116. $id = $row['id'];
  117. if (isset($row['extension_attributes'])) {
  118. $taxRates = $row['extension_attributes'] instanceof OrderTaxDetailsAppliedTaxExtension
  119. ? $row['extension_attributes']->getRates()
  120. : $row['extension_attributes']['rates'];
  121. if (is_array($taxRates)) {
  122. foreach ($taxRates as $tax) {
  123. if ($row['percent'] == null) {
  124. $baseRealAmount = $row['base_amount'];
  125. } else {
  126. if ($row['percent'] == 0 || $tax['percent'] == 0) {
  127. continue;
  128. }
  129. $baseRealAmount = $row['base_amount'] / $row['percent'] * $tax['percent'];
  130. }
  131. $hidden = isset($row['hidden']) ? $row['hidden'] : 0;
  132. $priority = isset($tax['priority']) ? $tax['priority'] : 0;
  133. $position = isset($tax['position']) ? $tax['position'] : 0;
  134. $process = isset($row['process']) ? $row['process'] : 0;
  135. $data = [
  136. 'order_id' => $order->getEntityId(),
  137. 'code' => $tax['code'],
  138. 'title' => $tax['title'],
  139. 'hidden' => $hidden,
  140. 'percent' => $tax['percent'],
  141. 'priority' => $priority,
  142. 'position' => $position,
  143. 'amount' => $row['amount'],
  144. 'base_amount' => $row['base_amount'],
  145. 'process' => $process,
  146. 'base_real_amount' => $baseRealAmount,
  147. ];
  148. /** @var $orderTax \Magento\Tax\Model\Sales\Order\Tax */
  149. $orderTax = $this->orderTaxFactory->create();
  150. $result = $orderTax->setData($data)->save();
  151. if (isset($ratesIdQuoteItemId[$id])) {
  152. foreach ($ratesIdQuoteItemId[$id] as $quoteItemId) {
  153. if ($quoteItemId['code'] === $tax['code']) {
  154. $itemId = null;
  155. $associatedItemId = null;
  156. if (isset($quoteItemId['id'])) {
  157. //This is a product item
  158. $item = $order->getItemByQuoteItemId($quoteItemId['id']);
  159. if ($item !== null && $item->getId()) {
  160. $itemId = $item->getId();
  161. }
  162. } elseif (isset($quoteItemId['associated_item_id'])) {
  163. //This item is associated with a product item
  164. $item = $order->getItemByQuoteItemId($quoteItemId['associated_item_id']);
  165. $associatedItemId = $item->getId();
  166. }
  167. $data = [
  168. 'item_id' => $itemId,
  169. 'tax_id' => $result->getTaxId(),
  170. 'tax_percent' => $quoteItemId['percent'],
  171. 'associated_item_id' => $associatedItemId,
  172. 'amount' => $quoteItemId['amount'],
  173. 'base_amount' => $quoteItemId['base_amount'],
  174. 'real_amount' => $quoteItemId['real_amount'],
  175. 'real_base_amount' => $quoteItemId['real_base_amount'],
  176. 'taxable_item_type' => $quoteItemId['item_type'],
  177. ];
  178. /** @var $taxItem \Magento\Sales\Model\Order\Tax\Item */
  179. $taxItem = $this->taxItemFactory->create();
  180. $taxItem->setData($data)->save();
  181. }
  182. }
  183. }
  184. }
  185. }
  186. }
  187. }
  188. $order->setAppliedTaxIsSaved(true);
  189. return $this;
  190. }
  191. }