How to change shipping method programmatically

I have tried various ways so far with CartService and Collector/Processor as well. There is similar class DeliveryProcessor.php and I overwrited the file but I didn’t succeed in changing the shipment. Can someone shine some light.

For test purpose this is how i calculate shipping costs.

$manualShippingCosts = new CalculatedPrice(0.0, 0.0, new CalculatedTaxCollection(), new TaxRuleCollection());

I am really not sure whether we should use collector/processor to change shipping as we change price or use cartService.

Complete class

class DeliveryProcessorOverWrite implements CartDataCollectorInterface, CartProcessorInterface
{
    public const MANUAL_SHIPPING_COSTS = 'manualShippingCosts';

    public const SKIP_DELIVERY_PRICE_RECALCULATION = 'skipDeliveryPriceRecalculation';

    public const SKIP_DELIVERY_TAX_RECALCULATION = 'skipDeliveryTaxRecalculation';

    /**
     * @var DeliveryBuilder
     */
    protected $builder;

    /**
     * @var DeliveryCalculator
     */
    protected $deliveryCalculator;

    /**
     * @var EntityRepositoryInterface
     */
    protected $shippingMethodRepository;

    public function __construct(
        DeliveryBuilder $builder,
        DeliveryCalculator $deliveryCalculator,
        EntityRepositoryInterface $shippingMethodRepository
    ) {
        $this->builder = $builder;
        $this->deliveryCalculator = $deliveryCalculator;
        $this->shippingMethodRepository = $shippingMethodRepository;
    }

    public static function buildKey(string $shippingMethodId): string
    {
        return 'shipping-method-' . $shippingMethodId;
    }

    public function collect(CartDataCollection $data, Cart $original, SalesChannelContext $context, CartBehavior $behavior): void
    {
        Profiler::trace('cart::delivery::collect', function () use ($data, $original, $context): void {
            $default = $context->getShippingMethod()->getId();

            if (!$data->has(self::buildKey($default))) {
                $ids = [$default];
            }

            foreach ($original->getDeliveries() as $delivery) {
                $id = $delivery->getShippingMethod()->getId();

                if (!$data->has(self::buildKey($id))) {
                    $ids[] = $id;
                }
            }

            if (empty($ids)) {
                return;
            }

            $criteria = new Criteria($ids);
            $criteria->addAssociation('prices');
            $criteria->addAssociation('deliveryTime');
            $criteria->addAssociation('tax');
            $criteria->setTitle('cart::shipping-methods');

            $shippingMethods = $this->shippingMethodRepository->search($criteria, $context->getContext());

            foreach ($ids as $id) {
                $key = self::buildKey($id);

                if (!$shippingMethods->has($id)) {
                    continue;
                }

                $data->set($key, $shippingMethods->get($id));
            }
        }, 'cart');
    }

    public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void
    {
        Profiler::trace('cart::delivery::process', function () use ($data, $original, $toCalculate, $context, $behavior): void {
            $deliveries = $this->builder->build($toCalculate, $data, $context, $behavior);

            $delivery = $deliveries->first();

            if ($behavior->hasPermission(self::SKIP_DELIVERY_PRICE_RECALCULATION)) {
                $originalDeliveries = $original->getDeliveries();

                $originalDelivery = $originalDeliveries->first();

                if ($delivery !== null && $originalDelivery !== null) {
                    $originalDelivery->setShippingMethod($delivery->getShippingMethod());

                    //Keep old prices
                    $manualShippingCosts = new CalculatedPrice(0.0, 0.0, new CalculatedTaxCollection(), new TaxRuleCollection());

                    $delivery->setShippingCosts($manualShippingCosts);

                    //Recalculate tax
                    $this->deliveryCalculator->calculate($data, $toCalculate, $deliveries, $context);
                    $originalDelivery->setShippingCosts($manualShippingCosts);
                }

                // New shipping method (if changed) but with old prices
                $toCalculate->setDeliveries($originalDeliveries);

                return;
            }
            $manualShippingCosts = new CalculatedPrice(0.0, 0.0, new CalculatedTaxCollection(), new TaxRuleCollection());

            if ($delivery !== null && $manualShippingCosts instanceof CalculatedPrice) {
                $delivery->setShippingCosts($manualShippingCosts);
            }

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

            $toCalculate->setDeliveries($deliveries);
        }, 'cart');
    }
}
1 „Gefällt mir“