diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 9228b9687b82a..1f534ff2833bd 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory as CustomOptionFactory; use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory as ProductLinkFactory; use Magento\Catalog\Api\ProductRepositoryInterface\Proxy as ProductRepository; +use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks; use Magento\Catalog\Model\Product\Link\Resolver as LinkResolver; use Magento\Framework\App\ObjectManager; @@ -203,34 +204,7 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra } $product = $this->setProductLinks($product); - - /** - * Initialize product options - */ - if ($productOptions && !$product->getOptionsReadonly()) { - // mark custom options that should to fall back to default value - $options = $this->mergeProductOptions( - $productOptions, - $this->request->getPost('options_use_default') - ); - $customOptions = []; - foreach ($options as $customOptionData) { - if (empty($customOptionData['is_delete'])) { - if (empty($customOptionData['option_id'])) { - $customOptionData['option_id'] = null; - } - if (isset($customOptionData['values'])) { - $customOptionData['values'] = array_filter($customOptionData['values'], function ($valueData) { - return empty($valueData['is_delete']); - }); - } - $customOption = $this->customOptionFactory->create(['data' => $customOptionData]); - $customOption->setProductSku($product->getSku()); - $customOptions[] = $customOption; - } - } - $product->setOptions($customOptions); - } + $product = $this->fillProductOptions($product, $productOptions); $product->setCanSaveCustomOptions( !empty($productData['affect_product_custom_options']) && !$product->getOptionsReadonly() @@ -427,4 +401,50 @@ private function filterWebsiteIds($websiteIds) return $websiteIds; } + + /** + * Fills $product with options from $productOptions array + * + * @param Product $product + * @param array $productOptions + * @return Product + */ + private function fillProductOptions(Product $product, array $productOptions) + { + if ($product->getOptionsReadonly()) { + return $product; + } + + if (empty($productOptions)) { + return $product->setOptions([]); + } + + // mark custom options that should to fall back to default value + $options = $this->mergeProductOptions( + $productOptions, + $this->request->getPost('options_use_default') + ); + $customOptions = []; + foreach ($options as $customOptionData) { + if (!empty($customOptionData['is_delete'])) { + continue; + } + + if (empty($customOptionData['option_id'])) { + $customOptionData['option_id'] = null; + } + + if (isset($customOptionData['values'])) { + $customOptionData['values'] = array_filter($customOptionData['values'], function ($valueData) { + return empty($valueData['is_delete']); + }); + } + + $customOption = $this->customOptionFactory->create(['data' => $customOptionData]); + $customOption->setProductSku($product->getSku()); + $customOptions[] = $customOption; + } + + return $product->setOptions($customOptions); + } } diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index 09fd015d2114d..bcc5ad451a533 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -10,20 +10,6 @@ define([ ], function (DynamicRows, _, utils) { 'use strict'; - var maxId = 0, - - /** - * Stores max option_id value of the options from recordData once on initialization - * @param {Array} data - array with records data - */ - initMaxId = function (data) { - if (data && data.length) { - maxId = ~~_.max(data, function (record) { - return ~~record['option_id']; - })['option_id']; - } - }; - return DynamicRows.extend({ defaults: { mappingSettings: { @@ -38,18 +24,11 @@ define([ identificationDRProperty: 'option_id' }, - /** @inheritdoc */ - initialize: function () { - this._super(); - initMaxId(this.recordData()); - - return this; - }, - /** @inheritdoc */ processingInsertData: function (data) { var options = [], - currentOption; + currentOption, + generalContext = this; if (!data) { return; @@ -70,10 +49,7 @@ define([ } if (currentOption.values.length > 0) { - _.each(currentOption.values, function (optionValue) { - delete optionValue['option_id']; - delete optionValue['option_type_id']; - }); + generalContext.removeOptionsIds(currentOption.values); } options.push(currentOption); }); @@ -91,17 +67,20 @@ define([ }, /** - * Set empty array to dataProvider + * Removes option_id and option_type_id from every option + * + * @param {Array} options */ - clearDataProvider: function () { - this.source.set(this.dataProvider, []); + removeOptionsIds: function (options) { + _.each(options, function (optionValue) { + delete optionValue['option_id']; + delete optionValue['option_type_id']; + }); }, /** @inheritdoc */ processingAddChild: function (ctx, index, prop) { - if (ctx && !_.isNumber(ctx['option_id'])) { - ctx['option_id'] = ++maxId; - } else if (!ctx) { + if (!ctx) { this.showSpinner(true); this.addChild(ctx, index, prop); @@ -111,6 +90,13 @@ define([ this._super(ctx, index, prop); }, + /** + * Set empty array to dataProvider + */ + clearDataProvider: function () { + this.source.set(this.dataProvider, []); + }, + /** * Mutes parent method */