Skip to content

Commit eb490ad

Browse files
committed
Merge remote-tracking branch 'origin/MC-31396' into 2.4-develop-pr14
2 parents 714642f + 95c176a commit eb490ad

File tree

8 files changed

+445
-14
lines changed

8 files changed

+445
-14
lines changed

app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ public function collectRates(RateRequest $request)
141141
}
142142
}
143143
$oldValue = $request->getPackageValue();
144-
$request->setPackageValue($oldValue - $freePackageValue);
144+
$newPackageValue = $oldValue - $freePackageValue;
145+
$request->setPackageValue($newPackageValue);
146+
$request->setPackageValueWithDiscount($newPackageValue);
145147
}
146148

147149
if (!$request->getConditionName()) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate;
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
10+
$objectManager = Bootstrap::getObjectManager();
11+
/**
12+
* @var Tablerate $resourceModel
13+
*/
14+
$resourceModel = $objectManager->create(Tablerate::class);
15+
$tableRatesData = [
16+
[
17+
'website_id' => 1,
18+
'dest_country_id' => 'US',
19+
'dest_region_id' => 0,
20+
'dest_zip' => '*',
21+
'condition_name' => 'package_value_with_discount',
22+
'condition_value' => 0.00,
23+
'price' => 15,
24+
'cost' => 0
25+
],
26+
[
27+
'website_id' => 1,
28+
'dest_country_id' => 'US',
29+
'dest_region_id' => 0,
30+
'dest_zip' => '*',
31+
'condition_name' => 'package_value_with_discount',
32+
'condition_value' => 50.00,
33+
'price' => 10,
34+
'cost' => 0
35+
],
36+
[
37+
'website_id' => 1,
38+
'dest_country_id' => 'US',
39+
'dest_region_id' => 0,
40+
'dest_zip' => '*',
41+
'condition_name' => 'package_value_with_discount',
42+
'condition_value' => 100.00,
43+
'price' => 5,
44+
'cost' => 0
45+
]
46+
];
47+
$columns = [
48+
'website_id',
49+
'dest_country_id',
50+
'dest_region_id',
51+
'dest_zip',
52+
'condition_name',
53+
'condition_value',
54+
'price',
55+
'cost'
56+
];
57+
$resourceModel->getConnection()->insertArray($resourceModel->getMainTable(), $columns, $tableRatesData);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate;
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
10+
$objectManager = Bootstrap::getObjectManager();
11+
$resourceModel = $objectManager->create(Tablerate::class);
12+
$resourceModel->getConnection()->delete($resourceModel->getMainTable());

dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,24 @@
66

77
namespace Magento\Quote\Model;
88

9-
use Magento\Customer\Model\Vat;
10-
use Magento\Store\Model\ScopeInterface;
11-
use Magento\Tax\Model\Config as TaxConfig;
12-
use Magento\TestFramework\Helper\Bootstrap;
13-
use Magento\TestFramework\Quote\Model\GetQuoteByReservedOrderId;
14-
use Magento\Framework\ObjectManagerInterface;
15-
use Magento\Customer\Api\Data\GroupInterface;
16-
use Magento\Customer\Api\GroupRepositoryInterface;
17-
use Magento\Tax\Model\ClassModel;
18-
use Magento\Framework\App\Config\MutableScopeConfigInterface;
199
use Magento\Customer\Api\AddressRepositoryInterface;
20-
use Magento\Customer\Api\Data\CustomerInterface;
2110
use Magento\Customer\Api\CustomerRepositoryInterface;
22-
use Magento\Quote\Api\ShippingMethodManagementInterface;
2311
use Magento\Customer\Api\Data\AddressInterface;
12+
use Magento\Customer\Api\Data\GroupInterface;
13+
use Magento\Customer\Api\GroupRepositoryInterface;
14+
use Magento\Customer\Model\Vat;
2415
use Magento\Framework\Api\SearchCriteriaBuilder;
25-
use Magento\Tax\Api\TaxClassRepositoryInterface;
16+
use Magento\Framework\App\Config\MutableScopeConfigInterface;
17+
use Magento\Framework\ObjectManagerInterface;
18+
use Magento\Quote\Api\CartRepositoryInterface;
19+
use Magento\Quote\Api\ShippingMethodManagementInterface;
20+
use Magento\Store\Model\ScopeInterface;
2621
use Magento\Tax\Api\Data\TaxClassInterface;
22+
use Magento\Tax\Api\TaxClassRepositoryInterface;
23+
use Magento\Tax\Model\ClassModel;
24+
use Magento\Tax\Model\Config as TaxConfig;
25+
use Magento\TestFramework\Helper\Bootstrap;
26+
use Magento\TestFramework\Quote\Model\GetQuoteByReservedOrderId;
2727

2828
/**
2929
* Test for shipping methods management
@@ -56,6 +56,7 @@ protected function setUp()
5656
* @magentoDataFixture Magento/SalesRule/_files/cart_rule_100_percent_off.php
5757
* @magentoDataFixture Magento/Sales/_files/quote_with_customer.php
5858
* @return void
59+
* @throws \Magento\Framework\Exception\NoSuchEntityException
5960
*/
6061
public function testRateAppliedToShipping(): void
6162
{
@@ -118,6 +119,71 @@ public function testTableRateFreeShipping()
118119
}
119120
}
120121

122+
/**
123+
* Test table rate amount for the cart that contains some items with free shipping applied.
124+
*
125+
* @magentoConfigFixture current_store carriers/tablerate/active 1
126+
* @magentoConfigFixture current_store carriers/flatrate/active 0
127+
* @magentoConfigFixture current_store carriers/freeshipping/active 0
128+
* @magentoConfigFixture current_store carriers/tablerate/condition_name package_value_with_discount
129+
* @magentoDataFixture Magento/Catalog/_files/categories.php
130+
* @magentoDataFixture Magento/SalesRule/_files/cart_rule_free_shipping_by_category.php
131+
* @magentoDataFixture Magento/Sales/_files/quote_with_multiple_products.php
132+
* @magentoDataFixture Magento/OfflineShipping/_files/tablerates_price.php
133+
* @return void
134+
*/
135+
public function testTableRateWithCartRuleForFreeShipping()
136+
{
137+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
138+
$quote = $this->getQuote('tableRate');
139+
$cartId = $quote->getId();
140+
if (!$cartId) {
141+
$this->fail('quote fixture failed');
142+
}
143+
/** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
144+
$quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
145+
->create(\Magento\Quote\Model\QuoteIdMaskFactory::class)
146+
->create();
147+
$quoteIdMask->load($cartId, 'quote_id');
148+
//Use masked cart Id
149+
$cartId = $quoteIdMask->getMaskedId();
150+
$addressFactory = $this->objectManager->get(\Magento\Quote\Api\Data\AddressInterfaceFactory::class);
151+
/** @var \Magento\Quote\Api\Data\AddressInterface $address */
152+
$address = $addressFactory->create();
153+
$address->setCountryId('US');
154+
/** @var \Magento\Quote\Api\GuestShippingMethodManagementInterface $shippingEstimation */
155+
$shippingEstimation = $objectManager->get(\Magento\Quote\Api\GuestShippingMethodManagementInterface::class);
156+
$result = $shippingEstimation->estimateByExtendedAddress($cartId, $address);
157+
$this->assertCount(1, $result);
158+
$rate = reset($result);
159+
$expectedResult = [
160+
'method_code' => 'bestway',
161+
'amount' => 10
162+
];
163+
$this->assertEquals($expectedResult['method_code'], $rate->getMethodCode());
164+
$this->assertEquals($expectedResult['amount'], $rate->getAmount());
165+
}
166+
167+
/**
168+
* Retrieves quote by reserved order id.
169+
*
170+
* @param string $reservedOrderId
171+
* @return Quote
172+
*/
173+
private function getQuote(string $reservedOrderId): Quote
174+
{
175+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
176+
$searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
177+
$searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId)
178+
->create();
179+
180+
/** @var CartRepositoryInterface $quoteRepository */
181+
$quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
182+
$items = $quoteRepository->getList($searchCriteria)->getItems();
183+
184+
return array_pop($items);
185+
}
186+
121187
/**
122188
* @magentoConfigFixture current_store carriers/tablerate/active 1
123189
* @magentoConfigFixture current_store carriers/tablerate/condition_name package_qty
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\Product\Visibility;
11+
use Magento\Quote\Api\CartRepositoryInterface;
12+
use Magento\Quote\Model\Quote;
13+
use Magento\Quote\Model\Quote\Address;
14+
use Magento\Quote\Model\QuoteIdMask;
15+
use Magento\Quote\Model\QuoteIdMaskFactory;
16+
use Magento\Store\Model\StoreManagerInterface;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
19+
20+
Bootstrap::getInstance()->loadArea('frontend');
21+
/** @var ObjectManager $objectManager */
22+
$objectManager = Bootstrap::getObjectManager();
23+
$productRepository = $objectManager
24+
->create(ProductRepositoryInterface::class);
25+
$firstProduct = $objectManager->create(Product::class);
26+
$firstProduct->setTypeId('simple')
27+
->setCategoryIds([3])
28+
->setId(123)
29+
->setAttributeSetId(4)
30+
->setName('First Test Product For TableRate')
31+
->setSku('simple-tableRate-1')
32+
->setPrice(30)
33+
->setTaxClassId(0)
34+
->setMetaTitle('meta title')
35+
->setMetaKeyword('meta keyword')
36+
->setMetaDescription('meta description')
37+
->setVisibility(Visibility::VISIBILITY_BOTH)
38+
->setStatus(Status::STATUS_ENABLED);
39+
/** @var StockItemInterface $stockItem */
40+
$firstStockItem = $objectManager->create(StockItemInterface::class);
41+
$firstStockItem->setQty(100)
42+
->setIsInStock(true)
43+
->setManageStock(true);
44+
$extensionAttributes = $firstProduct->getExtensionAttributes();
45+
$extensionAttributes->setStockItem($firstStockItem);
46+
47+
/** @var ProductRepositoryInterface $productRepository */
48+
$firstProduct = $productRepository->save($firstProduct);
49+
50+
$secondProduct = $objectManager->create(Product::class);
51+
$secondProduct->setTypeId('simple')
52+
->setCategoryIds([6])
53+
->setId(124)
54+
->setAttributeSetId(4)
55+
->setName('Second Test Product For TableRate')
56+
->setSku('simple-tableRate-2')
57+
->setPrice(40)
58+
->setTaxClassId(0)
59+
->setMetaTitle('meta title')
60+
->setMetaKeyword('meta keyword')
61+
->setMetaDescription('meta description')
62+
->setVisibility(Visibility::VISIBILITY_BOTH)
63+
->setStatus(Status::STATUS_ENABLED);
64+
/** @var StockItemInterface $stockItem */
65+
$secondStockItem = $objectManager->create(StockItemInterface::class);
66+
$secondStockItem->setQty(100)
67+
->setIsInStock(true)
68+
->setManageStock(true);
69+
$extensionAttributes = $secondProduct->getExtensionAttributes();
70+
$extensionAttributes->setStockItem($secondStockItem);
71+
72+
/** @var ProductRepositoryInterface $productRepository */
73+
$secondProduct = $productRepository->save($secondProduct);
74+
75+
$thirdProduct = $objectManager->create(Product::class);
76+
$thirdProduct->setTypeId('simple')
77+
->setCategoryIds([6])
78+
->setId(658)
79+
->setAttributeSetId(4)
80+
->setName('Third Test Product For TableRate')
81+
->setSku('simple-tableRate-3')
82+
->setPrice(50)
83+
->setTaxClassId(0)
84+
->setMetaTitle('meta title')
85+
->setMetaKeyword('meta keyword')
86+
->setMetaDescription('meta description')
87+
->setVisibility(Visibility::VISIBILITY_BOTH)
88+
->setStatus(Status::STATUS_ENABLED);
89+
/** @var StockItemInterface $stockItem */
90+
$thirdStockItem = $objectManager->create(StockItemInterface::class);
91+
$thirdStockItem->setQty(100)
92+
->setIsInStock(true)
93+
->setManageStock(true);
94+
$extensionAttributes = $thirdProduct->getExtensionAttributes();
95+
$extensionAttributes->setStockItem($thirdStockItem);
96+
97+
/** @var ProductRepositoryInterface $productRepository */
98+
$thirdProduct = $productRepository->save($thirdProduct);
99+
100+
$addressData = include __DIR__ . '/address_data.php';
101+
$billingAddress = $objectManager->create(
102+
Address::class,
103+
['data' => $addressData]
104+
);
105+
$billingAddress->setAddressType('billing');
106+
$shippingAddress = $objectManager->create(
107+
Address::class,
108+
['data' => $addressData]
109+
);
110+
$shippingAddress->setAddressType('shipping');
111+
$store = $objectManager
112+
->get(StoreManagerInterface::class)
113+
->getStore();
114+
115+
/** @var Quote $quote */
116+
$quote = $objectManager->create(Quote::class);
117+
$quote->setCustomerIsGuest(true)
118+
->setStoreId($store->getId())
119+
->setReservedOrderId('tableRate')
120+
->setBillingAddress($billingAddress)
121+
->setShippingAddress($shippingAddress);
122+
$quote->getPayment()->setMethod('checkmo');
123+
$quote->addProduct($firstProduct);
124+
$quote->addProduct($secondProduct);
125+
$quote->addProduct($thirdProduct);
126+
$quote->setIsMultiShipping(false);
127+
$quoteRepository = $objectManager
128+
->get(CartRepositoryInterface::class);
129+
$quoteRepository->save($quote);
130+
131+
/** @var QuoteIdMask $quoteIdMask */
132+
$quoteIdMask = $objectManager
133+
->create(QuoteIdMaskFactory::class)
134+
->create();
135+
$quoteIdMask->setQuoteId($quote->getId());
136+
$quoteIdMask->setDataChanges(true);
137+
$quoteIdMask->save();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\CatalogInventory\Model\StockRegistryStorage;
9+
use Magento\Framework\Exception\NoSuchEntityException;
10+
use Magento\Framework\Registry;
11+
use Magento\Quote\Model\Quote;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
14+
/** @var ObjectManager $objectManager */
15+
$objectManager = Bootstrap::getObjectManager();
16+
/** @var Registry $registry */
17+
$registry = $objectManager->get(Registry::class);
18+
$registry->unregister('isSecureArea');
19+
$registry->register('isSecureArea', true);
20+
21+
/** @var $quote Quote */
22+
$quote = $objectManager->create(Quote::class);
23+
$quote->load('tableRate', 'reserved_order_id');
24+
if ($quote->getId()) {
25+
$quote->delete();
26+
}
27+
28+
/** @var ProductRepositoryInterface $productRepository */
29+
$productRepository = $objectManager
30+
->create(ProductRepositoryInterface::class);
31+
32+
try {
33+
$firstProduct = $productRepository->get('simple-tableRate-1', false, null, true);
34+
$productRepository->delete($firstProduct);
35+
} catch (NoSuchEntityException $exception) {
36+
//Product already removed
37+
}
38+
try {
39+
$secondProduct = $productRepository->get('simple-tableRate-2', false, null, true);
40+
$productRepository->delete($secondProduct);
41+
} catch (NoSuchEntityException $exception) {
42+
//Product already removed
43+
}
44+
try {
45+
$thirdProduct = $productRepository->get('simple-tableRate-3', false, null, true);
46+
$productRepository->delete($thirdProduct);
47+
} catch (NoSuchEntityException $exception) {
48+
//Product already removed
49+
}
50+
/** @var StockRegistryStorage $stockRegistryStorage */
51+
$stockRegistryStorage = $objectManager
52+
->get(StockRegistryStorage::class);
53+
$stockRegistryStorage->removeStockItem(123);
54+
$stockRegistryStorage->removeStockItem(124);
55+
$stockRegistryStorage->removeStockItem(658);
56+
$registry->unregister('isSecureArea');
57+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)