Cách thêm nút tùy chỉnh để xem đơn đặt hàng bán hàng của quản trị viên trong Magento2


12

nhập mô tả hình ảnh ở đây

Cách thêm nút tùy chỉnh vào chế độ xem đơn đặt hàng trong magento2, vì một số sự kiện đã được gỡ bỏ có lợi cho plugin.

  • Đã xóa một số sự kiện (plugin phải được sử dụng thay thế):

Xem Nhật ký thay đổi Magento2

Câu trả lời:


17

Giải pháp sạch nhất tôi từng thấy cho đến nay là sử dụng plugin nhắm mục tiêu 'trước SetLayout'

Điều này có thể nhắm mục tiêu khối chính xác, lưu kiểm tra cho yêu cầu hiện tại và cũng tránh plugin được bật 'getOrderId' mà trong trường hợp của tôi không thể sử dụng được vì tôi cần gọi getOrderId trong phương thức plugin của mình.

Vì vậy, điều này trong di.xml

   <type name="Magento\Sales\Block\Adminhtml\Order\View">
    <plugin name="addMyButton" type="My\Module\Plugin\Block\Adminhtml\Order\View"/>
   </type>

Và sau đó trong tệp My \ Module \ Plugin \ Block \ adminhtml \ Order \ View.php

public function beforeSetLayout(\Magento\Sales\Block\Adminhtml\Order\View $view)
{
    $message ='Are you sure you want to do this?';
    $url = '/mymodule/controller/action/id/' . $view->getOrderId();


    $view->addButton(
        'order_myaction',
        [
            'label' => __('My Action'),
            'class' => 'myclass',
            'onclick' => "confirmSetLocation('{$message}', '{$url}')"
        ]
    );


}

Làm việc như một cơ duyên
Raul Sanchez

16

Sau khi thử nhiều cách khác nhau, đây là giải pháp duy nhất tôi có thể thấy dường như hoạt động mà không ảnh hưởng đến các mô-đun khác. Tôi rất thích xem các giải pháp khác.

lựa chọn 1

Tạo một plugin trong Công ty / Mô-đun / etc / adminhtml / di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Backend\Block\Widget\Button\Toolbar">
        <plugin name="MagePal_TestBed::pluginBefore" type="MagePal\TestBed\Plugin\PluginBefore" />
    </type>
</config>

Sau đó, trong Plugin / PluginB Before.php

namespace MagePal\TestBed\Plugin;

class PluginBefore
{
    public function beforePushButtons(
        \Magento\Backend\Block\Widget\Button\Toolbar\Interceptor $subject,
        \Magento\Framework\View\Element\AbstractBlock $context,
        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
    ) {

        $this->_request = $context->getRequest();
        if($this->_request->getFullActionName() == 'sales_order_view'){
              $buttonList->add(
                'mybutton',
                ['label' => __('My Button'), 'onclick' => 'setLocation(window.location.href)', 'class' => 'reset'],
                -1
            );
        }

    }
}

Lựa chọn 2

Tạo một plugin trong Công ty / Mô-đun / etc / adminhtml / di.xml

<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">
        <plugin name="MagePal_TestBed::pluginBeforeView" type="MagePal\TestBed\Plugin\PluginBeforeView" />
    </type>
</config>

Sau đó, trong Plugin / PluginB BeforeView.php

namespace MagePal\TestBed\Plugin;

class PluginBeforeView
{

    public function beforeGetOrderId(\Magento\Sales\Block\Adminhtml\Order\View $subject){
        $subject->addButton(
                'mybutton',
                ['label' => __('My Buttion'), 'onclick' => 'setLocation(window.location.href)', 'class' => 'reset'],
                -1
            );

        return null;
    }

}

Xem mã nguồn đầy đủ


@rs Tôi đã thử tùy chọn thứ 2 và nó gây ra lỗi - Warning: call_user_func_array() expects parameter 2 to be array, object given in D:\new\OpenServer\domains\graffiticaps-m2.loc\vendor\magento\framework\Interception\Interceptor.php on line 144, vì phương thức __callPlugin () thêm beforeGetOrderId()phương thức nào trả về các đối số của getOrderId()phương thức. \ nhà cung cấp \ magento \ framework \ Interception \ Interceptor.php [dòng 124] - $arguments = $beforeResult;. Vì vậy, tôi nghĩ rằng phải có trả lại smth khác, nhưng không phải đối tượng, có nghĩa là chủ đề $
Kate Suykovskaya

1
Tôi mới thử nghiệm trên Magento 2.0.2 ... Hãy xem bản cập nhật của tôi cho tùy chọn # 2 .... Xem github.com/magepal/stackexchange/tree/develop/91071
Renon Stewart

Có cách nào để gọi ajax khi nhấp vào nút này không?
nuwaus

@nuwaus ... bạn có thể thay đổi 'onclick' thành 'onclick = "processAjax ()" "sau đó thêm chức năng ajax ở đó hoặc một số chức năng khác khi nhấp vào liên kết jquery
Renon Stewart

đây là một vấn đề tương tự magento.stackexchange.com/questions/251458/ Ấn
Ajwad Syed

9

Tạo tập tin DI app/code/YourVendor/YourModule/etc/di.xml::

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="SalesOrderViewWidgetContext" type="\Magento\Backend\Block\Widget\Context">
        <arguments>
            <argument name="buttonList" xsi:type="object">YourVendor\YourModule\Block\Adminhtml\Order\View\ButtonList
            </argument>
        </arguments>
    </virtualType>
    <type name="Magento\Sales\Block\Adminhtml\Order\View">
        <arguments>
            <argument name="context" xsi:type="object">SalesOrderViewWidgetContext</argument>
        </arguments>
    </type>
</config>

Những gì chúng tôi làm ở đây là:

  1. Đặt contextđối số tùy chỉnh vàoOrder\View khối. Bối cảnh này được định nghĩa là một loại ảo.
  2. Xác định loại ảo cho bối cảnh widget. Chúng tôi đặt tùy chỉnhbuttonList đối số với lớp danh sách nút riêng của chúng tôi.

Thực hiện lớp danh sách nút của bạn:

<?php
namespace YourVendor\YourModule\Block\Adminhtml\Order\View;

class ButtonList extends \Magento\Backend\Block\Widget\Button\ButtonList
{
   public function __construct(\Magento\Backend\Block\Widget\Button\ItemFactory $itemFactory)
   {
       parent::__construct($itemFactory);
       $this->add('mybutton', [
           'label' => __('My button label')
       ]);
   }
}

1
Cảm ơn bạn cho giải pháp này! Tôi nghĩ rằng đây là tốt nhất và thanh lịch nhất.
eInyzant

Điều này nhìn đẹp, thanh lịch và dễ hiểu nhưng thật không may, nó không hoạt động. Trong Magento 2.3.4 khi nhấp vào một đơn hàng, nó sẽ báo lỗiException occurred during order load
Gianni Di Falco

3

Đây là một trong những giải pháp tốt nhất tôi thấy cho đến nay mà không cần sử dụng plugin

MagePal / CustomButton / 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="sales_order_edit">
            <block class="MagePal\CustomButton\Block\Adminhtml\Order\View\Buttons" name="custom_buttons">
                <action method="addButtons"/>
            </block>
        </referenceBlock>
    </body>
</page>

MagePal / CustomButton / Chặn / adminhtml / Đặt hàng / Xem / Nút.php

namespace MagePal\CustomButton\Block\Adminhtml\Order\View;

class Buttons extends \Magento\Sales\Block\Adminhtml\Order\View
{    
    public function __construct(
        \Magento\Backend\Block\Widget\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Sales\Model\Config $salesConfig,
        \Magento\Sales\Helper\Reorder $reorderHelper,
        array $data = []
    ) {
        parent::__construct($context, $registry, $salesConfig, $reorderHelper, $data);
    }

    public function addButtons()
    {
        $parentBlock = $this->getParentBlock();

        if(!$parentBlock instanceof \Magento\Backend\Block\Template || !$parentBlock->getOrderId()) {
            return;
        }

        $buttonUrl = $this->_urlBuilder->getUrl(
            'adminhtml/custombutton/new',
            ['order_id' => $parentBlock->getOrderId()]
        );

        $this->getToolbar()->addChild(
              'create_custom_button',
              \Magento\Backend\Block\Widget\Button::class,
              ['label' => __('Custom Button'), 'onclick' => 'setLocation(\'' . $buttonUrl . '\')']
            );
        }
        return $this;
    }

}

Có lỗi trong adminhtml_sales_order_view.xmlđó làsales_order_view.xml
Zaheerabbas

2

Tạo vị trí sau

ứng dụng / mã / Học tập / RewriteSales / etc / di.xml

Nội dung nên

<? xml phiên bản = "1.0"?>
<config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "urn: magento: framework: ObjectManager / etc / config.xsd">
    <type name = "Magento \ Backend \ Block \ Widget \ Context">
        <plugin name = "add_custom_button_sales_veiw" type = "Học tập \ RewriteSales \ Plugin \ Widget \ Context" sortOrder = "1" />
    </ loại>
</ config>

Tạo Context.php sau khi mất

ứng dụng / mã / Học tập / RewriteSales / Plugin / Widget / Context.php

Nội dung nên

không gian tên Học tập \ RewriteSales \ Plugin \ Widget;


lớp học bối cảnh
{
    chức năng công khai afterGetButtonList (
        \ Magento \ Backend \ Block \ Widget \ Context $ chủ đề,
        $ nút Danh sách
    )
    {
        $ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance ();
        $ request = $ objectManager-> get ('Magento \ Framework \ App \ Action \ Context') -> getRequest ();
        if ($ request-> getFullActionName () == 'sales_order_view') {
            $ buttonList-> thêm (
                'custom_button',
                [
                    'nhãn' => __ ('Nút tùy chỉnh'),
                    'onclick' => 'setLocation (\' '. $ this-> getCustomUrl ().' \ ')',
                    'lớp' => 'tàu'
                ]
            );
        }

        trả về $ buttonList;
    }

    Hàm công khai getCustomUrl ()
    {
        $ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance ();
        $ urlManager = $ objectManager-> get ('Magento \ Framework \ Url');
        trả về $ urlManager-> getUrl ('sales / * / custom');
    }
}

Xóa bộ nhớ cache Magento và chạy lệnh cập nhật

Thiết lập php bin / magento: nâng cấp

Sửa lỗi cho tôi nếu tôi sai, nhưng từ tất cả các thử nghiệm của tôi cho đến nay, preferenceloại tương đương với viết lại trong magento 1. Do đó, chỉ có một mô-đun có thể tận dụng lợi thế của nó
Renon Stewart

Đúng. Nhưng bạn không thể tạo plugin cho chức năng được bảo vệ.
Sohel Rana

Chỉ cần cập nhật câu trả lời của tôi bằng cách sử dụng plugin
Sohel Rana

1
Thay vì tải trình quản lý đối tượng bạn có thể thực hiện$subject->getRequest()->getFullActionName()
Renon Stewart

thêm phần này trước hàm afterGetButtonList ....... được bảo vệ $ urlBuider; chức năng công cộng __construct (\ Magento \ Framework \ UrlInterface $ urlBuilder) {$ this-> urlBuilder = $ urlBuilder; } Sau đó, trong hàm getCustomUrl () chỉ thêm dòng này ..... return $ this-> urlBuilder-> getUrl ('modulename / controlsername / methodname', mảng ('tham số' => tham số_value));
KA9
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.