1

We want to add a row count in the order sales view items table.

So that we can see and define the rows, to make it more easy to manage the order. We already tried $block->getItem()->getId() for the class Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn but the problem is that this number is not specific for this order but the Id of all orders.

How can we achieve this?

enter image description here

1 Answer 1

1

There are 2 ways to achieve this:

Lets start by creating a module Vendor_RowCounter, with the required files, and shared files for both solutions:

  1. Add registration.php:
<?php

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Vendor_RowCounter',
    __DIR__
);
  1. Add etc/module.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_RowCounter"/>
</config>
  1. Create a block file, Block/Adminhtml/Items/Column/Row.php:
<?php

declare(strict_types=1);

namespace Vendor\RowCounter\Block\Adminhtml\Items\Column;

use Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn;

class Row extends DefaultColumn
{

    /** @var int */
    private int $row = 1;

    /**
     * @return int
     */
    public function getRow(): int
    {
        return $this->row++;
    }
}
  1. Create template file, view/adminhtml/templates/items/column/row.phtml:
<?php
use Vendor\RowCounter\Block\Adminhtml\Items\Column\Row;
/** @var Row $block */
?>

<?php if ($_item = $block->getItem()): ?>
    <div id="order_item_<?= (int) $_item->getId() ?>_row">
        <?= $block->getRow(); ?>
    </div>
<?php endif; ?>

Solution #1 (By adding a column via sales_order_view.xml):

  1. Create view/adminhtml/layout/sales_order_view.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_items">
            <arguments>
                <argument name="columns" xsi:type="array">
                    <item name="row" xsi:type="string" translate="true">#</item>
                </argument>
            </arguments>
            <block class="Vendor\RowCounter\Block\Adminhtml\Items\Column\Row" name="column_row" template="Vendor_RowCounter::items/column/row.phtml" group="column"/>
        </referenceBlock>
        <referenceBlock name="default_order_items_renderer">
            <arguments>
                <argument name="columns" xsi:type="array">
                    <item name="row" xsi:type="string" translate="true">col-row</item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

The drawback with this approach is you won't have control over the order of columns and a new column will be added at the end: Solution#1

Solution #2 (By adding a column via plugins):

To take more control over the column order, we can add column via plugin instead of sales_order_view.xml.

  1. Add view/adminhtml/layout/sales_order_view.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_items">
            <block class="Vendor\RowCounter\Block\Adminhtml\Items\Column\Row" name="column_row" template="Vendor_RowCounter::items/column/row.phtml" group="column"/>
        </referenceBlock>
    </body>
</page>
  1. Add etc/adminhtml/di.xml for the plugins:
<?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\Sales\Block\Adminhtml\Order\View\Items">
        <plugin name="Vendor_RowCounter::OrderViewItems" type="Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items"/>
    </type>
    <type name="Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer">
        <plugin name="Vendor_RowCounter::OrderViewItemsDefaultRenderer" type="Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer"/>
    </type>
</config>
  1. Add first plugin class, Plugin/Block/Adminhtml/Order/View/Items.php
<?php

declare(strict_types=1);

namespace Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View;

use Magento\Sales\Block\Adminhtml\Order\View\Items as BaseItems;

class Items
{

    /**
     * @param BaseItems $subject
     * @param array $result
     *
     * @return array
     */
    public function afterGetColumns(
        BaseItems $subject,
        array $result
    ): array {
        return [
            'row' => __('#'),
            ...$result,
        ];
    }
}
  1. Add the other plugin, Plugin/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
<?php

declare(strict_types=1);

namespace Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items\Renderer;

use Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer as BaseDefaultRenderer;

class DefaultRenderer
{

    /**
     * @param BaseDefaultRenderer $subject
     * @param array $result
     *
     * @return array
     */
    public function afterGetColumns(
        BaseDefaultRenderer $subject,
        array $result
    ): array {
        return [
            'row' => 'col-row',
            ...$result,
        ];
    }
}

Result of Solution #2: Solution#2

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.