Я разрабатываю способ доставки для какой-то логистической компании. Эта компания имеет много офисов, где клиент может получить свой заказ. Я могу получить список офисов по городам в API но я не знаю, как лучше представить этот шаг?
На данный момент я просто установил новый \Magento\Quote\Model\Quote\Address\RateResult\Method
для каждого офиса в городе, в большом городе это число> 100 и я думаю, что не очень хорошо устанавливать 100 строк в кассе.
Это будет общедоступный модуль для другого дизайна оформления заказа, так как я могу отобразить рядом с выбранным моим способом доставки какой-либо выпадающий список со списком офисов и установить цену и метод после того, как пользователь выберет один.
magento-2.1
checkout
shipping-methods
Джеймс Мориарти
источник
источник
Ответы:
Magento Checkout не поддерживает какие-либо формы для дополнительных данных метода доставки. Но это обеспечивает
shippingAdditional
блок в кассе, который может быть использован для этого. Следующее решение будет работать для стандартной проверки magento.Сначала давайте подготовим наш контейнер, куда мы можем поместить некоторую форму. Для этого создайте файл в
view/frontend/layout/checkout_index_index.xml
Теперь создайте файл, в
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
котором будет отображаться шаблон для нокаута. Его содержание выглядит такЭтот файл использует шаблон нокаута, который должен быть помещен в
Vendor/Module/view/frontend/web/template/checkout/shipping/form.html
Теперь у нас есть поле выбора, которое будет видно, когда наш метод (определенный его кодом) будет выбран в таблице методов доставки. Время заполнить его некоторыми опциями. Поскольку значения зависят от адреса, лучшим способом является создание конечной точки отдыха, которая будет предоставлять доступные параметры. В
Vendor/Module/etc/webapi.xml
Теперь определите интерфейс
Vendor/Module/Api/OfficeManagementInterface.php
какОпределить интерфейс для офисных данных в
Vendor\Module\Api\Data\OfficeInterface.php
. Этот интерфейс будет использоваться модулем webapi для фильтрации данных для вывода, поэтому вам нужно определить все, что нужно добавить в ответ.Время для реальных занятий. Начните с создания настроек для всех интерфейсов в
Vendor/Module/etc/di.xml
Теперь создайте
Vendor\Module\Model\OfficeManagement.php
класс, который будет фактически выполнять логику извлечения данных.И, наконец, класс для
OfficeInterface
вVendor/Module/Model/Office.php
Это должно показать поле выбора и обновить его при изменении адреса. Но мы упускаем еще один элемент для манипулирования интерфейсом. Нам нужно создать функцию, которая будет вызывать конечную точку. Вызов к нему уже включен,
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
со следующим кодом:Он использует еще 2 файла JS.
Vendor_Module/js/view/checkout/shipping/model/resource-url-manager
создает ссылку на конечную точку и довольно простоVendor_Module/js/view/checkout/shipping/model/office-registry
способ сохранить результат в локальном хранилище Его код:Итак, мы должны все работать на фронтенде. Но теперь есть еще одна проблема, которую нужно решить. Поскольку Checkout ничего не знает об этой форме, он не отправит результат выбора бэкэнду. Чтобы это произошло, нам нужно использовать
extension_attributes
функцию. В magento2 это способ информировать систему о том, что в остальных вызовах ожидаются дополнительные данные. Без этого magento отфильтровывал бы эти данные, и они никогда не достигли бы кода.Итак, сначала
Vendor/Module/etc/extension_attributes.xml
определимся:Это значение уже вставлено в запрос
form.js
поthis.selectedOffice.subscribe()
определению. Таким образом, приведенная выше конфигурация будет проходить только при входе. Чтобы получить его в коде, создайте плагин вVendor/Module/etc/di.xml
Внутри этого класса
Конечно, где вы сохраните ценность, полностью зависит от ваших требований. Приведенный выше код потребует создания дополнительного столбца
carrier_office
вquote_address
иsales_address
таблиц и события (вVendor/Module/etc/events.xml
)Это скопировало бы данные, сохраненные в адресе цитаты, в адрес продажи.
Я написал это для моего модуля для польского носителя InPost, поэтому я изменил некоторые имена, которые могут нарушить код, но я надеюсь, что это даст вам то, что вам нужно.
[РЕДАКТИРОВАТЬ]
Модель носителя по запросу @sangan
источник
Я добавляю новый ответ, чтобы расширить то, что уже было предоставлено ранее, но не искажая его.
Это маршрут, который
QuoteAddressPlugin
был подключен к:Последний метод был вызовом,
Magento\Quote\Model\Quote\Address::setShippingMethod()
который фактически был вызовом,Magento\Quote\Model\Quote\Address::__call()
который я использовал. Прямо сейчас я нашел лучшее место для плагина, этоMagento\Quote\Model\ShippingAssignment::setShipping()
метод. Так что часть плагина может быть переписана на:и сам плагин:
источник
@Zefiryn, я столкнулся с проблемой:
quote.shippingAddress().extensionAttributes.carrier_office = office;
Когда я вхожу в кассу в первый раз (новое личное окно) в качестве гостя (но то же самое происходит с зарегистрированным клиентом), атрибут office не сохраняется в базе данных после первого «Next». Хотя в консоли я вижу правильный вывод для:
console.log(quote.shippingAddress().extensionAttributes.carrier_office);
Когда я возвращаюсь на первую страницу оформления заказа и снова выбираю офис, он сохраняется. Что может быть причиной такого поведения?
Я пытался использовать:
address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);
но без успеха ...
источник
@Zefiryn, не могли бы вы в двух словах объяснить, как работает ваш плагин выше? Я немного запутался, потому что, как я знаю, метод __call выполняется, если мы пытаемся выполнить метод execute, который не существует для определенного объекта. Кажется, это правда, потому что в app / code / Magento / Quote / Model / Quote / Address.php я не вижу такой метод - только комментарий:
/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)
$subject->setInpostMachine
и$subject->getCarrierOffice(null);
означает ли это, что вышеуказанный метод плагина будет выполнен снова, так как в классе Adress нет метода setInpostMachine () и getCarrierOffice ()? Это выглядит как петля для меня.setShippingMethod()
? Как обычно этот метод используется? Я не могу найти никаких схожих перехватов в коде Magento.источник
setShippingMethod
вызоваAddressInterface
объекта, и, поскольку такого метода нет, мне пришлось использовать около__call, чтобы увидеть,setShippingMethod
Называлось или какое-то другое магическое поле. Прямо сейчас я нашел лучшее место, и я отправлю это в новом ответе.