私はMagento 2 サイトでWebShopApps_MatrixRatesモジュールを使用しています。モジュールは、地域向けの 1 つの配信方法と、その地域の一部の都市向けの他の 2 つの配信方法で構成されています。
カートページに「税と配送料の見積もり」フォームを設定して、地域と都市のフィールドを表示しました。好み:
Magento\Checkout\Block\Cart\LayoutProcessor
public function process($jsLayout)
{
$elements = [
'city' => [
'visible' => true,
'formElement' => 'select',
'label' => __('City'),
'options' => $this->bcCitiesOptionsArray,
],
'country_id' => [
'visible' => false, //Remove the country
'formElement' => 'select',
'label' => __('Country'),
'options' => [],
'value' => null
],
'region_id' => [
'visible' => true,
'formElement' => 'select',
'label' => __('State/Province'),
'options' => [],
'value' => null
],
'postcode' => [
'visible' => false, //Remove Postal Code
'formElement' => 'input',
'label' => __('Zip/Postal Code'),
'value' => null
]
];
if (!isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {
$jsLayout['components']['checkoutProvider']['dictionaries'] = [
'country_id' => $this->countryCollection->loadByStore()->toOptionArray(),
'region_id' => $this->regionCollection->addAllowedCountriesFilter()->toOptionArray(),
];
}
if (isset($jsLayout['components']['block-summary']['children']['block-shipping']['children']
['address-fieldsets']['children'])
) {
$fieldSetPointer = &$jsLayout['components']['block-summary']['children']['block-shipping']
['children']['address-fieldsets']['children'];
$fieldSetPointer = $this->merger->merge($elements, 'checkoutProvider', 'shippingAddress', $fieldSetPointer);
$fieldSetPointer['region_id']['config']['skipValidation'] = true;
}
return $jsLayout;
}
2 つの方法で都市を選択すると、正しい方法と価格の配送フォームが読み込まれます。
ただし、メソッドが選択された後、$addressInformationパラメータがクラスのcalculate()メソッドに渡されます。
Magento\Checkout\Model\TotalsInformationManagement
public function calculate(
$cartId,
\Magento\Checkout\Api\Data\TotalsInformationInterface $addressInformation
) {
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $this->cartRepository->get($cartId);
$this->validateQuote($quote);
if ($quote->getIsVirtual()) {
$quote->setBillingAddress($addressInformation->getAddress());
} else {
$quote->setShippingAddress($addressInformation->getAddress());
$quote->getShippingAddress()->setCollectShippingRates(true)->setShippingMethod(
$addressInformation->getShippingCarrierCode() . '_' . $addressInformation->getShippingMethodCode()
);
}
$quote->collectTotals();
return $this->cartTotalRepository->get($cartId);
}
都市に関する情報は含まれていません。
このため、モジュール MatrixRates はデータベースから間違った配送方法をロードし、2 つの異なる$this->getShippingMethod()および$rate->getGode()コードを取得します。
Magento\見積もり\モデル\見積もり\住所
public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractItem $item = null)
{
/** @var $request \Magento\Quote\Model\Quote\Address\RateRequest */
$request = $this->_rateRequestFactory->create();
$request->setAllItems($item ? [$item] : $this->getAllItems());
$request->setDestCountryId($this->getCountryId());
$request->setDestRegionId($this->getRegionId());
$request->setDestRegionCode($this->getRegionCode());
$request->setDestStreet($this->getStreetFull());
$request->setDestCity($this->getCity());
$request->setDestPostcode($this->getPostcode());
$request->setPackageValue($item ? $item->getBaseRowTotal() : $this->getBaseSubtotal());
$packageWithDiscount = $item ? $item->getBaseRowTotal() -
$item->getBaseDiscountAmount() : $this->getBaseSubtotalWithDiscount();
$request->setPackageValueWithDiscount($packageWithDiscount);
$request->setPackageWeight($item ? $item->getRowWeight() : $this->getWeight());
$request->setPackageQty($item ? $item->getQty() : $this->getItemQty());
/**
* Need for shipping methods that use insurance based on price of physical products
*/
$packagePhysicalValue = $item ? $item->getBaseRowTotal() : $this->getBaseSubtotal() -
$this->getBaseVirtualAmount();
$request->setPackagePhysicalValue($packagePhysicalValue);
$request->setFreeMethodWeight($item ? 0 : $this->getFreeMethodWeight());
/**
* Store and website identifiers specified from StoreManager
*/
$request->setQuoteStoreId($this->getQuote()->getStoreId());
$request->setStoreId($this->storeManager->getStore()->getId());
$request->setWebsiteId($this->storeManager->getWebsite()->getId());
$request->setFreeShipping($this->getFreeShipping());
/**
* Currencies need to convert in free shipping
*/
$request->setBaseCurrency($this->storeManager->getStore()->getBaseCurrency());
$request->setPackageCurrency($this->storeManager->getStore()->getCurrentCurrency());
$request->setLimitCarrier($this->getLimitCarrier());
$baseSubtotalInclTax = $this->getBaseSubtotalTotalInclTax();
$request->setBaseSubtotalInclTax($baseSubtotalInclTax);
$result = $this->_rateCollector->create()->collectRates($request)->getResult();
$found = false;
if ($result) {
$shippingRates = $result->getAllRates();
foreach ($shippingRates as $shippingRate) {
$rate = $this->_addressRateFactory->create()->importShippingRate($shippingRate);
if (!$item) {
$this->addShippingRate($rate);
}
if($this->getShippingMethod() === "_" && $this->getShippingMethod() === null){
$this->setShippingMethod($rate->getCode());
}
if ($this->getShippingMethod() == $rate->getCode()) {
if ($item) {
$item->setBaseShippingAmount($rate->getPrice());
} else {
/** @var \Magento\Store\Api\Data\StoreInterface */
$store = $this->storeManager->getStore();
$amountPrice = $store->getBaseCurrency()
->convert($rate->getPrice(), $store->getCurrentCurrencyCode());
$this->setBaseShippingAmount($rate->getPrice());
$this->setShippingAmount($amountPrice);
}
$found = true;
}
}
}
この条件
if ($this->getShippingMethod() == $rate->getCode()) {
if ($item) {
$item->setBaseShippingAmount($rate->getPrice());
} else {
/** @var \Magento\Store\Api\Data\StoreInterface */
$store = $this->storeManager->getStore();
$amountPrice = $store->getBaseCurrency()
->convert($rate->getPrice(), $store->getCurrentCurrencyCode());
$this->setBaseShippingAmount($rate->getPrice());
$this->setShippingAmount($amountPrice);
}
$found = true;
}
は満たされておらず、関数はfalseを返します
これにより、クラスでメソッドcollectShippingRates()が発生します
Magento\見積もり\モデル\見積もり\住所
配送方法の価格を 0 に設定:
$found = $this->requestShippingRates();
if (!$found) {
$this->setShippingAmount(0)->setBaseShippingAmount(0)->setShippingMethod('')->setShippingDescription('');
}
では、 $shippingInformation変数に都市を追加するにはどうすればよいでしょうか。