购物车估计含税运费-收取运费总额的问题

时间:2019-04-27 12:16:12

标签: php magento2 cart shipping-method

我在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 变量中添加城市?

1 个答案:

答案 0 :(得分:0)

我找到了解决方法,这很简单!
由于文件中的过滤,未将城市添加到地址中

vendor/magento/module-checkout/view/frontend/web/js/model/cart/totals-processor/default.js

方法 loadFromServer()第32行:

    FXMLDocumentController controller = loader.getController();
    controller.initForsikredeKunder(passedCustomer);

所以我只是覆盖文件

vendor/magento/module-checkout/view/frontend/web/js/model/cart/cache.js
更改为我的主题,并更改了第78行

来自:

address: _.pick(address, cartCache.requiredFields)

收件人:

        requiredFields: ['countryId', 'region', 'regionId', 'postcode'],

它解决了问题!