我正在尝试实施一个PromotionAction,将免费添加多个产品到订单中,而我似乎无法正确实现Action的revert()方法。
这会导致用户向购物车中添加的每个商品都将免费商品添加到订单中。
我正在使用"sylius/sylius": "~1.5.0@rc"
这是类的一部分,我省略了_construct()
和isConfigurationValid()
方法,并且类常量ADJUSTMENT_TYPE
等于AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT
:
public function revert(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): void
{
/** @var OrderInterface $subject */
Assert::isInstanceOf($subject, OrderInterface::class);
try {
$this->isConfigurationValid($configuration);
$productVariant = $this->productVariantRepository->findOneByCode($configuration['variant']);
Assert::notNull($productVariant);
} catch (\InvalidArgumentException $exception) {
return;
}
$quantity = $configuration['quantity'];
foreach ($subject->getItems() as $item) {
if ($item->getVariant()->getCode() !== $configuration['variant']) {
continue;
}
// Find the OrderItemUnits that have adjustments from this promotion
// so we can remove them
$promoCode = $promotion->getCode();
$unitsToRemove = [];
foreach ($item->getUnits() as $unit) {
$adjustments = $unit->getAdjustments(self::ADJUSTMENT_TYPE)->filter(
function (AdjustmentInterface $adjustment) use ($promoCode) {
return $promoCode === $adjustment->getOriginCode();
}
);
$count = $adjustments->count(); // THIS ALWAYS RETURNS 0
if ($count > 0) {
$unitsToRemove[] = $unit;
}
}
foreach ($unitsToRemove as $unit) {
$item->removeUnit($unit);
}
}
return;
}
public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): bool
{
/** @var OrderInterface $subject */
Assert::isInstanceOf($subject, OrderInterface::class);
if (0 === $subject->countItems()) {
return false;
}
try {
$this->isConfigurationValid($configuration);
$productVariant = $this->productVariantRepository->findOneByCode($configuration['variant']);
Assert::notNull($productVariant);
} catch (\InvalidArgumentException $exception) {
return false;
}
$orderItem = null;
foreach ($subject->getItems() as $item) {
if ($item->getVariant()->getCode() === $productVariant->getCode()) {
$orderItem = $item;
break;
}
}
$unitPrice = $this->productVariantPriceCalculator->calculate(
$productVariant,
['channel' => $subject->getChannel()]
);
if (is_null($orderItem)) {
$orderItem = $this->orderItemFactory->createNew($subject);
$orderItem->setVariant($productVariant);
$orderItem->setUnitPrice($unitPrice);
$subject->addItem($orderItem);
}
$quantity = $this->calculateQuantity($subject, $configuration);
if ($quantity <= 0) {
return false;
}
$this->createUnits($quantity, $orderItem, $promotion);
return true;
}
private function createUnits(int $quantity, OrderItemInterface $orderItem, PromotionInterface $promotion): void
{
for ($i = 0; $i < $quantity; $i++) {
$unit = new OrderItemUnit($orderItem);
$this->addAdjustment($promotion, $unit, -$orderItem->getUnitPrice());
}
}
private function calculateQuantity(OrderInterface $order, array $configuration): int
{
if ($configuration['type'] === self::TYPE_FIXED) {
return $configuration['quantity'];
}
if ($configuration['itemQuantity'] == 0) {
return 0;
}
foreach ($order->getItems() as $item) {
if ($item->getVariant()->getCode() === $configuration['variant']) {
$quantity = intval(floor($item->getQuantity() / $configuration['itemQuantity']));
return $quantity * $configuration['quantity'];
}
}
return 0;
}
private function addAdjustment(PromotionInterface $promotion, OrderItemUnitInterface $unit, int $amount): void
{
$adjustment = $this->adjustmentFactory
->createWithData(self::ADJUSTMENT_TYPE, $promotion->getName(), $amount)
;
$adjustment->setOriginCode($promotion->getCode());
$unit->addAdjustment($adjustment);
}
The
// This always returns an empty array, even if I remove the filter() call
$adjustments = $unit->getAdjustments(self::ADJUSTMENT_TYPE)->filter(
function (AdjustmentInterface $adjustment) use ($promoCode) {
return $promoCode === $adjustment->getOriginCode();
}
);
revert()
方法中的应该返回在execute()
函数中添加的调整,但是它总是返回一个空集合。如果我使用AdjustmentRepository
,则可以检索它们,因此将它们添加到数据库中。
问题是我需要能够从内存中加载它们,因为我有一些端点需要对订单进行“预览”并应用所有促销。