Comment joindre la collection de grille de commande à une table personnalisée dans Magento2?

12

J'essaie d'ajouter une nouvelle colonne à la grille de commande dans Magento 2.0. Donc, je dois faire la jonction pour commander la collecte de la grille. Comment puis-je atteindre cet objectif ? Parce que, dans magento2, la grille utilise un composant d'interface utilisateur.

Pradeep Kumar
la source

Réponses:

12

Magento 2 ajoute des colonnes personnalisées à la grille de commande client,

Joindre

Magento \ Ventes \ Commande \ Grille \ Collection

à n'importe quelle table, l'utilisation du plugin serait la meilleure option car cela ne dépend pas des réécritures et rend le code plus léger.

Créez le plugin dans etc / di.xml de votre module

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <plugin name="sales_order_additional_columns" type="Vendor\ModuleName\Plugins\AddColumnsSalesOrderGridCollection" sortOrder="100" disabled="false" />
</type>

Donc, nous interceptons

Magento \ Framework \ View \ Element \ UiComponent \ DataProvider \ CollectionFactory

parce que si vous regardez la

Magento \ Sales \ etc \ di.xml

tu verrais

Magento \ Ventes \ Commande \ Grille \ Collection

a été injecté dans

Magento \ Framework \ View \ Element \ UiComponent \ DataProvider \ CollectionFactory

Créez un dossier de plugin et une classe de plugin dans votre module

<?php namespace Vendor\ModuleName\Plugins;

use Magento\Framework\Message\ManagerInterface as MessageManager;
use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as SalesOrderGridCollection;

class AddColumnsSalesOrderGridCollection
{
    private $messageManager;
    private $collection;

    public function __construct(MessageManager $messageManager,
        SalesOrderGridCollection $collection
    ) {

        $this->messageManager = $messageManager;
        $this->collection = $collection;
    }

    public function aroundGetReport(
        \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $subject,
        \Closure $proceed,
        $requestName
    ) {
        $result = $proceed($requestName);
        if ($requestName == 'sales_order_grid_data_source') {
            if ($result instanceof $this->collection
            ) {
                $select = $this->collection->getSelect();
                $select->join(
                    ["soi" => "sales_order_item"],
                    'main_table.entity_id = soi.order_id AND soi.product_type="simple"',
                    array('weight', 'product_type')
                )
                    ->distinct();

                $select->join(
                    ["soa" => "sales_order_address"],
                    'main_table.entity_id = soa.parent_id AND soa.address_type="shipping"',
                    array('email', 'country_id', 'postcode', 'city', 'telephone')
                )
                    ->distinct();
            }

        }
        return $this->collection;
    }
}

Ici, nous observons autour de l' événement de la méthode getReport ().

Copie

fournisseur / magento / module-sales / view / adminhtml / ui_component / sales_order_grid.xml

à la portée de votre module

Fournisseur / ModuleName / view / adminhtml / ui_component / sales_order_grid.xml

Supprimez tout le contenu de votre sales_order_grid.xml copié car nous ne voulons pas remplacer tout le contenu.

Entrez le code suivant dans sales_order_grid.xml de votre module

    <?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="sales_order_columns">

        <!-- sales_order_item weight -->
        <column name="weight">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Weight</item>
                    <item name="sortOrder" xsi:type="number">222</item>
                    <item name="align" xsi:type="string">right</item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

        <!-- sales_order_item product_type-->
        <column name="product_type">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Vendor\ModuleName\Ui\Component\Listing\Column\ProductTypes</item>
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Product Type</item>
                    <item name="sortOrder" xsi:type="number">232</item>
                    <item name="align" xsi:type="string">right</item>
                    <!--<item name="filter" 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="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

        <!-- sales_order_address country_id -->
        <column name="country_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Country ID</item>
                    <item name="sortOrder" xsi:type="number">242</item>
                    <item name="align" xsi:type="string">right</item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

        <!-- sales_order_address post_code -->
        <column name="postcode">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Postcode</item>
                    <item name="sortOrder" xsi:type="number">252</item>
                    <item name="align" xsi:type="string">right</item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

        <!-- sales_order_address city -->
        <column name="city">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">City</item>
                    <item name="sortOrder" xsi:type="number">252</item>
                    <item name="align" xsi:type="string">right</item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

        <!-- sales_order_address telephone -->
        <column name="telephone">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Telephone</item>
                    <item name="sortOrder" xsi:type="number">252</item>
                    <item name="align" xsi:type="string">right</item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <!--<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>-->
                </item>
            </argument>
        </column>

    </columns>

</listing>

Maintenant, supprimez le cache du dossier var / cache ou actualisez votre cache. Vous pourrez voir vos colonnes ajoutées dans la grille de commande client.

Asrar
la source
Merci beaucoup pour celui-là, mon seul problème (avec Magento 2.2.0) était que je devais ajouter un préfixe de table sur les lignes ["soi" => "sales_order_item"]et ["soa" => "sales_order_address"].
David
Je pensais que cela fonctionnait bien, mais il semble également jouer avec la grille de facturation .. Avec le module activé, l'ID et le statut de la commande sont étrangement vides dans la grille de facturation .. Une idée de ce qui pourrait ne pas bien se passer?
David
Merci pour ces informations, cela m'a aidé à ajouter le nom de l'entreprise. Mais comment afficher les informations de facturation et d'expédition au lieu de simplement envoyer? Je peux afficher 1 ou l'autre mais je n'arrive pas à renommer «société» pour dire «billing_company» et «shipping_company» afin d'utiliser dans sales_order_grid.xml
RLTcode
1
Obtenir des erreurs dans les grilles de page CMS, de bloc CMS, de client et de Creditmemo lors de l'utilisation de la classe de plug-in, veuillez me faire savoir s'il existe une autre solution pour modifier la collection de grilles.
Vishal
Quelles erreurs pouvez-vous voir pour la grille de facturation, etc.?
Asrar
9

Lorsque vous regardez \Magento\Framework\Data\Collection\AbstractDbmagento2 lui-même, fournissez une opération de crochet pour votre collection.

protected function _renderFilters()
{
    if ($this->_isFiltersRendered) {
        return $this;
    }

    $this->_renderFiltersBefore(); // Hook for operations before rendering filters

    ....................
}

Donc, ce que vous devez faire en ajoutant simplement dans votre collection [ NAMESPACE\MODULENAME\Model\ResourceModel\YOUR_CLASSNAME\Grid\Collection]

protected function _renderFiltersBefore() {
    $joinTable = $this->getTable('catalog_product_entity_varchar');
    $this->getSelect()->join($joinTable.' as cpev','main_table.entity_id = cpev.entity_id', array('*'));
    parent::_renderFiltersBefore();
}
Keyur Shah
la source
j'ai besoin de montrer mon champ de table personnalisé dans la grille de commande dans ce cas ho pour le montrer?
Pradeep Kumar
@Keyur Shah Merci, ça m'aide beaucoup.
Rohit Goel
Heureux d'entendre que cela vous aide :) @RohitGoel Keep aide l'autre membre de la communauté
Keyur Shah
Bien sûr :) @KeyurShah j'aime aider la communauté .Je crée une grille sans composant d'interface utilisateur, pouvez-vous s'il vous plaît me dire comment puis-je ajouter une fonction d'exportation à cela.
Rohit Goel
1
Au lieu de _renderFiltersBefore, vous pouvez également remplacer / étendre _initSelect.
Jānis Elmeris
3

J'ai créé une grille d'administration qui a joint deux tables personnalisées. vous ne pouvez pas le faire en utilisant le type virtuel est di.xml, vous devez donc suivre ces étapes et mettre à jour votre

etc / di.xml,

Model / Resource / Modulename / Collection.php ajouter une jointure dans ce fichier,

Model / Resource / Modulename / Grid / Collection.php,

DANS votre etc / di.xml

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="namespace_modulename_listing_data_source" xsi:type="string">Namespace\Modulename\Model\Resource\Modulename\Grid\Collection</item>
            </argument>
        </arguments>
</type>
<type name="Namespace\Modulename\Model\Resource\Modulename\Grid\Collection">
    <arguments>
        <argument name="mainTable" xsi:type="string">tablename</argument>
        <argument name="eventPrefix" xsi:type="string">namespace_modulename_grid_collection</argument>
        <argument name="eventObject" xsi:type="string">namespace_grid_collection</argument>
        <argument name="resourceModel" xsi:type="string">Namespace\Modulename\Model\Resource\Modulename</argument>
    </arguments>
</type>

DANS votre modèle / ressource / nom de module / collection.php

<?php
namespace Namespace\Modulename\Model\Resource\Modulename;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    /**
     * Define model & resource model
     */
    const YOUR_TABLE = 'tablename';

    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
    ) {
        $this->_init(
            'Namespace\Modulename\Model\Modulename',
            'Namespace\Modulename\Model\Resource\Modulename'
        );
        parent::__construct(
            $entityFactory, $logger, $fetchStrategy, $eventManager, $connection,
            $resource
        );
        $this->storeManager = $storeManager;
    }
    protected function _initSelect()
    {
        parent::_initSelect();

        $this->getSelect()->joinLeft(
                ['secondTable' => $this->getTable('tablename')],
                'main_table.columnname = secondTable.columnname',
                ['columnname1','columnname2','columnname3']
            );
    }
}
?>

DANS votre modèle / ressource / nom de module / grille / collection.php

<?php
namespace Namespace\Modulename\Model\Resource\Modulename\Grid;

use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\Search\AggregationInterface;
use Namespace\Modulename\Model\Resource\Modulename\Collection as ModulenameCollection;

/**
 * Class Collection
 * Collection for displaying grid
 */
class Collection extends ModulenameCollection implements SearchResultInterface
{
    /**
     * Resource initialization
     * @return $this
     */
   public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
        $connection = null,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
    ) {
        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $storeManager,
            $connection,
            $resource
        );
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }

    /**
     * @return AggregationInterface
     */
    public function getAggregations()
    {
        return $this->aggregations;
    }

    /**
     * @param AggregationInterface $aggregations
     *
     * @return $this
     */
    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }


    /**
     * Get search criteria.
     *
     * @return \Magento\Framework\Api\SearchCriteriaInterface|null
     */
    public function getSearchCriteria()
    {
        return null;
    }

    /**
     * Set search criteria.
     *
     * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
     *
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setSearchCriteria(
        \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null
    ) {
        return $this;
    }

    /**
     * Get total count.
     *
     * @return int
     */
    public function getTotalCount()
    {
        return $this->getSize();
    }

    /**
     * Set total count.
     *
     * @param int $totalCount
     *
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setTotalCount($totalCount)
    {
        return $this;
    }

    /**
     * Set items list.
     *
     * @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
     *
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setItems(array $items = null)
    {
        return $this;
    }
}

?>
Ekta Puri
la source
Cela ne fonctionnait pas
saravanavelu
fonctionne bien pour moi .. quelle est l'erreur pour vous?
Ekta Puri
Erreur Interne du Serveur. pouvez-vous vérifier et reformater votre code
saravanavelu
puis-je voir vos fichiers quelque part? parce que cela a fonctionné parfaitement pour moi, je vais encore essayer de reformater
Ekta Puri
etc / di.xml Model / Resource / Modulename / Collection il n'y a rien de tel dans di.xml
saravanavelu
2

Dans la définition de l'interface utilisateur xml, il existe un nœud de source de données similaire à celui-ci

<dataSource name="listing_name_data_source">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">UniqueNameGridDataProvider</argument>
        <argument name="name" xsi:type="string">listing_name_data_source</argument>

listing_name_data_sourcepeut être défini dans votre di.xmlou simplement référencer une classe directement. La classe elle-même doit s'étendre Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactoryet avoir comme collectionsargument votre collection personnalisée. Dans la _initSelect()méthode de cette classe de collection, vous pouvez joindre vos tables.

Kristof chez Fooman
la source
1
dans sales di.xml, il montre Magento \ Sales \ Model \ ResourceModel \ Order \ Grid \ Collection où ce fichier ne se ferme pas, dans ce cas, nous ne pouvons pas réécrire le plugin ou l'événement, o comment le faire, veuillez vérifier les ventes et commander code de collecte de la grille, j'espère que cela effacera plus
Pradeep Kumar
Il est défini ici github.com/magento/magento2/blob/develop/app/code/Magento/Sales/… et est un type virtuel s'étendant de Magento \ Framework \ View \ Element \ UiComponent \ DataProvider \ SearchResult
Kristof at Fooman
puis ho pour ajouter join à ce class.can vous donnez un exemple de code
Pradeep Kumar
ici comme exemple de jointure github.com/magento/magento2/blob/develop/app/code/Magento/… tel qu'utilisé dans cette initSelect github.com/magento/magento2/blob/develop/app/code/Magento/…
Kristof au Fooman
@KristofatFooman vous donnez un mauvais exemple car c'est un type virtuel, pourriez-vous donner un exemple de collection de grilles défini comme type virtuel?
LucScu
2

Pour toute personne ayant des problèmes avec la solution @Asrar , procédez comme suit :

public function aroundGetReport(
    \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $subject,
    \Closure $proceed,
    $requestName
) {
    $result = $proceed($requestName);
    if ($requestName == 'sales_order_grid_data_source_firsty') {
        if ($result instanceof $this->collection
        ) {
            $select = $this->collection->getSelect();
            $select->join(
                ["soi" => "sales_order_item"],
                'main_table.entity_id = soi.order_id',
                array('sku', 'name','item_id')
            )
                ->distinct();
            return $this->collection;
        }

    }
    return $result;
}

Cela semble fonctionner correctement pour moi.

vbak
la source