Skip to content

Commit d636119

Browse files
committed
MAGETWO-70634: Issues in customizable options section of add/edit product pages
1 parent 4d9d6b0 commit d636119

File tree

27 files changed

+423
-13
lines changed

27 files changed

+423
-13
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414
*/
1515
class Price implements ProductPriceOptionsInterface
1616
{
17+
/**
18+
* Store manager.
19+
*
20+
* @var \Magento\Store\Model\StoreManagerInterface
21+
*/
22+
private $storeManager;
23+
24+
/**
25+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
26+
*/
27+
public function __construct(\Magento\Store\Model\StoreManagerInterface $storeManager)
28+
{
29+
$this->storeManager = $storeManager;
30+
}
31+
1732
/**
1833
* {@inheritdoc}
1934
*
@@ -26,4 +41,27 @@ public function toOptionArray()
2641
['value' => self::VALUE_PERCENT, 'label' => __('Percent')],
2742
];
2843
}
44+
45+
/**
46+
* Get option array of prefixes.
47+
*
48+
* @return array
49+
*/
50+
public function prefixesToOptionArray()
51+
{
52+
return [
53+
['value' => self::VALUE_FIXED, 'label' => $this->getCurrencySymbol()],
54+
['value' => self::VALUE_PERCENT, 'label' => '%'],
55+
];
56+
}
57+
58+
/**
59+
* Get currency symbol.
60+
*
61+
* @return string
62+
*/
63+
private function getCurrencySymbol()
64+
{
65+
return $this->storeManager->getStore()->getBaseCurrency()->getCurrencySymbol();
66+
}
2967
}

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/DefaultValidatorTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class DefaultValidatorTest extends \PHPUnit\Framework\TestCase
2121
protected function setUp()
2222
{
2323
$configMock = $this->createMock(\Magento\Catalog\Model\ProductOptions\ConfigInterface::class);
24-
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price();
24+
$storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
25+
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price($storeManagerMock);
2526
$config = [
2627
[
2728
'label' => 'group label 1',

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/FileTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class FileTest extends \PHPUnit\Framework\TestCase
2121
protected function setUp()
2222
{
2323
$configMock = $this->createMock(\Magento\Catalog\Model\ProductOptions\ConfigInterface::class);
24-
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price();
24+
$storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
25+
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price($storeManagerMock);
2526
$config = [
2627
[
2728
'label' => 'group label 1',

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/SelectTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class SelectTest extends \PHPUnit\Framework\TestCase
2121
protected function setUp()
2222
{
2323
$configMock = $this->createMock(\Magento\Catalog\Model\ProductOptions\ConfigInterface::class);
24-
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price();
24+
$storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
25+
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price($storeManagerMock);
2526
$config = [
2627
[
2728
'label' => 'group label 1',

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/TextTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class TextTest extends \PHPUnit\Framework\TestCase
2121
protected function setUp()
2222
{
2323
$configMock = $this->createMock(\Magento\Catalog\Model\ProductOptions\ConfigInterface::class);
24-
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price();
24+
$storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
25+
$priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price($storeManagerMock);
2526
$config = [
2627
[
2728
'label' => 'group label 1',

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ protected function getStaticTypeContainerConfig($sortOrder)
603603
'showLabel' => false,
604604
'additionalClasses' => 'admin__field-group-columns admin__control-group-equal',
605605
'sortOrder' => $sortOrder,
606+
'fieldTemplate' => 'Magento_Catalog/form/field',
607+
'visible' => false,
606608
],
607609
],
608610
],
@@ -677,7 +679,7 @@ protected function getSelectTypeGridConfig($sortOrder)
677679
10,
678680
$this->locator->getProduct()->getStoreId() ? $options : []
679681
),
680-
static::FIELD_PRICE_NAME => $this->getPriceFieldConfig(20),
682+
static::FIELD_PRICE_NAME => $this->getPriceFieldConfigForSelectType(20),
681683
static::FIELD_PRICE_TYPE_NAME => $this->getPriceTypeFieldConfig(30, ['fit' => true]),
682684
static::FIELD_SKU_NAME => $this->getSkuFieldConfig(40),
683685
static::FIELD_SORT_ORDER_NAME => $this->getPositionFieldConfig(50),
@@ -912,10 +914,12 @@ protected function getPriceFieldConfig($sortOrder)
912914
'config' => [
913915
'label' => __('Price'),
914916
'componentType' => Field::NAME,
917+
'component' => 'Magento_Catalog/js/components/custom-options-component',
915918
'formElement' => Input::NAME,
916919
'dataScope' => static::FIELD_PRICE_NAME,
917920
'dataType' => Number::NAME,
918921
'addbefore' => $this->getCurrencySymbol(),
922+
'addbeforePool' => $this->productOptionsPrice->prefixesToOptionArray(),
919923
'sortOrder' => $sortOrder,
920924
'validation' => [
921925
'validate-zero-or-greater' => true
@@ -926,6 +930,20 @@ protected function getPriceFieldConfig($sortOrder)
926930
];
927931
}
928932

933+
/**
934+
* Get config for "Price" field for select type.
935+
*
936+
* @param int $sortOrder
937+
* @return array
938+
*/
939+
private function getPriceFieldConfigForSelectType(int $sortOrder)
940+
{
941+
$priceFieldConfig = $this->getPriceFieldConfig($sortOrder);
942+
$priceFieldConfig['arguments']['data']['config']['template'] = 'Magento_Catalog/form/field';
943+
944+
return $priceFieldConfig;
945+
}
946+
929947
/**
930948
* Get config for "Price Type" field
931949
*
@@ -942,12 +960,16 @@ protected function getPriceTypeFieldConfig($sortOrder, array $config = [])
942960
'data' => [
943961
'config' => [
944962
'label' => __('Price Type'),
963+
'component' => 'Magento_Catalog/js/components/custom-options-price-type',
945964
'componentType' => Field::NAME,
946965
'formElement' => Select::NAME,
947966
'dataScope' => static::FIELD_PRICE_TYPE_NAME,
948967
'dataType' => Text::NAME,
949968
'sortOrder' => $sortOrder,
950969
'options' => $this->productOptionsPrice->toOptionArray(),
970+
'imports' => [
971+
'priceIndex' => self::FIELD_PRICE_NAME,
972+
],
951973
],
952974
],
953975
],
@@ -1050,6 +1072,7 @@ protected function getImageSizeXFieldConfig($sortOrder)
10501072
'label' => __('Maximum Image Size'),
10511073
'notice' => __('Please leave blank if it is not an image.'),
10521074
'addafter' => __('px.'),
1075+
'component' => 'Magento_Catalog/js/components/custom-options-component',
10531076
'componentType' => Field::NAME,
10541077
'formElement' => Input::NAME,
10551078
'dataScope' => static::FIELD_IMAGE_SIZE_X_NAME,
@@ -1079,6 +1102,7 @@ protected function getImageSizeYFieldConfig($sortOrder)
10791102
'config' => [
10801103
'label' => ' ',
10811104
'addafter' => __('px.'),
1105+
'component' => 'Magento_Catalog/js/components/custom-options-component',
10821106
'componentType' => Field::NAME,
10831107
'formElement' => Input::NAME,
10841108
'dataScope' => static::FIELD_IMAGE_SIZE_Y_NAME,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'underscore',
8+
'Magento_Ui/js/form/element/abstract'
9+
], function (_, Abstract) {
10+
'use strict';
11+
12+
return Abstract.extend({
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
setInitialValue: function () {
17+
this._super();
18+
19+
this.addBefore(this.addbefore);
20+
21+
return this;
22+
},
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
initObservable: function () {
28+
this._super();
29+
30+
this.observe('addBefore');
31+
32+
return this;
33+
}
34+
});
35+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'underscore',
8+
'Magento_Ui/js/form/element/select',
9+
'uiRegistry'
10+
], function (_, Select, uiRegistry) {
11+
'use strict';
12+
13+
return Select.extend({
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
onUpdate: function () {
18+
this._super();
19+
20+
this.updateAddBeforeForPrice();
21+
},
22+
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
setInitialValue: function () {
27+
this._super();
28+
29+
this.updateAddBeforeForPrice();
30+
31+
return this;
32+
},
33+
34+
/**
35+
* Update addbefore for price field. Change it to currency or % depends of price_type value.
36+
*/
37+
updateAddBeforeForPrice: function () {
38+
var priceIndex = typeof this.imports.priceIndex == 'undefined'
39+
? 'price'
40+
: this.imports.priceIndex;
41+
42+
var priceName = this.parentName + '.' + priceIndex;
43+
44+
var uiPrice = uiRegistry.get(priceName);
45+
46+
if (uiPrice && uiPrice.addbeforePool) {
47+
var currentValue = this.value();
48+
var addBefore;
49+
50+
uiPrice.addbeforePool.forEach(function (item) {
51+
if (item.value == currentValue) {
52+
addBefore = item.label;
53+
}
54+
});
55+
56+
if (typeof addBefore != 'undefined') {
57+
uiPrice.addBefore(addBefore);
58+
}
59+
}
60+
}
61+
});
62+
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!--
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
-->
7+
<div class="admin__field"
8+
visible="visible"
9+
css="$data.additionalClasses"
10+
attr="'data-index': index">
11+
<label class="admin__field-label" if="$data.label" visible="$data.labelVisible" attr="for: uid">
12+
<span translate="label" attr="'data-config-scope': $data.scopeLabel"/>
13+
</label>
14+
<div class="admin__field-control"
15+
css="'_with-tooltip': $data.tooltip, '_with-reset': $data.showFallbackReset && $data.isDifferedFromDefault">
16+
<render args="elementTmpl" ifnot="hasAddons()"/>
17+
18+
<div class="admin__control-addon" if="hasAddons()">
19+
<render args="elementTmpl"/>
20+
21+
<label class="admin__addon-prefix" if="addBefore()" attr="for: uid">
22+
<span text="addBefore()"/>
23+
</label>
24+
<label class="admin__addon-suffix" if="$data.addafter" attr="for: uid">
25+
<span text="addafter"/>
26+
</label>
27+
</div>
28+
29+
<render args="tooltipTpl" if="$data.tooltip"/>
30+
31+
<render args="fallbackResetTpl" if="$data.showFallbackReset && $data.isDifferedFromDefault"/>
32+
33+
<label class="admin__field-error" if="error" attr="for: uid" text="error"/>
34+
35+
<div class="admin__field-note" if="$data.notice" attr="id: noticeId">
36+
<span translate="notice"/>
37+
</div>
38+
39+
<div class="admin__additional-info" if="$data.additionalInfo" html="$data.additionalInfo"></div>
40+
41+
<render args="$data.service.template" if="$data.hasService()"/>
42+
</div>
43+
</div>

app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public function afterInitialize(
9393
protected function getConfigurations()
9494
{
9595
$result = [];
96-
$configurableMatrix = $this->request->getParam('configurable-matrix-serialized', '[]');
96+
$configurableMatrix = $this->request->getParam('configurable-matrix-serialized') ?: [];
9797
if ($configurableMatrix != null && !empty($configurableMatrix)) {
9898
$configurableMatrix = json_decode($configurableMatrix, true);
9999
}

0 commit comments

Comments
 (0)