Magento 2: How to add a custom attribute column to the child products grid view in configurable product in backend
-
15-04-2021 - |
Question
I need to add a custom attribute column to the child products grid view in configurable products in backend.
My initial findings: Added 2 custom attributes(similar to the sku) to the products and give corresponding values to that.
By editing the below file:
vendor/magento/module-configurable-product/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php
//Added 2 line code to the below function, able to add 2 columns in the grid.
protected function getRows()
{
'oem_sku_container' => $this->getColumn('oem_sku', __('OEM_SKU')),
'internal_sku_container' => $this->getColumn('internal_sku', __('INTERNAL_SKU')),
}
But I didn't get any values of that custom attributes in the column. There is any way to get the value?
Solution
Step 1: in Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\ConfigurablePane page,on
protected function getRows()
{
}
remove 'sku_container' => $this->getColumn('sku', __('SKU')),
and add
'oem_sku_container' => $this->getColumn('oem_sku', __('OEMSKU')),
'internal_sku_container' => $this->getColumn('internal_sku', __('INTERNALSKU')),
Step:2
In this page, Magento\Ui\Component\Form
on
public function getDataSourceData()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');//get current product
$type_id = $product->getTypeId();
if($type_id == 'configurable'){
foreach ($data as $key_id => $data_value) {
if (array_key_exists('configurable-matrix', $data_value)) {
foreach ($data_value['configurable-matrix'] as $configurableMatrixKey => $configurableMatrix)
{
$sam_pid = $configurableMatrix['id'];
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productObj = $objectManager->get('Magento\Catalog\Model\Product')
->load($sam_pid);
$product_oem_sku = $productObj->getOemSku();
$product_internal_sku = $productObj->getInternalSku();
$data[$key_id]['configurable-matrix'][$configurableMatrixKey]['oem_sku'] = $product_oem_sku;
$data[$key_id]['configurable-matrix'][$configurableMatrixKey]['internal_sku'] = $product_internal_sku;
}
}
}
}
}
OTHER TIPS
Step 1: create di.xml @ app/code/ABC/XYZ/etc/adminhtml/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\Composite">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="abcXyzConfigurablePanel" xsi:type="string">ABC\XYZ\Ui\DataProvider\Product\Form\Modifier\AbcXyzAttribute</item>
</argument>
</arguments>
</type>
</config>
Step:2 Create Data Provider Class AbcXyzAttribute.php app/code/ABC/XYZ/Ui/DataProvider/Product/Form/Modifier/AbcXyzAttribute.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace ABC\XYZ\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\ConfigurablePanel;
use Magento\Ui\Component\Form;
/**
* Data provider for Configurable panel.
*/
class AbcXyzAttribute extends AbstractModifier
{
/**
* @var LocatorInterface
*/
private $locator;
/**
* @var ProductRepository
*/
protected $_productRepository;
/**
* @param LocatorInterface $locator
* @param ProductRepository $productRepository
*/
public function __construct(
LocatorInterface $locator,
\Magento\Catalog\Model\ProductRepository $productRepository
) {
$this->locator = $locator;
$this->_productRepository = $productRepository;
}
/**
* @inheritdoc
*/
public function modifyData(array $data)
{
$productId = $this->locator->getProduct()->getId();
if (isset($data[$productId][ConfigurablePanel::CONFIGURABLE_MATRIX])) {
foreach ($data[$productId][ConfigurablePanel::CONFIGURABLE_MATRIX] as $key => $productArray) {
$product = $this->_productRepository->get($productArray[ProductInterface::SKU]);
$abcXyz = $product->getData('abc_xyz');
$data[$productId][ConfigurablePanel::CONFIGURABLE_MATRIX][$key]['abc_xyz'] = $abcXyz;
}
}
return $data;
}
/**
* Composes configuration for "abc_xyz_container" component.
*
* @return array
*/
private function getAbcXyzContainerConfig(): array
{
return [
'arguments' => [
'data' => [
'config' => [
'componentType' => Form\Field::NAME,
'formElement' => Form\Element\Input::NAME,
'component' => 'Magento_Ui/js/form/element/text',
'elementTmpl' => 'ui/dynamic-rows/cells/text',
'dataType' => Form\Element\DataType\Text::NAME,
'dataScope' => 'abc_xyz',
'label' => __('ABC XYZ'),
],
],
],
];
}
/**
* @inheritdoc
*/
public function modifyMeta(array $meta)
{
$meta[ConfigurablePanel::GROUP_CONFIGURABLE]['children']
[ConfigurablePanel::CONFIGURABLE_MATRIX]['children']
['record']['children']['abc_xyz_container'] = $this->getAbcXyzContainerConfig();
return $meta;
}
}
I achieved adding Special Price column by following these steps.
You have to override 3 files by using preference.
Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\ConfigurablePanel
Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\Data\AssociatedProducts
Magento\ConfigurableProduct\Controller\Adminhtml\Product\Initialization\Helper\Plugin\UpdateConfigurations
These are the files you need to override by preference.
STEP 1 i add special price column before Price column##
ConfigurablePanel.php
'special_price_container' => $this->getColumn('special_price', __('Special Price')),
'price_container' => $this->getColumn(
'price',
__('Price'),
[
'imports' => ['addbefore' => '${$.provider}:${$.parentScope}.price_currency'],
'validation' => ['validate-zero-or-greater' => true]
],
['dataScope' => 'price_string']
),
STEP 2 in $productMatrix[] i assign special_price
AssociatedProducts.php
$productMatrix[] = [
'id' => $product->getId(),
'product_link' => '<a href="' . $this->urlBuilder->getUrl(
'catalog/product/edit',
['id' => $product->getId()]
) . '" target="_blank">' . $this->escaper->escapeHtml($product->getName()) . '</a>',
'sku' => $product->getSku(),
'name' => $this->escaper->escapeHtml($product->getName()),
'qty' => $this->getProductStockQty($product),
'price' => $price,
// 'special_price' => $product->getSpecialPrice()?$product->getSpecialPrice():0,
'price_string' => $currency->toCurrency(sprintf("%f", $price)),
'special_price' => $currency->toCurrency(sprintf("%f",($product->getSpecialPrice())?$product->getSpecialPrice():0)),
'price_currency' => $this->locator->getStore()->getBaseCurrency()->getCurrencySymbol(),
'configurable_attribute' => $this->getJsonConfigurableAttributes($variationOptions),
'weight' => $product->getWeight(),
'status' => $product->getStatus(),
'variationKey' => $this->getVariationKey($variationOptions),
'canEdit' => 0,
'newProduct' => 0,
'attributes' => $this->getTextAttributes($variationOptions),
'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(),
];
STEP 3 private $keysPost array i add special_price
UpdateConfigurations.php
private $keysPost = [
'status',
'sku',
'name',
'price',
'special_price',
'configurable_attribute',
'weight',
'media_gallery',
'swatch_image',
'small_image',
'thumbnail',
'image',
];
Works for me, hope it helps someone.