Search code examples
shopwareshopware6shopware6-api

Shopware 6 Plugin - Unable to Retrieve Shipping Costs and Shipping Methods on Product Detail Page


I'm currently working on a Shopware 6 plugin that aims to dynamically determine the shipping costs for a single product based on the default country of the store. I've created a custom file CustomShippingMethodRoute.php within my plugin's directory, and I've extended the ShippingMethodRoute class to modify the shipping prices. However, I'm facing an issue where I can't see the output of the modified shipping methods on either the product detail page or the shopping cart.

Here's my current implementation:

use Shopware\Core\Checkout\Shipping\ShippingMethodCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class CustomShippingMethodRoute extends ShippingMethodRoute
{
    public function load(Request $request, SalesChannelContext $context, Criteria $criteria): ShippingMethodRouteResponse
    {
        $originalResult = parent::load($request, $context, $criteria);
        $shippingMethods = $originalResult->getShippingMethods();

        foreach ($shippingMethods as $shippingMethod) {
            $shippingPrice = 2; // Placeholder for the actual shipping price calculation
            $shippingMethod->setShippingPrice($shippingPrice);
        }

        $modifiedResult = new ShippingMethodRouteResponse($shippingMethods);

        return $modifiedResult;
    }
}

My config.xml:

<service id="Tanmar\TanmarProductReviews\CustomShippingPrices\Core\Checkout\Shipping\SalesChannel\CustomShippingMethodRoute">
    <tag name="shopware.sales_channel.shipping_method_route" />
    <argument type="service" id="Shopware\Core\Checkout\Shipping\SalesChannel\ShippingMethodRoute" />
</service>

I've added dd($shippingMethods) to output the shipping methods for debugging, but I can't see the output neither on the product detail page nor on the shopping cart. It seems like my modifications aren't reflected.

My questions are:

  1. How can I ensure that the modified shipping methods are being correctly loaded and applied to the product detail page?

  2. Is there an alternative or recommended approach to dynamically retrieving shipping costs for a single product in Shopware 6 without adding the product to the shopping cart?

I appreciate any insights or guidance on how to resolve this issue and successfully retrieve the shipping costs based on my plugin's logic.


Solution

  • You have to decorate the original route.

    <service id="SwagBasicExample\Route\MyCustomShippingMethodRoute" 
             decorates="Shopware\Core\Checkout\Shipping\SalesChannel\ShippingMethodRoute" 
             public="true">
        <argument type="service" id="SwagBasicExample\Route\MyCustomShippingMethodRoute.inner"/>
    </service>
    
    use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
    use Shopware\Core\Framework\Routing\Annotation\Entity;
    use Shopware\Core\System\SalesChannel\SalesChannelContext;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    
    /**
     * @Route(defaults={"_routeScope"={"store-api"}})
     */
    class MyCustomShippingMethodRoute extends AbstractShippingMethodRoute
    {
        private AbstractShippingMethodRoute $decorated;
    
        public function __construct(AbstractShippingMethodRoute $decorated) 
        {
            $this->decorated = $decorated;
        }
    
        public function getDecorated(): AbstractShippingMethodRoute
        {
            return $this->decorated;
        }
    
        /**
         * @Entity("shipping_method")
         * @Route("/store-api/shipping-method", name="store-api.shipping.method", methods={"GET", "POST"})
         */
        public function load(Request $request, SalesChannelContext $context, Criteria $criteria): ShippingMethodRouteResponse
        {
            $original = $this->decorated->load($request, $context, $criteria);
            
            // ...
        }
    }