วิธีการเพิ่มปุ่มที่กำหนดเองเพื่อดูคำสั่งขายผู้ดูแลระบบใน Magento2


13

ป้อนคำอธิบายรูปภาพที่นี่

วิธีเพิ่มปุ่มที่กำหนดเองในมุมมองคำสั่งขายใน magento2 เนื่องจากเหตุการณ์บางอย่างถูกลบออกโดยไม่ชอบปลั๊กอิน

  • ลบบางกิจกรรม (ต้องใช้ปลั๊กอินแทน):

ดูMagento2 เปลี่ยนบันทึก

คำตอบ:


19

วิธีการแก้ปัญหาที่สะอาดที่สุดที่ฉันเคยเห็นคือใช้ปลั๊กอินที่กำหนดเป้าหมาย 'beforeSetLayout'

สิ่งนี้สามารถกำหนดเป้าหมายบล็อกที่แน่นอนบันทึกการตรวจสอบสำหรับคำขอปัจจุบันและหลีกเลี่ยงปลั๊กอินที่อยู่ใน 'getOrderId' ซึ่งในกรณีของฉันไม่สามารถใช้งานได้ตามที่ฉันต้องการเรียกใช้ getOrderId ในวิธีปลั๊กอินของฉัน

ดังนั้นนี่ใน di.xml

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

แล้วนี่คือไฟล์ 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}')"
        ]
    );


}

ทำงานเหมือนเสน่ห์
Raul Sanchez

17

หลังจากลองใช้วิธีต่างๆมากมายนี่เป็นทางออกเดียวที่ฉันพบว่าใช้งานได้โดยไม่กระทบกับโมดูลอื่น ฉันชอบที่จะเห็นวิธีแก้ปัญหาอื่น ๆ

ตัวเลือกที่ 1

สร้างปลั๊กอินใน Company / Module / 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>

จากนั้นใน Plugin / PluginBefore.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
            );
        }

    }
}

ตัวเลือก 2

สร้างปลั๊กอินใน Company / Module / 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>

จากนั้นใน Plugin / PluginBeforeView.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;
    }

}

ดูรหัสที่มาแบบเต็ม


@rs ฉันได้ลองใช้ตัวเลือกที่ 2 และมันทำให้เกิดข้อผิดพลาด - 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เนื่องจากเมธอด __callPlugin () เพิ่มbeforeGetOrderId()วิธีที่เมธอดส่งกลับไปยังอาร์กิวเมนต์ของgetOrderId()เมธอด \ ผู้ขาย \ วีโอไอพี \ Framework \ สกัดกั้น \ Interceptor.php [สาย 124] $arguments = $beforeResult;- ดังนั้นฉันคิดว่าจะต้องมีการส่งคืนอย่างอื่น แต่ไม่คัดค้านความหมาย $ subject
Kate Suykovskaya

1
ฉันเพิ่งทดสอบ Magento 2.0.2 ... ดูการอัปเดตของฉันสำหรับตัวเลือก # 2 .... ดูgithub.com/magepal/stackexchange/tree/develop/91071
Renon Stewart

มีวิธีใดที่จะเรียก ajax เมื่อคลิกปุ่มนี้หรือไม่?
nuwaus

@nuwaus ... คุณสามารถเปลี่ยน 'onclick' เป็น 'onclick = "processAjax ()" "แล้วเพิ่มฟังก์ชั่น ajax ที่นั่นหรืออื่น ๆ เมื่อคลิก jquery ผูกพัน
Renon Stewart

นี่คือปัญหาที่คล้ายกัน magento.stackexchange.com/questions/251458/…
Ajwad Syed

9

สร้างไฟล์ 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>

สิ่งที่เราทำที่นี่คือ:

  1. ตั้งค่าcontextอาร์กิวเมนต์ที่กำหนดเองลงในOrder\Viewบล็อก บริบทนี้ถูกกำหนดให้เป็นประเภทเสมือน
  2. กำหนดประเภทเสมือนสำหรับบริบทวิดเจ็ต เราตั้งค่าbuttonListอาร์กิวเมนต์ที่กำหนดเองด้วยคลาสรายการปุ่มของเราเอง

ใช้คลาสรายการปุ่มของคุณ:

<?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
ขอบคุณสำหรับการแก้ปัญหานี้! ฉันคิดว่านี่เป็นสิ่งที่ดีที่สุดและสวยงามที่สุด
eInyzant

มันดูดีสง่างามและเข้าใจง่าย แต่น่าเสียดายที่มันไม่ทำงาน ใน Magento 2.3.4 เมื่อคลิกคำสั่งจะมีข้อผิดพลาดException occurred during order load
Gianni Di Falco

3

นี่เป็นหนึ่งในโซลูชั่นที่ดีที่สุดที่ฉันเคยเห็นมาโดยไม่ใช้ปลั๊กอิน

MagePal / CustomButton / ดู / adminhtml / รูปแบบ / 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 / บล็อก / Adminhtml / สั่งซื้อ / ดู / Buttons.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;
    }

}

มีข้อผิดพลาดในที่adminhtml_sales_order_view.xmlควรจะเป็นsales_order_view.xml
Zaheerabbas

ไม่จำเป็นต้องมีpublic function __construct
Serhii Koval

2

สร้าง di.xml ตามตำแหน่ง

app / รหัส / เรียนรู้ / RewriteSales / etc / di.xml

เนื้อหาควรจะเป็น

<? xml version = "1.0"?>
<config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "โกศ: magento: กรอบงาน: ObjectManager / etc / config.xsd">
    <type name = "Magento \ Backend \ Block \ Widget \ Context">
        <plugin name = "add_custom_button_sales_veiw" type = "การเรียนรู้ \ RewriteSales \ Plugin \ Widget \ บริบท \ บริบท" sortOrder = "1" />
    </ type>
</ config>

สร้าง Context.php ตาม loaction

app / รหัส / เรียนรู้ / RewriteSales / ปลั๊กอิน / เครื่องมือ / Context.php

เนื้อหาควรจะเป็น

เรียนรู้ namespace \ RewriteSales \ Plugin \ Widget;


บริบทของคลาส
{
    ฟังก์ชั่นสาธารณะ afterGetButtonList (
        \ Magento \ Backend \ Block \ Widget \ Context $ subject,
        $ buttonList
    )
    {
        $ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance ();
        $ request = $ objectManager-> get ('Magento \ Framework \ App \ Action \ Context') -> getRequest ();
        if ($ request-> getFullActionName () == 'sales_order_view') {
            $ buttonList-> เพิ่ม (
                'custom_button'
                [
                    'label' => __ ('ปุ่มกำหนดเอง')
                    'onclick' => 'setLocation (\' '. $ this-> getCustomUrl ().' \ ')',
                    'class' => 'ship'
                ]
            );
        }

        ส่งกลับ $ buttonList;
    }

    ฟังก์ชันสาธารณะ getCustomUrl ()
    {
        $ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance ();
        $ urlManager = $ objectManager-> get ('Magento \ Framework \ Url');
        ส่งคืน $ urlManager-> getUrl ('sales / * / custom');
    }
}

ล้างแคชของวีโอไอพีและเรียกใช้คำสั่งอัปเดต

php bin / magento setup: upgrade

แก้ไขฉันถ้าฉันผิด แต่จากการทดสอบทั้งหมดจนถึงpreferenceประเภทนี้เทียบเท่ากับการเขียนในวีโอไอพี 1 ดังนั้นมีเพียงโมดูลเดียวเท่านั้นที่สามารถใช้ประโยชน์จากมันได้
Renon Stewart

ใช่. แต่คุณไม่สามารถสร้างปลั๊กอินสำหรับฟังก์ชั่นการป้องกัน
Sohel Rana

เพียงอัปเดตคำตอบของฉันโดยใช้ปลั๊กอิน
Sohel Rana

1
แทนที่จะโหลด objectManager ที่คุณสามารถทำได้$subject->getRequest()->getFullActionName()
Renon Stewart

เพิ่มนี้ก่อนฟังก์ชั่น afterGetButtonList ....... ป้องกัน $ urlBuider; ฟังก์ชั่นสาธารณะ __ โครงสร้าง (\ Magento \ Framework \ UrlInterface $ urlBuilder) {$ this-> urlBuilder = $ urlBuilder; } จากนั้นใน getCustomUrl () ฟังก์ชั่นเพิ่มบรรทัดนี้เท่านั้น ..... ส่งกลับ $ this-> urlBuilder-> getUrl ('modulename / controllername / methodname', array ('พารามิเตอร์' => parameter_value));
KA9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.