Weee.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Weee\Model\Total\Quote;
  7. use Magento\Framework\Pricing\PriceCurrencyInterface;
  8. use Magento\Quote\Model\Quote\Address\Total\AbstractTotal;
  9. use Magento\Store\Model\Store;
  10. use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector;
  11. class Weee extends AbstractTotal
  12. {
  13. /**
  14. * Constant for weee item code prefix
  15. */
  16. const ITEM_CODE_WEEE_PREFIX = 'weee';
  17. /**
  18. * Constant for weee item type
  19. */
  20. const ITEM_TYPE = 'weee';
  21. /**
  22. * @var \Magento\Weee\Helper\Data
  23. */
  24. protected $weeeData;
  25. /**
  26. * @var \Magento\Store\Model\Store
  27. */
  28. protected $_store;
  29. /**
  30. * Counter
  31. *
  32. * @var int
  33. */
  34. protected $counter = 0;
  35. /**
  36. * Array to keep track of weee taxable item code to quote item
  37. *
  38. * @var array
  39. */
  40. protected $weeeCodeToItemMap;
  41. /**
  42. * Accumulates totals for Weee excluding tax
  43. *
  44. * @var int
  45. */
  46. protected $weeeTotalExclTax;
  47. /**
  48. * Accumulates totals for Weee base excluding tax
  49. *
  50. * @var int
  51. */
  52. protected $weeeBaseTotalExclTax;
  53. /**
  54. * @var PriceCurrencyInterface
  55. */
  56. protected $priceCurrency;
  57. /**
  58. * @param \Magento\Weee\Helper\Data $weeeData
  59. * @param PriceCurrencyInterface $priceCurrency
  60. */
  61. public function __construct(
  62. \Magento\Weee\Helper\Data $weeeData,
  63. PriceCurrencyInterface $priceCurrency
  64. ) {
  65. $this->priceCurrency = $priceCurrency;
  66. $this->weeeData = $weeeData;
  67. $this->setCode('weee');
  68. $this->weeeCodeToItemMap = [];
  69. }
  70. /**
  71. * Collect Weee amounts for the quote / order
  72. *
  73. * @param \Magento\Quote\Model\Quote $quote
  74. * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
  75. * @param \Magento\Quote\Model\Quote\Address\Total $total
  76. * @return $this
  77. */
  78. public function collect(
  79. \Magento\Quote\Model\Quote $quote,
  80. \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
  81. \Magento\Quote\Model\Quote\Address\Total $total
  82. ) {
  83. AbstractTotal::collect($quote, $shippingAssignment, $total);
  84. $this->_store = $quote->getStore();
  85. if (!$this->weeeData->isEnabled($this->_store)) {
  86. return $this;
  87. }
  88. $address = $shippingAssignment->getShipping()->getAddress();
  89. $items = $shippingAssignment->getItems();
  90. if (!count($items)) {
  91. return $this;
  92. }
  93. $this->weeeTotalExclTax = 0;
  94. $this->weeeBaseTotalExclTax = 0;
  95. foreach ($items as $item) {
  96. if ($item->getParentItem()) {
  97. continue;
  98. }
  99. $this->resetItemData($item);
  100. if ($item->getHasChildren() && $item->isChildrenCalculated()) {
  101. foreach ($item->getChildren() as $child) {
  102. $this->resetItemData($child);
  103. $this->process($address, $total, $child);
  104. }
  105. $this->recalculateParent($item);
  106. } else {
  107. $this->process($address, $total, $item);
  108. }
  109. }
  110. $total->setWeeeCodeToItemMap($this->weeeCodeToItemMap);
  111. $total->setWeeeTotalExclTax($this->weeeTotalExclTax);
  112. $total->setWeeeBaseTotalExclTax($this->weeeBaseTotalExclTax);
  113. return $this;
  114. }
  115. /**
  116. * Calculate item fixed tax and prepare information for discount and regular taxation
  117. *
  118. * @param \Magento\Quote\Model\Quote\Address $address
  119. * @param \Magento\Quote\Model\Quote\Address\Total $total
  120. * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
  121. * @return void|$this
  122. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  123. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  124. */
  125. protected function process(
  126. \Magento\Quote\Model\Quote\Address $address,
  127. \Magento\Quote\Model\Quote\Address\Total $total,
  128. $item
  129. ) {
  130. $attributes = $this->weeeData->getProductWeeeAttributes(
  131. $item->getProduct(),
  132. $address,
  133. $address->getQuote()->getBillingAddress(),
  134. $this->_store->getWebsiteId()
  135. );
  136. $productTaxes = [];
  137. $totalValueInclTax = 0;
  138. $baseTotalValueInclTax = 0;
  139. $totalRowValueInclTax = 0;
  140. $baseTotalRowValueInclTax = 0;
  141. $totalValueExclTax = 0;
  142. $baseTotalValueExclTax = 0;
  143. $totalRowValueExclTax = 0;
  144. $baseTotalRowValueExclTax = 0;
  145. $associatedTaxables = $item->getAssociatedTaxables();
  146. if (!$associatedTaxables) {
  147. $associatedTaxables = [];
  148. } else {
  149. // remove existing weee associated taxables
  150. foreach ($associatedTaxables as $iTaxable => $taxable) {
  151. if ($taxable[CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TYPE] == self::ITEM_TYPE) {
  152. unset($associatedTaxables[$iTaxable]);
  153. }
  154. }
  155. }
  156. foreach ($attributes as $key => $attribute) {
  157. $title = $attribute->getName();
  158. $baseValueExclTax = $baseValueInclTax = $attribute->getAmount();
  159. $valueExclTax = $valueInclTax = $this->priceCurrency->round(
  160. $this->priceCurrency->convert($baseValueExclTax, $this->_store)
  161. );
  162. $rowValueInclTax = $rowValueExclTax = $this->priceCurrency->round($valueInclTax * $item->getTotalQty());
  163. $baseRowValueInclTax = $this->priceCurrency->round($baseValueInclTax * $item->getTotalQty());
  164. $baseRowValueExclTax = $baseRowValueInclTax;
  165. $totalValueInclTax += $valueInclTax;
  166. $baseTotalValueInclTax += $baseValueInclTax;
  167. $totalRowValueInclTax += $rowValueInclTax;
  168. $baseTotalRowValueInclTax += $baseRowValueInclTax;
  169. $totalValueExclTax += $valueExclTax;
  170. $baseTotalValueExclTax += $baseValueExclTax;
  171. $totalRowValueExclTax += $rowValueExclTax;
  172. $baseTotalRowValueExclTax += $baseRowValueExclTax;
  173. $productTaxes[] = [
  174. 'title' => $title,
  175. 'base_amount' => $baseValueExclTax,
  176. 'amount' => $valueExclTax,
  177. 'row_amount' => $rowValueExclTax,
  178. 'base_row_amount' => $baseRowValueExclTax,
  179. 'base_amount_incl_tax' => $baseValueInclTax,
  180. 'amount_incl_tax' => $valueInclTax,
  181. 'row_amount_incl_tax' => $rowValueInclTax,
  182. 'base_row_amount_incl_tax' => $baseRowValueInclTax,
  183. ];
  184. if ($this->weeeData->isTaxable($this->_store)) {
  185. $weeeItemCode = self::ITEM_CODE_WEEE_PREFIX . $this->getNextIncrement();
  186. $weeeItemCode .= '-' . $title;
  187. $associatedTaxables[] = [
  188. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TYPE => self::ITEM_TYPE,
  189. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_CODE => $weeeItemCode,
  190. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_UNIT_PRICE => $valueExclTax,
  191. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE => $baseValueExclTax,
  192. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_QUANTITY => $item->getTotalQty(),
  193. CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID => $item->getProduct()->getTaxClassId(),
  194. ];
  195. $this->weeeCodeToItemMap[$weeeItemCode] = $item;
  196. }
  197. }
  198. $item->setAssociatedTaxables($associatedTaxables);
  199. $item->setWeeeTaxAppliedAmount($totalValueExclTax)
  200. ->setBaseWeeeTaxAppliedAmount($baseTotalValueExclTax)
  201. ->setWeeeTaxAppliedRowAmount($totalRowValueExclTax)
  202. ->setBaseWeeeTaxAppliedRowAmnt($baseTotalRowValueExclTax);
  203. $item->setWeeeTaxAppliedAmountInclTax($totalValueInclTax)
  204. ->setBaseWeeeTaxAppliedAmountInclTax($baseTotalValueInclTax)
  205. ->setWeeeTaxAppliedRowAmountInclTax($totalRowValueInclTax)
  206. ->setBaseWeeeTaxAppliedRowAmntInclTax($baseTotalRowValueInclTax);
  207. $this->processTotalAmount(
  208. $total,
  209. $totalRowValueExclTax,
  210. $baseTotalRowValueExclTax,
  211. $totalRowValueInclTax,
  212. $baseTotalRowValueInclTax
  213. );
  214. $this->weeeData->setApplied($item, array_merge($this->weeeData->getApplied($item), $productTaxes));
  215. }
  216. /**
  217. * Process row amount based on FPT total amount configuration setting
  218. *
  219. * @param \Magento\Quote\Model\Quote\Address\Total $total
  220. * @param float $rowValueExclTax
  221. * @param float $baseRowValueExclTax
  222. * @param float $rowValueInclTax
  223. * @param float $baseRowValueInclTax
  224. * @return $this
  225. */
  226. protected function processTotalAmount(
  227. $total,
  228. $rowValueExclTax,
  229. $baseRowValueExclTax,
  230. $rowValueInclTax,
  231. $baseRowValueInclTax
  232. ) {
  233. if (!$this->weeeData->isTaxable($this->_store)) {
  234. //Accumulate the values. Will be used later in the 'weee tax' collector
  235. $this->weeeTotalExclTax += $this->priceCurrency->round($rowValueExclTax);
  236. $this->weeeBaseTotalExclTax += $this->priceCurrency->round($baseRowValueExclTax);
  237. }
  238. //This value is used to calculate shipping cost; it will be overridden by tax collector
  239. $total->setSubtotalInclTax(
  240. $total->getSubtotalInclTax() + $this->priceCurrency->round($rowValueInclTax)
  241. );
  242. $total->setBaseSubtotalInclTax(
  243. $total->getBaseSubtotalInclTax() + $this->priceCurrency->round($baseRowValueInclTax)
  244. );
  245. return $this;
  246. }
  247. /**
  248. * Increment and return counter. This function is intended to be used to generate temporary
  249. * id for an item.
  250. *
  251. * @return int
  252. */
  253. protected function getNextIncrement()
  254. {
  255. return ++$this->counter;
  256. }
  257. /**
  258. * Recalculate parent item amounts based on children results
  259. *
  260. * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
  261. * @return void
  262. *
  263. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  264. */
  265. protected function recalculateParent(\Magento\Quote\Model\Quote\Item\AbstractItem $item)
  266. {
  267. $associatedTaxables = [];
  268. foreach ($item->getChildren() as $child) {
  269. $associatedTaxables = array_merge($associatedTaxables, $child->getAssociatedTaxables());
  270. }
  271. $item->setAssociatedTaxables($associatedTaxables);
  272. }
  273. /**
  274. * Reset information about Tax and Wee on FPT for shopping cart item
  275. *
  276. * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
  277. * @return void
  278. */
  279. protected function resetItemData($item)
  280. {
  281. $this->weeeData->setApplied($item, []);
  282. $item->setAssociatedTaxables([]);
  283. $item->setBaseWeeeTaxDisposition(0);
  284. $item->setWeeeTaxDisposition(0);
  285. $item->setBaseWeeeTaxRowDisposition(0);
  286. $item->setWeeeTaxRowDisposition(0);
  287. $item->setBaseWeeeTaxAppliedAmount(0);
  288. $item->setBaseWeeeTaxAppliedRowAmnt(0);
  289. $item->setWeeeTaxAppliedAmount(0);
  290. $item->setWeeeTaxAppliedRowAmount(0);
  291. }
  292. /**
  293. * @param \Magento\Quote\Model\Quote $quote
  294. * @param \Magento\Quote\Model\Quote\Address\Total $total
  295. * @return array|null
  296. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  297. */
  298. public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
  299. {
  300. return null;
  301. }
  302. /**
  303. * Process model configuration array.
  304. * This method can be used for changing totals collect sort order
  305. *
  306. * @param array $config
  307. * @param Store $store
  308. * @return array
  309. *
  310. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  311. */
  312. public function processConfigArray($config, $store)
  313. {
  314. return $config;
  315. }
  316. /**
  317. * No aggregated label for fixed product tax
  318. *
  319. * TODO: fix
  320. * @return string
  321. */
  322. public function getLabel()
  323. {
  324. return '';
  325. }
  326. }