마 젠토 2 배송 방법에 드롭 다운 목록 추가


16

일부 물류 회사의 배송 방법을 개발합니다. 이 회사에는 고객이 주문을받을 수있는 많은 사무실이 있습니다. API 에서 сity별로 사무실 목록을 가져올 수 있지만 이제이 단계를 더 잘 표현하지 못합니까?

지금 난 그냥 새로운 설정 \Magento\Quote\Model\Quote\Address\RateResult\Method 큰 도시에 그것의, 도시의 모든 사무실에 카운트> (100) 와 나는 그것을 체크 아웃에 100 선을 설정하는 것은 매우 좋지 않다 생각합니다.

다른 체크 아웃 디자인을위한 공용 모듈이되므로 선택한 배송 방법 근처에 사무실 목록이있는 드롭 다운 목록을 렌더링하고 사용자가 하나를 선택한 후 가격과 방법을 설정하는 방법은 무엇입니까?


@ Zefiryn이 게시물이 매우 흥미 롭다는 것을 알았지 만 사무실이 아니라 Amasty 모듈 내부의 상점에 표시 해야하는 경우 게시물의 두 번째 부분을 어떻게 수행합니까? 내 말은 : XML 컴포넌트 "vendor_carrier_form"을 채우기 위해 Amasty의 헬퍼를 호출하는 곳은 어디에 있습니까? 감사합니다
maverickk89

새로운 질문이 있으면 질문하기 버튼 을 클릭하여 질문하십시오 . 컨텍스트를 제공하는 데 도움이되는 경우이 질문에 대한 링크를 포함하십시오. - 리뷰에서
Jai

이것은 새로운 질문이 아니라 Zefiryn이 사용한 방식의 변형입니다. 왜냐하면 포스트의 첫 부분을 그대로 사용했기 때문입니다
maverickk89

답변:


17

Magento Checkout은 배송 방법 추가 데이터에 대한 모든 종류의 양식을 지원하지 않습니다. 그러나 shippingAdditional체크 아웃에 사용할 수있는 차단을 제공합니다 . 다음 솔루션은 표준 마 젠토 체크 아웃에서 작동합니다.

먼저 양식을 넣을 수있는 용기를 준비합시다. 파일을 만들려면view/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>

이제 Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js녹아웃 템플릿을 렌더링 할 파일을 만듭니다 . 내용은 다음과 같습니다

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();
        }
    });
});

이 파일은에 배치 해야하는 녹아웃 템플릿을 사용합니다 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>

이제 배송 방법 표에서 방법 (코드로 정의 됨)을 선택할 때 표시 될 선택 필드가 있습니다. 몇 가지 옵션으로 채울 시간입니다. 값은 주소에 따라 다르므로 사용 가능한 옵션을 제공하는 나머지 끝점을 만드는 것이 가장 좋습니다. 에Vendor/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>

이제 인터페이스를 다음 Vendor/Module/Api/OfficeManagementInterface.php과 같이 정의하십시오.

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);
}

에서 사무실 데이터에 대한 인터페이스를 정의하십시오 Vendor\Module\Api\Data\OfficeInterface.php. 이 인터페이스는 webapi 모듈에서 출력에 대한 데이터를 필터링하는 데 사용되므로 응답에 추가 할 항목을 정의해야합니다.

namespace Vendor\Module\Api\Data;

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

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

실제 수업 시간. 모든 인터페이스에 대한 환경 설정 작성으로 시작하십시오.Vendor/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>

이제 Vendor\Module\Model\OfficeManagement.php데이터를 가져 오는 논리를 실제로 수행 할 클래스를 작성 하십시오.

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;
    }
}

그리고위한 마지막 수업 OfficeInterface에서Vendor/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');
    }
}

주소가 변경되면 선택 필드가 표시되고 업데이트되어야합니다. 그러나 프론트 엔드 조작을위한 요소가 하나 더 누락되었습니다. 엔드 포인트를 호출 할 함수를 작성해야합니다. 그것에 대한 호출은 이미 포함되어 Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js있으며 다음 코드 Vendor_Module/js/view/checkout/shipping/office-service로 이동 해야하는 클래스입니다 Vendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.js.

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);
                        }
                    );
                }
            }
        };
    }
);

2 개 이상의 js 파일을 사용합니다. Vendor_Module/js/view/checkout/shipping/model/resource-url-manager엔드 포인트에 대한 URL을 작성하고 매우 간단합니다.

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-registry로컬 저장소에 결과를 유지하는 방법입니다. 코드는 다음과 같습니다.

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;
            }
        };
    }
);

자, 우리는 모두 프론트 엔드에서 작업해야합니다. 그러나 이제 해결해야 할 또 다른 문제가 있습니다. 체크 아웃은이 양식에 대해 아무것도 모르므로 선택 결과를 백엔드로 보내지 않습니다. 이를 위해서는 extension_attributes기능 을 사용해야 합니다. 이는 magento2에서 일부 추가 데이터가 나머지 호출에있을 것으로 시스템에 알리는 방법입니다. 그것이 없으면 magento는 그 데이터를 걸러 내고 결코 코드에 도달하지 않을 것입니다.

따라서 먼저 Vendor/Module/etc/extension_attributes.xml정의하십시오.

<?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>

이 값은 이미 요청에 form.js의해 this.selectedOffice.subscribe()정의 에 의해 삽입되었습니다 . 따라서 위의 구성은 입구에서만 전달합니다. 코드에서 가져 오려면 플러그인을 만드십시오.Vendor/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>

그 수업 안에서

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;
    }
}

물론 가치를 저장할 위치는 전적으로 요구 사항에 달려 있습니다. 위의 코드는 추가 열 만들 필요 carrier_office에서 quote_addresssales_address(의 테이블 및 이벤트 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>

견적 주소에 저장된 데이터를 판매 주소로 복사합니다.

폴란드어 캐리어 InPost에 대한 내 모듈에 이것을 작성 했으므로 코드를 손상시킬 수있는 이름을 변경했지만 필요한 것을 줄 수 있기를 바랍니다.

[편집하다]

@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;
    }
}

답장을 보내 주셔서 감사합니다. 방법을 사용하여 문제를 해결하려고 노력하며 요즘 결과에 답장합니다.
Siarhey Uchukhlebau

@ Zefiryn 사용자 정의 배송 방법을 만들었습니다. 아래에 고객의 배송 계정 번호가있는 드롭 다운이 표시됩니다 (사용자 정의 고객 속성이 생성되어 있음)이 드롭 다운을 표시 해야하는 경우 코드의 몇 퍼센트가 도움이됩니까? 제공 한 코드에서 무엇을 선택해야합니까?
Shireen N

@shireen 나는 약 70 %를 말할 것입니다. 기계를 계정 번호로 가져 오는 부분을 변경해야합니다. 따라서 API 정의는 slighlty
different

이 모듈을 사용해 보았습니다 ...하지만 변경 사항이 표시되지 않으므로 작업 모듈을 공유하십시오. 있다면
sangan

성공적인 모듈 ..in checkout ajax loading 지속적으로 추가 한 후 콘솔 오류가 다음과 같이 표시됩니다. require.js : 166 Uncaught Error : 스크립트 오류 : Vendor_Module / js / view / checkout / shipping / model / office- 레지스트리. requirejs.org/docs/errors.html#scripterror
sangan

2

이전에 이미 제공했지만 왜곡시키지 않고 확장 할 수있는 새로운 답변을 추가하고 있습니다.

이것은 QuoteAddressPlugin연결되는 경로입니다 .

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() 

마지막 방법은 Magento\Quote\Model\Quote\Address::setShippingMethod()실제로 호출 한 호출이었습니다 Magento\Quote\Model\Quote\Address::__call(). 지금은 플러그인을위한 더 좋은 곳을 찾았습니다 Magento\Quote\Model\ShippingAssignment::setShipping(). 방법입니다. 따라서 플러그인 부분을 다음과 같이 다시 작성할 수 있습니다.

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

플러그인 자체 :

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, 나는 다음과 같은 문제를 겪었습니다. quote.shippingAddress().extensionAttributes.carrier_office = office;

손님으로 처음 체크 아웃 (새 개인 창)을 시작하면 (하지만 등록 된 클라이언트에서도 동일하게 발생) 속성 사무실은 처음 "다음"후에 데이터베이스에 저장되지 않습니다. 콘솔에서는 다음에 대한 올바른 출력이 표시됩니다.console.log(quote.shippingAddress().extensionAttributes.carrier_office);

첫 번째 결제 페이지로 돌아가서 office를 다시 선택하면 저장됩니다. 이 행동의 원인은 무엇입니까?

나는 사용하려고했다 : address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);

그러나 성공하지 못하면 ...


0

@ Zefiryn, 위의 플러그인이 어떻게 작동하는지 몇 마디로 설명 할 수 있습니까? 특정 객체에 존재하지 않는 메소드를 실행하려고하면 __call 메소드가 실행되기 때문에 혼란 스러울 것입니다. app / code / Magento / Quote / Model / Quote / Address.php에서 그런 방법을 보지 못하기 때문에 사실 인 것 같습니다.

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

  1. 메소드 구현이 없을 때 왜 인터 셉션을 사용합니까?
  2. 내가 볼 다음으로 $subject->setInpostMachine$subject->getCarrierOffice(null);합니까 그것은 그 위의 플러그인의 방법은 ADRESS 클래스에는 setInpostMachine ()와 getCarrierOffice () 메소드가 없기 때문에 다시 실행됩니다 의미? 그것은 나에게 루프처럼 보입니다.
  3. Magento가 어디에서 실행 setShippingMethod()됩니까? 이 방법이 얼마나 일반적으로 사용됩니까? 마 젠토 코드에서 비슷한 코드를 찾을 수 없습니다.

좋아, 테스트를 위해 작성한 모듈을 기반으로 답변을 준비했으며 inpost_machine 필드를 사용했기 때문에이 곳에서는 carrier_office로 올바르게 변경되지 않았습니다. 둘째,이 모듈을 개발할 때 객체 setShippingMethod에 대한 호출을 제외하고 전송 된 확장 속성으로 선택된 반송파와 주소를 모두 얻을 수있는 장소를 찾지 AddressInterface못했습니다. 그런 방법이 없기 때문에 around__call을 사용하여 setShippingMethod또는 다른 마술 분야라고 불렀습니다. 지금은 더 좋은 곳을 찾았으며 새 답장에 게시하겠습니다.
Zefiryn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.