Ich entwickle eine Versandmethode für ein Logistikunternehmen. Diese Firma hat viele Büros, in denen der Kunde seine Bestellung erhalten kann. Ich kann die Liste der Büros nach Stadt in der API abrufen, aber wie kann ich diesen Schritt jetzt nicht besser darstellen?
Im Moment habe ich \Magento\Quote\Model\Quote\Address\RateResult\Method
jedes Büro in der Stadt neu eingerichtet, in der Großstadt sind es mehr als 100, und ich denke, es ist nicht sehr gut, 100 Zeilen in der Kasse einzustellen.
Es wird ein öffentliches Modul für verschiedene Checkout-Designs sein, also wie kann ich eine Dropdown-Liste mit einer Liste von Büros in der Nähe meiner ausgewählten Versandmethode rendern und den Preis und die Methode festlegen, nachdem der Benutzer eine ausgewählt hat.
quelle
Antworten:
Magento Checkout unterstützt keine Formulare für zusätzliche Versandartdaten. Aber es gibt einen
shippingAdditional
Block in der Kasse, der dafür verwendet werden kann. Die folgende Lösung funktioniert für die normale Magento-Kaufabwicklung.Lassen Sie uns zuerst unseren Container vorbereiten, in den wir eine Form einfügen können. Erstellen Sie dazu eine Datei in
view/frontend/layout/checkout_index_index.xml
Erstellen Sie nun eine Datei, in
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
der eine Aussparungsvorlage gerendert wird. Sein Inhalt sieht so ausDiese Datei verwendet eine Aussparungsvorlage, die abgelegt werden sollte
Vendor/Module/view/frontend/web/template/checkout/shipping/form.html
Wir haben jetzt ein Auswahlfeld, das sichtbar ist, wenn unsere (durch ihren Code definierte) Methode in der Versandartentabelle ausgewählt wird. Zeit, es mit einigen Optionen zu füllen. Da die Werte von der Adresse abhängig sind, können Sie am besten einen Ruheendpunkt erstellen, der die verfügbaren Optionen bereitstellt. Im
Vendor/Module/etc/webapi.xml
Definieren Sie nun die Schnittstelle in
Vendor/Module/Api/OfficeManagementInterface.php
alsSchnittstelle für Bürodaten definieren in
Vendor\Module\Api\Data\OfficeInterface.php
. Diese Schnittstelle wird vom webapi-Modul verwendet, um Daten für die Ausgabe zu filtern, sodass Sie definieren müssen, was Sie der Antwort hinzufügen möchten.Zeit für den eigentlichen Unterricht. Beginnen Sie mit dem Erstellen von Einstellungen für alle Schnittstellen in
Vendor/Module/etc/di.xml
Erstellen Sie nun eine
Vendor\Module\Model\OfficeManagement.php
Klasse, die die Logik zum Abrufen der Daten ausführt.Und zum Schluss Klasse für
OfficeInterface
inVendor/Module/Model/Office.php
Dies sollte das Auswahlfeld anzeigen und aktualisieren, wenn die Adresse geändert wird. Es fehlt jedoch noch ein Element für die Frontend-Manipulation. Wir müssen eine Funktion erstellen, die den Endpunkt aufruft. Der Aufruf dazu ist bereits in enthalten
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
und es ist eineVendor_Module/js/view/checkout/shipping/office-service
Klasse, dieVendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.js
mit dem folgenden Code aufgerufen werden sollte:Es werden 2 weitere js-Dateien verwendet.
Vendor_Module/js/view/checkout/shipping/model/resource-url-manager
Erstellt eine URL zum Endpunkt und ist ziemlich einfachVendor_Module/js/view/checkout/shipping/model/office-registry
ist eine Möglichkeit, das Ergebnis im lokalen Speicher zu halten. Sein Code lautet:Ok, wir sollten also alle am Frontend arbeiten. Aber jetzt gibt es ein anderes Problem zu lösen. Da Checkout nichts über dieses Formular weiß, wird das Auswahlergebnis nicht an das Backend gesendet. Um dies zu erreichen, müssen wir verwenden
extension_attributes
Funktion verwenden. Dies ist eine Möglichkeit in magento2, das System darüber zu informieren, dass einige zusätzliche Daten in den restlichen Aufrufen erwartet werden. Ohne sie würde Magento diese Daten herausfiltern und sie würden niemals den Code erreichen.Also zuerst
Vendor/Module/etc/extension_attributes.xml
definieren:Dieser Wert ist
form.js
perthis.selectedOffice.subscribe()
Definition bereits in die Anfrage eingefügt . Die obige Konfiguration wird also nur am Eingang übergeben. Um es in den Code zu holen, erstelle ein PluginVendor/Module/etc/di.xml
In dieser Klasse
Wo Sie den Wert speichern, hängt natürlich ganz von Ihren Anforderungen ab. Für den obigen Code müssten zusätzliche Spalten
carrier_office
inquote_address
undsales_address
Tabellen sowie ein Ereignis (inVendor/Module/etc/events.xml
) erstellt werden.Dadurch würden die in der Angebotsadresse gespeicherten Daten in die Verkaufsadresse kopiert.
Ich habe dies für mein Modul für den polnischen Anbieter InPost geschrieben, sodass ich einige Namen geändert habe, die möglicherweise den Code sprengen, aber ich hoffe, dies wird Ihnen das geben, was Sie brauchen.
[BEARBEITEN]
Carrier-Modell von @sangan gefragt
quelle
Ich füge eine neue Antwort hinzu, um das bereits Gelieferte zu erweitern, ohne es zu verzerren.
Dies ist die Route,
QuoteAddressPlugin
die eingehakt wurde:Die letzte Methode war das Aufrufen des
Magento\Quote\Model\Quote\Address::setShippingMethod()
Anrufs,Magento\Quote\Model\Quote\Address::__call()
den ich verwendet habe. Im Moment habe ich einen besseren Ort für das Plugin gefunden, es ist eineMagento\Quote\Model\ShippingAssignment::setShipping()
Methode. So kann der Plugin-Teil umgeschrieben werden:und Plugin selbst:
quelle
@Zefiryn, ich bin auf folgendes Problem gestoßen:
quote.shippingAddress().extensionAttributes.carrier_office = office;
Wenn ich zum ersten Mal (neues privates Fenster) als Gast zur Kasse gehe (aber dasselbe gilt für einen registrierten Kunden), wird das Attribut office nach dem ersten "Weiter" nicht in der Datenbank gespeichert. Obwohl ich in der Konsole die korrekte Ausgabe für Folgendes sehe:
console.log(quote.shippingAddress().extensionAttributes.carrier_office);
Wenn ich zur ersten Checkout-Seite zurückkehre und erneut Büro auswähle, wird es gespeichert. Was könnte der Grund für dieses Verhalten sein?
Ich habe versucht zu benutzen:
address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);
aber ohne Erfolg...
quelle
@Zefiryn, Kannst du in wenigen Worten erklären, wie dein obiges Plugin funktioniert? Ich bin wenig verwirrt, weil, wie ich weiß, die __call-Methode ausgeführt wird, wenn wir versuchen, eine Methode auszuführen, die für ein bestimmtes Objekt nicht existiert. Es scheint wahr zu sein, denn in app / code / Magento / Quote / Model / Quote / Address.php sehe ich keine solche Methode - nur Kommentar:
/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)
$subject->setInpostMachine
und$subject->getCarrierOffice(null);
Bedeutet dies, dass die Methode des obigen Plugins erneut ausgeführt wird, da es in der Adressklasse keine setInpostMachine () - und getCarrierOffice () -Methode gibt? Es sieht aus wie Schleife für mich.setShippingMethod()
? Wie normal wird diese Methode angewendet? Ich kann keine ähnlichen Interceptions in Magento-Code finden.quelle
setShippingMethod
Call-on-AddressInterface
ObjectsetShippingMethod
genannt wurde oder ein anderes magisches Feld. Im Moment habe ich einen besseren Ort gefunden und werde ihn in einer neuen Antwort veröffentlichen.