Saya mengembangkan metode pengiriman untuk beberapa perusahaan logistik. Perusahaan ini memiliki banyak kantor di mana pelanggan dapat memperoleh pesanannya. Saya bisa mendapatkan daftar kantor dengan сity di API tetapi saya tidak tahu bagaimana sebaiknya mewakili langkah ini?
Untuk saat ini saya baru saja menetapkan baru \Magento\Quote\Model\Quote\Address\RateResult\Method
untuk setiap kantor di kota, di kota besar itu menghitung> 100 dan saya pikir itu tidak terlalu baik untuk mengatur 100 baris di checkout.
Ini akan menjadi modul publik untuk desain checkout yang berbeda, jadi bagaimana saya bisa membuat dekat metode pengiriman saya memilih beberapa daftar dropdown dengan daftar kantor dan menetapkan harga dan metode setelah pengguna memilih satu.
sumber
Jawaban:
Checkout Magento tidak mendukung segala bentuk formulir untuk data tambahan metode pengiriman. Tetapi ia menyediakan
shippingAdditional
blokir dalam checkout yang dapat digunakan untuk ini. Solusi berikut akan berfungsi untuk checkout magento standar.Pertama mari kita siapkan wadah kita di mana kita bisa meletakkan beberapa formulir. Untuk melakukan ini, buat file di
view/frontend/layout/checkout_index_index.xml
Sekarang buat file di
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
mana akan membuat templat knockout. Isinya terlihat seperti iniFile ini menggunakan templat knockout yang harus ditempatkan
Vendor/Module/view/frontend/web/template/checkout/shipping/form.html
Kami sekarang memiliki bidang pilih yang akan terlihat ketika metode kami (ditentukan oleh kodenya) akan dipilih dalam tabel metode pengiriman. Saatnya mengisinya dengan beberapa opsi. Karena nilai tergantung pada alamat, cara terbaik adalah membuat titik akhir yang akan menyediakan opsi yang tersedia. Di
Vendor/Module/etc/webapi.xml
Sekarang tentukan antarmuka
Vendor/Module/Api/OfficeManagementInterface.php
sebagaiTentukan antarmuka untuk data kantor di
Vendor\Module\Api\Data\OfficeInterface.php
. Antarmuka ini akan digunakan oleh modul webapi untuk memfilter data untuk output sehingga Anda perlu mendefinisikan apa pun yang perlu Anda tambahkan ke dalam respons.Saatnya kelas aktual. Mulailah dengan membuat preferensi untuk semua antarmuka di
Vendor/Module/etc/di.xml
Sekarang buat
Vendor\Module\Model\OfficeManagement.php
kelas yang benar-benar akan melakukan logika pengambilan data.Dan akhirnya kelas
OfficeInterface
masukVendor/Module/Model/Office.php
Ini akan menampilkan bidang pilih dan memperbaruinya ketika alamat diubah. Tapi kita kehilangan satu elemen lagi untuk manipulasi frontend. Kita perlu membuat fungsi yang akan memanggil titik akhir. Panggilan untuk itu sudah termasuk dalam
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
dan ituVendor_Module/js/view/checkout/shipping/office-service
kelas yang harus pergiVendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.js
dengan kode berikut:Ini menggunakan 2 file js lebih.
Vendor_Module/js/view/checkout/shipping/model/resource-url-manager
membuat url ke titik akhir dan cukup sederhanaVendor_Module/js/view/checkout/shipping/model/office-registry
adalah cara menjaga hasil penyimpanan lokal. Kodenya adalah:Ok, jadi kita semua harus bekerja di frontend. Tapi sekarang ada masalah lain untuk diselesaikan. Karena checkout tidak tahu apa-apa tentang formulir ini, ia tidak akan mengirim hasil seleksi ke backend. Untuk mewujudkannya, kita perlu menggunakan
extension_attributes
fitur. Ini adalah cara di magento2 untuk menginformasikan sistem bahwa beberapa data tambahan diharapkan ada dalam panggilan lainnya. Tanpanya magento akan menyaring data itu dan mereka tidak akan pernah mencapai kode.Jadi yang pertama di
Vendor/Module/etc/extension_attributes.xml
definisikan:Nilai ini sudah dimasukkan dalam permintaan
form.js
menurutthis.selectedOffice.subscribe()
definisi. Jadi konfigurasi di atas hanya akan melewatinya di pintu masuk. Untuk mengambilnya di dalam kode, buat plugin diVendor/Module/etc/di.xml
Di dalam kelas itu
Tentu saja di mana Anda akan menghemat nilai sepenuhnya tergantung pada kebutuhan Anda. Kode di atas akan membutuhkan pembuatan kolom tambahan
carrier_office
diquote_address
dansales_address
tabel dan acara (dalamVendor/Module/etc/events.xml
)Itu akan menyalin data yang disimpan dalam alamat penawaran ke alamat penjualan.
Saya menulis ini untuk modul saya untuk carrier Polandia InPost jadi saya mengubah beberapa nama yang mungkin memecahkan kode tapi saya harap ini akan memberi Anda apa yang Anda butuhkan.
[EDIT]
Model pembawa ditanyakan oleh @sangan
sumber
Saya menambahkan jawaban baru untuk memperluas apa yang sudah disediakan sebelumnya tetapi tanpa merusaknya.
Ini adalah rute yang
QuoteAddressPlugin
menghubungkan ke:Metode terakhir adalah panggilan
Magento\Quote\Model\Quote\Address::setShippingMethod()
yang sebenarnya adalah panggilanMagento\Quote\Model\Quote\Address::__call()
yang saya gunakan. Saat ini saya menemukan tempat yang lebih baik untuk plugin, itu adalahMagento\Quote\Model\ShippingAssignment::setShipping()
metode. Jadi bagian plugin dapat ditulis ulang menjadi:dan plugin itu sendiri:
sumber
@Zefiryn, saya menemukan masalah dengan:
quote.shippingAddress().extensionAttributes.carrier_office = office;
Ketika saya masuk ke checkout pertama kali (jendela pribadi baru) sebagai tamu (tetapi hal yang sama terjadi dengan klien terdaftar) kantor atribut tidak disimpan ke dalam basis data setelah "Next" pertama. Meskipun di konsol saya melihat output yang benar untuk:
console.log(quote.shippingAddress().extensionAttributes.carrier_office);
Ketika saya kembali ke halaman checkout pertama dan memilih kantor lagi kemudian disimpan. Apa yang bisa menjadi alasan perilaku ini?
Saya mencoba menggunakan:
address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);
tetapi tanpa hasil ...
sumber
@Zefiryn, Dapatkah Anda menjelaskan dalam beberapa kata bagaimana cara kerja plugin Anda di atas? Saya sedikit bingung karena saya tahu metode __call dijalankan jika kita mencoba menjalankan metode yang tidak ada untuk objek tertentu. Tampaknya benar karena dalam aplikasi / kode / Magento / Kutipan / Model / Kutipan / Address.php Saya tidak melihat metode seperti itu - hanya komentar:
/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)
$subject->setInpostMachine
dan$subject->getCarrierOffice(null);
Apakah itu berarti bahwa metode plugin di atas akan dieksekusi lagi karena tidak ada metode setInpostMachine () dan getCarrierOffice () di Adress Class? Sepertinya loop ke saya.setShippingMethod()
? Bagaimana biasanya metode ini digunakan? Saya tidak dapat menemukan intersepsi simillar dalam kode Magento.sumber
setShippingMethod
memanggilAddressInterface
objek dan karena tidak ada metode seperti itu maka saya harus menggunakan around__call untuk melihat apakahsetShippingMethod
dipanggil atau bidang sihir lainnya. Saat ini saya telah menemukan tempat yang lebih baik dan saya akan mempostingnya di balasan baru.