Skip to content

Commit eca7429

Browse files
author
Prabhu Ram
committed
Merge branch 'MC-18402' of github.com:magento-honey-badgers/magento2ce into MC-18402
2 parents 78b6776 + 0a4b127 commit eca7429

File tree

6 files changed

+250
-50
lines changed

6 files changed

+250
-50
lines changed

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CartPromotionsTest.php

Lines changed: 164 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
use Magento\Catalog\Api\ProductRepositoryInterface;
1212
use Magento\Catalog\Model\Product;
1313
use Magento\Catalog\Model\Product\Visibility;
14-
use Magento\SalesRule\Api\RuleRepositoryInterface;
1514
use Magento\SalesRule\Model\ResourceModel\Rule\Collection;
1615
use Magento\SalesRule\Model\Rule;
1716
use Magento\TestFramework\Helper\Bootstrap;
1817
use Magento\TestFramework\TestCase\GraphQlAbstract;
18+
use Magento\Tax\Model\ClassModel as TaxClassModel;
19+
use Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory as TaxClassCollectionFactory;
1920

2021
/**
2122
* Test cases for applying cart promotions to items in cart
@@ -56,14 +57,26 @@ public function testCartPromotionSingleCartRule()
5657
foreach ($ruleCollection as $rule) {
5758
$ruleLabels = $rule->getStoreLabels();
5859
}
59-
6060
$qty = 2;
6161
$cartId = $this->createEmptyCart();
6262
$this->addMultipleSimpleProductsToCart($cartId, $qty, $skus[0], $skus[1]);
6363
$query = $this->getCartItemPricesQuery($cartId);
6464
$response = $this->graphQlMutation($query);
6565
$this->assertCount(2, $response['cart']['items']);
6666
//validating the line item prices, quantity and discount
67+
$this->assertLineItemDiscountPrices($response, $productsInCart, $qty, $ruleLabels);
68+
}
69+
70+
/**
71+
* Assert the row total discounts and individual discount break down and cart rule labels
72+
*
73+
* @param $response
74+
* @param $productsInCart
75+
* @param $qty
76+
* @param $ruleLabels
77+
*/
78+
private function assertLineItemDiscountPrices($response, $productsInCart, $qty, $ruleLabels)
79+
{
6780
$productsInResponse = array_map(null, $response['cart']['items'], $productsInCart);
6881
$count = count($productsInCart);
6982
for ($itemIndex = 0; $itemIndex < $count; $itemIndex++) {
@@ -80,54 +93,17 @@ public function testCartPromotionSingleCartRule()
8093
0 =>[
8194
'amount' =>
8295
['value' => $productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5],
83-
'label' => $ruleLabels[0]
96+
'label' => 'TestRule_Label'
8497
]
8598
]
8699
],
87100
]
88101
);
89102
}
90-
91-
/** @var Collection $ruleCollection */
92-
// $ruleCollection = $objectManager->get(Collection::class);
93-
/** @var RuleRepositoryInterface $ruleRepository */
94-
// $ruleRepository = $objectManager->get(RuleRepositoryInterface::class);
95-
96-
/** @var Rule $rule */
97-
// foreach ($ruleCollection as $rule) {
98-
// $ruleName = $rule->getName();
99-
// if($ruleName === '50% Off on Large Orders'){
100-
// $ruleId = $rule->getRuleId();
101-
/** @var \Magento\SalesRule\Model\Data\Rule $salesRule */
102-
// $salesRule = $ruleRepository->getById($ruleId);
103-
// $salesRule->setStoreLabels(['store_labels' => 'Test Label']);
104-
105-
// $salesRule->setStoreLabels([
106-
// 'store_labels' => [
107-
// [
108-
// 'store_id' => 0,
109-
// 'store_label' => 'TestRule_Label',
110-
// ]
111-
// ]
112-
//
113-
// ]
114-
// );
115-
// $ruleRepository->save($salesRule);
116-
// $salesRule->save();
117-
/** @var Rule $salesRule */
118-
// $salesRule = $objectManager->get(Rule::class);
119-
// $salesRule->setData
120-
// ([
121-
// 'store_labels' => [0 => '50% discount for products in category']
122-
// ]
123-
// );
124-
// $salesRule->save();
125-
126-
127103
}
128104

129105
/**
130-
* Test adding multiple cart rules to multiple products in a cart
106+
* Test applying multiple cart rules to multiple products in a cart
131107
*
132108
* @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
133109
* @magentoApiDataFixture Magento/SalesRule/_files/rules_category.php
@@ -174,15 +150,22 @@ public function testCartPromotionsMultipleCartRules()
174150
for ($itemIndex = 0; $itemIndex < $count; $itemIndex++) {
175151
$this->assertNotEmpty($productsInResponse[$itemIndex]);
176152
$lineItemDiscount = $productsInResponse[$itemIndex][0]['prices']['discounts'];
177-
$expectedTotalDiscountValue = ($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5)+($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5*0.1);
178-
$this->assertEquals($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5, current($lineItemDiscount)['amount']['value']);
153+
$expectedTotalDiscountValue = ($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5) +
154+
($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5*0.1);
155+
$this->assertEquals(
156+
$productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5,
157+
current($lineItemDiscount)['amount']['value']
158+
);
179159
$this->assertEquals('TestRule_Label', current($lineItemDiscount)['label']);
180160

181161
$lineItemDiscountValue = next($lineItemDiscount)['amount']['value'];
182-
$this->assertEquals(round($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5)*0.1, $lineItemDiscountValue );
162+
$this->assertEquals(
163+
round($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5)*0.1,
164+
$lineItemDiscountValue
165+
);
183166
$this->assertEquals('10% off with two items_Label', end($lineItemDiscount)['label']);
184-
$actualTotalDiscountValue = $lineItemDiscount[0]['amount']['value'] + $lineItemDiscount[1]['amount']['value'];
185-
$this->assertEquals(round($expectedTotalDiscountValue,2), $actualTotalDiscountValue);
167+
$actualTotalDiscountValue = $lineItemDiscount[0]['amount']['value']+$lineItemDiscount[1]['amount']['value'];
168+
$this->assertEquals(round($expectedTotalDiscountValue, 2), $actualTotalDiscountValue);
186169

187170
//removing the elements from the response so that the rest of the response values can be compared
188171
unset($productsInResponse[$itemIndex][0]['prices']['discounts']);
@@ -200,6 +183,90 @@ public function testCartPromotionsMultipleCartRules()
200183
}
201184
}
202185

186+
/**
187+
* Test applying single cart rules to multiple products in a cart with tax settings
188+
* Tax settings are : Including and Excluding tax for Price Display and Shopping cart display settings
189+
* Discount on Prices Includes Tax
190+
* Tax rate = 7.5%
191+
* Cart rule to apply 50% for products assigned to a specific category
192+
*
193+
* @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
194+
* @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php
195+
* @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_calculation_price_and_cart_display_settings.php
196+
* @magentoApiDataFixture Magento/SalesRule/_files/rules_category.php
197+
*
198+
*/
199+
public function testCartPromotionsSingleCartRulesWithTaxes()
200+
{
201+
$objectManager = Bootstrap::getObjectManager();
202+
/** @var ProductRepositoryInterface $productRepository */
203+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
204+
/** @var Product $prod2 */
205+
$prod1 = $productRepository->get('simple1');
206+
$prod2 = $productRepository->get('simple2');
207+
$productsInCart = [$prod1, $prod2];
208+
$skus =['simple1', 'simple2'];
209+
210+
/** @var TaxClassCollectionFactory $taxClassCollectionFactory */
211+
$taxClassCollectionFactory = $objectManager->get(TaxClassCollectionFactory::class);
212+
$taxClassCollection = $taxClassCollectionFactory->create();
213+
214+
/** @var TaxClassModel $taxClass */
215+
$taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT);
216+
$taxClass = $taxClassCollection->getFirstItem();
217+
foreach ($productsInCart as $product) {
218+
$product->setCustomAttribute('tax_class_id', $taxClass->getClassId());
219+
$productRepository->save($product);
220+
}
221+
$categoryId = 66;
222+
/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */
223+
$categoryLinkManagement = $objectManager->create(CategoryLinkManagementInterface::class);
224+
foreach ($skus as $sku) {
225+
$categoryLinkManagement->assignProductToCategories(
226+
$sku,
227+
[$categoryId]
228+
);
229+
}
230+
$qty = 1;
231+
$cartId = $this->createEmptyCart();
232+
$this->addMultipleSimpleProductsToCart($cartId, $qty, $skus[0], $skus[1]);
233+
$this->setShippingAddressOnCart($cartId);
234+
$query = $this->getCartItemPricesQuery($cartId);
235+
$response = $this->graphQlMutation($query);
236+
$this->assertCount(2, $response['cart']['items']);
237+
$productsInResponse = array_map(null, $response['cart']['items'], $productsInCart);
238+
$count = count($productsInCart);
239+
for ($itemIndex = 0; $itemIndex < $count; $itemIndex++) {
240+
$this->assertNotEmpty($productsInResponse[$itemIndex]);
241+
$rowTotalIncludingTax = round(
242+
$productsInCart[$itemIndex]->getSpecialPrice()*$qty +
243+
$productsInCart[$itemIndex]->getSpecialPrice()*$qty*.075,
244+
2
245+
);
246+
$this->assertResponseFields(
247+
$productsInResponse[$itemIndex][0],
248+
[
249+
'quantity' => $qty,
250+
'prices' => [
251+
// row_total is the line item price without the tax
252+
'row_total' => ['value' => $productsInCart[$itemIndex]->getSpecialPrice()*$qty],
253+
// row_total including tax is the price + price * tax rate
254+
'row_total_including_tax' => ['value' => $rowTotalIncludingTax],
255+
// discount from cart rule after tax is applied : 50% of row_total_including_tax
256+
'discount' => ['value' => round($rowTotalIncludingTax/2, 2)],
257+
'discounts' => [
258+
0 =>[
259+
'amount' =>
260+
['value' => round($rowTotalIncludingTax/2, 2)],
261+
'label' => 'TestRule_Label'
262+
]
263+
]
264+
],
265+
]
266+
);
267+
}
268+
}
269+
203270
/**
204271
* @param string $cartId
205272
* @return string
@@ -292,4 +359,55 @@ private function addMultipleSimpleProductsToCart(string $cartId, int $qty, strin
292359
self::assertEquals($qty, $response['addSimpleProductsToCart']['cart']['items'][1]['quantity']);
293360
self::assertEquals($sku2, $response['addSimpleProductsToCart']['cart']['items'][1]['product']['sku']);
294361
}
362+
363+
/**
364+
* Set shipping address for the region for which tax rule is set
365+
*
366+
* @param string $cartId
367+
* @return void
368+
*/
369+
private function setShippingAddressOnCart(string $cartId) :void
370+
{
371+
$query = <<<QUERY
372+
mutation {
373+
setShippingAddressesOnCart(
374+
input: {
375+
cart_id: "$cartId"
376+
shipping_addresses: [
377+
{
378+
address: {
379+
firstname: "John"
380+
lastname: "Doe"
381+
company: "Magento"
382+
street: ["test street 1", "test street 2"]
383+
city: "Montgomery"
384+
region: "AL"
385+
postcode: "36043"
386+
country_code: "US"
387+
telephone: "88776655"
388+
save_in_address_book: false
389+
}
390+
}
391+
]
392+
}
393+
) {
394+
cart {
395+
shipping_addresses {
396+
city
397+
region{label}
398+
}
399+
}
400+
}
401+
}
402+
QUERY;
403+
$response = $this->graphQlMutation($query);
404+
self::assertEquals(
405+
'Montgomery',
406+
$response['setShippingAddressesOnCart']['cart']['shipping_addresses'][0]['city']
407+
);
408+
self::assertEquals(
409+
'Alabama',
410+
$response['setShippingAddressesOnCart']['cart']['shipping_addresses'][0]['region']['label']
411+
);
412+
}
295413
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Framework\App\Config\Storage\Writer;
9+
use Magento\Framework\App\Config\Storage\WriterInterface;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
13+
$objectManager = Bootstrap::getObjectManager();
14+
/** @var Writer $configWriter */
15+
$configWriter = $objectManager->get(WriterInterface::class);
16+
17+
//Apply discount on prices to include tax
18+
$configWriter->save('tax/calculation/discount_tax', '1');
19+
$configWriter->save('tax/display/type', '3');
20+
$configWriter->save('tax/display/shipping', '3');
21+
22+
$configWriter->save('tax/cart_display/price', '3');
23+
$configWriter->save('tax/cart_display/subtotal', '3');
24+
$configWriter->save('tax/cart_display/shipping', '3');
25+
$configWriter->save('tax/cart_display/grandtotal', '1');
26+
27+
$scopeConfig = $objectManager->get(ScopeConfigInterface::class);
28+
$scopeConfig->clean();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Framework\App\Config\Storage\Writer;
9+
use Magento\Framework\App\Config\Storage\WriterInterface;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
13+
$objectManager = Bootstrap::getObjectManager();
14+
/** @var Writer $configWriter */
15+
$configWriter = $objectManager->get(WriterInterface::class);
16+
17+
//Apply discount on prices to include tax
18+
$configWriter->save('tax/calculation/discount_tax', '0');
19+
$configWriter->save('tax/display/type', '1');
20+
$configWriter->save('tax/display/shipping', '1');
21+
22+
$configWriter->save('tax/cart_display/price', '1');
23+
$configWriter->save('tax/cart_display/subtotal', '1');
24+
$configWriter->save('tax/cart_display/shipping', '1');
25+
$configWriter->save('tax/cart_display/grandtotal', '0');
26+
27+
$scopeConfig = $objectManager->get(ScopeConfigInterface::class);
28+
$scopeConfig->clean();

dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_10_percent_off_qty_more_than_2_items_rollback.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
declare(strict_types=1);
77

88
// phpcs:ignore Magento2.Security.IncludeFile
9-
require __DIR__ . '/rules_rollback.php';
9+
require __DIR__ . '/rules_rollback.php';

dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_categories_rollback.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,35 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
use Magento\TestFramework\Helper\Bootstrap;
7+
use Magento\Framework\Api\SearchCriteriaBuilder;
8+
use Magento\Catalog\Api\CategoryListInterface;
9+
use Magento\Catalog\Api\CategoryRepositoryInterface;
10+
11+
$objectManager = Bootstrap::getObjectManager();
612

713
/** @var Magento\Framework\Registry $registry */
8-
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
14+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
915

1016
/** @var Magento\SalesRule\Model\Rule $rule */
1117
$rule = $registry->registry('_fixture/Magento_SalesRule_Multiple_Categories');
1218

1319
$rule->delete();
20+
21+
// logic to delete the category that was created as part of the rules_category fixture
22+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
23+
$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class);
24+
$searchCriteria = $searchCriteriaBuilder->addFilter('name', 'Category 1')
25+
->create();
26+
27+
/** @var CategoryListInterface $categoryList */
28+
$categoryList = $objectManager->get(CategoryListInterface::class);
29+
$categories = $categoryList->getList($searchCriteria)
30+
->getItems();
31+
32+
/** @var CategoryRepositoryInterface $categoryRepository */
33+
$categoryRepository = $objectManager->get(CategoryRepositoryInterface::class);
34+
35+
foreach ($categories as $category) {
36+
$categoryRepository->delete($category);
37+
}

dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_category.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
]
3131
);
3232

33-
$salesRule->getConditions()->loadArray([
33+
$salesRule->getConditions()->loadArray(
34+
[
3435
'type' => \Magento\SalesRule\Model\Rule\Condition\Combine::class,
3536
'attribute' => null,
3637
'operator' => null,
@@ -58,7 +59,8 @@
5859
],
5960
],
6061
],
61-
]);
62+
]
63+
);
6264

6365
$salesRule->save();
6466

0 commit comments

Comments
 (0)