Skip to content

Commit a474225

Browse files
authored
Merge pull request #3244 from magento-epam/EPAM-PR-12
[epam] MAGETWO-71375: [Magento Cloud] Zero Subtotal Orders have incorrect status
2 parents 80469a6 + 3880bce commit a474225

File tree

31 files changed

+887
-41
lines changed

31 files changed

+887
-41
lines changed

app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ public function getJsonConfig()
188188
$configValue = $preConfiguredValues->getData('bundle_option/' . $optionId);
189189
if ($configValue) {
190190
$defaultValues[$optionId] = $configValue;
191+
$configQty = $preConfiguredValues->getData('bundle_option_qty/' . $optionId);
192+
if ($configQty) {
193+
$options[$optionId]['selections'][$configValue]['qty'] = $configQty;
194+
}
191195
}
192196
}
193197
$position++;

app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Eraser.php

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
namespace Magento\Catalog\Model\Indexer\Product\Flat\Action;
99

1010
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
12+
use Magento\Store\Model\Store;
1113

14+
/**
15+
* Flat item eraser. Used to clear items from the catalog flat table.
16+
*/
1217
class Eraser
1318
{
1419
/**
@@ -50,12 +55,7 @@ public function __construct(
5055
*/
5156
public function removeDeletedProducts(array &$ids, $storeId)
5257
{
53-
$select = $this->connection->select()->from(
54-
$this->productIndexerHelper->getTable('catalog_product_entity')
55-
)->where(
56-
'entity_id IN(?)',
57-
$ids
58-
);
58+
$select = $this->getSelectForProducts($ids);
5959
$result = $this->connection->query($select);
6060

6161
$existentProducts = [];
@@ -69,6 +69,61 @@ public function removeDeletedProducts(array &$ids, $storeId)
6969
$this->deleteProductsFromStore($productsToDelete, $storeId);
7070
}
7171

72+
/**
73+
* Remove products with "Disabled" status from the flat table(s).
74+
*
75+
* @param array $ids
76+
* @param int $storeId
77+
* @return void
78+
*/
79+
public function removeDisabledProducts(array &$ids, $storeId)
80+
{
81+
/* @var $statusAttribute \Magento\Eav\Model\Entity\Attribute */
82+
$statusAttribute = $this->productIndexerHelper->getAttribute('status');
83+
84+
$select = $this->getSelectForProducts($ids);
85+
$select->joinLeft(
86+
['status_global_attr' => $statusAttribute->getBackendTable()],
87+
' status_global_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
88+
. ' AND status_global_attr.store_id = ' . Store::DEFAULT_STORE_ID,
89+
[]
90+
);
91+
$select->joinLeft(
92+
['status_attr' => $statusAttribute->getBackendTable()],
93+
' status_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
94+
. ' AND status_attr.store_id = ' . $storeId,
95+
[]
96+
);
97+
$select->where('IFNULL(status_attr.value, status_global_attr.value) = ?', Status::STATUS_DISABLED);
98+
99+
$result = $this->connection->query($select);
100+
101+
$disabledProducts = [];
102+
foreach ($result->fetchAll() as $product) {
103+
$disabledProducts[] = $product['entity_id'];
104+
}
105+
106+
if (!empty($disabledProducts)) {
107+
$ids = array_diff($ids, $disabledProducts);
108+
$this->deleteProductsFromStore($disabledProducts, $storeId);
109+
}
110+
}
111+
112+
/**
113+
* Get Select object for existed products.
114+
*
115+
* @param array $ids
116+
* @return \Magento\Framework\DB\Select
117+
*/
118+
private function getSelectForProducts(array $ids)
119+
{
120+
$productTable = $this->productIndexerHelper->getTable('catalog_product_entity');
121+
$select = $this->connection->select()->from($productTable)
122+
->columns('entity_id')
123+
->where('entity_id IN(?)', $ids);
124+
return $select;
125+
}
126+
72127
/**
73128
* Delete products from flat table(s)
74129
*

app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public function execute($id = null)
9090
$tableExists = $this->_isFlatTableExists($store->getId());
9191
if ($tableExists) {
9292
$this->flatItemEraser->removeDeletedProducts($ids, $store->getId());
93+
$this->flatItemEraser->removeDisabledProducts($ids, $store->getId());
9394
}
9495

9596
/* @var $status \Magento\Eav\Model\Entity\Attribute */

app/code/Magento/Catalog/Model/Product/Url.php

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\UrlRewrite\Model\UrlFinderInterface;
99
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
1011

1112
/**
1213
* Product Url model
@@ -45,38 +46,37 @@ class Url extends \Magento\Framework\DataObject
4546
*/
4647
protected $urlFinder;
4748

49+
/**
50+
* @var \Magento\Framework\App\Config\ScopeConfigInterface
51+
*/
52+
private $scopeConfig;
53+
4854
/**
4955
* @param \Magento\Framework\UrlFactory $urlFactory
5056
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
5157
* @param \Magento\Framework\Filter\FilterManager $filter
5258
* @param \Magento\Framework\Session\SidResolverInterface $sidResolver
5359
* @param UrlFinderInterface $urlFinder
5460
* @param array $data
61+
* @param ScopeConfigInterface|null $scopeConfig
5562
*/
5663
public function __construct(
5764
\Magento\Framework\UrlFactory $urlFactory,
5865
\Magento\Store\Model\StoreManagerInterface $storeManager,
5966
\Magento\Framework\Filter\FilterManager $filter,
6067
\Magento\Framework\Session\SidResolverInterface $sidResolver,
6168
UrlFinderInterface $urlFinder,
62-
array $data = []
69+
array $data = [],
70+
ScopeConfigInterface $scopeConfig = null
6371
) {
6472
parent::__construct($data);
6573
$this->urlFactory = $urlFactory;
6674
$this->storeManager = $storeManager;
6775
$this->filter = $filter;
6876
$this->sidResolver = $sidResolver;
6977
$this->urlFinder = $urlFinder;
70-
}
71-
72-
/**
73-
* Retrieve URL Instance
74-
*
75-
* @return \Magento\Framework\UrlInterface
76-
*/
77-
private function getUrlInstance()
78-
{
79-
return $this->urlFactory->create();
78+
$this->scopeConfig = $scopeConfig ?:
79+
\Magento\Framework\App\ObjectManager::getInstance()->get(ScopeConfigInterface::class);
8080
}
8181

8282
/**
@@ -157,10 +157,19 @@ public function getUrl(\Magento\Catalog\Model\Product $product, $params = [])
157157
UrlRewrite::ENTITY_TYPE => \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::ENTITY_TYPE,
158158
UrlRewrite::STORE_ID => $storeId,
159159
];
160+
$useCategories = $this->scopeConfig->getValue(
161+
\Magento\Catalog\Helper\Product::XML_PATH_PRODUCT_URL_USE_CATEGORY,
162+
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
163+
);
164+
160165
if ($categoryId) {
161166
$filterData[UrlRewrite::METADATA]['category_id'] = $categoryId;
167+
} elseif (!$useCategories) {
168+
$filterData[UrlRewrite::METADATA]['category_id'] = '';
162169
}
170+
163171
$rewrite = $this->urlFinder->findOneByData($filterData);
172+
164173
if ($rewrite) {
165174
$requestPath = $rewrite->getRequestPath();
166175
$product->setRequestPath($requestPath);
@@ -194,6 +203,7 @@ public function getUrl(\Magento\Catalog\Model\Product $product, $params = [])
194203
$routeParams['_query'] = [];
195204
}
196205

197-
return $this->getUrlInstance()->setScope($storeId)->getUrl($routePath, $routeParams);
206+
$url = $this->urlFactory->create()->setScope($storeId);
207+
return $url->getUrl($routePath, $routeParams);
198208
}
199209
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,8 +1423,13 @@ protected function _addUrlRewrite()
14231423
['cu' => $this->getTable('catalog_url_rewrite_product_category')],
14241424
'u.url_rewrite_id=cu.url_rewrite_id'
14251425
)->where('cu.category_id IN (?)', $this->_urlRewriteCategory);
1426+
} else {
1427+
$select->joinLeft(
1428+
['cu' => $this->getTable('catalog_url_rewrite_product_category')],
1429+
'u.url_rewrite_id=cu.url_rewrite_id'
1430+
)->where('cu.url_rewrite_id IS NULL');
14261431
}
1427-
1432+
14281433
// more priority is data with category id
14291434
$urlRewrites = [];
14301435

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<element name="productStatusUseDefault" type="checkbox" selector="input[name='use_default[status]']"/>
2424
<element name="productNameUseDefault" type="checkbox" selector="input[name='use_default[name]']"/>
2525
<element name="productPrice" type="input" selector=".admin__field[data-index=price] input"/>
26+
<element name="productTaxClass" type="select" selector="//*[@name='product[tax_class_id]']"/>
2627
<element name="productTaxClassUseDefault" type="checkbox" selector="input[name='use_default[tax_class_id]']"/>
2728
<element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/>
2829
<element name="categoriesDropdown" type="multiselect" selector="div[data-index='category_ids']"/>

app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/EraserTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function testRemoveDeletedProducts()
5454
$productsToDeleteIds = [1, 2];
5555
$select = $this->createMock(\Magento\Framework\DB\Select::class);
5656
$select->expects($this->once())->method('from')->with('catalog_product_entity')->will($this->returnSelf());
57+
$select->expects($this->once())->method('columns')->with('entity_id')->will($this->returnSelf());
5758
$select->expects($this->once())->method('where')->with('entity_id IN(?)', $productsToDeleteIds)
5859
->will($this->returnSelf());
5960
$products = [['entity_id' => 2]];

app/code/Magento/Catalog/etc/adminhtml/system.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@
8383
<backend_model>Magento\Catalog\Model\Indexer\Product\Flat\System\Config\Mode</backend_model>
8484
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
8585
</field>
86-
<field id="default_sort_by" translate="label" type="select" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
86+
<field id="default_sort_by" translate="label comment" type="select" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
8787
<label>Product Listing Sort by</label>
88+
<comment>Applies to category pages</comment>
8889
<source_model>Magento\Catalog\Model\Config\Source\ListSort</source_model>
8990
</field>
9091
<field id="list_allow_all" translate="label comment" type="select" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1">
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
11+
<!--Fill shipment form for free shipping-->
12+
<actionGroup name="ShipmentFormFreeShippingActionGroup">
13+
<fillField selector="{{CheckoutShippingSection.email}}" userInput="{{CustomerEntityOne.email}}" stepKey="setCustomerEmail"/>
14+
<fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{CustomerEntityOne.firstname}}" stepKey="SetCustomerFirstName"/>
15+
<fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{CustomerEntityOne.lastname}}" stepKey="SetCustomerLastName"/>
16+
<fillField selector="{{CheckoutShippingSection.street}}" userInput="{{CustomerAddressSimple.street}}" stepKey="SetCustomerStreetAddress"/>
17+
<fillField selector="{{CheckoutShippingSection.city}}" userInput="{{CustomerAddressSimple.city}}" stepKey="SetCustomerCity"/>
18+
<fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="SetCustomerZipCode"/>
19+
<fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="SetCustomerPhoneNumber"/>
20+
<click selector="{{CheckoutShippingSection.region}}" stepKey="clickToSetState"/>
21+
<click selector="{{CheckoutShippingSection.state}}" stepKey="clickToChooseState"/>
22+
<see userInput="$0.00 Free Free Shipping" selector="{{CheckoutShippingMethodsSection.shippingMethodRowByName('Free Shipping')}}" stepKey="seeShippingMethod" after="clickToChooseState"/>
23+
<click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Free Shipping')}}" stepKey="selectFlatShippingMethod" after="seeShippingMethod"/>
24+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMask" after="selectFlatShippingMethod"/>
25+
<click selector="{{CheckoutShippingSection.next}}" stepKey="clickToSaveShippingInfo"/>
26+
<waitForPageLoad time="5" stepKey="waitForReviewAndPaymentsPageIsLoaded"/>
27+
<seeInCurrentUrl url="payment" stepKey="reviewAndPaymentIsShown"/>
28+
</actionGroup>
29+
</actionGroups>

app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<element name="next" type="button" selector="button.button.action.continue.primary" timeout="30"/>
3232
<element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/>
3333
<element name="defaultShipping" type="button" selector=".billing-address-details"/>
34+
<element name="state" type="button" selector="//*[text()='Alabama']"/>
3435
<element name="stateInput" type="input" selector="input[name=region]"/>
3536
</section>
3637
</sections>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="ZeroSubtotalOrdersWithProcessingStatusTest">
12+
<annotations>
13+
<features value="Checkout"/>
14+
<stories value="MAGETWO-71375: Zero Subtotal Orders have incorrect status"/>
15+
<title value="Checking status of Zero Subtotal Orders with 'Processing' New Order Status"/>
16+
<description value="Created order should be in Processing status"/>
17+
<severity value="MAJOR"/>
18+
<testCaseId value="MAGETWO-94178"/>
19+
<group value="checkout"/>
20+
</annotations>
21+
<before>
22+
<createData entity="SimpleSubCategory" stepKey="simplecategory"/>
23+
<createData entity="SimpleProduct" stepKey="simpleproduct">
24+
<requiredEntity createDataKey="simplecategory"/>
25+
</createData>
26+
<createData entity="PaymentMethodsSettingConfig" stepKey="paymentMethodsSettingConfig"/>
27+
<createData entity="FreeShippingMethodsSettingConfig" stepKey="freeShippingMethodsSettingConfig"/>
28+
<!--Go to Admin page-->
29+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
30+
</before>
31+
32+
<after>
33+
<actionGroup ref="DeleteCartPriceRuleByName" stepKey="deleteSalesRule">
34+
<argument name="ruleName" value="{{ApiSalesRule.name}}"/>
35+
</actionGroup>
36+
<createData entity="DefaultShippingMethodsConfig" stepKey="defaultShippingMethodsConfig"/>
37+
<createData entity="DisableFreeShippingConfig" stepKey="disableFreeShippingConfig"/>
38+
<createData entity="DisablePaymentMethodsSettingConfig" stepKey="disablePaymentMethodsSettingConfig"/>
39+
<actionGroup ref="logout" stepKey="logout"/>
40+
<deleteData createDataKey="simpleproduct" stepKey="deleteProduct"/>
41+
<deleteData createDataKey="simplecategory" stepKey="deleteCategory"/>
42+
</after>
43+
44+
<!--Open MARKETING > Cart Price Rules-->
45+
<amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/>
46+
<waitForPageLoad stepKey="waitForRulesPage"/>
47+
48+
<!--Add New Rule-->
49+
<click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/>
50+
<fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ApiSalesRule.name}}" stepKey="fillRuleName"/>
51+
<selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsite"/>
52+
<actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="chooseNotLoggedInCustomerGroup"/>
53+
<selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/>
54+
<fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/>
55+
<fillField selector="{{AdminCartPriceRulesFormSection.userPerCoupon}}" userInput="99" stepKey="fillUserPerCoupon"/>
56+
<click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/>
57+
<selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/>
58+
<fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="100" stepKey="fillDiscountAmount"/>
59+
<click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/>
60+
<see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/>
61+
62+
<!--Proceed to store front and place an order with free shipping using created coupon-->
63+
<!--Add product to card-->
64+
<actionGroup ref="AddSimpleProductToCart" stepKey="AddProductToCard">
65+
<argument name="product" value="$$simpleproduct$$"/>
66+
</actionGroup>
67+
68+
<!--Proceed to shipment-->
69+
<click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickToOpenCard"/>
70+
<click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="clickToProceedToCheckout"/>
71+
<waitForPageLoad stepKey="waitForTheFormIsOpened"/>
72+
73+
<!--Fill shipping form-->
74+
<actionGroup ref="ShipmentFormFreeShippingActionGroup" stepKey="shipmentFormFreeShippingActionGroup"/>
75+
76+
<click selector="{{DiscountSection.DiscountTab}}" stepKey="clickToAddDiscount"/>
77+
<fillField selector="{{DiscountSection.DiscountInput}}" userInput="{{_defaultCoupon.code}}" stepKey="TypeDiscountCode"/>
78+
<click selector="{{DiscountSection.ApplyCodeBtn}}" stepKey="clickToApplyDiscount"/>
79+
<waitForPageLoad stepKey="WaitForDiscountToBeAdded"/>
80+
<see userInput="Your coupon was successfully applied." stepKey="verifyText"/>
81+
82+
<waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/>
83+
<click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/>
84+
<grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/>
85+
86+
<!--Proceed to Admin panel > SALES > Orders. Created order should be in Processing status-->
87+
<amOnPage url="/admin/sales/order/" stepKey="navigateToSalesOrderPage"/>
88+
<waitForPageLoad stepKey="waitForSalesOrderPageLoaded"/>
89+
90+
<!-- Open Order -->
91+
<actionGroup ref="filterOrderGridById" stepKey="filterOrderGridById">
92+
<argument name="orderId" value="$grabOrderNumber"/>
93+
</actionGroup>
94+
<click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/>
95+
<waitForPageLoad stepKey="waitForCreatedOrderPageOpened"/>
96+
97+
<!--Verify that Created order is in Processing status-->
98+
<see selector="{{AdminShipmentOrderInformationSection.orderStatus}}" userInput="Processing" stepKey="seeShipmentOrderStatus"/>
99+
</test>
100+
</tests>

0 commit comments

Comments
 (0)