Home > Back-end >  Shopware 6 change shipping method programmatically in checkout on order submission
Shopware 6 change shipping method programmatically in checkout on order submission

Time:05-22

I have two of same shipping methods with different price matrix, depending on customer distance, one of the two shipping method should be selected. This has to be done programmatically on checkout order confirmation, I looked at the cart collector, but it's about changing price of an item. I didn't find anything covered in documentation regarding shipping method change.

Following is my attempt to change it onOrderValidation.

private function getShippingMethod(string $id, Context $context): ?ShippingMethodEntity
{
    $criteria = new Criteria();
    $criteria->addFilter(new EqualsFilter("id", $id));
    $criteria->setLimit(1);
    $result = $this->shippingMethodRepository->search($criteria, $context);
    return $result->getEntities()->first();
}

    public function onOrderValidation(BuildValidationEvent $event)
{

    $cart = $this->cartService->getCart($this->salesChannelContext->getToken(), $this->salesChannelContext);

    $delivery = $cart->getDeliveries()->first();

    //test


    $shippingMethod = $this->getShippingMethod($this->getShippingMethodZoneXId(), $event->getContext());
    
    $delivery->setshippingMethod($shippingMethod);

    $cartDeliveries = new DeliveryCollection();

    $cartDeliveries->add($delivery);

    $cart->addDeliveries($cartDeliveries);

    $this->cartService->setCart($cart);
    
    ...

}

In the above code I have cart object, and delivery. I get the shipping method which I need to set, but it doesn't get updated.

Also i need to recalculate shipping price, what is the correct way to do it. any suggestion will be appreciated.

Update: I have also tried from shopware doc collect/process, but that also didn't work.

public function collect(CartDataCollection $data, Cart $original, SalesChannelContext $context, CartBehavior $behavior): void
{
    $shippingMethod = $this->getShippingMethod($this->getShippingMethodZoneXId(), $context->getContext());
    $shippingMethodId = $shippingMethod->getId();

    $key = self::buildShippingKey($shippingMethodId);

    $data->set($key, $shippingMethod);
}

public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void
{

    // change delviery

    $deliveries = $this->builder->build($toCalculate, $data, $context, $behavior);

    $deliveryOriginal = $deliveries->first();
    
    if($deliveryOriginal === null) {
        return;
    }

    $shippingMethod = $this->getShippingMethod($this->getShippingMethodZoneXId(), $context->getContext());

    $deliveries->first()->setShippingMethod($shippingMethod);

    $this->deliveryCalculator->calculate($data, $toCalculate, $deliveries, $context);

    $toCalculate->setDeliveries($deliveries);

}

CodePudding user response:

I completely ended up with another approach, none of the above seem to work for me. Item price updation was taking place but not shipment.

So here's what you need, this contextSwitcher dependency i injected and it did the job. update() method that can be used to switch shipment method.

SalesChannelContextSwitcher $contextSwitcher,

CodePudding user response:

thanks for sharing your answer, but how exactly did you use the SalesChannelContextSwitcher in your code?

I'm actually struggling with a similar problem...trying to change the shipping costs... Unfortunately, without any success. Maybe your solution will give me the right direction to go.

  • Related