Skip to content

Fix bug 26449: Configurable product attribute issue #27339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jun 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StorefrontCheckNoAppearDefaultOptionConfigurableProductTest">
<annotations>
<stories value="Configurable Product"/>
<title value="Check for Configurable Product the default option doesn't appear."/>
<description value="Check for Configurable Product the default option doesn't appear on the list options product when an option use."/>
<testCaseId value="MC-35074"/>
</annotations>
<before>
<createData entity="ApiCategory" stepKey="createCategory"/>
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/>
</before>
<after>
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
<actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteAttribute">
<argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}" />
</actionGroup>
<actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/>
</after>

<actionGroup ref="AdminFillBasicValueConfigurableProductActionGroup" stepKey="fillBasicValue">
<argument name="product" value="_defaultProduct"/>
<argument name="category" value="$$createCategory$$"/>
</actionGroup>
<actionGroup ref="AdminAddOptionsToAttributeWithDefaultLayeredNavigationActionGroup" stepKey="createOptions"/>
<actionGroup ref="AdminGotoSelectValueAttributePageActionGroup" stepKey="gotoSelectValuePage">
<argument name="defaultLabelAttribute" value="{{colorProductAttribute.default_label}}"/>
</actionGroup>
<actionGroup ref="AdminSelectValueFromAttributeActionGroup" stepKey="selectColorProductAttribute2">
<argument name="option" value="colorProductAttribute2"/>
</actionGroup>
<actionGroup ref="AdminSelectValueFromAttributeActionGroup" stepKey="selectColorProductAttribute3">
<argument name="option" value="colorProductAttribute3"/>
</actionGroup>
<actionGroup ref="AdminSetQuantityToEachSkusConfigurableProductActionGroup" stepKey="saveConfigurable"/>
<grabValueFrom selector="{{NewProductPageSection.sku}}" stepKey="grabSkuProduct"/>
<magentoCLI command="indexer:reindex" stepKey="reindex"/>

<actionGroup ref="SelectStorefrontSideBarAttributeOption" stepKey="expandOption">
<argument name="categoryName" value="$$createCategory.name$$"/>
<argument name="attributeDefaultLabel" value="{{colorProductAttribute.default_label}}"/>
</actionGroup>
<dontSeeElement selector="{{LayeredNavigationSection.filterOptionContent(colorProductAttribute.default_label,colorProductAttribute1.name)}}" stepKey="dontSeeCaptchaField"/>
<actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteConfigurableProduct">
<argument name="sku" value="$grabSkuProduct"/>
</actionGroup>
</test>
</tests>
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
use Magento\ConfigurableProduct\Api\Data\OptionInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Indexer\ActionInterface;

/**
* Plugin product resource model
*/
class Product
{
/**
Expand All @@ -21,18 +31,45 @@ class Product
*/
private $productIndexer;

/**
* @var ProductAttributeRepositoryInterface
*/
private $productAttributeRepository;

/**
* @var SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;

/**
* @var FilterBuilder
*/
private $filterBuilder;

/**
* Initialize Product dependencies.
*
* @param Configurable $configurable
* @param ActionInterface $productIndexer
* @param ProductAttributeRepositoryInterface $productAttributeRepository
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param FilterBuilder $filterBuilder
*/
public function __construct(
Configurable $configurable,
ActionInterface $productIndexer
ActionInterface $productIndexer,
ProductAttributeRepositoryInterface $productAttributeRepository = null,
SearchCriteriaBuilder $searchCriteriaBuilder = null,
FilterBuilder $filterBuilder = null
) {
$this->configurable = $configurable;
$this->productIndexer = $productIndexer;
$this->productAttributeRepository = $productAttributeRepository ?: ObjectManager::getInstance()
->get(ProductAttributeRepositoryInterface::class);
$this->searchCriteriaBuilder = $searchCriteriaBuilder ?: ObjectManager::getInstance()
->get(SearchCriteriaBuilder::class);
$this->filterBuilder = $filterBuilder ?: ObjectManager::getInstance()
->get(FilterBuilder::class);
}

/**
Expand All @@ -41,6 +78,7 @@ public function __construct(
* @param \Magento\Catalog\Model\ResourceModel\Product $subject
* @param \Magento\Framework\DataObject $object
* @return void
* @throws \Magento\Framework\Exception\NoSuchEntityException
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
Expand All @@ -51,6 +89,39 @@ public function beforeSave(
/** @var \Magento\Catalog\Model\Product $object */
if ($object->getTypeId() == Configurable::TYPE_CODE) {
$object->getTypeInstance()->getSetAttributes($object);
$this->resetConfigurableOptionsData($object);
}
}

/**
* Set null for configurable options attribute of configurable product
*
* @param \Magento\Catalog\Model\Product $object
* @return void
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function resetConfigurableOptionsData($object)
{
$extensionAttribute = $object->getExtensionAttributes();
if ($extensionAttribute && $extensionAttribute->getConfigurableProductOptions()) {
$attributeIds = [];
/** @var OptionInterface $option */
foreach ($extensionAttribute->getConfigurableProductOptions() as $option) {
$attributeIds[] = $option->getAttributeId();
}

$filter = $this->filterBuilder
->setField(ProductAttributeInterface::ATTRIBUTE_ID)
->setConditionType('in')
->setValue($attributeIds)
->create();
$this->searchCriteriaBuilder->addFilters([$filter]);
$searchCriteria = $this->searchCriteriaBuilder->create();
$optionAttributes = $this->productAttributeRepository->getList($searchCriteria)->getItems();

foreach ($optionAttributes as $optionAttribute) {
$object->setData($optionAttribute->getAttributeCode(), null);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminAddOptionsToAttributeWithDefaultLayeredNavigationActionGroup">
<annotations>
<description>Adds 3 provided Options to a new Attribute on the Configurable Product creation/edit page. Selected default first option. Set "Use in Layered Navigation" to "Yes".</description>
</annotations>
<arguments>
<argument name="label" defaultValue="colorProductAttribute" />
<argument name="option1" defaultValue="colorProductAttribute1"/>
<argument name="option2" defaultValue="colorProductAttribute2"/>
<argument name="option3" defaultValue="colorProductAttribute3"/>
</arguments>

<click selector="{{AdminProductFormConfigurationsSection.createConfigurations}}" stepKey="clickOnCreateConfigurations"/>
<click selector="{{AdminCreateProductConfigurationsPanel.createNewAttribute}}" stepKey="clickOnNewAttribute"/>
<waitForPageLoad stepKey="waitForIFrame"/>
<switchToIFrame selector="{{AdminNewAttributePanel.newAttributeIFrame}}" stepKey="switchToNewAttributeIFrame"/>
<fillField selector="{{AdminNewAttributePanel.defaultLabel}}" userInput="{{label.default_label}}" stepKey="fillDefaultLabel"/>

<!--Add option 1 to attribute-->
<click selector="{{AdminNewAttributePanel.addOption}}" stepKey="clickAddOption1"/>
<waitForElementVisible selector="{{AdminNewAttributePanel.isDefault('1')}}" time="30" stepKey="waitForOptionRow1" after="clickAddOption1"/>
<fillField selector="{{AdminNewAttributePanel.optionAdminValue('0')}}" userInput="{{option1.name}}" stepKey="fillAdminLabel1" after="waitForOptionRow1"/>
<click selector="{{AdminNewAttributePanel.isDefault('1')}}" stepKey="selectDefault" after="fillAdminLabel1"/>

<!--Add option 2 to attribute-->
<click selector="{{AdminNewAttributePanel.addOption}}" stepKey="clickAddOption2" after="selectDefault"/>
<waitForElementVisible selector="{{AdminNewAttributePanel.isDefault('2')}}" time="30" stepKey="waitForOptionRow2" after="clickAddOption2"/>
<fillField selector="{{AdminNewAttributePanel.optionAdminValue('1')}}" userInput="{{option2.name}}" stepKey="fillAdminLabel2" after="waitForOptionRow2"/>

<!--Add option 3 to attribute-->
<click selector="{{AdminNewAttributePanel.addOption}}" stepKey="clickAddOption3" after="fillAdminLabel2"/>
<waitForElementVisible selector="{{AdminNewAttributePanel.isDefault('3')}}" time="30" stepKey="waitForOptionRow3" after="clickAddOption3"/>
<fillField selector="{{AdminNewAttributePanel.optionAdminValue('2')}}" userInput="{{option3.name}}" stepKey="fillAdminLabel3" after="waitForOptionRow3"/>

<!-- Set Use In Layered Navigation -->
<click selector="{{AdminNewAttributePanel.storefrontPropertiesTab}}" stepKey="goToStorefrontPropertiesTab" after="fillAdminLabel3"/>
<waitForElementVisible selector="{{AdminNewAttributePanel.storefrontPropertiesTitle}}" stepKey="waitTabLoad" after="goToStorefrontPropertiesTab"/>
<selectOption selector="{{AdminNewAttributePanel.useInLayeredNavigation}}" stepKey="selectUseInLayer" userInput="Filterable (with results)" after="waitTabLoad"/>

<!--Save attribute-->
<click selector="{{AdminNewAttributePanel.saveAttribute}}" stepKey="clickSaveAttribute"/>
<waitForPageLoad stepKey="waitForSavingAttribute"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminFillBasicValueConfigurableProductActionGroup">
<annotations>
<description>Goes to the Admin Product grid page. Fill basic value for Configurable Product using the default Product Options.</description>
</annotations>
<arguments>
<argument name="product" defaultValue="_defaultProduct"/>
<argument name="category" defaultValue="_defaultCategory"/>
</arguments>
<amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage"/>
<waitForPageLoad time="30" stepKey="wait1"/>
<click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickOnAddProductToggle"/>
<click selector="{{AdminProductGridActionSection.addConfigurableProduct}}" stepKey="clickOnAddConfigurableProduct"/>
<fillField userInput="{{product.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/>
<fillField userInput="{{product.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/>
<fillField userInput="{{product.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/>
<fillField userInput="{{product.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/>
<searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[{{category.name}}]" stepKey="fillCategory"/>
<selectOption userInput="{{product.visibility}}" selector="{{AdminProductFormSection.visibility}}" stepKey="fillVisibility"/>
<click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/>
<fillField userInput="{{product.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminGotoSelectValueAttributePageActionGroup">
<annotations>
<description>Goes to the select values page from each attribute to include in the product.</description>
</annotations>

<arguments>
<argument name="defaultLabelAttribute" type="string" defaultValue="{{colorProductAttribute.default_label}}"/>
</arguments>

<click selector="{{AdminCreateProductConfigurationsPanel.filters}}" stepKey="clickOnFilters"/>
<fillField selector="{{AdminCreateProductConfigurationsPanel.attributeCode}}" userInput="{{defaultLabelAttribute}}" stepKey="fillFilterAttributeCodeField"/>
<click selector="{{AdminCreateProductConfigurationsPanel.applyFilters}}" stepKey="clickApplyFiltersButton"/>
<click selector="{{AdminCreateProductConfigurationsPanel.firstCheckbox}}" stepKey="clickOnFirstCheckbox"/>
<click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton"/>

</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminSelectValueFromAttributeActionGroup">
<annotations>
<description>Click to check option.</description>
</annotations>

<arguments>
<argument name="option" defaultValue="colorProductAttribute1"/>
</arguments>
<click selector="{{AdminCreateProductConfigurationsPanel.attributeOption(option.name)}}" stepKey="clickOnCreateNewValue2"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminSetQuantityToEachSkusConfigurableProductActionGroup">
<annotations>
<description>Set quantity 1 to all child skus for configurable product. Save a configurable product and confirm.</description>
</annotations>

<click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton2"/>
<click selector="{{AdminCreateProductConfigurationsPanel.applySingleQuantityToEachSkus}}" stepKey="clickOnApplySingleQuantityToEachSku"/>
<fillField selector="{{AdminCreateProductConfigurationsPanel.quantity}}" userInput="1" stepKey="enterAttributeQuantity"/>
<click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton3"/>
<click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton4"/>
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton2"/>
<click selector="{{AdminChooseAffectedAttributeSetPopup.confirm}}" stepKey="clickOnConfirmInPopup"/>
<seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessage"/>
</actionGroup>
</actionGroups>
Loading