@@ -67,127 +67,207 @@ protected function getCustomerById($id)
67
67
* @magentoDataFixture Magento/Catalog/_files/products.php
68
68
* @magentoConfigFixture current_store tax/calculation/algorithm UNIT_BASE_CALCULATION
69
69
* @dataProvider collectUnitBasedDataProvider
70
+ * @param array $quoteItems
71
+ * @param array $expected
72
+ * @return void
70
73
*/
71
- public function testCollectUnitBased ($ expected )
74
+ public function testCollectUnitBased (array $ quoteItems , array $ expected ): void
72
75
{
73
- $ customerTaxClassId = $ this ->getCustomerTaxClassId ();
74
- $ fixtureCustomerId = 1 ;
75
- /** @var \Magento\Customer\Model\Customer $customer */
76
- $ customer = $ this ->objectManager ->create (\Magento \Customer \Model \Customer::class)->load ($ fixtureCustomerId );
77
- /** @var \Magento\Customer\Model\Group $customerGroup */
78
- $ customerGroup = $ this ->objectManager ->create (
79
- \Magento \Customer \Model \Group::class
80
- )->load (
81
- 'custom_group ' ,
82
- 'customer_group_code '
83
- );
84
- $ customerGroup ->setTaxClassId ($ customerTaxClassId )->save ();
85
- $ customer ->setGroupId ($ customerGroup ->getId ())->save ();
76
+ $ this ->quote ($ quoteItems , $ expected );
77
+ }
78
+
79
+ public function collectUnitBasedDataProvider (): array
80
+ {
81
+ return [
82
+ 'one_item ' => [
83
+ [
84
+ [
85
+ 'sku ' => 'simple ' ,
86
+ 'qty ' => 2
87
+ ],
88
+ ],
89
+ [
90
+ [
91
+ 'subtotal ' => 20 ,
92
+ 'subtotal_incl_tax ' => 21.5 ,
93
+ 'base_subtotal_total_incl_tax ' => 21.5 ,
94
+ 'tax_amount ' => 1.5 ,
95
+ 'discount_amount ' => 0 ,
96
+ ],
97
+ [
98
+ [
99
+ 'tax_amount ' => 1.5 ,
100
+ 'price ' => 10 ,
101
+ 'price_incl_tax ' => 10.75 ,
102
+ 'row_total ' => 20 ,
103
+ 'row_total_incl_tax ' => 21.5 ,
104
+ 'tax_percent ' => 7.5 ,
105
+ ],
106
+ ],
107
+ ],
108
+ ],
109
+ ];
110
+ }
86
111
112
+ /**
113
+ * @magentoDataFixture Magento/Customer/_files/customer.php
114
+ * @magentoDataFixture Magento/Customer/_files/customer_address.php
115
+ * @magentoDataFixture Magento/Tax/_files/tax_classes.php
116
+ * @magentoDataFixture Magento/Customer/_files/customer_group.php
117
+ * @magentoDataFixture Magento/Bundle/_files/product.php
118
+ * @magentoConfigFixture current_store tax/calculation/algorithm UNIT_BASE_CALCULATION
119
+ * @dataProvider collectUnitBasedBundleProductDataProvider
120
+ * @param array $quoteItems
121
+ * @param array $expected
122
+ * @return void
123
+ */
124
+ public function testCollectUnitBasedBundleProduct (array $ quoteItems , array $ expected ): void
125
+ {
87
126
$ productTaxClassId = $ this ->getProductTaxClassId ();
88
127
/** @var \Magento\Catalog\Model\Product $product */
89
- $ product = $ this ->productRepository ->get ('simple ' );
90
- $ product ->setTaxClassId ($ productTaxClassId )->save ();
91
-
92
- $ quoteShippingAddressDataObject = $ this ->getShippingAddressDataObject ($ fixtureCustomerId );
93
-
94
- /** @var \Magento\Quote\Model\Quote\Address $quoteShippingAddress */
95
- $ quoteShippingAddress = $ this ->objectManager ->create (\Magento \Quote \Model \Quote \Address::class);
96
- $ quoteShippingAddress ->importCustomerAddressData ($ quoteShippingAddressDataObject );
97
- $ quantity = 2 ;
98
-
99
- /** @var \Magento\Quote\Model\Quote $quote */
100
- $ quote = $ this ->objectManager ->create (\Magento \Quote \Model \Quote::class);
101
- $ quote ->setStoreId (
102
- 1
103
- )->setIsActive (
104
- true
105
- )->setIsMultiShipping (
106
- false
107
- )->assignCustomerWithAddressChange (
108
- $ this ->getCustomerById ($ customer ->getId ())
109
- )->setShippingAddress (
110
- $ quoteShippingAddress
111
- )->setBillingAddress (
112
- $ quoteShippingAddress
113
- )->setCheckoutMethod (
114
- $ customer ->getMode ()
115
- )->setPasswordHash (
116
- $ customer ->encryptPassword ($ customer ->getPassword ())
117
- )->addProduct (
118
- $ product ->load ($ product ->getId ()),
119
- $ quantity
120
- );
121
- $ address = $ quote ->getShippingAddress ();
122
- /** @var \Magento\Quote\Model\ShippingAssignment $shippingAssignment */
123
- $ shippingAssignment = $ this ->objectManager ->create (\Magento \Quote \Model \ShippingAssignment::class);
124
- $ shipping = $ this ->objectManager ->create (\Magento \Quote \Model \Shipping::class);
125
- $ shipping ->setAddress ($ address );
126
- $ shippingAssignment ->setShipping ($ shipping );
127
- $ shippingAssignment ->setItems ($ address ->getAllItems ());
128
- /** @var \Magento\Quote\Model\Quote\Address\Total $total */
129
- $ total = $ this ->objectManager ->create (\Magento \Quote \Model \Quote \Address \Total::class);
130
- /** @var \Magento\Quote\Model\Quote\Address\Total\Subtotal $addressSubtotalCollector */
131
- $ addressSubtotalCollector = $ this ->objectManager ->create (
132
- \Magento \Quote \Model \Quote \Address \Total \Subtotal::class
133
- );
134
- $ addressSubtotalCollector ->collect ($ quote , $ shippingAssignment , $ total );
135
-
136
- /** @var \Magento\Tax\Model\Sales\Total\Quote\Subtotal $subtotalCollector */
137
- $ subtotalCollector = $ this ->objectManager ->create (\Magento \Tax \Model \Sales \Total \Quote \Subtotal::class);
138
- $ subtotalCollector ->collect ($ quote , $ shippingAssignment , $ total );
139
-
140
- $ this ->assertEquals ($ expected ['subtotal ' ], $ total ->getSubtotal ());
141
- $ this ->assertEquals ($ expected ['subtotal ' ] + $ expected ['tax_amount ' ], $ total ->getSubtotalInclTax ());
142
- $ this ->assertEquals ($ expected ['subtotal ' ] + $ expected ['tax_amount ' ], $ address ->getBaseSubtotalTotalInclTax ());
143
- $ this ->assertEquals ($ expected ['discount_amount ' ], $ total ->getDiscountAmount ());
144
- $ items = $ address ->getAllItems ();
145
- /** @var \Magento\Quote\Model\Quote\Address\Item $item */
146
- $ item = $ items [0 ];
147
- $ this ->assertEquals ($ expected ['items ' ][0 ]['price ' ], $ item ->getPrice ());
148
- $ this ->assertEquals ($ expected ['items ' ][0 ]['price_incl_tax ' ], $ item ->getPriceInclTax ());
149
- $ this ->assertEquals ($ expected ['items ' ][0 ]['row_total ' ], $ item ->getRowTotal ());
150
- $ this ->assertEquals ($ expected ['items ' ][0 ]['row_total_incl_tax ' ], $ item ->getRowTotalInclTax ());
151
- $ this ->assertEquals ($ expected ['items ' ][0 ]['tax_percent ' ], $ item ->getTaxPercent ());
128
+ $ childProduct = $ this ->productRepository ->get ('simple ' );
129
+ $ childProduct ->setTaxClassId ($ productTaxClassId )->save ();
130
+ /** @var \Magento\Catalog\Model\Product $product */
131
+ $ product = $ this ->productRepository ->get ('bundle-product ' );
132
+ $ product ->setTaxClassId ($ productTaxClassId )
133
+ ->setPriceType (\Magento \Catalog \Model \Product \Type \AbstractType::CALCULATE_CHILD )
134
+ ->save ();
135
+ $ quoteItems [0 ]['product ' ] = $ product ;
136
+ $ this ->quote ($ quoteItems , $ expected );
152
137
}
153
138
154
- public function collectUnitBasedDataProvider ()
139
+ public function collectUnitBasedBundleProductDataProvider (): array
155
140
{
156
141
return [
157
142
'one_item ' => [
158
143
[
159
- 'subtotal ' => 20 ,
160
- 'tax_amount ' => 1.5 ,
161
- 'discount_amount ' => 0 ,
162
- 'items ' => [
144
+ [
145
+ 'sku ' => 'bundle-product ' ,
146
+ 'qty ' => 2
147
+ ],
148
+ ],
149
+ [
150
+ [
151
+ 'subtotal ' => 20 ,
152
+ 'subtotal_incl_tax ' => 21.5 ,
153
+ 'base_subtotal_total_incl_tax ' => 21.5 ,
154
+ 'tax_amount ' => 1.5 ,
155
+ 'discount_amount ' => 0 ,
156
+ ],
157
+ [
163
158
[
164
159
'tax_amount ' => 1.5 ,
165
160
'price ' => 10 ,
166
161
'price_incl_tax ' => 10.75 ,
167
162
'row_total ' => 20 ,
168
163
'row_total_incl_tax ' => 21.5 ,
169
- 'taxable_amount ' => 10 ,
170
- 'code ' => 'simple ' ,
171
- 'type ' => 'product ' ,
172
- 'tax_percent ' => 7.5 ,
164
+ 'tax_percent ' => null ,
173
165
],
166
+ [
167
+ 'tax_amount ' => 1.5 ,
168
+ 'price ' => 10 ,
169
+ 'price_incl_tax ' => 10.75 ,
170
+ 'row_total ' => 20 ,
171
+ 'row_total_incl_tax ' => 21.5 ,
172
+ 'tax_percent ' => 7.5 ,
173
+ ]
174
174
],
175
175
],
176
176
],
177
177
];
178
178
}
179
179
180
180
/**
181
- * @magentoDbIsolation disabled
181
+ * @magentoAppIsolation enabled
182
+ * @magentoDbIsolation enabled
183
+ * @magentoConfigFixture current_store tax/calculation/cross_border_trade_enabled 1
182
184
* @magentoDataFixture Magento/Customer/_files/customer.php
183
185
* @magentoDataFixture Magento/Customer/_files/customer_address.php
184
186
* @magentoDataFixture Magento/Tax/_files/tax_classes.php
185
187
* @magentoDataFixture Magento/Customer/_files/customer_group.php
186
- * @magentoDataFixture Magento/Bundle /_files/product .php
188
+ * @magentoDataFixture Magento/Catalog /_files/products .php
187
189
* @magentoConfigFixture current_store tax/calculation/algorithm UNIT_BASE_CALCULATION
188
- * @dataProvider collectUnitBasedDataProvider
190
+ * @magentoConfigFixture current_store tax/calculation/price_includes_tax 1
191
+ * @dataProvider collectUnitBasedPriceIncludesTaxDataProvider
192
+ * @param array $quoteItems
193
+ * @param array $expected
194
+ */
195
+ public function testCollectUnitBasedPriceIncludesTax (array $ quoteItems , array $ expected ): void
196
+ {
197
+ $ this ->quote ($ quoteItems , $ expected );
198
+ }
199
+
200
+ /**
201
+ * @return array
202
+ */
203
+ public function collectUnitBasedPriceIncludesTaxDataProvider (): array
204
+ {
205
+ return [
206
+ [
207
+ [
208
+ [
209
+ 'sku ' => 'simple ' ,
210
+ 'qty ' => 1
211
+ ],
212
+ ],
213
+ [
214
+ [
215
+ 'subtotal ' => 9.3 ,
216
+ 'subtotal_incl_tax ' => 10 ,
217
+ 'base_subtotal_total_incl_tax ' => 10 ,
218
+ 'tax_amount ' => 0.7 ,
219
+ 'discount_amount ' => 0 ,
220
+ ],
221
+ [
222
+ [
223
+ 'tax_amount ' => 0.7 ,
224
+ 'price ' => 9.3 ,
225
+ 'price_incl_tax ' => 10 ,
226
+ 'row_total ' => 9.3 ,
227
+ 'row_total_incl_tax ' => 10 ,
228
+ 'tax_percent ' => 7.5 ,
229
+ ],
230
+ ],
231
+ ],
232
+ ],
233
+ [
234
+ [
235
+ [
236
+ 'sku ' => 'simple ' ,
237
+ 'qty ' => 2
238
+ ],
239
+ ],
240
+ [
241
+ [
242
+ 'subtotal ' => 18.6 ,
243
+ 'subtotal_incl_tax ' => 20 ,
244
+ 'base_subtotal_total_incl_tax ' => 20 ,
245
+ 'tax_amount ' => 1.4 ,
246
+ 'discount_amount ' => 0 ,
247
+ ],
248
+ [
249
+ [
250
+ 'tax_amount ' => 1.4 ,
251
+ 'price ' => 9.3 ,
252
+ 'price_incl_tax ' => 10 ,
253
+ 'row_total ' => 18.6 ,
254
+ 'row_total_incl_tax ' => 20 ,
255
+ 'tax_percent ' => 7.5 ,
256
+ ],
257
+ ],
258
+ ],
259
+ ],
260
+ ];
261
+ }
262
+
263
+ /**
264
+ * Create quote and assert totals values
265
+ *
266
+ * @param array $quoteItems
267
+ * @param array $expected
268
+ * @return void
189
269
*/
190
- public function testCollectUnitBasedBundleProduct ( $ expected )
270
+ private function quote ( array $ quoteItems , array $ expected ): void
191
271
{
192
272
$ customerTaxClassId = $ this ->getCustomerTaxClassId ();
193
273
$ fixtureCustomerId = 1 ;
@@ -202,23 +282,14 @@ public function testCollectUnitBasedBundleProduct($expected)
202
282
);
203
283
$ customerGroup ->setTaxClassId ($ customerTaxClassId )->save ();
204
284
$ customer ->setGroupId ($ customerGroup ->getId ())->save ();
205
-
206
285
$ productTaxClassId = $ this ->getProductTaxClassId ();
207
- /** @var \Magento\Catalog\Model\Product $product */
208
- $ childProduct = $ this ->productRepository ->get ('simple ' );
209
- $ childProduct ->setTaxClassId ($ productTaxClassId )->save ();
210
- /** @var \Magento\Catalog\Model\Product $product */
211
- $ product = $ this ->productRepository ->get ('bundle-product ' );
212
- $ product ->setTaxClassId ($ productTaxClassId )
213
- ->setPriceType (\Magento \Catalog \Model \Product \Type \AbstractType::CALCULATE_CHILD )
214
- ->save ();
286
+
215
287
216
288
$ quoteShippingAddressDataObject = $ this ->getShippingAddressDataObject ($ fixtureCustomerId );
217
289
218
290
/** @var \Magento\Quote\Model\Quote\Address $quoteShippingAddress */
219
291
$ quoteShippingAddress = $ this ->objectManager ->create (\Magento \Quote \Model \Quote \Address::class);
220
292
$ quoteShippingAddress ->importCustomerAddressData ($ quoteShippingAddressDataObject );
221
- $ quantity = 2 ;
222
293
223
294
/** @var \Magento\Quote\Model\Quote $quote */
224
295
$ quote = $ this ->objectManager ->create (\Magento \Quote \Model \Quote::class);
@@ -238,17 +309,25 @@ public function testCollectUnitBasedBundleProduct($expected)
238
309
$ customer ->getMode ()
239
310
)->setPasswordHash (
240
311
$ customer ->encryptPassword ($ customer ->getPassword ())
241
- )->addProduct (
242
- $ product ->load ($ product ->getId ()),
243
- $ quantity
244
312
);
313
+
314
+ foreach ($ quoteItems as $ quoteItem ) {
315
+ $ product = $ quoteItem ['product ' ] ?? null ;
316
+ if ($ product === null ) {
317
+ /** @var \Magento\Catalog\Model\Product $product */
318
+ $ product = $ this ->productRepository ->get ($ quoteItem ['sku ' ] ?? 'simple ' );
319
+ $ product ->setTaxClassId ($ productTaxClassId )->save ();
320
+ }
321
+ $ quote ->addProduct ($ product , $ quoteItem ['qty ' ]);
322
+ }
323
+
245
324
$ address = $ quote ->getShippingAddress ();
246
325
/** @var \Magento\Quote\Model\ShippingAssignment $shippingAssignment */
247
326
$ shippingAssignment = $ this ->objectManager ->create (\Magento \Quote \Model \ShippingAssignment::class);
248
327
$ shipping = $ this ->objectManager ->create (\Magento \Quote \Model \Shipping::class);
249
328
$ shipping ->setAddress ($ address );
250
329
$ shippingAssignment ->setShipping ($ shipping );
251
- $ shippingAssignment ->setItems ($ quote ->getAllItems ());
330
+ $ shippingAssignment ->setItems ($ address ->getAllItems ());
252
331
/** @var \Magento\Quote\Model\Quote\Address\Total $total */
253
332
$ total = $ this ->objectManager ->create (\Magento \Quote \Model \Quote \Address \Total::class);
254
333
/** @var \Magento\Quote\Model\Quote\Address\Total\Subtotal $addressSubtotalCollector */
@@ -261,16 +340,20 @@ public function testCollectUnitBasedBundleProduct($expected)
261
340
$ subtotalCollector = $ this ->objectManager ->create (\Magento \Tax \Model \Sales \Total \Quote \Subtotal::class);
262
341
$ subtotalCollector ->collect ($ quote , $ shippingAssignment , $ total );
263
342
264
- $ this ->assertEquals ($ expected ['subtotal ' ], $ total ->getSubtotal ());
265
- $ this ->assertEquals ($ expected ['subtotal ' ] + $ expected ['tax_amount ' ], $ total ->getSubtotalInclTax ());
266
- $ this ->assertEquals ($ expected ['discount_amount ' ], $ total ->getDiscountAmount ());
267
- $ items = $ address ->getAllItems ();
268
- /** @var \Magento\Quote\Model\Quote\Address\Item $item */
269
- $ item = $ items [0 ];
270
- $ this ->assertEquals ($ expected ['items ' ][0 ]['price ' ], $ item ->getPrice ());
271
- $ this ->assertEquals ($ expected ['items ' ][0 ]['price_incl_tax ' ], $ item ->getPriceInclTax ());
272
- $ this ->assertEquals ($ expected ['items ' ][0 ]['row_total ' ], $ item ->getRowTotal ());
273
- $ this ->assertEquals ($ expected ['items ' ][0 ]['row_total_incl_tax ' ], $ item ->getRowTotalInclTax ());
343
+ $ this ->assertEquals ($ address ->getSubtotal (), $ total ->getSubtotal ());
344
+ $ this ->assertEquals ($ address ->getBaseSubtotal (), $ total ->getBaseSubtotal ());
345
+ $ this ->assertEquals ($ address ->getBaseSubtotalTotalInclTax (), $ total ->getBaseSubtotalTotalInclTax ());
346
+
347
+ $ this ->assertEquals ($ expected [0 ], $ total ->toArray (array_keys ($ expected [0 ])));
348
+ $ actualAddressItemsData = [];
349
+ if ($ expected [1 ]) {
350
+ $ keys = array_keys ($ expected [1 ][0 ]);
351
+ /** @var \Magento\Quote\Model\Quote\Address\Item $addressItem */
352
+ foreach ($ address ->getAllItems () as $ addressItem ) {
353
+ $ actualAddressItemsData [] = array_intersect_key ($ addressItem ->toArray ($ keys ), array_flip ($ keys ));
354
+ }
355
+ }
356
+ $ this ->assertEquals ($ expected [1 ], $ actualAddressItemsData );
274
357
}
275
358
276
359
/**
0 commit comments