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

标签 php shopware

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

出于测试目的,购物车中的每个订单项产品的价格均为 100 欧元。

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

<?php declare(strict_types=1);

namespace Test\TestPlugin\Core\Checkout\Cart;

use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\CartBehavior;
use Shopware\Core\Checkout\Cart\CartDataCollectorInterface;
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\Price\AbsolutePriceCalculator;
use Shopware\Core\Checkout\Cart\Price\PercentagePriceCalculator;
use Shopware\Core\Checkout\Cart\Price\QuantityPriceCalculator;
use Shopware\Core\Checkout\Cart\Price\Struct\AbsolutePriceDefinition;
use Shopware\Core\Checkout\Cart\Price\Struct\PercentagePriceDefinition;
use Shopware\Core\Checkout\Cart\Price\Struct\QuantityPriceDefinition;
use Shopware\Core\System\SalesChannel\SalesChannelContext;

class OverwritePriceCollector implements CartDataCollectorInterface, CartProcessorInterface
{
    /**
     * @var QuantityPriceCalculator
     */
    private $calculator;

    public function __construct(QuantityPriceCalculator $calculator) {
        $this->calculator = $calculator;
    }

    public function collect(CartDataCollection $data, Cart $original, SalesChannelContext $context, CartBehavior $behavior): void
    {
        // get all product ids of current cart
        $productIds = $original->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE)->getReferenceIds();

        // remove all product ids which are already fetched from the database
        $filtered = $this->filterAlreadyFetchedPrices($productIds, $data);

        // Skip execution if there are no prices to be saved
        if (empty($filtered)) {
            return;
        }

        foreach ($filtered as $id) {
            $key = $this->buildKey($id);

            // Needs implementation, just an example
            $newPrice = 100;

            // we have to set a value for each product id to prevent duplicate queries in next calculation
            $data->set($key, $newPrice);
        }
    }

    public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void
    {
        // get all product line items
        $products = $toCalculate->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE);

        foreach ($products as $product) {
            $key = $this->buildKey($product->getReferencedId());

            // no overwritten price? continue with next product
            if (!$data->has($key) || $data->get($key) === null) {
                continue;
            }

            $newPrice = $data->get($key);

            // build new price definition
            $definition = new QuantityPriceDefinition(
                $newPrice,
                $product->getPrice()->getTaxRules(),
                $product->getPrice()->getQuantity()
            );

            // build CalculatedPrice over calculator class for overwritten price
            $calculated = $this->calculator->calculate($definition, $context);

            // set new price into line item
            $product->setPrice($calculated);
            $product->setPriceDefinition($definition);
        }
    }

    private function filterAlreadyFetchedPrices(array $productIds, CartDataCollection $data): array
    {
        $filtered = [];

        foreach ($productIds as $id) {
            $key = $this->buildKey($id);

            // already fetched from database?
            if ($data->has($key)) {
                continue;
            }

            $filtered[] = $id;
        }

        return $filtered;
    }

    private function buildKey(string $id): string
    {
        return 'price-overwrite-'.$id;
    }
}

enter image description here

最佳答案

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

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

关于php - Shopware 6 价格收集器/处理器的折扣计算错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69346405/

相关文章:

symfony - 商店 6 : Twig files not loaded when using sw_include

shopware - 重新发送特定订单状态电子邮件,例如订单交付在 Shopware 6 中发货

php - 如何在php中追加文本

javascript - 在 ajax 成功时刷新 DIV

PHP 计算数据库中特定条目的行数

php - 成功查询时出现 fetch_object() 错误

symfony - Shopware 6 后端 Controller 路径

php - 如何检查函数是否已存在于 SPL 堆栈中?

商店软件 6 : how to route shopware unit test output from fixture to original folder?

git - 如何在 Shopware 6 开发系统上管理媒体?提交到 git 还是不提交?