Tax.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Tax totals modification block. Can be used just as subblock of \Magento\Sales\Block\Order\Totals
  8. */
  9. namespace Magento\Tax\Block\Sales\Order;
  10. use Magento\Sales\Model\Order;
  11. /**
  12. * @api
  13. * @since 100.0.2
  14. */
  15. class Tax extends \Magento\Framework\View\Element\Template
  16. {
  17. /**
  18. * Tax configuration model
  19. *
  20. * @var \Magento\Tax\Model\Config
  21. */
  22. protected $_config;
  23. /**
  24. * @var Order
  25. */
  26. protected $_order;
  27. /**
  28. * @var \Magento\Framework\DataObject
  29. */
  30. protected $_source;
  31. /**
  32. * @param \Magento\Framework\View\Element\Template\Context $context
  33. * @param \Magento\Tax\Model\Config $taxConfig
  34. * @param array $data
  35. */
  36. public function __construct(
  37. \Magento\Framework\View\Element\Template\Context $context,
  38. \Magento\Tax\Model\Config $taxConfig,
  39. array $data = []
  40. ) {
  41. $this->_config = $taxConfig;
  42. parent::__construct($context, $data);
  43. }
  44. /**
  45. * Check if we nedd display full tax total info
  46. *
  47. * @return bool
  48. */
  49. public function displayFullSummary()
  50. {
  51. return $this->_config->displaySalesFullSummary($this->getOrder()->getStore());
  52. }
  53. /**
  54. * Get data (totals) source model
  55. *
  56. * @return \Magento\Framework\DataObject
  57. */
  58. public function getSource()
  59. {
  60. return $this->_source;
  61. }
  62. /**
  63. * Initialize all order totals relates with tax
  64. *
  65. * @return \Magento\Tax\Block\Sales\Order\Tax
  66. */
  67. public function initTotals()
  68. {
  69. /** @var $parent \Magento\Sales\Block\Adminhtml\Order\Invoice\Totals */
  70. $parent = $this->getParentBlock();
  71. $this->_order = $parent->getOrder();
  72. $this->_source = $parent->getSource();
  73. $store = $this->getStore();
  74. $allowTax = $this->_source->getTaxAmount() > 0 || $this->_config->displaySalesZeroTax($store);
  75. $grandTotal = (double)$this->_source->getGrandTotal();
  76. if (!$grandTotal || $allowTax && !$this->_config->displaySalesTaxWithGrandTotal($store)) {
  77. $this->_addTax();
  78. }
  79. $this->_initSubtotal();
  80. $this->_initShipping();
  81. $this->_initDiscount();
  82. $this->_initGrandTotal();
  83. return $this;
  84. }
  85. /**
  86. * Add tax total string
  87. *
  88. * @param string $after
  89. * @return \Magento\Tax\Block\Sales\Order\Tax
  90. */
  91. protected function _addTax($after = 'discount')
  92. {
  93. $taxTotal = new \Magento\Framework\DataObject(['code' => 'tax', 'block_name' => $this->getNameInLayout()]);
  94. $this->getParentBlock()->addTotal($taxTotal, $after);
  95. return $this;
  96. }
  97. /**
  98. * Get order store object
  99. *
  100. * @return \Magento\Store\Model\Store
  101. */
  102. public function getStore()
  103. {
  104. return $this->_order->getStore();
  105. }
  106. /**
  107. * @return $this
  108. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  109. */
  110. protected function _initSubtotal()
  111. {
  112. $store = $this->getStore();
  113. $parent = $this->getParentBlock();
  114. $subtotal = $parent->getTotal('subtotal');
  115. if (!$subtotal) {
  116. return $this;
  117. }
  118. if ($this->_config->displaySalesSubtotalBoth($store)) {
  119. $subtotal = (double)$this->_source->getSubtotal();
  120. $baseSubtotal = (double)$this->_source->getBaseSubtotal();
  121. $subtotalIncl = (double)$this->_source->getSubtotalInclTax();
  122. $baseSubtotalIncl = (double)$this->_source->getBaseSubtotalInclTax();
  123. if (!$subtotalIncl || !$baseSubtotalIncl) {
  124. // Calculate the subtotal if it is not set
  125. $subtotalIncl = $subtotal
  126. + $this->_source->getTaxAmount()
  127. - $this->_source->getShippingTaxAmount();
  128. $baseSubtotalIncl = $baseSubtotal
  129. + $this->_source->getBaseTaxAmount()
  130. - $this->_source->getBaseShippingTaxAmount();
  131. if ($this->_source instanceof Order) {
  132. // Adjust for the discount tax compensation
  133. foreach ($this->_source->getAllItems() as $item) {
  134. $subtotalIncl += $item->getDiscountTaxCompensationAmount();
  135. $baseSubtotalIncl += $item->getBaseDiscountTaxCompensationAmount();
  136. }
  137. }
  138. }
  139. $subtotalIncl = max(0, $subtotalIncl);
  140. $baseSubtotalIncl = max(0, $baseSubtotalIncl);
  141. $totalExcl = new \Magento\Framework\DataObject(
  142. [
  143. 'code' => 'subtotal_excl',
  144. 'value' => $subtotal,
  145. 'base_value' => $baseSubtotal,
  146. 'label' => __('Subtotal (Excl.Tax)'),
  147. ]
  148. );
  149. $totalIncl = new \Magento\Framework\DataObject(
  150. [
  151. 'code' => 'subtotal_incl',
  152. 'value' => $subtotalIncl,
  153. 'base_value' => $baseSubtotalIncl,
  154. 'label' => __('Subtotal (Incl.Tax)'),
  155. ]
  156. );
  157. $parent->addTotal($totalExcl, 'subtotal');
  158. $parent->addTotal($totalIncl, 'subtotal_excl');
  159. $parent->removeTotal('subtotal');
  160. } elseif ($this->_config->displaySalesSubtotalInclTax($store)) {
  161. $subtotalIncl = (double)$this->_source->getSubtotalInclTax();
  162. $baseSubtotalIncl = (double)$this->_source->getBaseSubtotalInclTax();
  163. if (!$subtotalIncl) {
  164. $subtotalIncl = $this->_source->getSubtotal() +
  165. $this->_source->getTaxAmount() -
  166. $this->_source->getShippingTaxAmount();
  167. }
  168. if (!$baseSubtotalIncl) {
  169. $baseSubtotalIncl = $this->_source->getBaseSubtotal() +
  170. $this->_source->getBaseTaxAmount() -
  171. $this->_source->getBaseShippingTaxAmount();
  172. }
  173. $total = $parent->getTotal('subtotal');
  174. if ($total) {
  175. $total->setValue(max(0, $subtotalIncl));
  176. $total->setBaseValue(max(0, $baseSubtotalIncl));
  177. }
  178. }
  179. return $this;
  180. }
  181. /**
  182. * @return $this
  183. */
  184. protected function _initShipping()
  185. {
  186. $store = $this->getStore();
  187. $parent = $this->getParentBlock();
  188. $shipping = $parent->getTotal('shipping');
  189. if (!$shipping) {
  190. return $this;
  191. }
  192. if ($this->_config->displaySalesShippingBoth($store)) {
  193. $shipping = (double)$this->_source->getShippingAmount();
  194. $baseShipping = (double)$this->_source->getBaseShippingAmount();
  195. $shippingIncl = (double)$this->_source->getShippingInclTax();
  196. if (!$shippingIncl) {
  197. $shippingIncl = $shipping + (double)$this->_source->getShippingTaxAmount();
  198. }
  199. $baseShippingIncl = (double)$this->_source->getBaseShippingInclTax();
  200. if (!$baseShippingIncl) {
  201. $baseShippingIncl = $baseShipping + (double)$this->_source->getBaseShippingTaxAmount();
  202. }
  203. $totalExcl = new \Magento\Framework\DataObject(
  204. [
  205. 'code' => 'shipping',
  206. 'value' => $shipping,
  207. 'base_value' => $baseShipping,
  208. 'label' => __('Shipping & Handling (Excl.Tax)'),
  209. ]
  210. );
  211. $totalIncl = new \Magento\Framework\DataObject(
  212. [
  213. 'code' => 'shipping_incl',
  214. 'value' => $shippingIncl,
  215. 'base_value' => $baseShippingIncl,
  216. 'label' => __('Shipping & Handling (Incl.Tax)'),
  217. ]
  218. );
  219. $parent->addTotal($totalExcl, 'shipping');
  220. $parent->addTotal($totalIncl, 'shipping');
  221. } elseif ($this->_config->displaySalesShippingInclTax($store)) {
  222. $shippingIncl = $this->_source->getShippingInclTax();
  223. if (!$shippingIncl) {
  224. $shippingIncl = $this->_source->getShippingAmount() + $this->_source->getShippingTaxAmount();
  225. }
  226. $baseShippingIncl = $this->_source->getBaseShippingInclTax();
  227. if (!$baseShippingIncl) {
  228. $baseShippingIncl = $this->_source->getBaseShippingAmount() +
  229. $this->_source->getBaseShippingTaxAmount();
  230. }
  231. $total = $parent->getTotal('shipping');
  232. if ($total) {
  233. $total->setValue($shippingIncl);
  234. $total->setBaseValue($baseShippingIncl);
  235. }
  236. }
  237. return $this;
  238. }
  239. /**
  240. * @return void
  241. */
  242. protected function _initDiscount()
  243. {
  244. }
  245. /**
  246. * @return $this
  247. */
  248. protected function _initGrandTotal()
  249. {
  250. $store = $this->getStore();
  251. $parent = $this->getParentBlock();
  252. $grandototal = $parent->getTotal('grand_total');
  253. if (!$grandototal || !(double)$this->_source->getGrandTotal()) {
  254. return $this;
  255. }
  256. if ($this->_config->displaySalesTaxWithGrandTotal($store)) {
  257. $grandtotal = $this->_source->getGrandTotal();
  258. $baseGrandtotal = $this->_source->getBaseGrandTotal();
  259. $grandtotalExcl = $grandtotal - $this->_source->getTaxAmount();
  260. $baseGrandtotalExcl = $baseGrandtotal - $this->_source->getBaseTaxAmount();
  261. $grandtotalExcl = max($grandtotalExcl, 0);
  262. $baseGrandtotalExcl = max($baseGrandtotalExcl, 0);
  263. $totalExcl = new \Magento\Framework\DataObject(
  264. [
  265. 'code' => 'grand_total',
  266. 'strong' => true,
  267. 'value' => $grandtotalExcl,
  268. 'base_value' => $baseGrandtotalExcl,
  269. 'label' => __('Grand Total (Excl.Tax)'),
  270. ]
  271. );
  272. $totalIncl = new \Magento\Framework\DataObject(
  273. [
  274. 'code' => 'grand_total_incl',
  275. 'strong' => true,
  276. 'value' => $grandtotal,
  277. 'base_value' => $baseGrandtotal,
  278. 'label' => __('Grand Total (Incl.Tax)'),
  279. ]
  280. );
  281. $parent->addTotal($totalExcl, 'grand_total');
  282. $this->_addTax('grand_total');
  283. $parent->addTotal($totalIncl, 'tax');
  284. }
  285. return $this;
  286. }
  287. /**
  288. * @return Order
  289. */
  290. public function getOrder()
  291. {
  292. return $this->_order;
  293. }
  294. /**
  295. * @return array
  296. */
  297. public function getLabelProperties()
  298. {
  299. return $this->getParentBlock()->getLabelProperties();
  300. }
  301. /**
  302. * @return array
  303. */
  304. public function getValueProperties()
  305. {
  306. return $this->getParentBlock()->getValueProperties();
  307. }
  308. }