如何在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" />
解决方案
要让附加费被折扣纳入计算,需要调整以下几点:
- 修改附加费的
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; }
- 调整处理器优先级,确保附加费在折扣前被添加
Shopware默认折扣处理器优先级为5000,当前4500的优先级会导致折扣计算时附加费尚未加入购物车。需将优先级调高至高于5000:
<tag name="shopware.cart.processor" priority="5500" />
- 修正价格定义的关联规则
当前代码中每个附加费关联所有符合条件的商品,逻辑存在重复。建议调整为单个附加费关联对应商品:
$definition = new AbsolutePriceDefinition( 10, new LineItemRule(LineItemRule::OPERATOR_EQ, [$product->getId()]) );
- 确保折扣规则包含附加费类型(自定义类型时)
如果坚持使用自定义my_surcharge类型,需在折扣规则的条件中添加LineItemTypeRule,明确包含该类型,让折扣应用到附加费条目上。
验证
修改后测试流程:
- 添加100€商品到购物车,自动添加10€附加费,购物车总价110€
- 应用10%折扣,应减免11€,最终总价99€
内容的提问来源于stack exchange,提问作者lucamario
相关产品推荐
相关产品推荐

