You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shopware 6中添加支持折扣计算的附加费?

问题描述

按照Shopware官方指南添加购物车附加费后,附加费未被折扣计算。例如购物车商品总价100€,添加10€附加费后,应用10%折扣仅减免10€,预期应减免11€。

当前实现代码如下:

处理器代码

<?php declare(strict_types=1);

namespace SurchargePlugin\Core\Checkout\Cart;

use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\CartBehavior;
use Shopware\Core\Checkout\Cart\CartProcessorInterface;
use Shopware\Core\Checkout\Cart\LineItem\CartDataCollection;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Checkout\Cart\Price\AbsolutePriceCalculator;
use Shopware\Core\Checkout\Cart\Price\Struct\AbsolutePriceDefinition;
use Shopware\Core\Checkout\Cart\Rule\LineItemRule;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Contracts\Translation\TranslatorInterface;

class ProductConfiguratorProcessor implements CartProcessorInterface
{
    public const SURCHARGE_LINE_ITEM_TYPE = 'my_surcharge';

    private AbsolutePriceCalculator $calculator;

    private TranslatorInterface $translator;

    public function __construct(AbsolutePriceCalculator $calculator, TranslatorInterface $translator)
    {
        $this->calculator = $calculator;
        $this->translator = $translator;
    }

    /**
     * @param CartDataCollection $data
     * @param Cart $original
     * @param Cart $toCalculate
     * @param SalesChannelContext $context
     * @param CartBehavior $behavior
     * @return void
     */
    public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void
    {
        $products = $this->findSurchargeProducts($toCalculate);

        // no surcharge products found? early return
        if ($products->count() === 0) {
            return;
        }

        foreach ($products as $product) {
            $surchargeLineItem = $this->createSurcharge($product);

            // declare price definition to define how this price is calculated
            $definition = new AbsolutePriceDefinition(
                10,
                new LineItemRule(LineItemRule::OPERATOR_EQ, $products->getKeys())
            );

            $surchargeLineItem->setPriceDefinition($definition);

            // calculate price
            $surchargeLineItem->setPrice(
                $this->calculator->calculate($definition->getPrice(), $products->getPrices(), $context)
            );

            // add surcharge to new cart
            $toCalculate->add($surchargeLineItem);
        }
    }

    /**
     * @param LineItem $product
     * @return LineItem
     */
    private function createSurcharge(LineItem $product): LineItem
    {
        $surchargeLineItem = new LineItem(Uuid::randomHex(), self::SURCHARGE_LINE_ITEM_TYPE, null, 1);

        $surchargeLineItem->setLabel("Surcharge");
        $surchargeLineItem->setGood(false);
        $surchargeLineItem->setStackable(true);
        $surchargeLineItem->setRemovable(false);
        $surchargeLineItem->setQuantity($product->getQuantity());

        return $surchargeLineItem;
    }
}

services.xml 优先级配置

<tag name="shopware.cart.processor" priority="4500" />
解决方案

要让附加费被折扣纳入计算,需要调整以下几点:

  1. 修改附加费的LineItem属性,标记为参与折扣计算
    Shopware默认仅将特定类型的条目纳入折扣范围,当前代码设置setGood(false)会排除附加费的折扣计算。建议使用Shopware内置的附加费类型,并调整属性:
private function createSurcharge(LineItem $product): LineItem
{
    // 使用Shopware内置附加费类型,确保被折扣系统识别
    $surchargeLineItem = new LineItem(Uuid::randomHex(), LineItem::TYPE_SURCHARGE, null, 1);

    $surchargeLineItem->setLabel("Surcharge");
    $surchargeLineItem->setGood(true); // 标记为商品类条目,纳入总价计算
    $surchargeLineItem->setStackable(true);
    $surchargeLineItem->setRemovable(false);
    $surchargeLineItem->setQuantity($product->getQuantity());

    return $surchargeLineItem;
}
  1. 调整处理器优先级,确保附加费在折扣前被添加
    Shopware默认折扣处理器优先级为5000,当前4500的优先级会导致折扣计算时附加费尚未加入购物车。需将优先级调高至高于5000:
<tag name="shopware.cart.processor" priority="5500" />
  1. 修正价格定义的关联规则
    当前代码中每个附加费关联所有符合条件的商品,逻辑存在重复。建议调整为单个附加费关联对应商品:
$definition = new AbsolutePriceDefinition(
    10,
    new LineItemRule(LineItemRule::OPERATOR_EQ, [$product->getId()])
);
  1. 确保折扣规则包含附加费类型(自定义类型时)
    如果坚持使用自定义my_surcharge类型,需在折扣规则的条件中添加LineItemTypeRule,明确包含该类型,让折扣应用到附加费条目上。
验证

修改后测试流程:

  • 添加100€商品到购物车,自动添加10€附加费,购物车总价110€
  • 应用10%折扣,应减免11€,最终总价99€

内容的提问来源于stack exchange,提问作者lucamario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:37:33