Shopware 6 价格收集器/处理器上的折扣计算错误

luc*_*rio 2 php shopware

我完全按照文档中的描述实现了价格收集器/处理器(https://developer.shopware.com/docs/guides/plugins/plugins/checkout/cart/change-price-of-item)。

\n

出于测试目的,购物车中的每个订单项产品的价格为 100\xe2\x82\xac。

\n

当应用我在管理员中创建的折扣 (10%) 时,折扣将应用于产品的原始价格,而不是实际的新购物车价格。\n我在这里错过了什么?我的 OverwritePriceCollector.php 如下所示:

\n
<?php declare(strict_types=1);\n\nnamespace Test\\TestPlugin\\Core\\Checkout\\Cart;\n\nuse Shopware\\Core\\Checkout\\Cart\\Cart;\nuse Shopware\\Core\\Checkout\\Cart\\CartBehavior;\nuse Shopware\\Core\\Checkout\\Cart\\CartDataCollectorInterface;\nuse Shopware\\Core\\Checkout\\Cart\\CartProcessorInterface;\nuse Shopware\\Core\\Checkout\\Cart\\LineItem\\CartDataCollection;\nuse Shopware\\Core\\Checkout\\Cart\\LineItem\\LineItem;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\AbsolutePriceCalculator;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\PercentagePriceCalculator;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\QuantityPriceCalculator;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\Struct\\AbsolutePriceDefinition;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\Struct\\PercentagePriceDefinition;\nuse Shopware\\Core\\Checkout\\Cart\\Price\\Struct\\QuantityPriceDefinition;\nuse Shopware\\Core\\System\\SalesChannel\\SalesChannelContext;\n\nclass OverwritePriceCollector implements CartDataCollectorInterface, CartProcessorInterface\n{\n    /**\n     * @var QuantityPriceCalculator\n     */\n    private $calculator;\n\n    public function __construct(QuantityPriceCalculator $calculator) {\n        $this->calculator = $calculator;\n    }\n\n    public function collect(CartDataCollection $data, Cart $original, SalesChannelContext $context, CartBehavior $behavior): void\n    {\n        // get all product ids of current cart\n        $productIds = $original->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE)->getReferenceIds();\n\n        // remove all product ids which are already fetched from the database\n        $filtered = $this->filterAlreadyFetchedPrices($productIds, $data);\n\n        // Skip execution if there are no prices to be saved\n        if (empty($filtered)) {\n            return;\n        }\n\n        foreach ($filtered as $id) {\n            $key = $this->buildKey($id);\n\n            // Needs implementation, just an example\n            $newPrice = 100;\n\n            // we have to set a value for each product id to prevent duplicate queries in next calculation\n            $data->set($key, $newPrice);\n        }\n    }\n\n    public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void\n    {\n        // get all product line items\n        $products = $toCalculate->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE);\n\n        foreach ($products as $product) {\n            $key = $this->buildKey($product->getReferencedId());\n\n            // no overwritten price? continue with next product\n            if (!$data->has($key) || $data->get($key) === null) {\n                continue;\n            }\n\n            $newPrice = $data->get($key);\n\n            // build new price definition\n            $definition = new QuantityPriceDefinition(\n                $newPrice,\n                $product->getPrice()->getTaxRules(),\n                $product->getPrice()->getQuantity()\n            );\n\n            // build CalculatedPrice over calculator class for overwritten price\n            $calculated = $this->calculator->calculate($definition, $context);\n\n            // set new price into line item\n            $product->setPrice($calculated);\n            $product->setPriceDefinition($definition);\n        }\n    }\n\n    private function filterAlreadyFetchedPrices(array $productIds, CartDataCollection $data): array\n    {\n        $filtered = [];\n\n        foreach ($productIds as $id) {\n            $key = $this->buildKey($id);\n\n            // already fetched from database?\n            if ($data->has($key)) {\n                continue;\n            }\n\n            $filtered[] = $id;\n        }\n\n        return $filtered;\n    }\n\n    private function buildKey(string $id): string\n    {\n        return \'price-overwrite-\'.$id;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

小智 7

我认为您的问题是您以与文档(4500)中相同的优先级注册了您的收集器。ShopwarePromotionProcessor的注册优先级为 4900,因此您的代码在 后调用PromotionProcessor

所以你需要的是以OverwritePriceCollector更高的优先级注册你的,例如5000。