Magento 2 Thêm danh sách thả xuống vào phương thức vận chuyển


16

Tôi phát triển phương pháp vận chuyển cho một số công ty hậu cần. Công ty này có nhiều văn phòng nơi khách hàng có thể nhận được đơn đặt hàng của mình. Tôi có thể nhận danh sách văn phòng theo tính thân thiện trong API nhưng bây giờ tôi không thể hiện bước này tốt hơn như thế nào?

Bây giờ tôi chỉ đặt mới \Magento\Quote\Model\Quote\Address\RateResult\Method cho mọi văn phòng trong thị trấn, trong thị trấn lớn, nó có số lượng> 100 và tôi nghĩ rằng việc đặt 100 dòng thanh toán là không tốt lắm.

Nó sẽ là mô-đun công khai cho thiết kế thanh toán khác nhau, làm thế nào tôi có thể kết xuất gần phương thức giao hàng đã chọn của mình một số danh sách thả xuống với danh sách các văn phòng và đặt giá và phương thức sau khi người dùng chọn một.


@Zefiryn Tôi thấy bài đăng này rất thú vị, nhưng tôi có một câu hỏi, nếu tôi phải hiển thị trong phần chọn không phải các văn phòng mà là các cửa hàng nằm trong mô-đun của Amasty, tôi sẽ làm phần thứ hai trong bài đăng của bạn như thế nào? Ý tôi là: nơi mà tôi gọi là người trợ giúp của Amasty để điền vào thành phần xml "eller_carrier_form"? Cảm ơn
maverickk89

Nếu bạn có một câu hỏi mới, vui lòng hỏi nó bằng cách nhấp vào nút Hỏi câu hỏi . Bao gồm một liên kết đến câu hỏi này nếu nó giúp cung cấp bối cảnh. - Từ đánh giá
Jai

đây không phải là một câu hỏi mới mà là một biến thể của cách được Zefiryn sử dụng ... bởi vì tôi đã sử dụng phần đầu tiên của bài viết
maverickk89

Câu trả lời:


17

Thanh toán Magento không hỗ trợ bất kỳ hình thức nào cho phương thức vận chuyển dữ liệu bổ sung. Nhưng nó cung cấp shippingAdditionalkhối trong thanh toán có thể được sử dụng cho việc này. Các giải pháp sau đây sẽ làm việc cho kiểm tra magento tiêu chuẩn.

Trước tiên, hãy chuẩn bị thùng chứa của chúng tôi, nơi chúng tôi có thể đặt một số hình thức. Để làm điều này tạo một tập tin trongview/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shippingAdditional" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">shippingAdditional</item>
                                                            <item name="children" xsi:type="array">
                                                                <item name="vendor_carrier_form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Vendor_Module/js/view/checkout/shipping/form</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Bây giờ tạo một tệp trong Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsđó sẽ hiển thị một mẫu loại trực tiếp. Nội dung của nó trông như thế này

define([
    'jquery',
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/shipping-service',
    'Vendor_Module/js/view/checkout/shipping/office-service',
    'mage/translate',
], function ($, ko, Component, quote, shippingService, officeService, t) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/checkout/shipping/form'
        },

        initialize: function (config) {
            this.offices = ko.observableArray();
            this.selectedOffice = ko.observable();
            this._super();
        },

        initObservable: function () {
            this._super();

            this.showOfficeSelection = ko.computed(function() {
                return this.ofices().length != 0
            }, this);

            this.selectedMethod = ko.computed(function() {
                var method = quote.shippingMethod();
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                return selectedMethod;
            }, this);

            quote.shippingMethod.subscribe(function(method) {
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                if (selectedMethod == 'carrier_method') {
                    this.reloadOffices();
                }
            }, this);

            this.selectedOffice.subscribe(function(office) {
                if (quote.shippingAddress().extensionAttributes == undefined) {
                    quote.shippingAddress().extensionAttributes = {};
                }
                quote.shippingAddress().extensionAttributes.carrier_office = office;
            });


            return this;
        },

        setOfficeList: function(list) {
            this.offices(list);
        },

        reloadOffices: function() {
            officeService.getOfficeList(quote.shippingAddress(), this);
            var defaultOffice = this.offices()[0];
            if (defaultOffice) {
                this.selectedOffice(defaultOffice);
            }
        },

        getOffice: function() {
            var office;
            if (this.selectedOffice()) {
                for (var i in this.offices()) {
                    var m = this.offices()[i];
                    if (m.name == this.selectedOffice()) {
                        office = m;
                    }
                }
            }
            else {
                office = this.offices()[0];
            }

            return office;
        },

        initSelector: function() {
            var startOffice = this.getOffice();
        }
    });
});

Tập tin này sử dụng mẫu loại trực tiếp nên được đặt trong Vendor/Module/view/frontend/web/template/checkout/shipping/form.html

<div id="carrier-office-list-wrapper" data-bind="visible: selectedMethod() == 'carrier_method'">
    <p data-bind="visible: !showOfficeSelection(), i18n: 'Please provide postcode to see nearest offices'"></p>
    <div data-bind="visible: showOfficeSelection()">
        <p>
            <span data-bind="i18n: 'Select pickup office.'"></span>
        </p>
        <select id="carrier-office-list" data-bind="options: offices(),
                                            value: selectedOffice,
                                            optionsValue: 'name',
                                            optionsText: function(item){return item.location + ' (' + item.name +')';}">
        </select>
    </div>
</div>

Bây giờ chúng ta có một trường chọn sẽ hiển thị khi phương thức của chúng ta (được xác định bởi mã của nó) sẽ được chọn trong bảng phương thức vận chuyển. Thời gian để điền vào nó với một số tùy chọn. Vì các giá trị phụ thuộc vào địa chỉ, cách tốt nhất là tạo điểm cuối nghỉ sẽ cung cấp các tùy chọn khả dụng. TrongVendor/Module/etc/webapi.xml

<?xml version="1.0"?>

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

    <!-- Managing Office List on Checkout page -->
    <route url="/V1/module/get-office-list/:postcode/:city" method="GET">
        <service class="Vendor\Module\Api\OfficeManagementInterface" method="fetchOffices"/>
        <resources>
            <resource ref="anonymous" />
        </resources>
    </route>
</routes>

Bây giờ xác định giao diện trong Vendor/Module/Api/OfficeManagementInterface.phpnhư

namespace Vendor\Module\Api;

interface OfficeManagementInterface
{

    /**
     * Find offices for the customer
     *
     * @param string $postcode
     * @param string $city
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city);
}

Xác định giao diện cho dữ liệu văn phòng trong Vendor\Module\Api\Data\OfficeInterface.php. Giao diện này sẽ được sử dụng bởi mô-đun webapi để lọc dữ liệu cho đầu ra, do đó bạn cần xác định bất cứ điều gì bạn cần thêm vào phản hồi.

namespace Vendor\Module\Api\Data;

/**
 * Office Interface
 */
interface OfficeInterface
{
    /**
     * @return string
     */
    public function getName();

    /**
     * @return string
     */
    public function getLocation();
}

Thời gian cho các lớp học thực tế. Bắt đầu với việc tạo tùy chọn cho tất cả các giao diện trongVendor/Module/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">
    <preference for="Vendor\Module\Api\OfficeManagementInterface" type="Vendor\Module\Model\OfficeManagement" />
    <preference for="Vendor\Module\Api\Data\OfficeInterface" type="Vendor\Module\Model\Office" />
</config>

Bây giờ tạo Vendor\Module\Model\OfficeManagement.phplớp thực sự sẽ làm logic tìm nạp dữ liệu.

namespace Vednor\Module\Model;

use Vednor\Module\Api\OfficeManagementInterface;
use Vednor\Module\Api\Data\OfficeInterfaceFactory;

class OfficeManagement implements OfficeManagementInterface
{
    protected $officeFactory;

    /**
     * OfficeManagement constructor.
     * @param OfficeInterfaceFactory $officeInterfaceFactory
     */
    public function __construct(OfficeInterfaceFactory $officeInterfaceFactory)
    {
        $this->officeFactory = $officeInterfaceFactory;
    }

    /**
     * Get offices for the given postcode and city
     *
     * @param string $postcode
     * @param string $limit
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city)
    {
        $result = [];
        for($i = 0, $i < 4;$i++) {
            $office = $this->officeFactory->create();
            $office->setName("Office {$i}");
            $office->setLocation("Address {$i}");
            $result[] = $office;
        }

        return $result;
    }
}

Và cuối cùng là lớp học OfficeInterfacetrongVendor/Module/Model/Office.php

namespace Vendor\Module\Model;

use Magento\Framework\DataObject;
use Vendor\Module\Api\Data\OfficeInterface;

class Office extends DataObject implements OfficeInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return (string)$this->_getData('name');
    }

    /**
     * @return string
     */
    public function getLocation()
    {
        return (string)$this->_getData('location');
    }
}

Điều này sẽ hiển thị trường chọn và cập nhật nó khi địa chỉ được thay đổi. Nhưng chúng ta đang thiếu một yếu tố nữa cho thao tác frontend. Chúng ta cần tạo hàm sẽ gọi điểm cuối. Gọi cho nó đã được bao gồm trong Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsvà nó là Vendor_Module/js/view/checkout/shipping/office-servicelớp nên đi Vendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.jsvới mã sau đây:

define(
    [
        'Vendor_Module/js/view/checkout/shipping/model/resource-url-manager',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/model/customer',
        'mage/storage',
        'Magento_Checkout/js/model/shipping-service',
        'Vendor_Module/js/view/checkout/shipping/model/office-registry',
        'Magento_Checkout/js/model/error-processor'
    ],
    function (resourceUrlManager, quote, customer, storage, shippingService, officeRegistry, errorProcessor) {
        'use strict';

        return {
            /**
             * Get nearest machine list for specified address
             * @param {Object} address
             */
            getOfficeList: function (address, form) {
                shippingService.isLoading(true);
                var cacheKey = address.getCacheKey(),
                    cache = officeRegistry.get(cacheKey),
                    serviceUrl = resourceUrlManager.getUrlForOfficeList(quote);

                if (cache) {
                    form.setOfficeList(cache);
                    shippingService.isLoading(false);
                } else {
                    storage.get(
                        serviceUrl, false
                    ).done(
                        function (result) {
                            officeRegistry.set(cacheKey, result);
                            form.setOfficeList(result);
                        }
                    ).fail(
                        function (response) {
                            errorProcessor.process(response);
                        }
                    ).always(
                        function () {
                            shippingService.isLoading(false);
                        }
                    );
                }
            }
        };
    }
);

Nó sử dụng thêm 2 tập tin js. Vendor_Module/js/view/checkout/shipping/model/resource-url-managertạo một url đến điểm cuối và khá đơn giản

define(
    [
        'Magento_Customer/js/model/customer',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/url-builder',
        'mageUtils'
    ],
    function(customer, quote, urlBuilder, utils) {
        "use strict";
        return {
            getUrlForOfficeList: function(quote, limit) {
                var params = {postcode: quote.shippingAddress().postcode, city: quote.shippingAddress().city};
                var urls = {
                    'default': '/module/get-office-list/:postcode/:city'
                };
                return this.getUrl(urls, params);
            },

            /** Get url for service */
            getUrl: function(urls, urlParams) {
                var url;

                if (utils.isEmpty(urls)) {
                    return 'Provided service call does not exist.';
                }

                if (!utils.isEmpty(urls['default'])) {
                    url = urls['default'];
                } else {
                    url = urls[this.getCheckoutMethod()];
                }
                return urlBuilder.createUrl(url, urlParams);
            },

            getCheckoutMethod: function() {
                return customer.isLoggedIn() ? 'customer' : 'guest';
            }
        };
    }
);

Vendor_Module/js/view/checkout/shipping/model/office-registrylà một cách giữ kết quả trong lưu trữ cục bộ. Mã của nó là:

define(
    [],
    function() {
        "use strict";
        var cache = [];
        return {
            get: function(addressKey) {
                if (cache[addressKey]) {
                    return cache[addressKey];
                }
                return false;
            },
            set: function(addressKey, data) {
                cache[addressKey] = data;
            }
        };
    }
);

Ok, vì vậy chúng ta nên có tất cả làm việc trên frontend. Nhưng bây giờ có một vấn đề khác để giải quyết. Vì thanh toán không biết gì về hình thức này nên nó sẽ không gửi kết quả lựa chọn đến phụ trợ. Để thực hiện điều này, chúng ta cần sử dụng extension_attributestính năng. Đây là một cách trong magento2 để thông báo cho hệ thống rằng một số dữ liệu bổ sung dự kiến ​​sẽ có trong các cuộc gọi còn lại. Không có nó, magento sẽ lọc ra những dữ liệu đó và họ sẽ không bao giờ đạt được mã.

Vì vậy, đầu tiên trong Vendor/Module/etc/extension_attributes.xmlđịnh nghĩa:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="carrier_office" type="string"/>
    </extension_attributes>
</config>

Giá trị này đã được chèn trong yêu cầu form.jstheo this.selectedOffice.subscribe()định nghĩa. Vì vậy, cấu hình trên sẽ chỉ vượt qua nó ở lối vào. Để tìm nạp nó trong mã, hãy tạo một pluginVendor/Module/etc/di.xml

<type name="Magento\Quote\Model\Quote\Address">
    <plugin name="inpost-address" type="Vendor\Module\Quote\AddressPlugin" sortOrder="1" disabled="false"/>
</type>

Bên trong lớp học đó

namespace Vendor\Module\Plugin\Quote;

use Magento\Quote\Model\Quote\Address;
use Vendor\Module\Model\Carrier;

class AddressPlugin
{
    /**
     * Hook into setShippingMethod.
     * As this is magic function processed by __call method we need to hook around __call
     * to get the name of the called method. after__call does not provide this information.
     *
     * @param Address $subject
     * @param callable $proceed
     * @param string $method
     * @param mixed $vars
     * @return Address
     */
    public function around__call($subject, $proceed, $method, $vars)
    {
        $result = $proceed($method, $vars);
        if ($method == 'setShippingMethod'
            && $vars[0] == Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $subject->getExtensionAttributes()
            && $subject->getExtensionAttributes()->getCarrierOffice()
        ) {
            $subject->setCarrierOffice($subject->getExtensionAttributes()->getCarrierOffice());
        }
        elseif (
            $method == 'setShippingMethod'
            && $vars[0] != Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
        ) {
            //reset office when changing shipping method
            $subject->getCarrierOffice(null);
        }
        return $result;
    }
}

Tất nhiên nơi bạn sẽ lưu giá trị phụ thuộc hoàn toàn vào yêu cầu của bạn. Đoạn mã trên sẽ yêu cầu tạo thêm cột carrier_officetrong quote_addresssales_addressbảng và một sự kiện (trong Vendor/Module/etc/events.xml)

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_model_service_quote_submit_before">
        <observer name="copy_carrier_office" instance="Vendor\Module\Observer\Model\Order" />
    </event>
</config>

Điều đó sẽ sao chép dữ liệu được lưu trong địa chỉ báo giá vào địa chỉ bán hàng.

Tôi đã viết cái này cho mô-đun của mình cho hãng vận chuyển đánh bóng InPost vì vậy tôi đã thay đổi một số tên có thể phá mã nhưng tôi hy vọng điều này sẽ cung cấp cho bạn những gì bạn cần.

[BIÊN TẬP]

Mô hình tàu sân bay được hỏi bởi @sangan

namespace Vendor\Module\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Phrase;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Simplexml\ElementFactory;

class Carrier extends AbstractCarrier implements CarrierInterface
{
    const CARRIER_CODE = 'mycarier';

    const METHOD_CODE = 'mymethod';

    /** @var string */
    protected $_code = self::CARRIER_CODE;

    /** @var bool */
    protected $_isFixed = true;

    /**
     * Prepare stores to show on frontend
     *
     * @param RateRequest $request
     * @return \Magento\Framework\DataObject|bool|null
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigData('active')) {
            return false;
        }

        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateFactory->create();

        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();
        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));

        $price = $this->getFinalPriceWithHandlingFee(0);
        $method->setMethod(self::METHOD_CODE);
        $method->setMethodTitle(new Phrase('MyMethod'));
        $method->setPrice($price);
        $method->setCost($price);
        $result->append($method);;

        return $result;
    }


    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        $methods = [
            'mymethod' => new Phrase('MyMethod')
        ];
        return $methods;
    }
}

Cảm ơn bạn đã trả lời mở rộng, tôi sẽ cố gắng giải quyết vấn đề của tôi bằng phương pháp của bạn và sẽ trả lời với kết quả trong những ngày này.
Siarhey Uchukhlebau

@Zefiryn Tôi đã tạo một phương thức giao hàng tùy chỉnh, bên dưới nó sẽ hiển thị danh sách thả xuống có số tài khoản vận chuyển của khách hàng (có một thuộc tính khách hàng tùy chỉnh được tạo), vì vậy nếu tôi phải hiển thị danh sách thả xuống này thì bao nhiêu phần trăm mã của bạn sẽ hữu ích? Tôi nên lấy gì từ mã bạn cung cấp?
Shireen N

@shireen Tôi sẽ nói khoảng 70%. Bạn cần thay đổi phần nơi nó tìm nạp máy vào số tài khoản. Vì vậy, định nghĩa api sẽ là slighlty khác nhau và là một phần của nó
Zefiryn

Tôi đã thử mô-đun này ... nhưng nó không hiển thị bất kỳ thay đổi nào, vì vậy hãy chia sẻ mô-đun làm việc. Nếu có
sangan

sau khi thêm mô-đun thành công .. trong kiểm tra ajax tải liên tục .. trong lỗi bảng điều khiển hiển thị như bên dưới: notify.js: 166 Uncaught Error: Script script cho: Vendor_Module / js / view / checkout / Shipping / model / office-registry. requestjs.org/docs/errors.html#scripterror
sangan

2

Tôi đang thêm câu trả lời mới để mở rộng về những gì đã được cung cấp trước đây nhưng không làm biến dạng nó.

Đây là tuyến đường QuoteAddressPluginđược nối vào:

1. Magento\Checkout\Api\ShippingInformationManagementInterface::saveAddressInformation()
2. Magento\Quote\Model\QuoteRepository::save() 
3. Magento\Quote\Model\QuoteRepository\SaveHandler::save() 
4. Magento\Quote\Model\QuoteRepository\SaveHandler::processShippingAssignment() 
5. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::save()
6. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::save()
7. Magento\Quote\Model\Quote\ShippingAssignment\ShippingProcessor::save()
8. Magento\Quote\Model\ShippingMethodManagement::apply() 

Phương pháp cuối cùng là gọi Magento\Quote\Model\Quote\Address::setShippingMethod()mà thực sự là cuộc gọi Magento\Quote\Model\Quote\Address::__call()mà tôi đã sử dụng. Ngay bây giờ tôi tìm thấy một nơi tốt hơn cho các plugin, đó là Magento\Quote\Model\ShippingAssignment::setShipping()phương pháp. Vì vậy, phần plugin có thể được viết lại thành:

<type name="Magento\Quote\Model\ShippingAssignment">
    <plugin name="carrier-office-plugin" type="Vendor\Module\Plugin\Quote\ShippingAssignmentPlugin" sortOrder="1" disabled="false"/>
</type>

và chính plugin:

namespace Vednor\Module\Plugin\Quote;

use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\ShippingInterface;
use Magento\Quote\Model\ShippingAssignment;
use Vendor\Module\Model\Carrier;

/**
 * ShippingAssignmentPlugin
 */
class ShippingAssignmentPlugin
{
    /**
     * Hook into setShipping.
     *
     * @param ShippingAssignment $subject
     * @param ShippingInterface $value
     * @return Address
     */
    public function beforeSetShipping($subject, ShippingInterface $value)
    {
        $method = $value->getMethod();
        /** @var AddressInterface $address */
        $address = $value->getAddress();
        if ($method === Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $address->getExtensionAttributes()
            && $address->getExtensionAttributes()->getCarrierOffice()
        ) {
            $address->setCarrierOffice($address->getExtensionAttributes()->getCarrierOffice());
        }
        elseif ($method !== Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE) {
            //reset inpost machine when changing shipping method
            $address->setCarrierOffice(null);
        }
        return [$value];
    }
}

1

@Zefiryn, tôi đã gặp vấn đề với: quote.shippingAddress().extensionAttributes.carrier_office = office;

Khi tôi vào kiểm tra lần đầu tiên (cửa sổ riêng mới) với tư cách là khách (nhưng điều tương tự xảy ra với khách hàng đã đăng ký), văn phòng thuộc tính không được lưu vào cơ sở dữ liệu sau lần đầu tiên "Tiếp theo". Mặc dù trong giao diện điều khiển tôi thấy đầu ra chính xác cho:console.log(quote.shippingAddress().extensionAttributes.carrier_office);

Khi tôi quay lại trang thanh toán đầu tiên và chọn lại văn phòng thì nó sẽ được lưu lại. Điều gì có thể là lý do của hành vi này?

Tôi đã cố gắng sử dụng: address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);

Nhưng không thành công...


0

@Zefiryn, bạn có thể giải thích trong vài từ làm thế nào để plugin trên của bạn hoạt động không? Tôi hơi bối rối vì như tôi biết phương thức __call được thực thi nếu chúng ta thử thực thi phương thức không tồn tại cho đối tượng cụ thể. Điều này có vẻ đúng bởi vì trong ứng dụng / mã / Magento / Trích dẫn / Mô hình / Trích dẫn / Địa chỉ.php Tôi không thấy phương pháp như vậy - chỉ nhận xét:

/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)

  1. Tại sao bạn sử dụng xung quanh việc đánh chặn khi không có phương thức thực hiện?
  2. Tiếp theo tôi thấy $subject->setInpostMachine$subject->getCarrierOffice(null);điều đó có nghĩa là phương thức của plugin trên sẽ được thực hiện lại vì không có phương thức setInpostMachine () và getCarrierOffice () trong Adress Class? Có vẻ như vòng lặp với tôi.
  3. Magento thực hiện từ setShippingMethod()đâu? Làm thế nào bình thường phương pháp này được sử dụng? Tôi không thể tìm thấy bất kỳ sự can thiệp nào của simillar trong mã Magento.

Ok, vì vậy tôi đã chuẩn bị câu trả lời dựa trên một mô-đun tôi đã viết để thử nghiệm, nó đã sử dụng trường inpost_machine, vì vậy, cái này không được thay đổi chính xác thành Carrier_office ở nơi này. Thứ hai, tại thời điểm tôi đang phát triển mô-đun này, tôi chưa tìm thấy nơi nào tôi có thể nhận được cả nhà mạng và địa chỉ được chọn với các thuộc tính mở rộng được gửi ngoại trừ setShippingMethodcuộc gọi trên AddressInterfaceđối tượng và vì không có phương thức nào như vậy nên tôi phải sử dụng khoảng _call để xem setShippingMethodđã được gọi hoặc một số lĩnh vực ma thuật khác. Ngay bây giờ tôi đã tìm thấy một nơi tốt hơn và tôi sẽ đăng nó trong bài trả lời mới.
Zefiryn
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.