我在Magento 2站点上使用WebShopApps_MatrixRates模块,模块配置了一个区域的交付方法和该区域中某些城市的另外两种交付方法。 我在购物车页面上设置了“估算税和运费”表格,以显示地区和城市字段。偏好:
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;
}
当我选择一个有两种方法的城市时,会加载具有正确方法和价格的运输表格。
但是选择该方法后,$ 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从数据库加载错误的送货方法,我们在这里得到两个不同的$ this-> getShippingMethod()和$ rate-> getGode()代码:
Magento\Quote\Model\Quote\Address
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\Quote\Model\Quote\Address
将送货方式价格设为0:
$found = $this->requestShippingRates();
if (!$found) {
$this->setShippingAmount(0)->setBaseShippingAmount(0)->setShippingMethod('')->setShippingDescription('');
}
那么,我如何将城市添加到$ shippingInformation变量?
我找到了解决方案,而且非常简单! 由于文件中的过滤,城市未添加到地址中
vendor/magento/module-checkout/view/frontend/web/js/model/cart/totals-processor/default.js
方法加载来自Server()第32行:
address: _.pick(address, cartCache.requiredFields)
所以我只是覆盖文件
vendor/magento/module-checkout/view/frontend/web/js/model/cart/cache.jsto my theme and changed line 78
从:
requiredFields: ['countryId', 'region', 'regionId', 'postcode'],
至:
requiredFields: ['countryId', 'region', 'regionId', 'city'],
它解决了这个问题!