TaxCalculationTest.php 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Tax\Model;
  7. use Magento\Tax\Api\Data\TaxClassKeyInterface;
  8. use Magento\Tax\Model\TaxClass\Key;
  9. use Magento\TestFramework\Helper\Bootstrap;
  10. /**
  11. * @magentoDbIsolation enabled
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. */
  14. class TaxCalculationTest extends \PHPUnit\Framework\TestCase
  15. {
  16. /**
  17. * Object Manager
  18. *
  19. * @var \Magento\Framework\ObjectManagerInterface
  20. */
  21. private $objectManager;
  22. /**
  23. * Tax calculation service
  24. *
  25. * @var \Magento\Tax\Api\TaxCalculationInterface
  26. */
  27. private $taxCalculationService;
  28. /**
  29. * Tax Details Factory
  30. *
  31. * @var \Magento\Tax\Api\Data\QuoteDetailsInterfaceFactory
  32. */
  33. private $quoteDetailsFactory;
  34. /**
  35. * Array of default tax classes ids
  36. *
  37. * Key is class name
  38. *
  39. * @var int[]
  40. */
  41. private $taxClassIds;
  42. /**
  43. * Array of default tax rates ids.
  44. *
  45. * Key is rate percentage as string.
  46. *
  47. * @var int[]
  48. */
  49. private $taxRates;
  50. /**
  51. * Array of default tax rules ids.
  52. *
  53. * Key is rule code.
  54. *
  55. * @var int[]
  56. */
  57. private $taxRules;
  58. /**
  59. * Helps in creating required tax rules.
  60. *
  61. * @var TaxRuleFixtureFactory
  62. */
  63. private $taxRuleFixtureFactory;
  64. /**
  65. * @var \Magento\Framework\Api\DataObjectHelper
  66. */
  67. private $dataObjectHelper;
  68. protected function setUp()
  69. {
  70. $this->objectManager = Bootstrap::getObjectManager();
  71. $this->quoteDetailsFactory = $this->objectManager->create(
  72. \Magento\Tax\Api\Data\QuoteDetailsInterfaceFactory::class
  73. );
  74. $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
  75. $this->taxCalculationService = $this->objectManager->get(\Magento\Tax\Api\TaxCalculationInterface::class);
  76. $this->taxRuleFixtureFactory = new TaxRuleFixtureFactory();
  77. $this->setUpDefaultRules();
  78. }
  79. protected function tearDown()
  80. {
  81. $this->tearDownDefaultRules();
  82. }
  83. /**
  84. * @magentoConfigFixture current_store tax/calculation/algorithm UNIT_BASE_CALCULATION
  85. * @dataProvider calculateUnitBasedDataProvider
  86. */
  87. public function testCalculateTaxUnitBased($quoteDetailsData, $expected)
  88. {
  89. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  90. $quoteDetails = $this->quoteDetailsFactory->create();
  91. $this->dataObjectHelper->populateWithArray(
  92. $quoteDetails,
  93. $quoteDetailsData,
  94. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  95. );
  96. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails, 1);
  97. $this->assertEquals($expected, $this->convertObjectToArray($taxDetails));
  98. }
  99. /**
  100. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  101. */
  102. public function calculateUnitBasedDataProvider()
  103. {
  104. $baseQuote = $this->getBaseQuoteData();
  105. $oneProduct = $baseQuote;
  106. $oneProduct['items'][] = [
  107. 'code' => 'sku_1',
  108. 'type' => 'product',
  109. 'quantity' => 2,
  110. 'unit_price' => 10,
  111. 'tax_class_key' => [
  112. Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
  113. Key::KEY_VALUE => 'DefaultProductClass',
  114. ],
  115. ];
  116. $oneProductResults = [
  117. 'subtotal' => 20,
  118. 'tax_amount' => 1.5,
  119. 'discount_tax_compensation_amount' => 0,
  120. 'applied_taxes' => [
  121. [
  122. 'amount' => 1.5,
  123. 'percent' => 7.5,
  124. 'rates' => [
  125. [
  126. 'code' => 'US - 42 - 7.5',
  127. 'title' => 'US - 42 - 7.5',
  128. 'percent' => 7.5,
  129. ],
  130. ],
  131. 'tax_rate_key' => 'US - 42 - 7.5',
  132. ],
  133. ],
  134. 'items' => [
  135. 'sku_1' => [
  136. 'code' => 'sku_1',
  137. 'row_tax' => 1.5,
  138. 'price' => 10,
  139. 'price_incl_tax' => 10.75,
  140. 'row_total' => 20,
  141. 'row_total_incl_tax' => 21.5,
  142. 'type' => 'product',
  143. 'tax_percent' => 7.5,
  144. 'discount_tax_compensation_amount' => 0,
  145. 'associated_item_code' => null,
  146. 'applied_taxes' => [
  147. 'US - 42 - 7.5' => [
  148. 'amount' => 1.5,
  149. 'percent' => 7.5,
  150. 'tax_rate_key' => 'US - 42 - 7.5',
  151. 'rates' => [
  152. 'US - 42 - 7.5' => [
  153. 'percent' => 7.5,
  154. 'code' => 'US - 42 - 7.5',
  155. 'title' => 'US - 42 - 7.5',
  156. ],
  157. ],
  158. ],
  159. ],
  160. ],
  161. ],
  162. ];
  163. $weeeProduct = $baseQuote;
  164. $weeeProduct['items'][] = [
  165. 'code' => 'sequence-1',
  166. 'type' => 'product',
  167. 'quantity' => 1,
  168. 'unit_price' => 10,
  169. 'tax_class_key' => 'WeeeProductClass',
  170. ];
  171. $weeeProduct['items'][] = [
  172. 'code' => 'weee1-Recycling Fee',
  173. 'type' => 'weee',
  174. 'quantity' => 1,
  175. 'unit_price' => 7,
  176. 'tax_class_key' => 'WeeeProductClass',
  177. 'associated_item_code' => 'sequence-1'
  178. ];
  179. $weeeProductResults = [
  180. 'subtotal' => 17,
  181. 'tax_amount' => 1.4,
  182. 'discount_tax_compensation_amount' => 0,
  183. 'applied_taxes' => [
  184. [
  185. 'amount' => 1.4,
  186. 'percent' => 8.25,
  187. 'rates' => [
  188. [
  189. 'code' => 'US - 42 - 8.25',
  190. 'title' => 'US - 42 - 8.25',
  191. 'percent' => 8.25,
  192. ],
  193. ],
  194. 'tax_rate_key' => 'US - 42 - 8.25',
  195. ],
  196. ],
  197. 'items' => [
  198. 'sequence-1' => [
  199. 'code' => 'sequence-1',
  200. 'row_tax' => 0.83,
  201. 'price' => 10,
  202. 'price_incl_tax' => 10.83,
  203. 'row_total' => 10,
  204. 'row_total_incl_tax' => 10.83,
  205. 'type' => 'product',
  206. 'tax_percent' => 8.25,
  207. 'discount_tax_compensation_amount' => 0,
  208. 'associated_item_code' => null,
  209. 'applied_taxes' => [
  210. 'US - 42 - 8.25' => [
  211. 'amount' => 0.83,
  212. 'percent' => 8.25,
  213. 'tax_rate_key' => 'US - 42 - 8.25',
  214. 'rates' => [
  215. 'US - 42 - 8.25' => [
  216. 'percent' => 8.25,
  217. 'code' => 'US - 42 - 8.25',
  218. 'title' => 'US - 42 - 8.25',
  219. ],
  220. ],
  221. ],
  222. ],
  223. ],
  224. 'weee1-Recycling Fee' => [
  225. 'code' => 'weee1-Recycling Fee',
  226. 'row_tax' => 0.57,
  227. 'price' => 7,
  228. 'price_incl_tax' => 7.57,
  229. 'row_total' => 7,
  230. 'row_total_incl_tax' => 7.57,
  231. 'type' => 'weee',
  232. 'tax_percent' => 8.25,
  233. 'discount_tax_compensation_amount' => 0,
  234. 'associated_item_code' => 'sequence-1',
  235. 'applied_taxes' => [
  236. 'US - 42 - 8.25' => [
  237. 'amount' => 0.57,
  238. 'percent' => 8.25,
  239. 'tax_rate_key' => 'US - 42 - 8.25',
  240. 'rates' => [
  241. 'US - 42 - 8.25' => [
  242. 'percent' => 8.25,
  243. 'code' => 'US - 42 - 8.25',
  244. 'title' => 'US - 42 - 8.25',
  245. ],
  246. ],
  247. ],
  248. ],
  249. ]
  250. ],
  251. ];
  252. $weeeProducts = $baseQuote;
  253. $weeeProducts['items'][] = [
  254. 'code' => 'sequence-1',
  255. 'type' => 'product',
  256. 'quantity' => 2,
  257. 'unit_price' => 10,
  258. 'tax_class_key' => 'WeeeProductClass',
  259. ];
  260. $weeeProducts['items'][] = [
  261. 'code' => 'weee1-Recycling Fee',
  262. 'type' => 'weee',
  263. 'quantity' => 2,
  264. 'unit_price' => 7,
  265. 'tax_class_key' => 'WeeeProductClass',
  266. 'associated_item_code' => 'sequence-1'
  267. ];
  268. $weeeProductsResults = [
  269. 'subtotal' => 34,
  270. 'tax_amount' => 2.80,
  271. 'discount_tax_compensation_amount' => 0,
  272. 'applied_taxes' => [
  273. [
  274. 'amount' => 2.80,
  275. 'percent' => 8.25,
  276. 'rates' => [
  277. [
  278. 'code' => 'US - 42 - 8.25',
  279. 'title' => 'US - 42 - 8.25',
  280. 'percent' => 8.25,
  281. ],
  282. ],
  283. 'tax_rate_key' => 'US - 42 - 8.25',
  284. ],
  285. ],
  286. 'items' => [
  287. 'sequence-1' => [
  288. 'code' => 'sequence-1',
  289. 'row_tax' => 1.66,
  290. 'price' => 10,
  291. 'price_incl_tax' => 10.83,
  292. 'row_total' => 20,
  293. 'row_total_incl_tax' => 21.66,
  294. 'type' => 'product',
  295. 'tax_percent' => 8.25,
  296. 'discount_tax_compensation_amount' => 0,
  297. 'associated_item_code' => null,
  298. 'applied_taxes' => [
  299. 'US - 42 - 8.25' => [
  300. 'amount' => 1.66,
  301. 'percent' => 8.25,
  302. 'tax_rate_key' => 'US - 42 - 8.25',
  303. 'rates' => [
  304. 'US - 42 - 8.25' => [
  305. 'percent' => 8.25,
  306. 'code' => 'US - 42 - 8.25',
  307. 'title' => 'US - 42 - 8.25',
  308. ],
  309. ],
  310. ],
  311. ],
  312. ],
  313. 'weee1-Recycling Fee' => [
  314. 'code' => 'weee1-Recycling Fee',
  315. 'row_tax' => 1.14,
  316. 'price' => 7,
  317. 'price_incl_tax' => 7.57,
  318. 'row_total' => 14,
  319. 'row_total_incl_tax' => 15.14,
  320. 'type' => 'weee',
  321. 'tax_percent' => 8.25,
  322. 'discount_tax_compensation_amount' => 0,
  323. 'associated_item_code' => 'sequence-1',
  324. 'applied_taxes' => [
  325. 'US - 42 - 8.25' => [
  326. 'amount' => 1.14,
  327. 'percent' => 8.25,
  328. 'tax_rate_key' => 'US - 42 - 8.25',
  329. 'rates' => [
  330. 'US - 42 - 8.25' => [
  331. 'percent' => 8.25,
  332. 'code' => 'US - 42 - 8.25',
  333. 'title' => 'US - 42 - 8.25',
  334. ],
  335. ],
  336. ],
  337. ],
  338. ]
  339. ],
  340. ];
  341. $multiWeeeProducts = $baseQuote;
  342. $multiWeeeProducts['items'][] = [
  343. 'code' => 'sequence-1',
  344. 'type' => 'product',
  345. 'quantity' => 2,
  346. 'unit_price' => 10,
  347. 'tax_class_key' => 'WeeeProductClass',
  348. ];
  349. $multiWeeeProducts['items'][] = [
  350. 'code' => 'weee1-Recycling Fee',
  351. 'type' => 'weee',
  352. 'quantity' => 2,
  353. 'unit_price' => 7,
  354. 'tax_class_key' => 'WeeeProductClass',
  355. 'associated_item_code' => 'sequence-1'
  356. ];
  357. $multiWeeeProducts['items'][] = [
  358. 'code' => 'sequence-2',
  359. 'type' => 'product',
  360. 'quantity' => 2,
  361. 'unit_price' => 10,
  362. 'tax_class_key' => 'WeeeProductClass',
  363. ];
  364. $multiWeeeProducts['items'][] = [
  365. 'code' => 'weee2-Recycling Fee',
  366. 'type' => 'weee',
  367. 'quantity' => 2,
  368. 'unit_price' => 7,
  369. 'tax_class_key' => 'WeeeProductClass',
  370. 'associated_item_code' => 'sequence-2'
  371. ];
  372. $multiWeeeProductsResults = [
  373. 'subtotal' => 68,
  374. 'tax_amount' => 5.60,
  375. 'discount_tax_compensation_amount' => 0,
  376. 'applied_taxes' => [
  377. [
  378. 'amount' => 5.60,
  379. 'percent' => 8.25,
  380. 'rates' => [
  381. [
  382. 'code' => 'US - 42 - 8.25',
  383. 'title' => 'US - 42 - 8.25',
  384. 'percent' => 8.25,
  385. ],
  386. ],
  387. 'tax_rate_key' => 'US - 42 - 8.25',
  388. ],
  389. ],
  390. 'items' => [
  391. 'sequence-1' => [
  392. 'code' => 'sequence-1',
  393. 'row_tax' => 1.66,
  394. 'price' => 10,
  395. 'price_incl_tax' => 10.83,
  396. 'row_total' => 20,
  397. 'row_total_incl_tax' => 21.66,
  398. 'type' => 'product',
  399. 'tax_percent' => 8.25,
  400. 'discount_tax_compensation_amount' => 0,
  401. 'associated_item_code' => null,
  402. 'applied_taxes' => [
  403. 'US - 42 - 8.25' => [
  404. 'amount' => 1.66,
  405. 'percent' => 8.25,
  406. 'tax_rate_key' => 'US - 42 - 8.25',
  407. 'rates' => [
  408. 'US - 42 - 8.25' => [
  409. 'percent' => 8.25,
  410. 'code' => 'US - 42 - 8.25',
  411. 'title' => 'US - 42 - 8.25',
  412. ],
  413. ],
  414. ],
  415. ],
  416. ],
  417. 'weee1-Recycling Fee' => [
  418. 'code' => 'weee1-Recycling Fee',
  419. 'row_tax' => 1.14,
  420. 'price' => 7,
  421. 'price_incl_tax' => 7.57,
  422. 'row_total' => 14,
  423. 'row_total_incl_tax' => 15.14,
  424. 'type' => 'weee',
  425. 'tax_percent' => 8.25,
  426. 'discount_tax_compensation_amount' => 0,
  427. 'associated_item_code' => 'sequence-1',
  428. 'applied_taxes' => [
  429. 'US - 42 - 8.25' => [
  430. 'amount' => 1.14,
  431. 'percent' => 8.25,
  432. 'tax_rate_key' => 'US - 42 - 8.25',
  433. 'rates' => [
  434. 'US - 42 - 8.25' => [
  435. 'percent' => 8.25,
  436. 'code' => 'US - 42 - 8.25',
  437. 'title' => 'US - 42 - 8.25',
  438. ],
  439. ],
  440. ],
  441. ],
  442. ],
  443. 'sequence-2' => [
  444. 'code' => 'sequence-2',
  445. 'row_tax' => 1.66,
  446. 'price' => 10,
  447. 'price_incl_tax' => 10.83,
  448. 'row_total' => 20,
  449. 'row_total_incl_tax' => 21.66,
  450. 'type' => 'product',
  451. 'tax_percent' => 8.25,
  452. 'discount_tax_compensation_amount' => 0,
  453. 'associated_item_code' => null,
  454. 'applied_taxes' => [
  455. 'US - 42 - 8.25' => [
  456. 'amount' => 1.66,
  457. 'percent' => 8.25,
  458. 'tax_rate_key' => 'US - 42 - 8.25',
  459. 'rates' => [
  460. 'US - 42 - 8.25' => [
  461. 'percent' => 8.25,
  462. 'code' => 'US - 42 - 8.25',
  463. 'title' => 'US - 42 - 8.25',
  464. ],
  465. ],
  466. ],
  467. ],
  468. ],
  469. 'weee2-Recycling Fee' => [
  470. 'code' => 'weee2-Recycling Fee',
  471. 'row_tax' => 1.14,
  472. 'price' => 7,
  473. 'price_incl_tax' => 7.57,
  474. 'row_total' => 14,
  475. 'row_total_incl_tax' => 15.14,
  476. 'type' => 'weee',
  477. 'tax_percent' => 8.25,
  478. 'discount_tax_compensation_amount' => 0,
  479. 'associated_item_code' => 'sequence-2',
  480. 'applied_taxes' => [
  481. 'US - 42 - 8.25' => [
  482. 'amount' => 1.14,
  483. 'percent' => 8.25,
  484. 'tax_rate_key' => 'US - 42 - 8.25',
  485. 'rates' => [
  486. 'US - 42 - 8.25' => [
  487. 'percent' => 8.25,
  488. 'code' => 'US - 42 - 8.25',
  489. 'title' => 'US - 42 - 8.25',
  490. ],
  491. ],
  492. ],
  493. ],
  494. ]
  495. ],
  496. ];
  497. $oneProductInclTax = $baseQuote;
  498. $oneProductInclTax['items'][] = [
  499. 'code' => 'sku_1',
  500. 'type' => 'product',
  501. 'quantity' => 2,
  502. 'unit_price' => 10.75,
  503. 'tax_class_key' => 'DefaultProductClass',
  504. 'is_tax_included' => true,
  505. ];
  506. $oneProductInclTaxResults = $oneProductResults;
  507. $oneProductInclTaxDiffRate = $baseQuote;
  508. $oneProductInclTaxDiffRate['items'][] = [
  509. 'code' => 'sku_1',
  510. 'type' => 'product',
  511. 'quantity' => 2,
  512. 'unit_price' => 11,
  513. 'tax_class_key' => 'HigherProductClass',
  514. 'is_tax_included' => true,
  515. ];
  516. $oneProductInclTaxDiffRateResults = [
  517. 'subtotal' => 20,
  518. 'tax_amount' => 4.4,
  519. 'discount_tax_compensation_amount' => 0,
  520. 'applied_taxes' => [
  521. [
  522. 'amount' => 4.4,
  523. 'percent' => 22,
  524. 'rates' => [
  525. [
  526. 'code' => 'US - 42 - 22',
  527. 'title' => 'US - 42 - 22',
  528. 'percent' => 22,
  529. ],
  530. ],
  531. 'tax_rate_key' => 'US - 42 - 22',
  532. ],
  533. ],
  534. 'items' => [
  535. 'sku_1' => [
  536. 'code' => 'sku_1',
  537. 'row_tax' => 4.4,
  538. 'price' => 10,
  539. 'price_incl_tax' => 12.2,
  540. 'row_total' => 20,
  541. 'row_total_incl_tax' => 24.4,
  542. 'type' => 'product',
  543. 'tax_percent' => 22.0,
  544. 'discount_tax_compensation_amount' => 0,
  545. 'associated_item_code' => null,
  546. 'applied_taxes' => [
  547. 'US - 42 - 22' => [
  548. 'amount' => 4.4,
  549. 'percent' => 22,
  550. 'tax_rate_key' => 'US - 42 - 22',
  551. 'rates' => [
  552. 'US - 42 - 22' => [
  553. 'percent' => 22,
  554. 'code' => 'US - 42 - 22',
  555. 'title' => 'US - 42 - 22',
  556. ],
  557. ],
  558. ],
  559. ],
  560. ],
  561. ],
  562. ];
  563. $twoProducts = $baseQuote;
  564. $twoProducts['items'] = [
  565. [
  566. 'code' => 'sku_1',
  567. 'type' => 'product',
  568. 'quantity' => 2,
  569. 'unit_price' => 10,
  570. 'tax_class_key' => 'DefaultProductClass',
  571. ],
  572. [
  573. 'code' => 'sku_2',
  574. 'type' => 'product',
  575. 'quantity' => 20,
  576. 'unit_price' => 11,
  577. 'tax_class_key' => 'DefaultProductClass',
  578. ],
  579. ];
  580. $twoProductsResults = [
  581. 'subtotal' => 240,
  582. 'tax_amount' => 18.1,
  583. 'discount_tax_compensation_amount' => 0,
  584. 'applied_taxes' => [
  585. [
  586. 'amount' => 18.1,
  587. 'percent' => 7.5,
  588. 'rates' => [
  589. [
  590. 'code' => 'US - 42 - 7.5',
  591. 'title' => 'US - 42 - 7.5',
  592. 'percent' => 7.5,
  593. ],
  594. ],
  595. 'tax_rate_key' => 'US - 42 - 7.5',
  596. ],
  597. ],
  598. 'items' => [
  599. 'sku_1' => [
  600. 'code' => 'sku_1',
  601. 'row_tax' => 1.5,
  602. 'price' => 10,
  603. 'price_incl_tax' => 10.75,
  604. 'row_total' => 20,
  605. 'row_total_incl_tax' => 21.5,
  606. 'type' => 'product',
  607. 'tax_percent' => 7.5,
  608. 'discount_tax_compensation_amount' => 0,
  609. 'associated_item_code' => null,
  610. 'applied_taxes' => [
  611. 'US - 42 - 7.5' => [
  612. 'amount' => 1.5,
  613. 'percent' => 7.5,
  614. 'tax_rate_key' => 'US - 42 - 7.5',
  615. 'rates' => [
  616. 'US - 42 - 7.5' => [
  617. 'percent' => 7.5,
  618. 'code' => 'US - 42 - 7.5',
  619. 'title' => 'US - 42 - 7.5',
  620. ],
  621. ],
  622. ],
  623. ],
  624. ],
  625. 'sku_2' => [
  626. 'code' => 'sku_2',
  627. 'row_tax' => 16.6,
  628. 'price' => 11,
  629. 'price_incl_tax' => 11.83,
  630. 'row_total' => 220,
  631. 'row_total_incl_tax' => 236.6,
  632. 'type' => 'product',
  633. 'tax_percent' => 7.5,
  634. 'discount_tax_compensation_amount' => 0,
  635. 'associated_item_code' => null,
  636. 'applied_taxes' => [
  637. 'US - 42 - 7.5' => [
  638. 'amount' => 16.6,
  639. 'percent' => 7.5,
  640. 'tax_rate_key' => 'US - 42 - 7.5',
  641. 'rates' => [
  642. 'US - 42 - 7.5' => [
  643. 'percent' => 7.5,
  644. 'code' => 'US - 42 - 7.5',
  645. 'title' => 'US - 42 - 7.5',
  646. ],
  647. ],
  648. ],
  649. ],
  650. ],
  651. ],
  652. ];
  653. $twoProductsInclTax = $baseQuote;
  654. $twoProductsInclTax['items'] = [
  655. [
  656. 'code' => 'sku_1',
  657. 'type' => 'product',
  658. 'quantity' => 2,
  659. 'unit_price' => 10.75,
  660. 'row_total' => 21.5,
  661. 'tax_class_key' => 'DefaultProductClass',
  662. 'is_tax_included' => true,
  663. ],
  664. [
  665. 'code' => 'sku_2',
  666. 'type' => 'product',
  667. 'quantity' => 20,
  668. 'unit_price' => 11.83,
  669. 'row_total' => 236.6,
  670. 'tax_class_key' => 'DefaultProductClass',
  671. 'is_tax_included' => true,
  672. ],
  673. ];
  674. $twoProductInclTaxResults = $twoProductsResults;
  675. $bundleProduct = $baseQuote;
  676. $bundleProduct['items'][] = [
  677. 'code' => 'sku_1',
  678. 'type' => 'product',
  679. 'quantity' => 1,
  680. 'unit_price' => 10,
  681. 'tax_class_key' => 'DefaultProductClass',
  682. 'parent_code' => 'bundle',
  683. ];
  684. $bundleProduct['items'][] = [
  685. 'code' => 'bundle',
  686. 'type' => 'product',
  687. 'quantity' => 2,
  688. 'unit_price' => 0,
  689. 'tax_class_key' => 'DefaultProductClass',
  690. ];
  691. $bundleProductResults = [
  692. 'subtotal' => 20,
  693. 'tax_amount' => 1.5,
  694. 'discount_tax_compensation_amount' => 0,
  695. 'applied_taxes' => [
  696. [
  697. 'amount' => 1.5,
  698. 'percent' => 7.5,
  699. 'rates' => [
  700. [
  701. 'code' => 'US - 42 - 7.5',
  702. 'title' => 'US - 42 - 7.5',
  703. 'percent' => 7.5,
  704. ],
  705. ],
  706. 'tax_rate_key' => 'US - 42 - 7.5',
  707. ],
  708. ],
  709. 'items' => [
  710. 'sku_1' => [
  711. 'code' => 'sku_1',
  712. 'row_tax' => 1.5,
  713. 'price' => 10,
  714. 'price_incl_tax' => 10.75,
  715. 'row_total' => 20,
  716. 'row_total_incl_tax' => 21.5,
  717. 'type' => 'product',
  718. 'tax_percent' => 7.5,
  719. 'discount_tax_compensation_amount' => 0,
  720. 'associated_item_code' => null,
  721. 'applied_taxes' => [
  722. 'US - 42 - 7.5' => [
  723. 'amount' => 1.5,
  724. 'percent' => 7.5,
  725. 'tax_rate_key' => 'US - 42 - 7.5',
  726. 'rates' => [
  727. 'US - 42 - 7.5' => [
  728. 'percent' => 7.5,
  729. 'code' => 'US - 42 - 7.5',
  730. 'title' => 'US - 42 - 7.5',
  731. ],
  732. ],
  733. ],
  734. ],
  735. ],
  736. 'bundle' => [
  737. 'price' => 10,
  738. 'price_incl_tax' => 10.75,
  739. 'row_total' => 20,
  740. 'row_total_incl_tax' => 21.5,
  741. 'row_tax' => 1.5,
  742. 'code' => 'bundle',
  743. 'type' => 'product',
  744. ],
  745. ],
  746. ];
  747. return [
  748. 'one product' => [
  749. 'quote_details' => $oneProduct,
  750. 'expected_tax_details' => $oneProductResults,
  751. ],
  752. 'weee product' => [
  753. 'quote_details' => $weeeProduct,
  754. 'expected_tax_details' => $weeeProductResults,
  755. ],
  756. 'weee products' => [
  757. 'quote_details' => $weeeProducts,
  758. 'expected_tax_details' => $weeeProductsResults,
  759. ],
  760. 'multi weee products' => [
  761. 'quote_details' => $multiWeeeProducts,
  762. 'expected_tax_details' => $multiWeeeProductsResults,
  763. ],
  764. 'one product, tax included' => [
  765. 'quote_details' => $oneProductInclTax,
  766. 'expected_tax_details' => $oneProductInclTaxResults,
  767. ],
  768. 'one product, tax included but differs from store rate' => [
  769. 'quote_details' => $oneProductInclTaxDiffRate,
  770. 'expected_tax_details' => $oneProductInclTaxDiffRateResults,
  771. ],
  772. 'two products' => [
  773. 'quote_details' => $twoProducts,
  774. 'expected_tax_details' => $twoProductsResults,
  775. ],
  776. 'two products, tax included' => [
  777. 'quote_details' => $twoProductsInclTax,
  778. 'expected_tax_details' => $twoProductInclTaxResults,
  779. ],
  780. 'bundle product' => [
  781. 'quote_details' => $bundleProduct,
  782. 'expected_tax_details' => $bundleProductResults,
  783. ],
  784. ];
  785. }
  786. /**
  787. * @dataProvider calculateTaxTotalBasedDataProvider
  788. * @magentoConfigFixture current_store tax/calculation/algorithm TOTAL_BASE_CALCULATION
  789. */
  790. public function testCalculateTaxTotalBased($quoteDetailsData, $expectedTaxDetails, $storeId = null)
  791. {
  792. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  793. $quoteDetails = $this->quoteDetailsFactory->create();
  794. $this->dataObjectHelper->populateWithArray(
  795. $quoteDetails,
  796. $quoteDetailsData,
  797. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  798. );
  799. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails, $storeId);
  800. $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
  801. }
  802. public function calculateTaxTotalBasedDataProvider()
  803. {
  804. return array_merge(
  805. $this->calculateTaxNoTaxInclDataProvider(),
  806. $this->calculateTaxTaxInclDataProvider(),
  807. $this->calculateTaxRoundingDataProvider()
  808. );
  809. }
  810. /**
  811. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  812. */
  813. public function calculateTaxNoTaxInclDataProvider()
  814. {
  815. $prodNoTaxInclBase = [
  816. 'quote_details' => [
  817. 'shipping_address' => [
  818. 'postcode' => '55555',
  819. 'country_id' => 'US',
  820. 'region' => ['region_id' => 42],
  821. ],
  822. 'items' => [
  823. [
  824. 'code' => 'code',
  825. 'type' => 'type',
  826. 'quantity' => 1,
  827. 'unit_price' => 10.0,
  828. 'is_tax_included' => false,
  829. ],
  830. ],
  831. 'customer_tax_class_key' => 'DefaultCustomerClass',
  832. ],
  833. 'expected_tax_details' => [
  834. 'subtotal' => 10.0,
  835. 'tax_amount' => 0.0,
  836. 'discount_tax_compensation_amount' => 0.0,
  837. 'applied_taxes' => [],
  838. 'items' => [],
  839. ],
  840. 'store_id' => null,
  841. ];
  842. $prodQuoteDetailItemBase = [
  843. 'code' => 'code',
  844. 'type' => 'type',
  845. 'quantity' => 1,
  846. 'unit_price' => 10.0,
  847. 'is_tax_included' => false,
  848. ];
  849. $quoteDetailAppliedTaxesBase = [
  850. [
  851. 'amount' => 0.75,
  852. 'percent' => 7.5,
  853. 'rates' => [
  854. [
  855. 'code' => 'US - 42 - 7.5',
  856. 'title' => 'US - 42 - 7.5',
  857. 'percent' => 7.5,
  858. ],
  859. ],
  860. 'tax_rate_key' => 'US - 42 - 7.5',
  861. ],
  862. ];
  863. $itemDetailAppliedTaxesBase = [
  864. 'US - 42 - 7.5' => [
  865. 'amount' => 0.75,
  866. 'percent' => 7.5,
  867. 'tax_rate_key' => 'US - 42 - 7.5',
  868. 'rates' => [
  869. 'US - 42 - 7.5' => [
  870. 'percent' => 7.5,
  871. 'code' => 'US - 42 - 7.5',
  872. 'title' => 'US - 42 - 7.5',
  873. ],
  874. ],
  875. ],
  876. ];
  877. $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase;
  878. $quoteDetailItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass';
  879. $prodExpectedItemWithNoProductTaxClass = [
  880. 'code' => [
  881. 'code' => 'code',
  882. 'row_tax' => 0,
  883. 'price' => 10.0,
  884. 'price_incl_tax' => 10.0,
  885. 'row_total' => 10.0,
  886. 'row_total_incl_tax' => 10.0,
  887. 'type' => 'type',
  888. 'tax_percent' => 0,
  889. 'discount_tax_compensation_amount' => 0,
  890. 'associated_item_code' => null,
  891. 'applied_taxes' => [],
  892. ],
  893. ];
  894. $itemAppliedTaxes = $itemDetailAppliedTaxesBase;
  895. $prodExpectedItemWithDefaultProductTaxClass = [
  896. 'code' => [
  897. 'code' => 'code',
  898. 'row_tax' => 0.75,
  899. 'price' => 10.0,
  900. 'price_incl_tax' => 10.75,
  901. 'row_total' => 10.0,
  902. 'row_total_incl_tax' => 10.75,
  903. 'type' => 'type',
  904. 'tax_percent' => 7.5,
  905. 'discount_tax_compensation_amount' => 0,
  906. 'associated_item_code' => null,
  907. 'applied_taxes' => $itemAppliedTaxes,
  908. ],
  909. ];
  910. $prodWithStoreIdWithTaxClassId = $prodNoTaxInclBase;
  911. $prodWithStoreIdWithoutTaxClassId = $prodNoTaxInclBase;
  912. $prodWithoutStoreIdWithTaxClassId = $prodNoTaxInclBase;
  913. $prodWithoutStoreIdWithoutTaxClassId = $prodNoTaxInclBase;
  914. $prodWithStoreIdWithTaxClassId['store_id'] = 1;
  915. $prodWithStoreIdWithTaxClassId['quote_details']['items'][] = $quoteDetailItemWithDefaultProductTaxClass;
  916. $prodWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.75;
  917. $prodWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
  918. $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
  919. $prodExpectedItemWithDefaultProductTaxClass;
  920. $prodWithStoreIdWithoutTaxClassId['store_id'] = 1;
  921. $prodWithStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
  922. $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  923. $prodExpectedItemWithNoProductTaxClass;
  924. $prodWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
  925. $quoteDetailItemWithDefaultProductTaxClass;
  926. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.75;
  927. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
  928. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
  929. $prodExpectedItemWithDefaultProductTaxClass;
  930. $prodWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
  931. $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  932. $prodExpectedItemWithNoProductTaxClass;
  933. return [
  934. 'product with store id, with tax class id' => $prodWithStoreIdWithTaxClassId,
  935. 'product with store id, without tax class id' => $prodWithStoreIdWithoutTaxClassId,
  936. 'product without store id, with tax class id' => $prodWithoutStoreIdWithTaxClassId,
  937. 'product without store id, without tax class id' => $prodWithoutStoreIdWithoutTaxClassId,
  938. ];
  939. }
  940. /**
  941. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  942. */
  943. public function calculateTaxTaxInclDataProvider()
  944. {
  945. $productTaxInclBase = [
  946. 'quote_details' => [
  947. 'shipping_address' => [
  948. 'postcode' => '55555',
  949. 'country_id' => 'US',
  950. 'region' => ['region_id' => 42],
  951. ],
  952. 'items' => [
  953. [
  954. 'code' => 'code',
  955. 'type' => 'type',
  956. 'quantity' => 1,
  957. 'unit_price' => 10.0,
  958. 'is_tax_included' => true,
  959. ],
  960. ],
  961. 'customer_tax_class_key' => [
  962. Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
  963. Key::KEY_VALUE => 'DefaultCustomerClass',
  964. ],
  965. ],
  966. 'expected_tax_details' => [
  967. 'subtotal' => 10.0,
  968. 'tax_amount' => 0.0,
  969. 'discount_tax_compensation_amount' => 0.0,
  970. 'applied_taxes' => [],
  971. 'items' => [],
  972. ],
  973. 'store_id' => null,
  974. ];
  975. $productTaxInclQuoteDetailItemBase = [
  976. 'code' => 'code',
  977. 'type' => 'type',
  978. 'quantity' => 1,
  979. 'unit_price' => 10.0,
  980. 'is_tax_included' => true,
  981. ];
  982. $quoteDetailTaxInclItemWithDefaultProductTaxClass = $productTaxInclQuoteDetailItemBase;
  983. $quoteDetailTaxInclItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass';
  984. $productTaxInclExpectedItemWithNoProductTaxClass = [
  985. 'code' => [
  986. 'code' => 'code',
  987. 'row_tax' => 0,
  988. 'price' => 10.0,
  989. 'price_incl_tax' => 10.0,
  990. 'row_total' => 10.0,
  991. 'row_total_incl_tax' => 10.0,
  992. 'type' => 'type',
  993. 'tax_percent' => 0,
  994. 'discount_tax_compensation_amount' => 0,
  995. 'associated_item_code' => null,
  996. 'applied_taxes' => [],
  997. ],
  998. ];
  999. $quoteDetailAppliedTaxesBase = [
  1000. [
  1001. 'amount' => 0.70,
  1002. 'percent' => 7.5,
  1003. 'rates' => [
  1004. [
  1005. 'code' => 'US - 42 - 7.5',
  1006. 'title' => 'US - 42 - 7.5',
  1007. 'percent' => 7.5,
  1008. ],
  1009. ],
  1010. 'tax_rate_key' => 'US - 42 - 7.5',
  1011. ],
  1012. ];
  1013. $productTaxInclExpectedItemWithDefaultProductTaxClass = [
  1014. 'code' => [
  1015. 'code' => 'code',
  1016. 'row_tax' => 0.70,
  1017. 'price' => 9.30,
  1018. 'price_incl_tax' => 10.00,
  1019. 'row_total' => 9.30,
  1020. 'row_total_incl_tax' => 10.00,
  1021. 'type' => 'type',
  1022. 'tax_percent' => 7.5,
  1023. 'discount_tax_compensation_amount' => 0,
  1024. 'associated_item_code' => null,
  1025. 'applied_taxes' => [
  1026. 'US - 42 - 7.5' => [
  1027. 'amount' => 0.7,
  1028. 'percent' => 7.5,
  1029. 'tax_rate_key' => 'US - 42 - 7.5',
  1030. 'rates' => [
  1031. 'US - 42 - 7.5' => [
  1032. 'percent' => 7.5,
  1033. 'code' => 'US - 42 - 7.5',
  1034. 'title' => 'US - 42 - 7.5',
  1035. ],
  1036. ],
  1037. ],
  1038. ],
  1039. ],
  1040. ];
  1041. $productInclTaxWithStoreIdWithTaxClassId = $productTaxInclBase;
  1042. $productInclTaxWithStoreIdWithoutTaxClassId = $productTaxInclBase;
  1043. $productInclTaxWithoutStoreIdWithTaxClassId = $productTaxInclBase;
  1044. $productInclTaxWithoutStoreIdWithoutTaxClassId = $productTaxInclBase;
  1045. $productInclTaxWithStoreIdWithTaxClassId['store_id'] = 1;
  1046. $productInclTaxWithStoreIdWithTaxClassId['quote_details']['items'][] =
  1047. $quoteDetailTaxInclItemWithDefaultProductTaxClass;
  1048. $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.70;
  1049. $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['subtotal'] = 9.30;
  1050. $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
  1051. $quoteDetailAppliedTaxesBase;
  1052. $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
  1053. $productTaxInclExpectedItemWithDefaultProductTaxClass;
  1054. $productInclTaxWithStoreIdWithoutTaxClassId['store_id'] = 1;
  1055. $productInclTaxWithStoreIdWithoutTaxClassId['quote_details']['items'][] =
  1056. $productTaxInclQuoteDetailItemBase;
  1057. $productInclTaxWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  1058. $productTaxInclExpectedItemWithNoProductTaxClass;
  1059. $productInclTaxWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
  1060. $quoteDetailTaxInclItemWithDefaultProductTaxClass;
  1061. $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.70;
  1062. $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['subtotal'] = 9.30;
  1063. $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
  1064. $quoteDetailAppliedTaxesBase;
  1065. $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
  1066. $productTaxInclExpectedItemWithDefaultProductTaxClass;
  1067. $productInclTaxWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $productTaxInclQuoteDetailItemBase;
  1068. $productInclTaxWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  1069. $productTaxInclExpectedItemWithNoProductTaxClass;
  1070. return [
  1071. 'product incl tax with store id, with tax class id' => $productInclTaxWithStoreIdWithTaxClassId,
  1072. 'product incl tax with store id, without tax class id' => $productInclTaxWithStoreIdWithoutTaxClassId,
  1073. 'product incl tax without store id, with tax class id' => $productInclTaxWithoutStoreIdWithTaxClassId,
  1074. 'product incl tax without store id, without tax class id' => $productInclTaxWithoutStoreIdWithoutTaxClassId,
  1075. ];
  1076. }
  1077. /**
  1078. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  1079. */
  1080. public function calculateTaxRoundingDataProvider()
  1081. {
  1082. $prodRoundingNoTaxInclBase = [
  1083. 'quote_details' => [
  1084. 'shipping_address' => [
  1085. 'postcode' => '55555',
  1086. 'country_id' => 'US',
  1087. 'region' => ['region_id' => 42],
  1088. ],
  1089. 'items' => [
  1090. [
  1091. 'code' => 'code',
  1092. 'type' => 'type',
  1093. 'quantity' => 2,
  1094. 'unit_price' => 7.97,
  1095. 'is_tax_included' => false,
  1096. ],
  1097. ],
  1098. 'customer_tax_class_key' => 'DefaultCustomerClass',
  1099. ],
  1100. 'expected_tax_details' => [
  1101. 'subtotal' => 15.94,
  1102. 'tax_amount' => 0.0,
  1103. 'discount_tax_compensation_amount' => 0.0,
  1104. 'applied_taxes' => [],
  1105. 'items' => [],
  1106. ],
  1107. 'store_id' => null,
  1108. ];
  1109. $prodQuoteDetailItemBase = [
  1110. 'code' => 'code',
  1111. 'type' => 'type',
  1112. 'quantity' => 2,
  1113. 'unit_price' => 7.97,
  1114. 'is_tax_included' => false,
  1115. ];
  1116. $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase;
  1117. $quoteDetailItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass';
  1118. $quoteDetailAppliedTaxesBase = [
  1119. [
  1120. 'amount' => 1.20,
  1121. 'percent' => 7.5,
  1122. 'rates' => [
  1123. [
  1124. 'code' => 'US - 42 - 7.5',
  1125. 'title' => 'US - 42 - 7.5',
  1126. 'percent' => 7.5,
  1127. ],
  1128. ],
  1129. 'tax_rate_key' => 'US - 42 - 7.5',
  1130. ],
  1131. ];
  1132. $prodExpectedItemWithNoProductTaxClass = [
  1133. 'code' => [
  1134. 'code' => 'code',
  1135. 'row_tax' => 0,
  1136. 'price' => 7.97,
  1137. 'price_incl_tax' => 7.97,
  1138. 'row_total' => 15.94,
  1139. 'row_total_incl_tax' => 15.94,
  1140. 'type' => 'type',
  1141. 'tax_percent' => 0,
  1142. 'discount_tax_compensation_amount' => 0,
  1143. 'associated_item_code' => null,
  1144. 'applied_taxes' => [],
  1145. ],
  1146. ];
  1147. $prodExpectedItemWithDefaultProductTaxClass = [
  1148. 'code' => [
  1149. 'code' => 'code',
  1150. 'row_tax' => 1.20,
  1151. 'price' => 7.97,
  1152. 'price_incl_tax' => 8.57,
  1153. 'row_total' => 15.94,
  1154. 'row_total_incl_tax' => 17.14,
  1155. 'type' => 'type',
  1156. 'tax_percent' => 7.5,
  1157. 'discount_tax_compensation_amount' => 0,
  1158. 'associated_item_code' => null,
  1159. 'applied_taxes' => [
  1160. 'US - 42 - 7.5' => [
  1161. 'amount' => 1.2,
  1162. 'percent' => 7.5,
  1163. 'tax_rate_key' => 'US - 42 - 7.5',
  1164. 'rates' => [
  1165. 'US - 42 - 7.5' => [
  1166. 'percent' => 7.5,
  1167. 'code' => 'US - 42 - 7.5',
  1168. 'title' => 'US - 42 - 7.5',
  1169. ],
  1170. ],
  1171. ],
  1172. ],
  1173. ],
  1174. ];
  1175. $prodWithStoreIdWithTaxClassId = $prodRoundingNoTaxInclBase;
  1176. $prodWithStoreIdWithoutTaxClassId = $prodRoundingNoTaxInclBase;
  1177. $prodWithoutStoreIdWithTaxClassId = $prodRoundingNoTaxInclBase;
  1178. $prodWithoutStoreIdWithoutTaxClassId = $prodRoundingNoTaxInclBase;
  1179. $prodWithStoreIdWithTaxClassId['store_id'] = 1;
  1180. $prodWithStoreIdWithTaxClassId['quote_details']['items'][] = $quoteDetailItemWithDefaultProductTaxClass;
  1181. $prodWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 1.20;
  1182. $prodWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
  1183. $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
  1184. $prodExpectedItemWithDefaultProductTaxClass;
  1185. $prodWithStoreIdWithoutTaxClassId['store_id'] = 1;
  1186. $prodWithStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
  1187. $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  1188. $prodExpectedItemWithNoProductTaxClass;
  1189. $prodWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
  1190. $quoteDetailItemWithDefaultProductTaxClass;
  1191. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 1.20;
  1192. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
  1193. $quoteDetailAppliedTaxesBase;
  1194. $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
  1195. $prodExpectedItemWithDefaultProductTaxClass;
  1196. $prodWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
  1197. $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
  1198. $prodExpectedItemWithNoProductTaxClass;
  1199. return [
  1200. 'rounding product with store id, with tax class id' => $prodWithStoreIdWithTaxClassId,
  1201. 'rounding product with store id, without tax class id' => $prodWithStoreIdWithoutTaxClassId,
  1202. 'rounding product without store id, with tax class id' => $prodWithoutStoreIdWithTaxClassId,
  1203. 'rounding product without store id, without tax class id' => $prodWithoutStoreIdWithoutTaxClassId,
  1204. ];
  1205. }
  1206. /**
  1207. * @magentoDbIsolation enabled
  1208. * @dataProvider calculateTaxRowBasedDataProvider
  1209. * @magentoConfigFixture default_store tax/calculation/algorithm ROW_BASE_CALCULATION
  1210. */
  1211. public function testCalculateTaxRowBased($quoteDetailsData, $expectedTaxDetails)
  1212. {
  1213. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  1214. $quoteDetails = $this->quoteDetailsFactory->create();
  1215. $this->dataObjectHelper->populateWithArray(
  1216. $quoteDetails,
  1217. $quoteDetailsData,
  1218. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  1219. );
  1220. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
  1221. $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
  1222. }
  1223. /**
  1224. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  1225. */
  1226. public function calculateTaxRowBasedDataProvider()
  1227. {
  1228. $baseQuote = $this->getBaseQuoteData();
  1229. $oneProduct = $baseQuote;
  1230. $oneProduct['items'][] = [
  1231. 'code' => 'sku_1',
  1232. 'type' => 'product',
  1233. 'quantity' => 10,
  1234. 'unit_price' => 1,
  1235. 'tax_class_key' => 'DefaultProductClass',
  1236. ];
  1237. $oneProductResults = [
  1238. 'subtotal' => 10,
  1239. 'tax_amount' => 0.75,
  1240. 'discount_tax_compensation_amount' => 0,
  1241. 'applied_taxes' => [
  1242. [
  1243. 'amount' => 0.75,
  1244. 'percent' => 7.5,
  1245. 'rates' => [
  1246. [
  1247. 'code' => 'US - 42 - 7.5',
  1248. 'title' => 'US - 42 - 7.5',
  1249. 'percent' => 7.5,
  1250. ],
  1251. ],
  1252. 'tax_rate_key' => 'US - 42 - 7.5',
  1253. ],
  1254. ],
  1255. 'items' => [
  1256. 'sku_1' => [
  1257. 'code' => 'sku_1',
  1258. 'row_tax' => 0.75,
  1259. 'price' => 1,
  1260. 'price_incl_tax' => 1.08,
  1261. 'row_total' => 10,
  1262. 'row_total_incl_tax' => 10.75,
  1263. 'type' => 'product',
  1264. 'tax_percent' => 7.5,
  1265. 'discount_tax_compensation_amount' => 0,
  1266. 'associated_item_code' => null,
  1267. 'applied_taxes' => [
  1268. 'US - 42 - 7.5' => [
  1269. 'amount' => 0.75,
  1270. 'percent' => 7.5,
  1271. 'tax_rate_key' => 'US - 42 - 7.5',
  1272. 'rates' => [
  1273. 'US - 42 - 7.5' => [
  1274. 'percent' => 7.5,
  1275. 'code' => 'US - 42 - 7.5',
  1276. 'title' => 'US - 42 - 7.5',
  1277. ],
  1278. ],
  1279. ],
  1280. ],
  1281. ],
  1282. ],
  1283. ];
  1284. $weeeProduct = $baseQuote;
  1285. $weeeProduct['items'][] = [
  1286. 'code' => 'sequence-1',
  1287. 'type' => 'product',
  1288. 'quantity' => 1,
  1289. 'unit_price' => 10,
  1290. 'tax_class_key' => 'WeeeProductClass',
  1291. ];
  1292. $weeeProduct['items'][] = [
  1293. 'code' => 'weee1-Recycling Fee',
  1294. 'type' => 'weee',
  1295. 'quantity' => 1,
  1296. 'unit_price' => 7,
  1297. 'tax_class_key' => 'WeeeProductClass',
  1298. 'associated_item_code' => 'sequence-1'
  1299. ];
  1300. $weeeProductResults = [
  1301. 'subtotal' => 17,
  1302. 'tax_amount' => 1.4,
  1303. 'discount_tax_compensation_amount' => 0,
  1304. 'applied_taxes' => [
  1305. [
  1306. 'amount' => 1.4,
  1307. 'percent' => 8.25,
  1308. 'rates' => [
  1309. [
  1310. 'code' => 'US - 42 - 8.25',
  1311. 'title' => 'US - 42 - 8.25',
  1312. 'percent' => 8.25,
  1313. ],
  1314. ],
  1315. 'tax_rate_key' => 'US - 42 - 8.25',
  1316. ],
  1317. ],
  1318. 'items' => [
  1319. 'sequence-1' => [
  1320. 'code' => 'sequence-1',
  1321. 'row_tax' => 0.83,
  1322. 'price' => 10,
  1323. 'price_incl_tax' => 10.83,
  1324. 'row_total' => 10,
  1325. 'row_total_incl_tax' => 10.83,
  1326. 'type' => 'product',
  1327. 'tax_percent' => 8.25,
  1328. 'discount_tax_compensation_amount' => 0,
  1329. 'associated_item_code' => null,
  1330. 'applied_taxes' => [
  1331. 'US - 42 - 8.25' => [
  1332. 'amount' => 0.83,
  1333. 'percent' => 8.25,
  1334. 'tax_rate_key' => 'US - 42 - 8.25',
  1335. 'rates' => [
  1336. 'US - 42 - 8.25' => [
  1337. 'percent' => 8.25,
  1338. 'code' => 'US - 42 - 8.25',
  1339. 'title' => 'US - 42 - 8.25',
  1340. ],
  1341. ],
  1342. ],
  1343. ],
  1344. ],
  1345. 'weee1-Recycling Fee' => [
  1346. 'code' => 'weee1-Recycling Fee',
  1347. 'row_tax' => 0.57,
  1348. 'price' => 7,
  1349. 'price_incl_tax' => 7.57,
  1350. 'row_total' => 7,
  1351. 'row_total_incl_tax' => 7.57,
  1352. 'type' => 'weee',
  1353. 'tax_percent' => 8.25,
  1354. 'discount_tax_compensation_amount' => 0,
  1355. 'associated_item_code' => 'sequence-1',
  1356. 'applied_taxes' => [
  1357. 'US - 42 - 8.25' => [
  1358. 'amount' => 0.57,
  1359. 'percent' => 8.25,
  1360. 'tax_rate_key' => 'US - 42 - 8.25',
  1361. 'rates' => [
  1362. 'US - 42 - 8.25' => [
  1363. 'percent' => 8.25,
  1364. 'code' => 'US - 42 - 8.25',
  1365. 'title' => 'US - 42 - 8.25',
  1366. ],
  1367. ],
  1368. ],
  1369. ],
  1370. ]
  1371. ],
  1372. ];
  1373. $weeeProducts = $baseQuote;
  1374. $weeeProducts['items'][] = [
  1375. 'code' => 'sequence-1',
  1376. 'type' => 'product',
  1377. 'quantity' => 2,
  1378. 'unit_price' => 10,
  1379. 'tax_class_key' => 'WeeeProductClass',
  1380. ];
  1381. $weeeProducts['items'][] = [
  1382. 'code' => 'weee1-Recycling Fee',
  1383. 'type' => 'weee',
  1384. 'quantity' => 2,
  1385. 'unit_price' => 7,
  1386. 'tax_class_key' => 'WeeeProductClass',
  1387. 'associated_item_code' => 'sequence-1'
  1388. ];
  1389. $weeeProductsResults = [
  1390. 'subtotal' => 34,
  1391. 'tax_amount' => 2.81,
  1392. 'discount_tax_compensation_amount' => 0,
  1393. 'applied_taxes' => [
  1394. [
  1395. 'amount' => 2.81,
  1396. 'percent' => 8.25,
  1397. 'rates' => [
  1398. [
  1399. 'code' => 'US - 42 - 8.25',
  1400. 'title' => 'US - 42 - 8.25',
  1401. 'percent' => 8.25,
  1402. ],
  1403. ],
  1404. 'tax_rate_key' => 'US - 42 - 8.25',
  1405. ],
  1406. ],
  1407. 'items' => [
  1408. 'sequence-1' => [
  1409. 'code' => 'sequence-1',
  1410. 'row_tax' => 1.65,
  1411. 'price' => 10,
  1412. 'price_incl_tax' => 10.83,
  1413. 'row_total' => 20,
  1414. 'row_total_incl_tax' => 21.65,
  1415. 'type' => 'product',
  1416. 'tax_percent' => 8.25,
  1417. 'discount_tax_compensation_amount' => 0,
  1418. 'associated_item_code' => null,
  1419. 'applied_taxes' => [
  1420. 'US - 42 - 8.25' => [
  1421. 'amount' => 1.65,
  1422. 'percent' => 8.25,
  1423. 'tax_rate_key' => 'US - 42 - 8.25',
  1424. 'rates' => [
  1425. 'US - 42 - 8.25' => [
  1426. 'percent' => 8.25,
  1427. 'code' => 'US - 42 - 8.25',
  1428. 'title' => 'US - 42 - 8.25',
  1429. ],
  1430. ],
  1431. ],
  1432. ],
  1433. ],
  1434. 'weee1-Recycling Fee' => [
  1435. 'code' => 'weee1-Recycling Fee',
  1436. 'row_tax' => 1.16,
  1437. 'price' => 7,
  1438. 'price_incl_tax' => 7.58,
  1439. 'row_total' => 14,
  1440. 'row_total_incl_tax' => 15.16,
  1441. 'type' => 'weee',
  1442. 'tax_percent' => 8.25,
  1443. 'discount_tax_compensation_amount' => 0,
  1444. 'associated_item_code' => 'sequence-1',
  1445. 'applied_taxes' => [
  1446. 'US - 42 - 8.25' => [
  1447. 'amount' => 1.16,
  1448. 'percent' => 8.25,
  1449. 'tax_rate_key' => 'US - 42 - 8.25',
  1450. 'rates' => [
  1451. 'US - 42 - 8.25' => [
  1452. 'percent' => 8.25,
  1453. 'code' => 'US - 42 - 8.25',
  1454. 'title' => 'US - 42 - 8.25',
  1455. ],
  1456. ],
  1457. ],
  1458. ],
  1459. ]
  1460. ],
  1461. ];
  1462. $multiWeeeProducts = $baseQuote;
  1463. $multiWeeeProducts['items'][] = [
  1464. 'code' => 'sequence-1',
  1465. 'type' => 'product',
  1466. 'quantity' => 2,
  1467. 'unit_price' => 10,
  1468. 'tax_class_key' => 'WeeeProductClass',
  1469. ];
  1470. $multiWeeeProducts['items'][] = [
  1471. 'code' => 'weee1-Recycling Fee',
  1472. 'type' => 'weee',
  1473. 'quantity' => 2,
  1474. 'unit_price' => 7,
  1475. 'tax_class_key' => 'WeeeProductClass',
  1476. 'associated_item_code' => 'sequence-1'
  1477. ];
  1478. $multiWeeeProducts['items'][] = [
  1479. 'code' => 'sequence-2',
  1480. 'type' => 'product',
  1481. 'quantity' => 2,
  1482. 'unit_price' => 10,
  1483. 'tax_class_key' => 'WeeeProductClass',
  1484. ];
  1485. $multiWeeeProducts['items'][] = [
  1486. 'code' => 'weee2-Recycling Fee',
  1487. 'type' => 'weee',
  1488. 'quantity' => 2,
  1489. 'unit_price' => 7,
  1490. 'tax_class_key' => 'WeeeProductClass',
  1491. 'associated_item_code' => 'sequence-2'
  1492. ];
  1493. $multiWeeeProductsResults = [
  1494. 'subtotal' => 68,
  1495. 'tax_amount' => 5.62,
  1496. 'discount_tax_compensation_amount' => 0,
  1497. 'applied_taxes' => [
  1498. [
  1499. 'amount' => 5.62,
  1500. 'percent' => 8.25,
  1501. 'rates' => [
  1502. [
  1503. 'code' => 'US - 42 - 8.25',
  1504. 'title' => 'US - 42 - 8.25',
  1505. 'percent' => 8.25,
  1506. ],
  1507. ],
  1508. 'tax_rate_key' => 'US - 42 - 8.25',
  1509. ],
  1510. ],
  1511. 'items' => [
  1512. 'sequence-1' => [
  1513. 'code' => 'sequence-1',
  1514. 'row_tax' => 1.65,
  1515. 'price' => 10,
  1516. 'price_incl_tax' => 10.83,
  1517. 'row_total' => 20,
  1518. 'row_total_incl_tax' => 21.65,
  1519. 'type' => 'product',
  1520. 'tax_percent' => 8.25,
  1521. 'discount_tax_compensation_amount' => 0,
  1522. 'associated_item_code' => null,
  1523. 'applied_taxes' => [
  1524. 'US - 42 - 8.25' => [
  1525. 'amount' => 1.65,
  1526. 'percent' => 8.25,
  1527. 'tax_rate_key' => 'US - 42 - 8.25',
  1528. 'rates' => [
  1529. 'US - 42 - 8.25' => [
  1530. 'percent' => 8.25,
  1531. 'code' => 'US - 42 - 8.25',
  1532. 'title' => 'US - 42 - 8.25',
  1533. ],
  1534. ],
  1535. ],
  1536. ],
  1537. ],
  1538. 'weee1-Recycling Fee' => [
  1539. 'code' => 'weee1-Recycling Fee',
  1540. 'row_tax' => 1.16,
  1541. 'price' => 7,
  1542. 'price_incl_tax' => 7.58,
  1543. 'row_total' => 14,
  1544. 'row_total_incl_tax' => 15.16,
  1545. 'type' => 'weee',
  1546. 'tax_percent' => 8.25,
  1547. 'discount_tax_compensation_amount' => 0,
  1548. 'associated_item_code' => 'sequence-1',
  1549. 'applied_taxes' => [
  1550. 'US - 42 - 8.25' => [
  1551. 'amount' => 1.16,
  1552. 'percent' => 8.25,
  1553. 'tax_rate_key' => 'US - 42 - 8.25',
  1554. 'rates' => [
  1555. 'US - 42 - 8.25' => [
  1556. 'percent' => 8.25,
  1557. 'code' => 'US - 42 - 8.25',
  1558. 'title' => 'US - 42 - 8.25',
  1559. ],
  1560. ],
  1561. ],
  1562. ],
  1563. ],
  1564. 'sequence-2' => [
  1565. 'code' => 'sequence-2',
  1566. 'row_tax' => 1.65,
  1567. 'price' => 10,
  1568. 'price_incl_tax' => 10.83,
  1569. 'row_total' => 20,
  1570. 'row_total_incl_tax' => 21.65,
  1571. 'type' => 'product',
  1572. 'tax_percent' => 8.25,
  1573. 'discount_tax_compensation_amount' => 0,
  1574. 'associated_item_code' => null,
  1575. 'applied_taxes' => [
  1576. 'US - 42 - 8.25' => [
  1577. 'amount' => 1.65,
  1578. 'percent' => 8.25,
  1579. 'tax_rate_key' => 'US - 42 - 8.25',
  1580. 'rates' => [
  1581. 'US - 42 - 8.25' => [
  1582. 'percent' => 8.25,
  1583. 'code' => 'US - 42 - 8.25',
  1584. 'title' => 'US - 42 - 8.25',
  1585. ],
  1586. ],
  1587. ],
  1588. ],
  1589. ],
  1590. 'weee2-Recycling Fee' => [
  1591. 'code' => 'weee2-Recycling Fee',
  1592. 'row_tax' => 1.16,
  1593. 'price' => 7,
  1594. 'price_incl_tax' => 7.58,
  1595. 'row_total' => 14,
  1596. 'row_total_incl_tax' => 15.16,
  1597. 'type' => 'weee',
  1598. 'tax_percent' => 8.25,
  1599. 'discount_tax_compensation_amount' => 0,
  1600. 'associated_item_code' => 'sequence-2',
  1601. 'applied_taxes' => [
  1602. 'US - 42 - 8.25' => [
  1603. 'amount' => 1.16,
  1604. 'percent' => 8.25,
  1605. 'tax_rate_key' => 'US - 42 - 8.25',
  1606. 'rates' => [
  1607. 'US - 42 - 8.25' => [
  1608. 'percent' => 8.25,
  1609. 'code' => 'US - 42 - 8.25',
  1610. 'title' => 'US - 42 - 8.25',
  1611. ],
  1612. ],
  1613. ],
  1614. ],
  1615. ]
  1616. ],
  1617. ];
  1618. $oneProductInclTax = $baseQuote;
  1619. $oneProductInclTax['items'][] = [
  1620. 'code' => 'sku_1',
  1621. 'type' => 'product',
  1622. 'quantity' => 10,
  1623. 'unit_price' => 1.0,
  1624. 'tax_class_key' => 'DefaultProductClass',
  1625. 'is_tax_included' => true,
  1626. ];
  1627. $oneProductInclTaxResults = [
  1628. 'subtotal' => 9.3,
  1629. 'tax_amount' => 0.7,
  1630. 'discount_tax_compensation_amount' => 0,
  1631. 'applied_taxes' => [
  1632. [
  1633. 'amount' => 0.7,
  1634. 'percent' => 7.5,
  1635. 'tax_rate_key' => 'US - 42 - 7.5',
  1636. 'rates' => [
  1637. [
  1638. 'percent' => 7.5,
  1639. 'code' => 'US - 42 - 7.5',
  1640. 'title' => 'US - 42 - 7.5',
  1641. ],
  1642. ],
  1643. ],
  1644. ],
  1645. 'items' => [
  1646. 'sku_1' => [
  1647. 'code' => 'sku_1',
  1648. 'row_tax' => .7,
  1649. 'price' => 0.93,
  1650. 'price_incl_tax' => 1.0,
  1651. 'row_total' => 9.3,
  1652. 'row_total_incl_tax' => 10,
  1653. 'type' => 'product',
  1654. 'tax_percent' => 7.5,
  1655. 'discount_tax_compensation_amount' => 0,
  1656. 'associated_item_code' => null,
  1657. 'applied_taxes' => [
  1658. 'US - 42 - 7.5' => [
  1659. 'amount' => 0.7,
  1660. 'percent' => 7.5,
  1661. 'tax_rate_key' => 'US - 42 - 7.5',
  1662. 'rates' => [
  1663. 'US - 42 - 7.5' => [
  1664. 'percent' => 7.5,
  1665. 'code' => 'US - 42 - 7.5',
  1666. 'title' => 'US - 42 - 7.5',
  1667. ],
  1668. ],
  1669. ],
  1670. ],
  1671. ],
  1672. ],
  1673. ];
  1674. $oneProductInclTaxDiffRate = $baseQuote;
  1675. $oneProductInclTaxDiffRate['items'][] = [
  1676. 'code' => 'sku_1',
  1677. 'type' => 'product',
  1678. 'quantity' => 9,
  1679. 'unit_price' => 0.33, // this is including the store tax of 10%. Pre tax is 0.3
  1680. 'tax_class_key' => [
  1681. Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
  1682. Key::KEY_VALUE => 'HigherProductClass',
  1683. ],
  1684. 'is_tax_included' => true,
  1685. ];
  1686. $oneProductInclTaxDiffRateResults = [
  1687. 'subtotal' => 2.73,
  1688. 'tax_amount' => 0.6,
  1689. 'discount_tax_compensation_amount' => 0,
  1690. 'applied_taxes' => [
  1691. [
  1692. 'amount' => 0.6,
  1693. 'percent' => 22,
  1694. 'rates' => [
  1695. [
  1696. 'percent' => 22,
  1697. 'code' => 'US - 42 - 22',
  1698. 'title' => 'US - 42 - 22',
  1699. ],
  1700. ],
  1701. 'tax_rate_key' => 'US - 42 - 22',
  1702. ],
  1703. ],
  1704. 'items' => [
  1705. 'sku_1' => [
  1706. 'code' => 'sku_1',
  1707. 'row_tax' => 0.6,
  1708. 'price' => 0.3,
  1709. 'price_incl_tax' => 0.37,
  1710. 'row_total' => 2.73,
  1711. 'row_total_incl_tax' => 3.33,
  1712. 'type' => 'product',
  1713. 'tax_percent' => 22.0,
  1714. 'discount_tax_compensation_amount' => 0,
  1715. 'associated_item_code' => null,
  1716. 'applied_taxes' => [
  1717. 'US - 42 - 22' => [
  1718. 'amount' => 0.6,
  1719. 'percent' => 22,
  1720. 'tax_rate_key' => 'US - 42 - 22',
  1721. 'rates' => [
  1722. 'US - 42 - 22' => [
  1723. 'percent' => 22,
  1724. 'code' => 'US - 42 - 22',
  1725. 'title' => 'US - 42 - 22',
  1726. ],
  1727. ],
  1728. ],
  1729. ],
  1730. ],
  1731. ],
  1732. ];
  1733. $twoProducts = $baseQuote;
  1734. $twoProducts['items'] = [
  1735. [
  1736. 'code' => 'sku_1',
  1737. 'type' => 'product',
  1738. 'quantity' => 10,
  1739. 'unit_price' => 1,
  1740. 'tax_class_key' => 'DefaultProductClass',
  1741. ],
  1742. [
  1743. 'code' => 'sku_2',
  1744. 'type' => 'product',
  1745. 'quantity' => 20,
  1746. 'unit_price' => 11,
  1747. 'tax_class_key' => 'DefaultProductClass',
  1748. ],
  1749. ];
  1750. $twoProductsResults = [
  1751. 'subtotal' => 230,
  1752. 'tax_amount' => 17.25,
  1753. 'discount_tax_compensation_amount' => 0,
  1754. 'applied_taxes' => [
  1755. [
  1756. 'amount' => 17.25,
  1757. 'percent' => 7.5,
  1758. 'tax_rate_key' => 'US - 42 - 7.5',
  1759. 'rates' => [
  1760. [
  1761. 'percent' => 7.5,
  1762. 'code' => 'US - 42 - 7.5',
  1763. 'title' => 'US - 42 - 7.5',
  1764. ],
  1765. ],
  1766. ],
  1767. ],
  1768. 'items' => [
  1769. 'sku_1' => [
  1770. 'code' => 'sku_1',
  1771. 'row_tax' => .75,
  1772. 'price' => 1,
  1773. 'price_incl_tax' => 1.08,
  1774. 'row_total' => 10,
  1775. 'row_total_incl_tax' => 10.75,
  1776. 'type' => 'product',
  1777. 'tax_percent' => 7.5,
  1778. 'discount_tax_compensation_amount' => 0,
  1779. 'associated_item_code' => null,
  1780. 'applied_taxes' => [
  1781. 'US - 42 - 7.5' => [
  1782. 'amount' => 0.75,
  1783. 'percent' => 7.5,
  1784. 'tax_rate_key' => 'US - 42 - 7.5',
  1785. 'rates' => [
  1786. 'US - 42 - 7.5' => [
  1787. 'percent' => 7.5,
  1788. 'code' => 'US - 42 - 7.5',
  1789. 'title' => 'US - 42 - 7.5',
  1790. ],
  1791. ],
  1792. ],
  1793. ],
  1794. ],
  1795. 'sku_2' => [
  1796. 'code' => 'sku_2',
  1797. 'row_tax' => 16.5,
  1798. 'price' => 11,
  1799. 'price_incl_tax' => 11.83,
  1800. 'row_total' => 220,
  1801. 'row_total_incl_tax' => 236.5,
  1802. 'type' => 'product',
  1803. 'tax_percent' => 7.5,
  1804. 'discount_tax_compensation_amount' => 0,
  1805. 'associated_item_code' => null,
  1806. 'applied_taxes' => [
  1807. 'US - 42 - 7.5' => [
  1808. 'amount' => 16.5,
  1809. 'percent' => 7.5,
  1810. 'tax_rate_key' => 'US - 42 - 7.5',
  1811. 'rates' => [
  1812. 'US - 42 - 7.5' => [
  1813. 'percent' => 7.5,
  1814. 'code' => 'US - 42 - 7.5',
  1815. 'title' => 'US - 42 - 7.5',
  1816. ],
  1817. ],
  1818. ],
  1819. ],
  1820. ],
  1821. ],
  1822. ];
  1823. $twoProductsInclTax = $baseQuote;
  1824. $twoProductsInclTax['items'] = [
  1825. [
  1826. 'code' => 'sku_1',
  1827. 'type' => 'product',
  1828. 'quantity' => 10,
  1829. 'unit_price' => 0.98,
  1830. 'tax_class_key' => 'DefaultProductClass',
  1831. 'is_tax_included' => true,
  1832. ],
  1833. [
  1834. 'code' => 'sku_2',
  1835. 'type' => 'product',
  1836. 'quantity' => 20,
  1837. 'unit_price' => 11.99,
  1838. 'tax_class_key' => 'DefaultProductClass',
  1839. 'is_tax_included' => true,
  1840. ],
  1841. ];
  1842. $twoProductInclTaxResults = [
  1843. 'subtotal' => 232.19,
  1844. 'tax_amount' => 17.41,
  1845. 'discount_tax_compensation_amount' => 0,
  1846. 'applied_taxes' => [
  1847. [
  1848. 'amount' => 17.41,
  1849. 'percent' => 7.5,
  1850. 'tax_rate_key' => 'US - 42 - 7.5',
  1851. 'rates' => [
  1852. [
  1853. 'percent' => 7.5,
  1854. 'code' => 'US - 42 - 7.5',
  1855. 'title' => 'US - 42 - 7.5',
  1856. ],
  1857. ],
  1858. ],
  1859. ],
  1860. 'items' => [
  1861. 'sku_1' => [
  1862. 'code' => 'sku_1',
  1863. 'row_tax' => .68,
  1864. 'price' => 0.91,
  1865. 'price_incl_tax' => 0.98,
  1866. 'row_total' => 9.12,
  1867. 'row_total_incl_tax' => 9.8,
  1868. 'type' => 'product',
  1869. 'tax_percent' => 7.5,
  1870. 'discount_tax_compensation_amount' => 0,
  1871. 'associated_item_code' => null,
  1872. 'applied_taxes' => [
  1873. 'US - 42 - 7.5' => [
  1874. 'amount' => 0.68,
  1875. 'percent' => 7.5,
  1876. 'tax_rate_key' => 'US - 42 - 7.5',
  1877. 'rates' => [
  1878. 'US - 42 - 7.5' => [
  1879. 'percent' => 7.5,
  1880. 'code' => 'US - 42 - 7.5',
  1881. 'title' => 'US - 42 - 7.5',
  1882. ],
  1883. ],
  1884. ],
  1885. ],
  1886. ],
  1887. 'sku_2' => [
  1888. 'code' => 'sku_2',
  1889. 'row_tax' => 16.73,
  1890. 'price' => 11.15,
  1891. 'price_incl_tax' => 11.99,
  1892. 'row_total' => 223.07,
  1893. 'row_total_incl_tax' => 239.8, // Shouldn't this be 223.07?
  1894. 'type' => 'product',
  1895. 'tax_percent' => 7.5,
  1896. 'discount_tax_compensation_amount' => 0,
  1897. 'associated_item_code' => null,
  1898. 'applied_taxes' => [
  1899. 'US - 42 - 7.5' => [
  1900. 'amount' => 16.73,
  1901. 'percent' => 7.5,
  1902. 'tax_rate_key' => 'US - 42 - 7.5',
  1903. 'rates' => [
  1904. 'US - 42 - 7.5' => [
  1905. 'percent' => 7.5,
  1906. 'code' => 'US - 42 - 7.5',
  1907. 'title' => 'US - 42 - 7.5',
  1908. ],
  1909. ],
  1910. ],
  1911. ],
  1912. ],
  1913. ],
  1914. ];
  1915. $oneProductWithChildren = $baseQuote;
  1916. $oneProductWithChildren['items'] = [
  1917. [
  1918. 'code' => 'child_1_sku',
  1919. 'type' => 'product',
  1920. 'quantity' => 2,
  1921. 'unit_price' => 12.34,
  1922. 'tax_class_key' => 'DefaultProductClass',
  1923. 'parent_code' => 'parent_sku',
  1924. ],
  1925. [
  1926. 'code' => 'parent_sku', // Put the parent in the middle of the children to test an edge case
  1927. 'type' => 'product',
  1928. 'quantity' => 10,
  1929. 'unit_price' => 0,
  1930. 'tax_class_key' => 'DefaultProductClass',
  1931. ],
  1932. [
  1933. 'code' => 'child_2_sku',
  1934. 'type' => 'product',
  1935. 'quantity' => 2,
  1936. 'unit_price' => 1.99,
  1937. 'tax_class_key' => 'HigherProductClass',
  1938. 'parent_code' => 'parent_sku',
  1939. ],
  1940. ];
  1941. $oneProductWithChildrenResults = [
  1942. 'subtotal' => 286.6,
  1943. 'tax_amount' => 27.27,
  1944. 'discount_tax_compensation_amount' => 0,
  1945. 'applied_taxes' => [
  1946. [
  1947. 'amount' => 18.51,
  1948. 'percent' => 7.5,
  1949. 'rates' => [
  1950. [
  1951. 'code' => 'US - 42 - 7.5',
  1952. 'title' => 'US - 42 - 7.5',
  1953. 'percent' => 7.5,
  1954. ],
  1955. ],
  1956. 'tax_rate_key' => 'US - 42 - 7.5',
  1957. ],
  1958. [
  1959. 'amount' => 8.76,
  1960. 'percent' => 22,
  1961. 'rates' => [
  1962. [
  1963. 'code' => 'US - 42 - 22',
  1964. 'title' => 'US - 42 - 22',
  1965. 'percent' => 22,
  1966. ],
  1967. ],
  1968. 'tax_rate_key' => 'US - 42 - 22',
  1969. ],
  1970. ],
  1971. 'items' => [
  1972. 'child_1_sku' => [
  1973. 'code' => 'child_1_sku',
  1974. 'row_tax' => 18.51,
  1975. 'price' => 12.34,
  1976. 'price_incl_tax' => 13.27,
  1977. 'row_total' => 246.8,
  1978. 'row_total_incl_tax' => 265.31,
  1979. 'type' => 'product',
  1980. 'tax_percent' => 7.5,
  1981. 'discount_tax_compensation_amount' => 0,
  1982. 'associated_item_code' => null,
  1983. 'applied_taxes' => [
  1984. 'US - 42 - 7.5' => [
  1985. 'amount' => 18.51,
  1986. 'percent' => 7.5,
  1987. 'tax_rate_key' => 'US - 42 - 7.5',
  1988. 'rates' => [
  1989. 'US - 42 - 7.5' => [
  1990. 'percent' => 7.5,
  1991. 'code' => 'US - 42 - 7.5',
  1992. 'title' => 'US - 42 - 7.5',
  1993. ],
  1994. ],
  1995. ],
  1996. ],
  1997. ],
  1998. 'child_2_sku' => [
  1999. 'code' => 'child_2_sku',
  2000. 'row_tax' => 8.76,
  2001. 'price' => 1.99,
  2002. 'price_incl_tax' => 2.43,
  2003. 'row_total' => 39.8,
  2004. 'row_total_incl_tax' => 48.56,
  2005. 'type' => 'product',
  2006. 'tax_percent' => 22,
  2007. 'discount_tax_compensation_amount' => 0,
  2008. 'associated_item_code' => null,
  2009. 'applied_taxes' => [
  2010. 'US - 42 - 22' => [
  2011. 'amount' => 8.76,
  2012. 'percent' => 22,
  2013. 'tax_rate_key' => 'US - 42 - 22',
  2014. 'rates' => [
  2015. 'US - 42 - 22' => [
  2016. 'percent' => 22,
  2017. 'code' => 'US - 42 - 22',
  2018. 'title' => 'US - 42 - 22',
  2019. ],
  2020. ],
  2021. ],
  2022. ],
  2023. ],
  2024. 'parent_sku' => [
  2025. 'price' => 28.66,
  2026. 'price_incl_tax' => 31.39,
  2027. 'row_total' => 286.6,
  2028. 'row_total_incl_tax' => 313.87,
  2029. 'row_tax' => 27.27,
  2030. 'code' => 'parent_sku',
  2031. 'type' => 'product',
  2032. ],
  2033. ],
  2034. ];
  2035. return [
  2036. 'one product' => [
  2037. 'quote_details' => $oneProduct,
  2038. 'expected_tax_details' => $oneProductResults,
  2039. ],
  2040. 'weee_product' => [
  2041. 'quote_details' => $weeeProduct,
  2042. 'expected_tax_details' => $weeeProductResults,
  2043. ],
  2044. 'weee_products' => [
  2045. 'quote_details' => $weeeProducts,
  2046. 'expected_tax_details' => $weeeProductsResults,
  2047. ],
  2048. 'multi weee_products' => [
  2049. 'quote_details' => $multiWeeeProducts,
  2050. 'expected_tax_details' => $multiWeeeProductsResults,
  2051. ],
  2052. 'one product, tax included' => [
  2053. 'quote_details' => $oneProductInclTax,
  2054. 'expected_tax_details' => $oneProductInclTaxResults,
  2055. ],
  2056. 'one product, tax included but differs from store rate' => [
  2057. 'quote_details' => $oneProductInclTaxDiffRate,
  2058. 'expected_tax_details' => $oneProductInclTaxDiffRateResults,
  2059. ],
  2060. 'two products' => [
  2061. 'quote_details' => $twoProducts,
  2062. 'expected_tax_details' => $twoProductsResults,
  2063. ],
  2064. 'two products, tax included' => [
  2065. 'quote_details' => $twoProductsInclTax,
  2066. 'expected_tax_details' => $twoProductInclTaxResults,
  2067. ],
  2068. 'one product with two children' => [
  2069. 'quote_details' => $oneProductWithChildren,
  2070. 'expected_tax_details' => $oneProductWithChildrenResults,
  2071. ],
  2072. ];
  2073. }
  2074. /**
  2075. * Create quote details for use with multi rules tests
  2076. *
  2077. * @return array
  2078. */
  2079. protected function setupMultiRuleQuote()
  2080. {
  2081. $baseQuote = $this->getBaseQuoteData();
  2082. $baseQuote['items'][] = [
  2083. 'code' => 'sku_1',
  2084. 'type' => 'product',
  2085. 'quantity' => 10,
  2086. 'unit_price' => 1.89,
  2087. 'tax_class_key' => 'MultipleRulesProductClass',
  2088. 'is_tax_included' => true,
  2089. 'discount_amount' => 5,
  2090. ];
  2091. $baseQuote['items'][] = [
  2092. 'code' => 'sku_2',
  2093. 'type' => 'product',
  2094. 'quantity' => 5,
  2095. 'unit_price' => 14.99,
  2096. 'tax_class_key' => 'MultipleRulesProductClass',
  2097. 'is_tax_included' => true,
  2098. 'discount_amount' => 10,
  2099. ];
  2100. $baseQuote['items'][] = [
  2101. 'code' => 'sku_3',
  2102. 'type' => 'product',
  2103. 'quantity' => 1,
  2104. 'unit_price' => 99.99,
  2105. 'tax_class_key' => 'MultipleRulesProductClass',
  2106. 'is_tax_included' => false,
  2107. 'discount_amount' => 5,
  2108. ];
  2109. return $baseQuote;
  2110. }
  2111. /**
  2112. * Create the base results for the multi rules test
  2113. *
  2114. * @return array
  2115. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  2116. */
  2117. protected function getBaseQuoteResult()
  2118. {
  2119. $result = [
  2120. 'subtotal' => 183.75,
  2121. 'tax_amount' => 42.88,
  2122. 'discount_tax_compensation_amount' => 3.08,
  2123. 'applied_taxes' => [
  2124. [
  2125. 'amount' => 22.1,
  2126. 'percent' => 13.25,
  2127. 'rates' => [
  2128. [
  2129. 'code' => 'US - 42 - 8.25',
  2130. 'title' => 'US - 42 - 8.25',
  2131. 'percent' => 8.25,
  2132. ],
  2133. [
  2134. 'code' => 'US - 42 - 5 - 55555',
  2135. 'title' => 'US - 42 - 5 - 55555',
  2136. 'percent' => 5,
  2137. ],
  2138. ],
  2139. 'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
  2140. ],
  2141. [
  2142. 'amount' => 20.78,
  2143. 'percent' => 12.4575,
  2144. 'rates' => [
  2145. [
  2146. 'code' => 'US - 42 - 11 - 55555',
  2147. 'title' => 'US - 42 - 11 - 55555',
  2148. 'percent' => 11,
  2149. ],
  2150. ],
  2151. 'tax_rate_key' => 'US - 42 - 11 - 55555',
  2152. ],
  2153. ],
  2154. 'items' => [
  2155. 'sku_1' => [
  2156. 'code' => 'sku_1',
  2157. 'row_tax' => 3.31,
  2158. 'price' => 1.69,
  2159. 'price_incl_tax' => 2.12,
  2160. 'row_total' => 16.86,
  2161. 'row_total_incl_tax' => 21.2,
  2162. 'type' => 'product',
  2163. 'tax_percent' => 25.7075,
  2164. 'discount_tax_compensation_amount' => 1.03,
  2165. 'associated_item_code' => null,
  2166. 'applied_taxes' => [
  2167. 'US - 42 - 8.25US - 42 - 5 - 55555' => [
  2168. 'amount' => 1.71,
  2169. 'percent' => 13.25,
  2170. 'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
  2171. 'rates' => [
  2172. 'US - 42 - 8.25' => [
  2173. 'percent' => 8.25,
  2174. 'code' => 'US - 42 - 8.25',
  2175. 'title' => 'US - 42 - 8.25',
  2176. ],
  2177. 'US - 42 - 5 - 55555' => [
  2178. 'percent' => 5,
  2179. 'code' => 'US - 42 - 5 - 55555',
  2180. 'title' => 'US - 42 - 5 - 55555',
  2181. ],
  2182. ],
  2183. ],
  2184. 'US - 42 - 11 - 55555' => [
  2185. 'amount' => 1.6,
  2186. 'percent' => 12.4575,
  2187. 'tax_rate_key' => 'US - 42 - 11 - 55555',
  2188. 'rates' => [
  2189. 'US - 42 - 11 - 55555' => [
  2190. 'percent' => 11,
  2191. 'code' => 'US - 42 - 11 - 55555',
  2192. 'title' => 'US - 42 - 11 - 55555',
  2193. ],
  2194. ],
  2195. ],
  2196. ],
  2197. ],
  2198. 'sku_2' => [
  2199. 'code' => 'sku_2',
  2200. 'row_tax' => 15.15,
  2201. 'price' => 13.38,
  2202. 'price_incl_tax' => 16.82,
  2203. 'row_total' => 66.9,
  2204. 'row_total_incl_tax' => 84.1,
  2205. 'type' => 'product',
  2206. 'tax_percent' => 25.7075,
  2207. 'discount_tax_compensation_amount' => 2.05,
  2208. 'associated_item_code' => null,
  2209. 'applied_taxes' => [
  2210. 'US - 42 - 8.25US - 42 - 5 - 55555' => [
  2211. 'amount' => 7.8,
  2212. 'percent' => 13.25,
  2213. 'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
  2214. 'rates' => [
  2215. 'US - 42 - 8.25' => [
  2216. 'percent' => 8.25,
  2217. 'code' => 'US - 42 - 8.25',
  2218. 'title' => 'US - 42 - 8.25',
  2219. ],
  2220. 'US - 42 - 5 - 55555' => [
  2221. 'percent' => 5,
  2222. 'code' => 'US - 42 - 5 - 55555',
  2223. 'title' => 'US - 42 - 5 - 55555',
  2224. ],
  2225. ],
  2226. ],
  2227. 'US - 42 - 11 - 55555' => [
  2228. 'amount' => 7.35,
  2229. 'percent' => 12.4575,
  2230. 'tax_rate_key' => 'US - 42 - 11 - 55555',
  2231. 'rates' => [
  2232. 'US - 42 - 11 - 55555' => [
  2233. 'percent' => 11,
  2234. 'code' => 'US - 42 - 11 - 55555',
  2235. 'title' => 'US - 42 - 11 - 55555',
  2236. ],
  2237. ],
  2238. ],
  2239. ],
  2240. ],
  2241. 'sku_3' => [
  2242. 'code' => 'sku_3',
  2243. 'row_tax' => 24.42,
  2244. 'price' => 99.99,
  2245. 'price_incl_tax' => 125.7,
  2246. 'row_total' => 99.99,
  2247. 'row_total_incl_tax' => 125.7,
  2248. 'type' => 'product',
  2249. 'tax_percent' => 25.7075,
  2250. 'discount_tax_compensation_amount' => 0,
  2251. 'associated_item_code' => null,
  2252. 'applied_taxes' => [
  2253. 'US - 42 - 8.25US - 42 - 5 - 55555' => [
  2254. 'amount' => 12.59,
  2255. 'percent' => 13.25,
  2256. 'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
  2257. 'rates' => [
  2258. 'US - 42 - 8.25' => [
  2259. 'percent' => 8.25,
  2260. 'code' => 'US - 42 - 8.25',
  2261. 'title' => 'US - 42 - 8.25',
  2262. ],
  2263. 'US - 42 - 5 - 55555' => [
  2264. 'percent' => 5,
  2265. 'code' => 'US - 42 - 5 - 55555',
  2266. 'title' => 'US - 42 - 5 - 55555',
  2267. ],
  2268. ],
  2269. ],
  2270. 'US - 42 - 11 - 55555' => [
  2271. 'amount' => 11.83,
  2272. 'percent' => 12.4575,
  2273. 'tax_rate_key' => 'US - 42 - 11 - 55555',
  2274. 'rates' => [
  2275. 'US - 42 - 11 - 55555' => [
  2276. 'percent' => 11,
  2277. 'code' => 'US - 42 - 11 - 55555',
  2278. 'title' => 'US - 42 - 11 - 55555',
  2279. ],
  2280. ],
  2281. ],
  2282. ],
  2283. ],
  2284. ],
  2285. ];
  2286. return $result;
  2287. }
  2288. /**
  2289. * @magentoDbIsolation enabled
  2290. * @dataProvider multiRulesRowBasedDataProvider
  2291. * @magentoConfigFixture default_store tax/calculation/algorithm ROW_BASE_CALCULATION
  2292. */
  2293. public function testMultiRulesRowBased($quoteDetailsData, $expectedTaxDetails)
  2294. {
  2295. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  2296. $quoteDetails = $this->quoteDetailsFactory->create();
  2297. $this->dataObjectHelper->populateWithArray(
  2298. $quoteDetails,
  2299. $quoteDetailsData,
  2300. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  2301. );
  2302. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
  2303. $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
  2304. }
  2305. /**
  2306. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  2307. */
  2308. public function multiRulesRowBasedDataProvider()
  2309. {
  2310. $quoteDetails = $this->setupMultiRuleQuote();
  2311. $results = $this->getBaseQuoteResult();
  2312. return [
  2313. 'multi rules, multi rows' => [
  2314. 'quote_details' => $quoteDetails,
  2315. 'expected_tax_details' => $results,
  2316. ],
  2317. ];
  2318. }
  2319. /**
  2320. * @magentoDbIsolation enabled
  2321. * @dataProvider multiRulesTotalBasedDataProvider
  2322. * @magentoConfigFixture default_store tax/calculation/algorithm TOTAL_BASE_CALCULATION
  2323. */
  2324. public function testMultiRulesTotalBased($quoteDetailsData, $expectedTaxDetails)
  2325. {
  2326. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  2327. $quoteDetails = $this->quoteDetailsFactory->create();
  2328. $this->dataObjectHelper->populateWithArray(
  2329. $quoteDetails,
  2330. $quoteDetailsData,
  2331. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  2332. );
  2333. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
  2334. $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
  2335. }
  2336. /**
  2337. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  2338. */
  2339. public function multiRulesTotalBasedDataProvider()
  2340. {
  2341. $quoteDetails = $this->setupMultiRuleQuote();
  2342. $results = $this->getBaseQuoteResult();
  2343. //Differences from the row base result
  2344. $results['subtotal'] = 183.76;
  2345. $results['tax_amount'] = 42.89;
  2346. $results['discount_tax_compensation_amount'] = 3.06;
  2347. $results['applied_taxes'][0]['amount'] = 22.11;
  2348. $results['items']['sku_2']['row_tax'] = 15.16;
  2349. $results['items']['sku_2']['row_total'] = 66.91;
  2350. $results['items']['sku_2']['discount_tax_compensation_amount'] = 2.03;
  2351. $results['items']['sku_2']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 7.81;
  2352. return [
  2353. 'multi rules, multi rows' => [
  2354. 'quote_details' => $quoteDetails,
  2355. 'expected_tax_details' => $results,
  2356. ],
  2357. ];
  2358. }
  2359. /**
  2360. * @magentoDbIsolation enabled
  2361. * @dataProvider multiRulesUnitBasedDataProvider
  2362. * @magentoConfigFixture default_store tax/calculation/algorithm UNIT_BASE_CALCULATION
  2363. */
  2364. public function testMultiRulesUnitBased($quoteDetailsData, $expectedTaxDetails)
  2365. {
  2366. $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
  2367. $quoteDetails = $this->quoteDetailsFactory->create();
  2368. $this->dataObjectHelper->populateWithArray(
  2369. $quoteDetails,
  2370. $quoteDetailsData,
  2371. \Magento\Tax\Api\Data\QuoteDetailsInterface::class
  2372. );
  2373. $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
  2374. $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
  2375. }
  2376. /**
  2377. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  2378. */
  2379. public function multiRulesUnitBasedDataProvider()
  2380. {
  2381. $quoteDetails = $this->setupMultiRuleQuote();
  2382. $results = $this->getBaseQuoteResult();
  2383. //Differences from the row base result
  2384. $results['subtotal'] = 183.79;
  2385. $results['tax_amount'] = 42.87;
  2386. $results['discount_tax_compensation_amount'] = 3.05;
  2387. $results['applied_taxes'][1]['amount'] = 20.77;
  2388. $results['items']['sku_1']['row_tax'] = 3.3;
  2389. $results['items']['sku_1']['row_total'] = 16.9;
  2390. $results['items']['sku_1']['discount_tax_compensation_amount'] = 1;
  2391. $results['items']['sku_1']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 1.7;
  2392. $results['items']['sku_2']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 7.81;
  2393. $results['items']['sku_2']['applied_taxes']['US - 42 - 11 - 55555']['amount'] = 7.34;
  2394. return [
  2395. 'multi rules, multi rows' => [
  2396. 'quote_details' => $quoteDetails,
  2397. 'expected_tax_details' => $results,
  2398. ],
  2399. ];
  2400. }
  2401. /**
  2402. * Substitutes an ID for the name of a tax class in a tax class ID field.
  2403. *
  2404. * @param array $data
  2405. * @return array
  2406. */
  2407. private function performTaxClassSubstitution($data)
  2408. {
  2409. array_walk_recursive(
  2410. $data,
  2411. function (&$value, $key) {
  2412. if (($key === 'tax_class_key' || $key === 'customer_tax_class_key')
  2413. && is_string($value)
  2414. ) {
  2415. $value = [
  2416. Key::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
  2417. Key::KEY_VALUE => $this->taxClassIds[$value],
  2418. ];
  2419. }
  2420. }
  2421. );
  2422. return $data;
  2423. }
  2424. /**
  2425. * Helper function that sets up some default rules
  2426. */
  2427. private function setUpDefaultRules()
  2428. {
  2429. $this->taxClassIds = $this->taxRuleFixtureFactory->createTaxClasses([
  2430. ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER],
  2431. ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
  2432. ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
  2433. ['name' => 'MultipleRulesProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
  2434. ['name' => 'WeeeProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
  2435. ]);
  2436. $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([
  2437. ['percentage' => 7.5, 'country' => 'US', 'region' => 42],
  2438. ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate
  2439. ]);
  2440. $weeeTaxRates = $this->taxRuleFixtureFactory->createTaxRates([
  2441. ['percentage' => 8.25, 'country' => 'US', 'region' => 12] // Default store rate
  2442. ]);
  2443. $multiTaxRates1 = $this->taxRuleFixtureFactory->createTaxRates([
  2444. ['percentage' => 8.25, 'country' => 'US', 'region' => 42],
  2445. ['percentage' => 12, 'country' => 'US', 'region' => 12], // Default store rate
  2446. ]);
  2447. $multiTaxRatesSamePriority = $this->taxRuleFixtureFactory->createTaxRates([
  2448. ['percentage' => 5, 'country' => 'US', 'region' => 42, 'postcode' => '55555'],
  2449. ]);
  2450. $multiTaxRatesDifferentPriority = $this->taxRuleFixtureFactory->createTaxRates([
  2451. ['percentage' => 11, 'country' => 'US', 'region' => 42, 'postcode' => '55555'],
  2452. ]);
  2453. $higherRates = $this->taxRuleFixtureFactory->createTaxRates([
  2454. ['percentage' => 22, 'country' => 'US', 'region' => 42],
  2455. ['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate
  2456. ]);
  2457. $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([
  2458. [
  2459. 'code' => 'Default Rule',
  2460. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2461. 'product_tax_class_ids' => [$this->taxClassIds['DefaultProductClass']],
  2462. 'tax_rate_ids' => array_values($this->taxRates),
  2463. 'sort_order' => 0,
  2464. 'priority' => 0,
  2465. ],
  2466. [
  2467. 'code' => 'Weee Rule',
  2468. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2469. 'product_tax_class_ids' => [$this->taxClassIds['WeeeProductClass']],
  2470. 'tax_rate_ids' => array_values($weeeTaxRates),
  2471. 'sort_order' => 0,
  2472. 'priority' => 0,
  2473. ],
  2474. [
  2475. 'code' => 'Higher Rate Rule',
  2476. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2477. 'product_tax_class_ids' => [$this->taxClassIds['HigherProductClass']],
  2478. 'tax_rate_ids' => array_values($higherRates),
  2479. 'sort_order' => 0,
  2480. 'priority' => 0,
  2481. ],
  2482. [
  2483. 'code' => 'MultiRule-1',
  2484. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2485. 'product_tax_class_ids' => [
  2486. $this->taxClassIds['MultipleRulesProductClass'],
  2487. $this->taxClassIds['WeeeProductClass']
  2488. ],
  2489. 'tax_rate_ids' => array_values($multiTaxRates1),
  2490. 'sort_order' => 0,
  2491. 'priority' => 0,
  2492. ],
  2493. [
  2494. 'code' => 'MultiRule-2',
  2495. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2496. 'product_tax_class_ids' => [$this->taxClassIds['MultipleRulesProductClass']],
  2497. 'tax_rate_ids' => array_values($multiTaxRatesSamePriority),
  2498. 'sort_order' => 0,
  2499. 'priority' => 0,
  2500. ],
  2501. [
  2502. 'code' => 'MultiRule-3',
  2503. 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3],
  2504. 'product_tax_class_ids' => [$this->taxClassIds['MultipleRulesProductClass']],
  2505. 'tax_rate_ids' => array_values($multiTaxRatesDifferentPriority),
  2506. 'sort_order' => 0,
  2507. 'priority' => 1,
  2508. ],
  2509. ]);
  2510. // For cleanup
  2511. $this->taxRates = array_merge($this->taxRates, $weeeTaxRates);
  2512. $this->taxRates = array_merge($this->taxRates, $higherRates);
  2513. $this->taxRates = array_merge($this->taxRates, $multiTaxRates1);
  2514. $this->taxRates = array_merge($this->taxRates, $multiTaxRatesSamePriority);
  2515. $this->taxRates = array_merge($this->taxRates, $multiTaxRatesDifferentPriority);
  2516. }
  2517. /**
  2518. * Helper function that tears down some default rules
  2519. */
  2520. private function tearDownDefaultRules()
  2521. {
  2522. $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules));
  2523. $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates));
  2524. $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClassIds));
  2525. }
  2526. /**
  2527. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  2528. *
  2529. * @return array
  2530. */
  2531. private function getBaseQuoteData()
  2532. {
  2533. $baseQuote = [
  2534. 'billing_address' => [
  2535. 'postcode' => '55555',
  2536. 'country_id' => 'US',
  2537. 'region' => ['region_id' => 42],
  2538. ],
  2539. 'shipping_address' => [
  2540. 'postcode' => '55555',
  2541. 'country_id' => 'US',
  2542. 'region' => ['region_id' => 42],
  2543. ],
  2544. 'items' => [],
  2545. 'customer_tax_class_key' => 'DefaultCustomerClass',
  2546. ];
  2547. return $baseQuote;
  2548. }
  2549. /**
  2550. * Convert given object to array.
  2551. *
  2552. * This utility function is used to simplify expected result verification.
  2553. *
  2554. * @param \Magento\Framework\DataObject $object
  2555. * @return array
  2556. */
  2557. private function convertObjectToArray($object)
  2558. {
  2559. if ($object instanceof \Magento\Framework\DataObject) {
  2560. $data = $object->getData();
  2561. } elseif (is_object($object)) {
  2562. $data = (array)$object;
  2563. } else {
  2564. throw new \InvalidArgumentException("Provided argument is not an object.");
  2565. }
  2566. foreach ($data as $key => $value) {
  2567. if (is_object($value)) {
  2568. $data[$key] = $this->convertObjectToArray($value);
  2569. } elseif (is_array($value)) {
  2570. foreach ($value as $nestedKey => $nestedValue) {
  2571. if (is_object($nestedValue)) {
  2572. $value[$nestedKey] = $this->convertObjectToArray($nestedValue);
  2573. }
  2574. }
  2575. $data[$key] = $value;
  2576. }
  2577. }
  2578. return $data;
  2579. }
  2580. }