Magento 2 - Como adicionar uma coluna personalizada na grade do cliente

7

Estou usando o código abaixo para adicionar uma coluna na grade do cliente em admin.

/app/code/Namespace/Module/view/adminhtml/ui_component/customer_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="magcustomer_customer_approve" class="Namespace\Module\Ui\Component\Listing\Column\Showisapproved">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="editor" xsi:type="string">select</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Is Approved</item>
                    <item name="sortOrder" xsi:type="number">51</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

/app/code/Namespace/Module/Ui/Component/Listing/Column/Showisapproved.php

<?php
namespace Namespace\Module\Ui\Component\Listing\Column;

use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;

class Showisapproved extends Column
{
    /**
     * 
     * @param ContextInterface   $context           
     * @param UiComponentFactory $uiComponentFactory   
     * @param array              $components        
     * @param array              $data              
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $item[$this->getData('name')] = 0;//Value which you want to display
            }
        }
        return $dataSource;
    }
}

magcustomer_customer_approve é o atributo do cliente criado usando o código abaixo.

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {

        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);

        $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        /** @var $attributeSet AttributeSet */
        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->addAttribute(Customer::ENTITY, 'magcustomer_customer_approve', [
            'type' => 'int',
            'label' => 'Is Approved',
            'input' => 'select',
            'required' => false,
            'visible' => true,
            'user_defined' => true,
            'sort_order' => 1001,
            'position' => 1001,
            'system' => 0,
            'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
            'adminhtml_only'=>1,
            'default'=>0
        ]);

        $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'magcustomer_customer_approve')
        ->addData([
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId,
            'used_in_forms' => ['adminhtml_customer'],
        ]);

        $attribute->save();


    }
  1. Se eu não usar o Magecoder \ Magcustomer \ Ui \ Component \ Listing \ Column \ Show é aprovado , a coluna personalizada ficará em branco.

insira a descrição da imagem aqui

Mas, se eu usar, preciso buscar o modelo do cliente na função prepareDataSource porque a variável $ dataSource não contém o valor da coluna personalizada. É possível mostrar valores sem buscar dados novamente?

  1. Além disso, quando o filtro é usado, um erro SQL é gerado.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'magcustomer_customer_approve' in 'where clause'
, query was: SELECT COUNT(*) FROM `customer_grid_flat` AS `main_table` WHERE (`magcustomer_customer_approve
` = '1') AND (`magcustomer_customer_approve` = '1') AND (`magcustomer_customer_approve` = '1') AND (
`magcustomer_customer_approve` = '1') AND (`magcustomer_customer_approve` = '1')
piyush_systematix
fonte
dê uma olhada aqui magento.stackexchange.com/questions/126534/... pode ser isso pode ajudar
Ekta Puri

Respostas:

5

Solução para Magento 2.1

  • Adicione o atributo ao índice da grade do cliente:

    etc/indexer.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
        <indexer id="customer_grid">
            <fieldset name="customer">
                <field name="magcustomer_customer_approve" xsi:type="filterable" dataType="int"/>
            </fieldset>
        </indexer>
    </config>

    Observe que os elementos "indexador" e "fieldset" possuem apenas os atributos "id" e "name", respectivamente. A estrutura é mesclada no indexador existente.

  • Marque o atributo como "usado na grade"

    No instalador:

            'is_used_in_grid' => true,

    caso contrário, você receberá outro erro SQL durante a indexação, porque o indexador procura a coluna na customer_entitytabela principal:

    SQLSTATE [42S22]: Coluna não encontrada: 1054 Coluna desconhecida 'e.magcustomer_customer_approve' na 'lista de campos'

Fabian Schmengler
fonte
qual é a solução para o magento 2.2? mesmo?
Amit Bera
Eu tenho um atributo varchar no campo do cliente, neste método não há erro, mas a classificação tem algum problema.
Naveenbos
5

Finalmente consegui a solução: precisamos criar o arquivo indexer.xml na pasta / etc / di .

O principal é view_id em view_id, precisamos passar " coloumn_name ", que precisamos mostrar na grade.

Por exemplo, aqui eu preciso exibir o apelido para que eu tenha passado " apelido " em view_id .

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
    <indexer id="customer_grid" view_id="nickname" class="Magento\Framework\Indexer\Action\Entity" primary="customer">
        <fieldset name="customer" source="Magento\Customer\Model\ResourceModel\Customer\Collection"
                  provider="Magento\Customer\Model\Indexer\AttributeProvider">
            <field name="nickname" xsi:type="filterable" dataType="varchar"/>
        </fieldset>
    </indexer>
</config>

Funciona no Magento 2.1.4

Manthan Dave
fonte
A solução funciona bem, mas durante a exportação, obtendo erro.
Chirag Patel
@ChiragPatel - Sim, isso está correto, porque eu não alterei / contornei nenhuma funcionalidade de exportação, portanto, você precisa substituir a funcionalidade de exportação de pedidos neste módulo personalizado e precisa contornar o mesmo problema
Manthan Dave
Obrigado, se você tem alguma idéia ou exemplo de como substituir a funcionalidade de exportação, compartilhe.
Chirag Patel
1

Adicione uma coluna personalizada na grade do cliente usando o caminho abaixo.

==> crie o primeiro módulo e siga a etapa abaixo ==> Agora nos acostumamos com o plug-in, por favor crie o arquivo no local abaixo.

Fornecedor / Módulo / etc / 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\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <plugin name="grid_customs_column" type="Vendor\Module\Plugin\GridCustomerJoinCollection" sortOrder="5" />
    </type>
</config>

==> Agora crie o plug-in para ingressar na tabela com sua coleção e retorne a coleção e crie o arquivo no local abaixo

Fornecedor / Módulo / Plugin / GridCustomerJoinCollection.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Plugin;

use Magento\Framework\Data\Collection;
use Magento\Framework\ObjectManagerInterface;

/**
 * Class CollectionPool
 */
class GridCustomerJoinCollection
{

    public static $table = 'customer_grid_flat';
    public static $leftJoinTable = 'sales_order'; // My custom table
    /**
     * Get report collection
     *
     * @param string $requestName
     * @return Collection
     * @throws \Exception
     */
    public function afterGetReport(
     \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $subject,
     $collection,
     $requestName
 ) {
     if($requestName == 'customer_listing_data_source')
     {
         if ($collection->getMainTable() === $collection->getConnection()->getTableName(self::$table)) {

            $leftJoinTableName = $collection->getConnection()->getTableName(self::$leftJoinTable);

            $collection
                ->getSelect()
                ->joinLeft(
                    ['co'=>$leftJoinTableName],
                    "co.customer_id = main_table.entity_id",
                    [
                        'customer_id' => 'co.customer_id',
                        'custom_filed'=> 'co.custom_filed'
                    ]
                );
                /* return data with left join customer_id from sales_order and custom_filed*/

            $where = $collection->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE);

            $collection->getSelect()->setPart(\Magento\Framework\DB\Select::WHERE, $where)->group('main_table.entity_id');;

            /*echo $collection->getSelect()->__toString();die;*/

        }

     }
     return $collection;
 }
}

==> Agora crie a pasta e o arquivo abaixo e adicione as colunas em Fornecedor / Módulo / view / adminhtml / ui_component / customer_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
   <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
       <column name="custom_filed">
           <argument name="data" xsi:type="array">
               <item name="config" xsi:type="array">
                   <item name="sortOrder" xsi:type="number">999</item>
                   <item name="filter" xsi:type="string">text</item>
                   <item name="label" translate="true" xsi:type="string">Customer Custom Column</item>
               </item>
           </argument>
       </column>
   </columns>
</listing>

===> Agora, por favor, chek e confirme .

Rasik Miyani
fonte
0

Sim, você precisa adicionar o seguinte código. Etapa 1: Criar arquivo your_module / etc / indexer.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
<indexer id="customer_grid" view_id="dummy" class="Magento\Framework\Indexer\Action\Entity" primary="customer">
    <fieldset name="customer" source="Magento\Customer\Model\ResourceModel\Customer\Collection" provider="Magento\Customer\Model\Indexer\AttributeProvider">
        <field name="<your_attribute>" xsi:type="filterable" dataType="int"/>
    </fieldset>
</indexer>

Agora você precisa abaixo do comando:

comando de execução: php bin / magento indexer: reindex

boa sorte

Gaurav Mehta
fonte
0

Eu tentei acima da solução, mas não está funcionando

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
<indexer id="customer_grid" view_id="dummy" class="Magento\Framework\Indexer\Action\Entity" primary="customer">
    <fieldset name="customer" source="Magento\Customer\Model\ResourceModel\Customer\Collection" provider="Magento\Customer\Model\Indexer\AttributeProvider">
        <field name="is_approved" xsi:type="filterable" dataType="int"/>
    </fieldset>
</indexer>

Mas não está funcionando. Primeiro, minha pergunta é como podemos substituir indexer.xml?

Depois que eu verifiquei a solução que você fonte Magento\Customer\Model\ResourceModel\Customer\Collectione no Magento_Customer/etc/indexer.xmluso Magento\Customer\Model\Indexer\Sourcee isso mostra erro durante a indexação.

Acho que não precisamos pensar apenas em aplicar o atributo do cliente

$customerSetup->addAttribute(Customer::ENTITY, 'is_approved', [
            'type' => 'int',
            'label' => 'Approved',
            'input' => 'select',
            'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
            'value' => 0,
            'default' => 0,
            'required' => false,
            'visible' => false,
            'user_defined' => true,
            'sort_order' => 90,
            'position' => 90,
            'system' => false,
            'is_used_in_grid' => true,
            'is_visible_in_grid' => true,
            'is_filterable_in_grid' => true,
            'is_searchable_in_grid' => true,
        ]);

Então precisa 'is_used_in_grid' => true e em di.xml adicione

<preference for="Magento\Customer\Model\Indexer\Source" type="Magento\Customer\Model\ResourceModel\Customer\Collection" />

Ou

<virtualType name="Magento\Customer\Model\Indexer\Source" type="Magento\Customer\Model\ResourceModel\Customer\Collection" />

E está funcionando

Prince Yadav
fonte