Files
kupshop/bundles/KupShop/PreordersBundle/Service/PreorderItemsUpdater.php
2025-08-02 16:30:27 +02:00

132 lines
4.6 KiB
PHP

<?php
namespace KupShop\PreordersBundle\Service;
use Doctrine\DBAL\Exception as DBALException;
use KupShop\CatalogBundle\ProductList\ProductCollection;
use KupShop\KupShopBundle\Exception\InvalidArgumentException;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use KupShop\PreordersBundle\Entity\Preorder;
use KupShop\PreordersBundle\Entity\UserPreorder;
class PreorderItemsUpdater
{
public function __construct(
private readonly DynamicContexts $contextsService,
private readonly PreorderUtil $listUtil,
) {
}
/**
* @throws DBALException|InvalidArgumentException
*/
public function updateItems(UserPreorder $userPreorder, array $items): void
{
/** @var ProductCollection $products */
$products = $this->contextsService->withBasePrices($userPreorder->getPreorder(), function () use ($items) {
return $this->listUtil->getPreorderProductList($items)->getProducts();
});
QueryHint::withRouteToMaster(function () use ($userPreorder, $products) {
foreach ($products as $product) {
$userPreorder->setItem(
idProduct: (int) $product->id,
idVariation: ($product instanceof \Variation)
? (int) $product->variationId : null,
count: (int) $product['pieces'],
);
}
$this->recalculatePiecePrices($userPreorder);
});
}
/**
* @throws DBALException|InvalidArgumentException
*/
public function recalculatePiecePrices(UserPreorder $userPreorder): void
{
if (PreorderUtil::useMultipleDates()) {
$this->recalculatePricesForAllDates($userPreorder->getPreorder(), $userPreorder->getUser());
} else {
$this->recalculatePricesForSingleUserPreorder($userPreorder);
}
}
/**
* @throws DBALException|InvalidArgumentException
*/
private function recalculatePricesForAllDates(Preorder $preorder, \User $user): void
{
$allItems = $preorder->getItemsByUser($user);
/** @var array<int, array> $itemsInDates mapping of id_preorder_date => user preorder items in specified date */
$itemsInDates = [];
foreach ($allItems as $item) {
foreach ($item['pieces_per_date'] as $dateId => $_) {
if (!isset($itemsInDates[$dateId])) {
$itemsInDates[$dateId] = [];
}
$itemsInDates[$dateId][] = $item;
}
}
foreach ($itemsInDates as $dateId => $items) {
$userPreorder = new UserPreorder($user->id, $dateId);
/** @var ProductCollection $products */
$products = $this->contextsService->withDynamicPrices(
preorder: $preorder,
items: $allItems,
callback: function () use ($userPreorder) {
$productList = $this->listUtil->getPreorderProductList($userPreorder->getItems(true));
$productList->addResultModifiers($this->listUtil->modifierProductPriceToActiveCurrency());
return $productList->getProducts();
},
);
foreach ($products as $product) {
$userPreorder->setItem(
idProduct: (int) $product->id,
idVariation: ($product instanceof \Variation)
? (int) $product->variationId : null,
piecePrice: $product->getProductPrice(),
);
}
}
}
/**
* @throws DBALException|InvalidArgumentException
*/
private function recalculatePricesForSingleUserPreorder(UserPreorder $userPreorder): void
{
$items = $userPreorder->getItems(true);
/** @var ProductCollection $products */
$products = $this->contextsService->withDynamicPrices(
preorder: $userPreorder->getPreorder(),
items: $items,
callback: function () use ($items) {
$productList = $this->listUtil->getPreorderProductList($items);
$productList->addResultModifiers($this->listUtil->modifierProductPriceToActiveCurrency());
return $productList->getProducts();
},
);
foreach ($products as $product) {
$userPreorder->setItem(
idProduct: (int) $product->id,
idVariation: ($product instanceof \Variation)
? (int) $product->variationId
: null,
piecePrice: $product->getProductPrice(),
);
}
}
}