Wie verbinde ich die Bestellraster-Sammlung mit einer benutzerdefinierten Tabelle in Magento2?

12

Ich versuche, eine neue Spalte zum Bestellraster in Magento 2.0 hinzuzufügen. Also muss ich mich anschließen, um die Rastersammlung zu bestellen. Wie kann ich das erreichen? In Magento2 verwendet das Raster eine UI-Komponente.

Pradeep Kumar
quelle

Antworten:

12

Magento 2 fügt dem Kundenauftragsraster benutzerdefinierte Spalten hinzu.

Beitreten

Magento \ Sales \ Order \ Grid \ Collection

Für alle Tabellen ist die Verwendung eines Plugins die beste Option, da dies nicht auf Umschreibungen beruht und den Code schlank macht.

Erstellen Sie das Plugin in der Datei etc / di.xml Ihres Moduls

<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>

Also fangen wir ab

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

denn wenn du dir das anschaust

Magento \ Sales \ etc \ di.xml

du würdest sehen

Magento \ Sales \ Order \ Grid \ Collection

wurde injiziert

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

Erstellen Sie einen Plugin-Ordner und eine Plugin-Klasse in Ihrem Modul

<?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;
    }
}

Hier beobachten wir um Fall getReport () -Methode.

Kopieren

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

zum Umfang Ihres Moduls

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

Löschen Sie alle Inhalte Ihrer kopierten sales_order_grid.xml, da wir nicht alle Inhalte überschreiben möchten.

Geben Sie den folgenden Code in die Datei sales_order_grid.xml Ihres Moduls ein

    <?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>

Löschen Sie jetzt den Cache aus dem Ordner var / cache oder aktualisieren Sie Ihren Cache. Sie können Ihre hinzugefügten Spalten im Kundenauftragsraster sehen.

Asrar
quelle
Vielen Dank dafür. Mein einziges Problem (mit Magento 2.2.0) war, dass ich Tabellenpräfixe in Zeilen ["soi" => "sales_order_item"]und hinzufügen musste ["soa" => "sales_order_address"].
David
Ich dachte, es funktioniert einwandfrei, aber es scheint auch mit dem Rechnungsraster in Konflikt zu geraten. Wenn das Modul aktiviert ist, sind die Bestellnummer und der Status im Rechnungsraster merkwürdig leer. Irgendeine Idee, was falsch sein könnte?
David
Vielen Dank für diese Informationen, es hat mir geholfen, den Firmennamen hinzuzufügen. Aber wie würde ich Rechnungs- und Versandinformationen anzeigen, anstatt nur zu versenden? Ich kann das eine oder das andere anzeigen, aber ich kann anscheinend nicht "Firma" umbenennen, um "Abrechnungsunternehmen" und "Versandunternehmen" zu sagen, um es in sales_order_grid.xml
RLTcode
1
Wenn bei Verwendung der Plugin-Klasse Fehler in CMS-Seiten-, CMS-Block-, Kunden- und Creditmemo-Rastern angezeigt werden, teilen Sie mir bitte eine alternative Lösung zum Ändern der Rastererfassung mit.
Vishal
Welche Fehler können Sie für das Rechnungsraster usw. sehen?
Asrar
9

Wenn Sie sich \Magento\Framework\Data\Collection\AbstractDbmagento2 selbst ansehen, stellen Sie eine Hook-Operation für Ihre Sammlung bereit.

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

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

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

Also, was Sie dazu tun müssen, indem Sie einfach Ihre Sammlung hinzufügen [ 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
quelle
Ich muss mein benutzerdefiniertes Tabellenfeld in der Reihenfolge Raster in diesem Fall anzeigen ho, um es anzuzeigen?
Pradeep Kumar
@ Keyur Shah Danke, es hilft mir sehr.
Rohit Goel
Freut mich zu hören, dass es dir hilft :) @RohitGoel Keep hilft dem anderen Community-Mitglied
Keyur Shah
Sicher :) @KeyurShah Ich liebe es, der Community zu helfen. Ich erstelle ein Raster ohne UI-Komponente. Kannst du mir bitte sagen, wie ich eine Exportfunktion hinzufügen kann?
Rohit Goel
1
Stattdessen _renderFiltersBeforekönnen Sie auch überschreiben / erweitern _initSelect.
Jānis Elmeris
3

Ich habe ein Admin-Raster erstellt, das aus zwei benutzerdefinierten Tabellen besteht. Sie können dies nicht tun, indem Sie den virtuellen Typ di.xml verwenden. Befolgen Sie daher diese Schritte und aktualisieren Sie Ihre

etc / di.xml,

Model / Resource / Modulename / Collection.php Join in dieser Datei hinzufügen,

Modell / Ressource / Modulname / Grid / Collection.php,

IN Ihrer 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>

IN Ihrem Model / Resource / Modulename / 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']
            );
    }
}
?>

IN Ihrem Model / Resource / Modulename / Grid / 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
quelle
Es hat nicht funktioniert
Saravanavelu
funktioniert gut für mich .. was ist der Fehler für Sie?
Ekta Puri
interner Serverfehler. können Sie Ihren Code überprüfen und neu formatieren
saravanavelu
Kann ich Ihre Dateien irgendwo anzeigen? weil dies für mich perfekt funktioniert hat, werde ich trotzdem erneut versuchen, neu zu formatieren
Ekta Puri
etc / di.xml Modell / Ressource / Modulname / Sammlung Es gibt nichts Vergleichbares in di.xml
saravanavelu
2

In der UI-Definition xml gibt es einen ähnlichen Datenquellenknoten

<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>

wo listing_name_data_sourcekann in Ihrer definiert werden di.xmloder nur eine Klasse direkt referenzieren. Die Klasse selbst sollte Ihre benutzerdefinierte Sammlung erweitern Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactoryund als collectionsArgument haben . In der _initSelect()Methode dieser Auflistungsklasse können Sie Ihre Tabellen verbinden.

Kristof bei Fooman
quelle
1
In sales di.xml wird Magento \ Sales \ Model \ ResourceModel \ Order \ Grid \ Collection angezeigt, wo diese Datei selbst nicht beendet wird. In diesem Fall können wir das Plugin oder Ereignis nicht neu schreiben Grid Collection Code, ich hoffe, das wird mehr klären
Pradeep Kumar
Es ist hier definiert: github.com/magento/magento2/blob/develop/app/code/Magento/Sales/… und ist ein virtueller Typ, der sich von Magento \ Framework \ View \ Element \ UiComponent \ DataProvider \ SearchResult
Kristof am 22.
Dann können Sie der Klasse einen Join hinzufügen. Können Sie einen Beispielcode angeben
Pradeep Kumar
@KristofatFooman Sie geben ein falsches Beispiel an, weil es sich um einen virtuellen Typ handelt. Können Sie ein Beispiel für eine als virtueller Typ definierte Rastersammlung angeben?
LucScu
2

Wenn Sie Probleme mit der @ Asrar- Lösung haben, gehen Sie wie folgt vor :

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;
}

Das scheint für mich in Ordnung zu sein.

vbak
quelle