Smile-SA / magento2-module-store-delivery

Magento2 Store Delivery Module
Open Software License 3.0
22 stars 29 forks source link

Store Delivery not working in M2 2.3.4 #28

Open Fdec opened 4 years ago

Fdec commented 4 years ago

Store Delivery not working in Magento 2.3.4 due to this Magento issue https://github.com/magento/magento2/issues/26682

We can't load the shpping method price in checkout.

maximbaibakov commented 4 years ago

Hi there,

The fix in Magento Core https://github.com/iMi-digital/magento2/commit/ea70c0ba65fd76c037c33ed77e1e1a40abbdb45a

Part of this issue https://github.com/magento/magento2/issues/26682

Regards, Maxim

pcs-matze commented 4 years ago

Hi, I had the same issue, i've fixed it without changing the Magento-Core. It's required to have an own module where code can be applied.

VENDOR_NAME/MODULE_NAME/CoreBugFix/Quote/ShippingMethodManagement.php

<?php
/**
 * @author Matthias Richter, PCS IT-Trading GmbH, Vienna, Austria
 * @see https://github.com/magento/magento2/issues/26682
 * @see https://github.com/Smile-SA/magento2-module-store-delivery/issues/28
 *
 * Magento Core Bugfix
 */
namespace VENDOR_NAME\MODULE_NAME\CoreBugFix\Quote;

use Magento\Quote\Model\Quote;
use Magento\Framework\App\ObjectManager;
use Magento\Quote\Api\Data\EstimateAddressInterface;
use Magento\Customer\Model\Session as CustomerSession;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Framework\Reflection\DataObjectProcessor;

class ShippingMethodManagement extends \Magento\Quote\Model\ShippingMethodManagement {

    /**
     * @var \Magento\Framework\Reflection\DataObjectProcessor $dataProcessor
     */
    private $dataProcessor;

    /**
     * @inheritdoc
     */
    public function estimateByExtendedAddress($cartId, AddressInterface $address)
    {
        /** @var \Magento\Quote\Model\Quote $quote */
        $quote = $this->quoteRepository->getActive($cartId);

        // no methods applicable for empty carts or carts with virtual products
        if ($quote->isVirtual() || 0 == $quote->getItemsCount()) {
            return [];
        }
        return $this->getShippingMethods($quote, $address);
    }

    /*
     * @inheritDoc
     * Get list of available shipping methods
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param \Magento\Framework\Api\ExtensibleDataInterface $address
     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[]
     */
    private function getShippingMethods(Quote $quote, $address)
    {
        $output = [];
        $shippingAddress    = $quote->getShippingAddress();
        $shippingAddress->addData($this->extractAddressData($address));

        // Bugfix!!!
        $shippingAddress->setExtensionAttributes( $address->getExtensionAttributes() );

        $shippingAddress->setCollectShippingRates(true);

        $this->totalsCollector->collectAddressTotals($quote, $shippingAddress);
        $quoteCustomerGroupId = $quote->getCustomerGroupId();
        $customerGroupId = $this->getCustomerSession()->getCustomerGroupId();
        $isCustomerGroupChanged = $quoteCustomerGroupId !== $customerGroupId;
        if ($isCustomerGroupChanged) {
            $quote->setCustomerGroupId($customerGroupId);
        }
        $shippingRates = $shippingAddress->getGroupedAllShippingRates();
        foreach ($shippingRates as $carrierRates) {
            foreach ($carrierRates as $rate) {
                $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode());
            }
        }
        if ($isCustomerGroupChanged) {
            $quote->setCustomerGroupId($quoteCustomerGroupId);
        }
        return $output;
    }

    /**
     * @inheritDoc
     * Get transform address interface into Array
     *
     * @param \Magento\Framework\Api\ExtensibleDataInterface  $address
     * @return array
     */
    private function extractAddressData($address)
    {
        $className = \Magento\Customer\Api\Data\AddressInterface::class;
        if ($address instanceof \Magento\Quote\Api\Data\AddressInterface) {
            $className = \Magento\Quote\Api\Data\AddressInterface::class;
        } elseif ($address instanceof EstimateAddressInterface) {
            $className = EstimateAddressInterface::class;
        }
        return $this->getDataObjectProcessor()->buildOutputDataArray(
            $address,
            $className
        );
    }

    /**
     * @inheritDoc
     * Gets the data object processor
     *
     * @return \Magento\Framework\Reflection\DataObjectProcessor
     * @deprecated 101.0.0
     */
    private function getDataObjectProcessor()
    {
        if ($this->dataProcessor === null) {
            $this->dataProcessor = ObjectManager::getInstance()
                ->get(DataObjectProcessor::class);
        }
        return $this->dataProcessor;
    }

    /**
     * To avoid copy of constructor, CustomerSession will be injected in the "dirty way". Constructor does it in the same way.
     * @author Matthias Richter, PCS IT-Trading GmbH, Vienna, Austria
     * @return CustomerSession
     */
    private function getCustomerSession() {
        return ObjectManager::getInstance()->get(CustomerSession::class);
    }

}

Register in etc/di.xml (Add following lines)

<preference for="Magento\Quote\Api\ShippingMethodManagementInterface" type="VENDOR_NAME\MODULE_NAME\CoreBugFix\Quote\ShippingMethodManagement" />
<preference for="Magento\Quote\Api\ShipmentEstimationInterface" type="VENDOR_NAME\MODULE_NAME\CoreBugFix\Quote\ShippingMethodManagement" />
<preference for="Magento\Quote\Model\ShippingMethodManagementInterface" type="VENDOR_NAME\MODULE_NAME\CoreBugFix\Quote\ShippingMethodManagement" />

Kind regards