Skip to content

Commit aad8562

Browse files
committed
MAGETWO-54054: Merge branch 'develop' of github.com:magento/magento2ce into MAGETWO-54054
2 parents 906ad38 + f66123e commit aad8562

File tree

49 files changed

+1079
-225
lines changed

Some content is hidden

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

49 files changed

+1079
-225
lines changed

app/code/Magento/Catalog/Api/Data/ProductAttributeInterface.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
interface ProductAttributeInterface extends \Magento\Catalog\Api\Data\EavAttributeInterface
1313
{
1414
const ENTITY_TYPE_CODE = 'catalog_product';
15-
const CODE_TIER_PRICE_FIELD_PRICE = 'price';
1615
const CODE_HAS_WEIGHT = 'product_has_weight';
1716
const CODE_SPECIAL_PRICE = 'special_price';
1817
const CODE_PRICE = 'price';
@@ -27,6 +26,9 @@ interface ProductAttributeInterface extends \Magento\Catalog\Api\Data\EavAttribu
2726
const CODE_COST = 'cost';
2827
const CODE_SEO_FIELD_URL_KEY = 'url_key';
2928
const CODE_TIER_PRICE = 'tier_price';
29+
const CODE_TIER_PRICE_FIELD_PRICE = 'price';
30+
const CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE = 'percentage_value';
31+
const CODE_TIER_PRICE_FIELD_VALUE_TYPE = 'value_type';
3032
const CODE_SEO_FIELD_META_DESCRIPTION = 'meta_description';
3133
const CODE_WEIGHT = 'weight';
3234
}

app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/**
1010
* @api
11+
* @deprecated use ScopedProductTierPriceManagementInterface instead
1112
*/
1213
interface ProductTierPriceManagementInterface
1314
{
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
*
4+
* Copyright © 2016 Magento. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
namespace Magento\Catalog\Api;
8+
9+
/**
10+
* @api
11+
*/
12+
interface ScopedProductTierPriceManagementInterface
13+
{
14+
/**
15+
* Create tier price for product
16+
*
17+
* @param string $sku
18+
* @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice
19+
* @return boolean
20+
* @throws \Magento\Framework\Exception\NoSuchEntityException
21+
* @throws \Magento\Framework\Exception\CouldNotSaveException
22+
*/
23+
public function add($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice);
24+
25+
/**
26+
* Remove tier price from product
27+
*
28+
* @param string $sku
29+
* @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice
30+
* @return boolean
31+
* @throws \Magento\Framework\Exception\NoSuchEntityException
32+
* @throws \Magento\Framework\Exception\CouldNotSaveException
33+
*/
34+
public function remove($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice);
35+
36+
/**
37+
* Get tier price of product
38+
*
39+
* @param string $sku
40+
* @param string $customerGroupId 'all' can be used to specify 'ALL GROUPS'
41+
* @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[]
42+
* @throws \Magento\Framework\Exception\NoSuchEntityException
43+
*/
44+
public function getList($sku, $customerGroupId);
45+
}

app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
*/
66
namespace Magento\Catalog\Model\Config\Source\Product\Options;
77

8+
use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface;
9+
810
/**
911
* Price types mode source
1012
*
1113
* @author Magento Core Team <[email protected]>
1214
*/
13-
class Price implements \Magento\Framework\Option\ArrayInterface
15+
class Price implements ProductPriceOptionsInterface
1416
{
1517
/**
1618
* {@inheritdoc}
@@ -20,8 +22,8 @@ class Price implements \Magento\Framework\Option\ArrayInterface
2022
public function toOptionArray()
2123
{
2224
return [
23-
['value' => 'fixed', 'label' => __('Fixed')],
24-
['value' => 'percent', 'label' => __('Percent')]
25+
['value' => self::VALUE_FIXED, 'label' => __('Fixed')],
26+
['value' => self::VALUE_PERCENT, 'label' => __('Percent')],
2527
];
2628
}
2729
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\Config\Source;
7+
8+
use Magento\Framework\Data\OptionSourceInterface;
9+
10+
/**
11+
* Interface ProductPriceOptionsInterface
12+
*/
13+
interface ProductPriceOptionsInterface extends OptionSourceInterface
14+
{
15+
/**#@+
16+
* Values
17+
*/
18+
const VALUE_FIXED = 'fixed';
19+
const VALUE_PERCENT = 'percent';
20+
/**#@-*/
21+
}

app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ abstract class AbstractAction
7070
*/
7171
protected $_indexers;
7272

73+
/**
74+
* @var \Magento\Catalog\Model\ResourceModel\Product
75+
*/
76+
private $productResource;
77+
7378
/**
7479
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
7580
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -213,12 +218,19 @@ protected function _prepareTierPriceIndex($entityIds = null)
213218
$table = $this->_defaultIndexerResource->getTable('catalog_product_index_tier_price');
214219
$this->_emptyTable($table);
215220

221+
$tierPriceExpression = $this->_connection->getCheckSql(
222+
'tp.value = 0',
223+
'product_price.value * (1 - tp.percentage_value / 100)',
224+
'tp.value'
225+
);
216226
$websiteExpression = $this->_connection->getCheckSql(
217227
'tp.website_id = 0',
218-
'ROUND(tp.value * cwd.rate, 4)',
219-
'tp.value'
228+
'ROUND(' . $tierPriceExpression . ' * cwd.rate, 4)',
229+
$tierPriceExpression
220230
);
221231
$linkField = $this->getProductIdFieldName();
232+
$priceAttribute = $this->getProductResource()->getAttribute('price');
233+
222234
$select = $this->_connection->select()->from(
223235
['cpe' => $this->_defaultIndexerResource->getTable('catalog_product_entity')],
224236
['cpe.entity_id']
@@ -238,8 +250,15 @@ protected function _prepareTierPriceIndex($entityIds = null)
238250
['cwd' => $this->_defaultIndexerResource->getTable('catalog_product_index_website')],
239251
'cw.website_id = cwd.website_id',
240252
[]
253+
)->join(
254+
['product_price' => $priceAttribute->getBackend()->getTable()],
255+
'tp.' . $linkField . ' = product_price.' . $linkField,
256+
[]
241257
)->where(
242258
'cw.website_id != 0'
259+
)->where(
260+
'product_price.attribute_id = ?',
261+
$priceAttribute->getAttributeId()
243262
)->columns(
244263
new \Zend_Db_Expr("MIN({$websiteExpression})")
245264
)->group(
@@ -462,4 +481,17 @@ protected function getProductIdFieldName()
462481
$indexList = $this->_connection->getIndexList($table);
463482
return $indexList[$this->_connection->getPrimaryKeyName($table)]['COLUMNS_LIST'][0];
464483
}
484+
485+
/**
486+
* @return \Magento\Catalog\Model\ResourceModel\Product
487+
* @deprecated
488+
*/
489+
private function getProductResource()
490+
{
491+
if (null === $this->productResource) {
492+
$this->productResource = \Magento\Framework\App\ObjectManager::getInstance()
493+
->get(\Magento\Catalog\Model\ResourceModel\Product::class);
494+
}
495+
return $this->productResource;
496+
}
465497
}

app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php

Lines changed: 102 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ protected function _getAdditionalUniqueFields($objectArray)
129129
return [];
130130
}
131131

132+
/**
133+
* Get additional fields
134+
*
135+
* @param array $objectArray
136+
* @return array
137+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
138+
*/
139+
protected function getAdditionalFields($objectArray)
140+
{
141+
return [];
142+
}
143+
132144
/**
133145
* Whether group price value fixed or percent of original price
134146
*
@@ -176,9 +188,7 @@ public function validate($object)
176188
throw new \Magento\Framework\Exception\LocalizedException(__($this->_getDuplicateErrorMessage()));
177189
}
178190

179-
if (!$this->isPositiveOrZero($priceRow['price'])) {
180-
return __('Group price must be a number greater than 0.');
181-
}
191+
$this->validatePrice($priceRow);
182192

183193
$duplicates[$compare] = true;
184194
}
@@ -228,6 +238,20 @@ public function validate($object)
228238
return true;
229239
}
230240

241+
/**
242+
* @param array $priceRow
243+
* @return void
244+
* @throws \Magento\Framework\Exception\LocalizedException
245+
*/
246+
protected function validatePrice(array $priceRow)
247+
{
248+
if (!isset($priceRow['price']) || !$this->isPositiveOrZero($priceRow['price'])) {
249+
throw new \Magento\Framework\Exception\LocalizedException(
250+
__('Group price must be a number greater than 0.')
251+
);
252+
}
253+
}
254+
231255
/**
232256
* Prepare group prices data for website
233257
*
@@ -270,37 +294,70 @@ public function preparePriceData(array $priceData, $productTypeId, $websiteId)
270294
*/
271295
public function afterLoad($object)
272296
{
273-
$storeId = $object->getStoreId();
297+
$data = $this->_getResource()->loadPriceData(
298+
$object->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()),
299+
$this->getWebsiteId($object->getStoreId())
300+
);
301+
$this->setPriceData($object, $data);
302+
303+
return $this;
304+
}
305+
306+
/**
307+
* @param int $storeId
308+
* @return int|null
309+
*/
310+
private function getWebsiteId($storeId)
311+
{
274312
$websiteId = null;
275313
if ($this->getAttribute()->isScopeGlobal()) {
276314
$websiteId = 0;
277315
} elseif ($storeId) {
278316
$websiteId = $this->_storeManager->getStore($storeId)->getWebsiteId();
279317
}
318+
return $websiteId;
319+
}
280320

281-
$data = $this->_getResource()->loadPriceData(
282-
$object->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()),
283-
$websiteId
284-
);
285-
foreach ($data as $k => $v) {
286-
$data[$k]['website_price'] = $v['price'];
287-
if ($v['all_groups']) {
288-
$data[$k]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId();
289-
}
290-
}
291-
321+
/**
322+
* @param \Magento\Catalog\Model\Product $object
323+
* @param array $priceData
324+
*/
325+
public function setPriceData($object, $priceData)
326+
{
327+
$priceData = $this->modifyPriceData($object, $priceData);
328+
$websiteId = $this->getWebsiteId($object->getStoreId());
292329
if (!$object->getData('_edit_mode') && $websiteId) {
293-
$data = $this->preparePriceData($data, $object->getTypeId(), $websiteId);
330+
$priceData = $this->preparePriceData($priceData, $object->getTypeId(), $websiteId);
294331
}
295332

296-
$object->setData($this->getAttribute()->getName(), $data);
297-
$object->setOrigData($this->getAttribute()->getName(), $data);
333+
$object->setData($this->getAttribute()->getName(), $priceData);
334+
$object->setOrigData($this->getAttribute()->getName(), $priceData);
298335

299336
$valueChangedKey = $this->getAttribute()->getName() . '_changed';
300337
$object->setOrigData($valueChangedKey, 0);
301338
$object->setData($valueChangedKey, 0);
339+
}
302340

303-
return $this;
341+
/**
342+
* Perform price modification
343+
*
344+
* @param \Magento\Catalog\Model\Product $object
345+
* @param array $data
346+
* @return array
347+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
348+
*/
349+
protected function modifyPriceData($object, $data)
350+
{
351+
/** @var array $priceItem */
352+
foreach ($data as $key => $priceItem) {
353+
if (isset($priceItem['price']) && $priceItem['price'] > 0) {
354+
$data[$key]['website_price'] = $priceItem['price'];
355+
}
356+
if ($priceItem['all_groups']) {
357+
$data[$key]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId();
358+
}
359+
}
360+
return $data;
304361
}
305362

306363
/**
@@ -372,13 +429,13 @@ public function afterSave($object)
372429

373430
$useForAllGroups = $data['cust_group'] == $this->_groupManagement->getAllCustomersGroup()->getId();
374431
$customerGroupId = !$useForAllGroups ? $data['cust_group'] : 0;
375-
376432
$new[$key] = array_merge(
433+
$this->getAdditionalFields($data),
377434
[
378435
'website_id' => $data['website_id'],
379436
'all_groups' => $useForAllGroups ? 1 : 0,
380437
'customer_group_id' => $customerGroupId,
381-
'value' => $data['price'],
438+
'value' => isset($data['price']) ? $data['price'] : null,
382439
],
383440
$this->_getAdditionalUniqueFields($data)
384441
);
@@ -412,14 +469,7 @@ public function afterSave($object)
412469
}
413470

414471
if (!empty($update)) {
415-
foreach ($update as $k => $v) {
416-
if ($old[$k]['price'] != $v['value']) {
417-
$price = new \Magento\Framework\DataObject(['value_id' => $old[$k]['price_id'], 'value' => $v['value']]);
418-
$this->_getResource()->savePriceData($price);
419-
420-
$isChanged = true;
421-
}
422-
}
472+
$isChanged = $this->updateValues($update, $old);
423473
}
424474

425475
if ($isChanged) {
@@ -430,6 +480,29 @@ public function afterSave($object)
430480
return $this;
431481
}
432482

483+
/**
484+
* @param array $valuesToUpdate
485+
* @param array $oldValues
486+
* @return boolean
487+
*/
488+
protected function updateValues(array $valuesToUpdate, array $oldValues)
489+
{
490+
$isChanged = false;
491+
foreach ($valuesToUpdate as $key => $value) {
492+
if ($oldValues[$key]['price'] != $value['value']) {
493+
$price = new \Magento\Framework\DataObject(
494+
[
495+
'value_id' => $oldValues[$key]['price_id'],
496+
'value' => $value['value']
497+
]
498+
);
499+
$this->_getResource()->savePriceData($price);
500+
$isChanged = true;
501+
}
502+
}
503+
return $isChanged;
504+
}
505+
433506
/**
434507
* Retrieve data for update attribute
435508
*

0 commit comments

Comments
 (0)