¿Cómo unir la colección de cuadrículas de pedidos a una tabla personalizada en Magento2?

12

Estoy tratando de agregar una nueva columna para ordenar la cuadrícula en Magento 2.0. Entonces, necesito unirme para ordenar la colección de cuadrículas. Cómo puedo conseguir esto ? Porque, en magento2, la cuadrícula usa el componente UI.

Pradeep Kumar
fuente

Respuestas:

12

Magento 2 agrega columnas personalizadas a la cuadrícula de pedidos de ventas,

Unir

Magento \ Sales \ Order \ Grid \ Collection

para cualquier tabla (s), usar el complemento sería la mejor opción ya que esto no se basa en reescrituras y hace que el código sea sencillo.

Cree el complemento en el etc / di.xml de su módulo

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

Entonces, estamos interceptando

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

porque si miras el

Magento \ Sales \ etc \ di.xml

tu verias

Magento \ Sales \ Order \ Grid \ Collection

fue inyectado en

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

Cree una carpeta de complementos y una clase de complemento en su módulo

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

Aquí estamos observando alrededor del evento del método getReport ().

Copiar

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

al alcance de su módulo

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

Elimine todo el contenido de su sales_order_grid.xml copiado ya que no queremos anular todo el contenido.

Ingrese el siguiente código en sales_order_grid.xml de su módulo

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

Ahora, elimine el caché de la carpeta var / cache o actualice su caché. Podrá ver las columnas agregadas en la cuadrícula de pedidos de ventas.

Asrar
fuente
Muchas gracias por eso, mi único problema (con Magento 2.2.0) fue que tuve que agregar el prefijo de tabla en las líneas ["soi" => "sales_order_item"]y ["soa" => "sales_order_address"].
David
Pensé que funcionaba bien, pero también parece alterar la grilla de la factura. Con el módulo habilitado, el ID y el estado del pedido están extrañamente vacíos en la grilla de la factura. ¿Alguna idea de qué podría estar mal?
David
Gracias por esta información, me ha ayudado a agregar el nombre de la empresa. Pero, ¿cómo mostraría la información de facturación y envío en lugar de solo enviar? Puedo mostrar 1 u otro, pero parece que no puedo cambiar el nombre de 'empresa' para decir 'billing_company' y 'shipping_company' para usar en sales_order_grid.xml
RLTcode
1
Obteniendo errores en las cuadrículas Página CMS, Bloque CMS, Cliente y Creditmemo cuando se usa la clase de complemento, Avíseme si hay alguna solución alternativa para modificar la colección de cuadrículas.
Vishal
¿Qué errores puede ver para la cuadrícula de facturas, etc.?
Asrar
9

Cuando miras a \Magento\Framework\Data\Collection\AbstractDbmagento2 en sí mismo, proporciona una operación de gancho para tu colección.

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

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

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

Entonces, lo que necesita hacer esto simplemente agregando en su colección [ 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
fuente
Necesito mostrar el campo de mi tabla personalizada en la cuadrícula de pedidos en este caso, ¿cómo mostrarlo?
Pradeep Kumar
@Keyur Shah Gracias, me ayuda mucho.
Rohit Goel
Me alegra saber que te ayuda :) @RohitGoel Keep ayuda al otro miembro de la comunidad
Keyur Shah
Claro :) @KeyurShah me encanta ayudar a la comunidad. Estoy creando una cuadrícula sin componente ui, ¿pueden decirme cómo puedo agregar una función de exportación en eso?
Rohit Goel
1
En lugar de _renderFiltersBefore, también puede anular / extender _initSelect.
Jānis Elmeris
3

Creé la grilla de administración que tiene una combinación de dos tablas personalizadas. no puede hacer esto usando el tipo virtual es di.xml, por lo que debe seguir estos pasos y actualizar su

etc / di.xml,

Model / Resource / Modulename / Collection.php add join en este archivo,

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

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

EN su Modelo / Recurso / Nombre del módulo / Colección.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']
            );
    }
}
?>

EN su Modelo / Recurso / Nombre del módulo / Cuadrícula / Colección.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
fuente
No estaba funcionando
saravanavelu
funciona bien para mí ... ¿cuál es el error para ti?
Ekta Puri
error de servidor interno. ¿puedes revisar y reformatear tu código?
saravanavelu
¿Puedo ver tus archivos en alguna parte? porque esto funcionó perfectamente para mí, aún así intentaré reformatear de nuevo
Ekta Puri
etc / di.xml Modelo / Recurso / Nombre del módulo / Colección no hay nada como esto en di.xml
saravanavelu
2

En la definición de interfaz de usuario xml hay un nodo de fuente de datos similar a este

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

donde listing_name_data_sourcese puede definir en su di.xmlo simplemente hacer referencia a una clase directamente. La clase en sí debe extenderse Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactoryy tener como collectionsargumento su colección personalizada. En el _initSelect()método de esa clase de colección puedes unir tus tablas.

Kristof en Fooman
fuente
1
en sales di.xml muestra Magento \ Sales \ Model \ ResourceModel \ Order \ Grid \ Collection donde ese archivo no sale, en ese caso no podemos reescribir el complemento o evento, o cómo hacerlo, verifique las ventas y el orden código de recopilación de la cuadrícula, espero que se borre más
Pradeep Kumar
Se define aquí github.com/magento/magento2/blob/develop/app/code/Magento/Sales/… y es un tipo virtual que se extiende desde Magento \ Framework \ View \ Element \ UiComponent \ DataProvider \ SearchResult
Kristof en Fooman el
luego, para agregar unirse a esa clase. ¿Puede dar un código de ejemplo
Pradeep Kumar
aquí como ejemplo para unir github.com/magento/magento2/blob/develop/app/code/Magento/… como se usa en este initSelect github.com/magento/magento2/blob/develop/app/code/Magento/…
Kristof en Fooman el
@ KristofatFooman, da un ejemplo incorrecto porque es un tipo virtual, ¿podría dar un ejemplo para la colección de cuadrícula definida como tipo virtual?
LucScu
2

Para cualquiera que tenga problemas con la solución @Asrar , simplemente haga esto:

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

Esto parece estar funcionando bien para mí.

vbak
fuente