Internet Marketing

Disabled Magento Customer Group Pricing for Store Scope

If you’ve ever Googled “disabled magento advanced pricing customer group price website field” or “disabled magento customer group price for store reach”, this blog post is for you. The lack of results prompted me to look under the hood and, therefore, write about my findings.

The History Behind Google Search

Why did I Google this? On one of our projects (two websites, each with a store view), I was setting up customer group pricing for a small subset of products. Pricing by customer group works much like tiered pricing; the only difference is that customer group prices have a quantity of 1.

When setting prices, I didn’t pay much attention to scope since the customer group pricing form contains elements for the website. The advanced pricing mode (where the customer group price is set) looked like this:

Everything looked and worked fine, both on the admin side and the front end. I informed the client that I had priced the client group and they were ready to test the staging, along with other agreed upon improvements. The customer responded with a screenshot similar to this, with the following message: addition Customer group pricing is disabled for website scope.

Checking with default Magento installation

At first I thought it was a bug because it worked on Magento by default with sample data. I checked our 3rd party modules and extensions that have something to do with rendering elements on the admin product edit page. At that time, I was unaware of the main prerequisite for this scenario:

Catalogue/price/scope configuration is defined on the website

Keep in mind that the default Magento installation has this configuration set to global.

Setting scope on tier_price attribute

A few hours of debugging later, this is what I found when inspecting the admin loading the product modification form. This is the story of the tier_price product attribute and (non)global scope which looks like this:

(…) MagentoCatalogModelProductAttributeBackendPrice->setAttribute() MagentoCatalogModelProductAttributeBackendPrice->setScope() public function setScope($attribute) // $attribute is tier_price { // checks catalog/price/scope configuration, in our case scope is ‘ website’ if ($this->_helper->isPriceGlobal()) { $attribute->setIsGlobal(ScopedAttributeInterface::SCOPE_GLOBAL); } else { // scope of attribute is set to ‘website’ $attribute->setIsGlobal(ScopedAttributeInterface::SCOPE_WEBSITE); } return $this; } (…)

Later, when the product attributes are prepared for rendering the form in

MagentoCatalogUiDataProviderProductFormModifierEav

the tier_price attribute is (among others) checked for its scope, is it global or not.

Detective mode activated: looking for a “disabled” property culprit

If catalog/price/scope is set to global (and therefore the scope of the tier_price attribute), some of the code in which the disabled property is set is never executed. This is why the “Add” button on the Customer Group Price form was not disabled when I was checking the problem reported on the default installation. This is the part of the product form configuration responsible for the customer group price container:

MagentoCatalogUiDataProviderProductFormProductDataProvider->getMeta() // returns $meta array with product form configuration // part of $meta array which is why this debug looks like this // (printed in JSON format for more readability easy) { “arguments”: { “data”: { “config”: { “formElement”: “container”, “componentType”: “container”, “breakLine”: false, “label”: “Tier Price”, “required”: “0”, “sortOrder”: 40 } } }, “children”: { “tier_price”: { “arguments”: { “data”: { “config”: { “dataType”: “text”, “formElement”: “input”, “visible”: “1”, “required”: “0”, “notice”: null, “default”: null, “label”: “Tier Price”, “code”: “tier_price”, “source”: “advanced pricing”, “scopeLabel”: “[WEBSITE]”, “globalScope”: false, “sortOrder”: 40, “service”: { “template”: “ui/form/element/helper/service” }, “componentType”: “field”, “disabled”: true – > causes the “I’m disabled” meme } } } } } }

Who and where says that the tier_price element is disabled? Let’s take a look at the stack trace and the methods responsible (pay attention to the comments!):

(…) // the group of interest is advanced pricing {MagentoEavModelEntityAttributeGroup} MagentoCatalogUiDataProviderProductFormModifierEav->modifyMeta() // here we “catch” the tier_price attribute MagentoCatalogUiDataProviderProductFormModifierEav->getAttributesMeta() MagentoCatalogUiDataProviderProductFormModifierEav->addContainerChildren() // attribute_code = tier_price, $groupCode = advanced pricing, $sortOrder = 4 MagentoCatalogUiDataProviderProductFormModifierEav->getContainerChildren(ProductAttributeInterface $attribute, $groupCode, $sortOrder) MagentoCatalogUiDataProviderProductFormModifierEav->setupAttributeMeta() MagentoCatalogUiDataProviderProductFormModifierEav->addUseDefaultValueCheckbox() private function addUseDefaultValueCheckbox(ProductAttributeInterface $attribute, array $meta) { /** * $canDisplayService = false if catalog/price/scope is global * so the ‘disabled’ property is never set in this case */ $canDisplayService = $this->canDisplayUseDefault($attribute); if ($canDisplayService) { $meta[‘arguments’][‘data’][‘config’][‘service’] = [
‘template’ => ‘ui/form/element/helper/service’,
]; /** * This results in !false = true, so the ‘disabled’ property for the tier_price element in the * Customer Group Price form is set to true. * Answer to the question “Who and where says that the tier_price element is disabled?” » It’s HERE! */ $meta[‘arguments’][‘data’][‘config’][‘disabled’] = !$this->scopeOverriddenValue->containsValue( MagentoCatalogApiDataProductInterface::class, $this->locator->getProduct(), $attribute->getAttributeCode(), $this->locator->getStore()->getId() ); } return $meta; } ————————————————- ————————————————– ——– private function canDisplayUseDefault (ProductAttributeInterface $attribute) { $attributeCode = $attribute->getAttributeCode(); /** @var Product $product */ $product = $this->locator->getProduct(); if ($product->isLockedAttribute($attributeCode)) { return false; } if (isset($this->canDisplayUseDefault[$attributeCode])) { return $this->canDisplayUseDefault[$attributeCode]; } // $attribute is tier_price, and its scope depends on catalog/price/scope return $this->canDisplayUseDefault[$attributeCode] = ( // scope ‘website’ != scope ‘global’ ($attribute->getScope() != ProductAttributeInterface::SCOPE_GLOBAL_TEXT) && $product && $product->getId() && $product->getStoreId() ) ; }

Workaround for enabling the Add button

However, since the customer explicitly requested to be able to change the customer group price as part of the store view, I prepared a workaround in the form of a plugin. Create a new module (mine is Inchoo_CustomerGroupPrice) and add the code below to your etc/di.xml file.

AdvancedPricingPlugin checks the $meta array which contains the necessary information about the tier_price form element and forces activation of this element. Here is the implementation:

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button

Adblock Detected

Please consider supporting us by disabling your ad blocker