9

I need add a tab tabs of sales order.

enter image description here

I think the tabs are defined in sales_order_view but I create a module in Vendor/ModuleName/view/adminhtml/layout/sales_order_view.xml and I put this:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_info">
          <action method="addTab">
              <argument name="name" xsi:type="string">order_transzuri</argument>
              <argument name="block" xsi:type="string">Sistel\Transzuri\Block\Adminhtml\Order\View\Tab\Custom</argument>
          </action>
        </referenceBlock>
    </body>
</page>

And I create in Sistel\Transzuri\Block\Adminhtml\Order\View\Tab\Custom this:

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sistel\Transzuri\Block\Adminhtml\Order\View\Tab;

/**
 * Order transactions tab
 *
 * @author     Magento Core Team <core@magentocommerce.com>
 */
class Custom extends \Magento\Framework\View\Element\Text\ListText implements
    \Magento\Backend\Block\Widget\Tab\TabInterface
{
    /**
     * @var \Magento\Framework\AuthorizationInterface
     */
    protected $_authorization;

    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry = null;

    /**
     * @param \Magento\Framework\View\Element\Context $context
     * @param \Magento\Framework\AuthorizationInterface $authorization
     * @param \Magento\Framework\Registry $registry
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Context $context,
        \Magento\Framework\AuthorizationInterface $authorization,
        \Magento\Framework\Registry $registry,
        array $data = []
    ) {
        $this->_authorization = $authorization;
        $this->_coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * Retrieve order model instance
     *
     * @return \Magento\Sales\Model\Order
     */
    public function getOrder()
    {
        return $this->_coreRegistry->registry('current_order');
    }

    /**
     * {@inheritdoc}
     */
    public function getTabLabel()
    {
        return __('Transzuri');
    }

    /**
     * {@inheritdoc}
     */
    public function getTabTitle()
    {
        return __('Transzuri');
    }

    /**
     * {@inheritdoc}
     */
    public function canShowTab()
    {
        return !$this->getOrder()->getPayment()->getMethodInstance()->isOffline();
    }

    /**
     * {@inheritdoc}
     */
    public function isHidden()
    {
        return !$this->_authorization->isAllowed('Sistel_Transzuri::transzuri');
    }
}

But It not shows in admin panel. Why?

AndresF
  • 431
  • 1
  • 5
  • 15

2 Answers2

18

You're really close. Here's what I did to make this work.

First create app/code/VENDOR/MODULE/view/adminhtml/layout/sales_order_view.xml and add

<?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>          
        <referenceContainer name="left">
            <referenceBlock name="sales_order_tabs">
                <action method="addTab">
                    <argument name="name" xsi:type="string">order_transzuri</argument>
                    <argument name="block" xsi:type="string">Sistel\Transzuri\Block\Adminhtml\Order\View\Tab\Custom</argument>
                </action>
            </referenceBlock>
        </referenceContainer>
    </body>
</page>

Next we'll create app/code/VENDOR/MODULE/Block/Adminhtml/Order/View/Tab/Custom.php

<?php

namespace Sistel\Transzuri\Block\Adminhtml\Order\View\Tab;


class Custom extends \Magento\Backend\Block\Template implements \Magento\Backend\Block\Widget\Tab\TabInterface
{
    /**
     * Template
     *
     * @var string
     */
    protected $_template = 'order/view/tab/custom.phtml';

    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $coreRegistry = null;

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        array $data = []
    ) {
        $this->coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * Retrieve order model instance
     *
     * @return \Magento\Sales\Model\Order
     */
    public function getOrder()
    {
        return $this->coreRegistry->registry('current_order');
    }

    /**
     * {@inheritdoc}
     */
    public function getTabLabel()
    {
        return __('Transzuri');
    }

    /**
     * {@inheritdoc}
     */
    public function getTabTitle()
    {
        return __('Transzuri');
    }

    /**
     * {@inheritdoc}
     */
    public function canShowTab()
    {
        // For me, I wanted this tab to always show
        // You can play around with the ACL settings 
        // to selectively show later if you want
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function isHidden()
    {
        // For me, I wanted this tab to always show
        // You can play around with conditions to
        // show the tab later
        return false;
    }

    /**
     * Get Tab Class
     *
     * @return string
     */
    public function getTabClass()
    {
        // I wanted mine to load via AJAX when it's selected
        // That's what this does
        return 'ajax only';
    }

    /**
     * Get Class
     *
     * @return string
     */
    public function getClass()
    {
        return $this->getTabClass();
    }

    /**
     * Get Tab Url
     *
     * @return string
     */
    public function getTabUrl()
    {
        // customtab is a adminhtml router we're about to define
        // the full route can really be whatever you want
        return $this->getUrl('customtab/*/customTab', ['_current' => true]);
    }
}

Next up we want to create app/code/VENDOR/MODULE/etc/adminhtml/routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="admin">
        <route id="transzuri_tab" frontName="customtab">
            <module name="VENDOR_MODULE" />
        </route>
    </router>
</config>

Next let's create our controller at app/code/VENDOR/MODULE/Controller/Adminhtml/Order/CustomTab.php

<?php

namespace Sistel\Transzuri\Controller\Adminhtml\Order;

use Magento\Backend\App\Action;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Psr\Log\LoggerInterface;

class CustomTab extends \Magento\Sales\Controller\Adminhtml\Order
{
    /**
     * @var \Magento\Framework\View\LayoutFactory
     */
    protected $layoutFactory;

    /**
     * @param Action\Context $context
     * @param \Magento\Framework\Registry $coreRegistry
     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
     * @param \Magento\Framework\Translate\InlineInterface $translateInline
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     * @param \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
     * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
     * @param OrderManagementInterface $orderManagement
     * @param OrderRepositoryInterface $orderRepository
     * @param LoggerInterface $logger
     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
     *
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
     */
    public function __construct(
        Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Framework\Translate\InlineInterface $translateInline,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory,
        \Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
        OrderManagementInterface $orderManagement,
        OrderRepositoryInterface $orderRepository,
        LoggerInterface $logger,
        \Magento\Framework\View\LayoutFactory $layoutFactory
    ) {
        $this->layoutFactory = $layoutFactory;
        parent::__construct(
            $context,
            $coreRegistry,
            $fileFactory,
            $translateInline,
            $resultPageFactory,
            $resultJsonFactory,
            $resultLayoutFactory,
            $resultRawFactory,
            $orderManagement,
            $orderRepository,
            $logger
        );
    }

    /**
     * Generate order history for ajax request
     *
     * @return \Magento\Framework\Controller\Result\Raw
     */
    public function execute()
    {
        $this->_initOrder();
        $layout = $this->layoutFactory->create();
        // Yes, this is the same block class that we defined in sales_order_view.xml
        $html = $layout->createBlock('Sistel\Transzuri\Block\Adminhtml\Order\View\Tab\Custom')
            ->toHtml();
        $this->_translateInline->processResponseBody($html);
        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
        $resultRaw = $this->resultRawFactory->create();
        $resultRaw->setContents($html);
        return $resultRaw;
    }
}

The last thing you'll need to create is app/code/VENDOR/MODULE/view/adminhtml/templates/order/view/tab/custom.phtml

<section class="admin__page-section custom-tab-content">
<h1>Hello New Tab!</h1>
</section>

After that, just flush your cache and reload the page.

Mike Levy
  • 795
  • 5
  • 15
1

The problem is in your layout. You are defining <referenceBlock name="order_info"> that node is not for the order view tabs. You need to replace that with this:

<referenceBlock name="name="sales_order_tabs">

As always don't forget to clear your caches.

André Ferraz
  • 3,483
  • 6
  • 20
  • 40
  • I think that my loyout is not working. I don't know if this is the error because I do the changes but not show anything. I put errors to do a blank page but it charge the same. I think that layout not do anything and I don't know anything to do. – AndresF Jan 27 '17 at 12:24
  • You need to do that under the theme not under a module. – André Ferraz Jan 27 '17 at 12:27
  • but I need a module to install in other magento's – AndresF Jan 27 '17 at 12:32