Skip to content

Commit 128db73

Browse files
merge magento/2.3-develop into magento-tsg/2.3-develop-mftf-pr16
2 parents 3b32bb4 + abbf068 commit 128db73

File tree

264 files changed

+6877
-1732
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

264 files changed

+6877
-1732
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertOrderGraphImageOnDashboardActionGroup">
12+
<click selector="{{AdminDashboardSection.ordersTab}}" stepKey="clickOrdersBtn"/>
13+
<seeElement selector="{{AdminDashboardSection.ordersChart}}" stepKey="seeGraphImage"/>
14+
</actionGroup>
15+
</actionGroups>

app/code/Magento/Backend/Test/Mftf/Page/AdminDashboardPage.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
1111
<page name="AdminDashboardPage" url="admin/dashboard/" area="admin" module="Magento_Backend">
1212
<section name="AdminMenuSection"/>
13+
<section name="AdminDashboardSection"/>
1314
</page>
1415
</pages>

app/code/Magento/Backend/Test/Mftf/Section/AdminDashboardSection.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="AdminDashboardSection">
12+
<element name="ordersTab" type="button" selector="#diagram_tab_orders"/>
13+
<element name="ordersChart" type="button" selector="#diagram_tab_orders_content .dashboard-diagram-image img"/>
1214
<element name="dashboardDiagramContent" type="button" selector="#diagram_tab_content"/>
1315
<element name="dashboardDiagramOrderContentTab" type="block" selector="#diagram_tab_orders_content"/>
1416
<element name="dashboardDiagramAmounts" type="button" selector="#diagram_tab_amounts"/>

app/code/Magento/Backend/Test/Mftf/Section/AdminSlideOutDialogSection.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
99
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1010
<section name="AdminSlideOutDialogSection">
11-
<element name="closeButton" type="button" selector=".modal-slide._show [data-role='closeBtn']" timeout="30"/>
11+
<element name="closeButton" type="button" selector=".modal-slide._show [data-role=&quot;closeBtn&quot;]" timeout="30"/>
1212
<element name="cancelButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Cancel']" timeout="30"/>
1313
<element name="doneButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Done']" timeout="30"/>
1414
<element name="saveButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Save']" timeout="30"/>

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

Lines changed: 117 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
namespace Magento\Catalog\Model\ResourceModel\Product;
77

88
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Framework\DataObject;
10+
use Magento\Framework\Model\AbstractModel;
911
use Magento\Store\Model\ScopeInterface;
12+
use Magento\Store\Model\Store;
1013

1114
/**
1215
* Catalog product custom option resource model
@@ -77,10 +80,10 @@ protected function _construct()
7780
/**
7881
* Save options store data
7982
*
80-
* @param \Magento\Framework\Model\AbstractModel $object
83+
* @param AbstractModel $object
8184
* @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
8285
*/
83-
protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
86+
protected function _afterSave(AbstractModel $object)
8487
{
8588
$this->_saveValuePrices($object);
8689
$this->_saveValueTitles($object);
@@ -91,138 +94,38 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
9194
/**
9295
* Save value prices
9396
*
94-
* @param \Magento\Framework\Model\AbstractModel $object
97+
* @param AbstractModel $object
9598
* @return $this
96-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
97-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
9899
*/
99-
protected function _saveValuePrices(\Magento\Framework\Model\AbstractModel $object)
100+
protected function _saveValuePrices(AbstractModel $object)
100101
{
101-
$priceTable = $this->getTable('catalog_product_option_price');
102-
$connection = $this->getConnection();
103-
104102
/*
105103
* Better to check param 'price' and 'price_type' for saving.
106104
* If there is not price skip saving price
107105
*/
108-
109106
if (in_array($object->getType(), $this->getPriceTypes())) {
110-
//save for store_id = 0
107+
// save for store_id = 0
111108
if (!$object->getData('scope', 'price')) {
112-
$statement = $connection->select()->from(
113-
$priceTable,
114-
'option_id'
115-
)->where(
116-
'option_id = ?',
117-
$object->getId()
118-
)->where(
119-
'store_id = ?',
120-
\Magento\Store\Model\Store::DEFAULT_STORE_ID
121-
);
122-
$optionId = $connection->fetchOne($statement);
123-
124-
if ($optionId) {
125-
$data = $this->_prepareDataForTable(
126-
new \Magento\Framework\DataObject(
127-
['price' => $object->getPrice(), 'price_type' => $object->getPriceType()]
128-
),
129-
$priceTable
130-
);
131-
132-
$connection->update(
133-
$priceTable,
134-
$data,
135-
[
136-
'option_id = ?' => $object->getId(),
137-
'store_id = ?' => \Magento\Store\Model\Store::DEFAULT_STORE_ID
138-
]
139-
);
140-
} else {
141-
$data = $this->_prepareDataForTable(
142-
new \Magento\Framework\DataObject(
143-
[
144-
'option_id' => $object->getId(),
145-
'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
146-
'price' => $object->getPrice(),
147-
'price_type' => $object->getPriceType(),
148-
]
149-
),
150-
$priceTable
151-
);
152-
$connection->insert($priceTable, $data);
153-
}
109+
$this->savePriceByStore($object, Store::DEFAULT_STORE_ID);
154110
}
155111

156112
$scope = (int)$this->_config->getValue(
157-
\Magento\Store\Model\Store::XML_PATH_PRICE_SCOPE,
158-
ScopeInterface::SCOPE_STORE
113+
Store::XML_PATH_PRICE_SCOPE,
114+
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
159115
);
160116

161-
if ($object->getStoreId() != '0' && $scope == \Magento\Store\Model\Store::PRICE_SCOPE_WEBSITE) {
162-
$website = $this->_storeManager->getStore($object->getStoreId())->getWebsite();
163-
164-
$websiteBaseCurrency = $this->_config->getValue(
165-
\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
166-
ScopeInterface::SCOPE_WEBSITE,
167-
$website
168-
);
169-
170-
$storeIds = $website->getStoreIds();
171-
if (is_array($storeIds)) {
172-
foreach ($storeIds as $storeId) {
173-
if ($object->getPriceType() == 'fixed') {
174-
$storeCurrency = $this->_storeManager->getStore($storeId)->getBaseCurrencyCode();
175-
$rate = $this->_currencyFactory->create()->load($websiteBaseCurrency)
176-
->getRate($storeCurrency);
177-
$rate ?: $rate = 1;
178-
$newPrice = $object->getPrice() * $rate;
179-
} else {
180-
$newPrice = $object->getPrice();
181-
}
182-
183-
$statement = $connection->select()->from(
184-
$priceTable
185-
)->where(
186-
'option_id = ?',
187-
$object->getId()
188-
)->where(
189-
'store_id = ?',
190-
$storeId
191-
);
192-
193-
if ($connection->fetchOne($statement)) {
194-
$data = $this->_prepareDataForTable(
195-
new \Magento\Framework\DataObject(
196-
['price' => $newPrice, 'price_type' => $object->getPriceType()]
197-
),
198-
$priceTable
199-
);
200-
201-
$connection->update(
202-
$priceTable,
203-
$data,
204-
['option_id = ?' => $object->getId(), 'store_id = ?' => $storeId]
205-
);
206-
} else {
207-
$data = $this->_prepareDataForTable(
208-
new \Magento\Framework\DataObject(
209-
[
210-
'option_id' => $object->getId(),
211-
'store_id' => $storeId,
212-
'price' => $newPrice,
213-
'price_type' => $object->getPriceType(),
214-
]
215-
),
216-
$priceTable
217-
);
218-
$connection->insert($priceTable, $data);
219-
}
220-
}
117+
if ($object->getStoreId() != '0' && $scope == Store::PRICE_SCOPE_WEBSITE) {
118+
$storeIds = $this->_storeManager->getStore($object->getStoreId())->getWebsite()->getStoreIds();
119+
if (empty($storeIds)) {
120+
return $this;
121+
}
122+
foreach ($storeIds as $storeId) {
123+
$newPrice = $this->calculateStorePrice($object, $storeId);
124+
$this->savePriceByStore($object, (int)$storeId, $newPrice);
221125
}
222-
} elseif ($scope == \Magento\Store\Model\Store::PRICE_SCOPE_WEBSITE && $object->getData('scope', 'price')
223-
) {
224-
$connection->delete(
225-
$priceTable,
126+
} elseif ($scope == Store::PRICE_SCOPE_WEBSITE && $object->getData('scope', 'price')) {
127+
$this->getConnection()->delete(
128+
$this->getTable('catalog_product_option_price'),
226129
['option_id = ?' => $object->getId(), 'store_id = ?' => $object->getStoreId()]
227130
);
228131
}
@@ -231,31 +134,114 @@ protected function _saveValuePrices(\Magento\Framework\Model\AbstractModel $obje
231134
return $this;
232135
}
233136

137+
/**
138+
* Save option price by store
139+
*
140+
* @param AbstractModel $object
141+
* @param int $storeId
142+
* @param float|null $newPrice
143+
*/
144+
private function savePriceByStore(AbstractModel $object, int $storeId, float $newPrice = null): void
145+
{
146+
$priceTable = $this->getTable('catalog_product_option_price');
147+
$connection = $this->getConnection();
148+
$price = $newPrice === null ? $object->getPrice() : $newPrice;
149+
150+
$statement = $connection->select()->from($priceTable, 'option_id')
151+
->where('option_id = ?', $object->getId())
152+
->where('store_id = ?', $storeId);
153+
$optionId = $connection->fetchOne($statement);
154+
155+
if (!$optionId) {
156+
$data = $this->_prepareDataForTable(
157+
new DataObject(
158+
[
159+
'option_id' => $object->getId(),
160+
'store_id' => $storeId,
161+
'price' => $price,
162+
'price_type' => $object->getPriceType(),
163+
]
164+
),
165+
$priceTable
166+
);
167+
$connection->insert($priceTable, $data);
168+
} else {
169+
// skip to update the default price when the store price is saving
170+
if ($storeId === Store::DEFAULT_STORE_ID && (int)$object->getStoreId() !== $storeId) {
171+
return;
172+
}
173+
174+
$data = $this->_prepareDataForTable(
175+
new DataObject(
176+
[
177+
'price' => $price,
178+
'price_type' => $object->getPriceType()
179+
]
180+
),
181+
$priceTable
182+
);
183+
184+
$connection->update(
185+
$priceTable,
186+
$data,
187+
[
188+
'option_id = ?' => $object->getId(),
189+
'store_id = ?' => $storeId
190+
]
191+
);
192+
}
193+
}
194+
195+
/**
196+
* Calculate price by store
197+
*
198+
* @param AbstractModel $object
199+
* @param int $storeId
200+
* @return float
201+
*/
202+
private function calculateStorePrice(AbstractModel $object, int $storeId): float
203+
{
204+
$price = $object->getPrice();
205+
if ($object->getPriceType() == 'fixed') {
206+
$website = $this->_storeManager->getStore($storeId)->getWebsite();
207+
$websiteBaseCurrency = $this->_config->getValue(
208+
\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
209+
ScopeInterface::SCOPE_WEBSITE,
210+
$website
211+
);
212+
$storeCurrency = $this->_storeManager->getStore($storeId)->getBaseCurrencyCode();
213+
$rate = $this->_currencyFactory->create()->load($websiteBaseCurrency)->getRate($storeCurrency);
214+
$price = $object->getPrice() * ($rate ?: 1);
215+
}
216+
217+
return (float)$price;
218+
}
219+
234220
/**
235221
* Save titles
236222
*
237-
* @param \Magento\Framework\Model\AbstractModel $object
223+
* @param AbstractModel $object
238224
* @return void
239225
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
240226
*/
241-
protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $object)
227+
protected function _saveValueTitles(AbstractModel $object)
242228
{
243229
$connection = $this->getConnection();
244230
$titleTableName = $this->getTable('catalog_product_option_title');
245-
foreach ([\Magento\Store\Model\Store::DEFAULT_STORE_ID, $object->getStoreId()] as $storeId) {
231+
foreach ([Store::DEFAULT_STORE_ID, $object->getStoreId()] as $storeId) {
246232
$existInCurrentStore = $this->getColFromOptionTable($titleTableName, (int)$object->getId(), (int)$storeId);
247-
$existInDefaultStore = (int)$storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID ?
233+
$existInDefaultStore = (int)$storeId == Store::DEFAULT_STORE_ID ?
248234
$existInCurrentStore :
249235
$this->getColFromOptionTable(
250236
$titleTableName,
251237
(int)$object->getId(),
252-
\Magento\Store\Model\Store::DEFAULT_STORE_ID
238+
Store::DEFAULT_STORE_ID
253239
);
254240

255241
if ($object->getTitle()) {
256242
$isDeleteStoreTitle = (bool)$object->getData('is_delete_store_title');
257243
if ($existInCurrentStore) {
258-
if ($isDeleteStoreTitle && (int)$storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID) {
244+
if ($isDeleteStoreTitle && (int)$storeId != Store::DEFAULT_STORE_ID) {
259245
$connection->delete($titleTableName, ['option_title_id = ?' => $existInCurrentStore]);
260246
} elseif ($object->getStoreId() == $storeId) {
261247
$data = $this->_prepareDataForTable(
@@ -273,9 +259,9 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
273259
}
274260
} else {
275261
// we should insert record into not default store only of if it does not exist in default store
276-
if (($storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
262+
if (($storeId == Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
277263
(
278-
$storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID &&
264+
$storeId != Store::DEFAULT_STORE_ID &&
279265
!$existInCurrentStore &&
280266
!$isDeleteStoreTitle
281267
)
@@ -294,7 +280,7 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
294280
}
295281
}
296282
} else {
297-
if ($object->getId() && $object->getStoreId() > \Magento\Store\Model\Store::DEFAULT_STORE_ID
283+
if ($object->getId() && $object->getStoreId() > Store::DEFAULT_STORE_ID
298284
&& $storeId
299285
) {
300286
$connection->delete(
@@ -473,7 +459,7 @@ public function getSearchableData($productId, $storeId)
473459
'option_title_default.option_id=product_option.option_id',
474460
$connection->quoteInto(
475461
'option_title_default.store_id = ?',
476-
\Magento\Store\Model\Store::DEFAULT_STORE_ID
462+
Store::DEFAULT_STORE_ID
477463
)
478464
]
479465
);
@@ -520,7 +506,7 @@ public function getSearchableData($productId, $storeId)
520506
'option_title_default.option_type_id=option_type.option_type_id',
521507
$connection->quoteInto(
522508
'option_title_default.store_id = ?',
523-
\Magento\Store\Model\Store::DEFAULT_STORE_ID
509+
Store::DEFAULT_STORE_ID
524510
)
525511
]
526512
);
@@ -585,7 +571,7 @@ public function getPriceTypes()
585571
}
586572

587573
/**
588-
* Returns metadata poll.
574+
* Get Metadata Pool
589575
*
590576
* @return \Magento\Framework\EntityManager\MetadataPool
591577
*/

0 commit comments

Comments
 (0)