Files
kupshop/bundles/KupShop/GlobalDiscountsBundle/Util/GlobalDiscounts.php
2025-08-02 16:30:27 +02:00

167 lines
4.7 KiB
PHP

<?php
namespace KupShop\GlobalDiscountsBundle\Util;
use KupShop\CatalogBundle\Util\ProductsFilterSpecs;
use Query\Operator;
class GlobalDiscounts
{
private $filterSpecs;
public function __construct(ProductsFilterSpecs $filterSpecs)
{
$this->filterSpecs = $filterSpecs;
}
public function activateDiscounts()
{
foreach ($this->getActivatableDiscounts() as $discount) {
$this->activateDiscount($discount);
}
}
public function deactivateDiscounts()
{
$deactivableDiscounts = $this->getDeactivableDiscounts();
foreach ($deactivableDiscounts as $discount) {
$this->deactivateDiscount($discount);
}
if (!empty($deactivableDiscounts)) {
$this->recalculateDiscounts();
}
}
public function recalculateDiscounts()
{
foreach ($this->getActiveDiscounts() as $discount) {
$this->updateProductsDiscount($discount['discount'], $discount['filter']);
}
}
public function activateDiscount(array $discount): bool
{
$this->updateProductsDiscount($discount['discount'], $discount['filter']);
$this->updateDiscount($discount['id'], ['active' => 1]);
return true;
}
public function deactivateDiscount(array $discount): bool
{
$this->updateProductsDiscount(0, $discount['filter']);
$this->updateDiscount($discount['id'], ['active' => 0]);
return true;
}
public function applyDiscountsOnProducts(array $productIds)
{
foreach ($this->getActiveDiscounts() as $discount) {
$this->updateProductsDiscount($discount['discount'], $discount['filter'], $productIds);
}
}
public function updateProductsDiscount($discountValue, $filter, ?array $productIds = null): void
{
$specs = $this->filterSpecs->getSpecs($filter);
$update = sqlQueryBuilder()->update('products', 'p')
->set('p.discount', ':discount')
->setParameter(':discount', $discountValue)
->andWhere($specs)
->andWhere(Operator::not(Operator::findInSet(['FS'], 'p.campaign')));
if ($productIds !== null) {
$update->andWhere(Operator::inIntArray($productIds, 'p.id'));
}
$update->execute();
}
public function updateDiscount(int $discountId, array $values)
{
sqlQueryBuilder()->update('global_discounts')
->directValues($values)
->where(Operator::equals(['id' => $discountId]))
->execute();
}
public function getDiscount(int $discountId)
{
$discount = $this->getQueryBuilder()->select('*')
->where(Operator::equals(['id' => $discountId]))
->execute()->fetch();
if (!$discount) {
return false;
}
return $this->prepareDiscount($discount);
}
public function getActiveDiscounts(): array
{
$discounts = $this->getQueryBuilder(true)
->execute()->fetchAll();
if (!$discounts) {
return [];
}
return array_map(function ($x) { return $this->prepareDiscount($x); }, $discounts);
}
public function getActivatableDiscounts(): array
{
$discounts = $this->getQueryBuilder(false)
->andWhere('(date_from <= :date AND date_to >= :date) OR (date_from IS NULL AND date_to IS NULL) OR (date_from <= :date AND date_to IS NULL) OR (date_from IS NULL AND date_to >= :date)')
->setParameter('date', new \DateTime(), 'datetime')
->execute()->fetchAll();
if (!$discounts) {
return [];
}
return array_map(function ($x) { return $this->prepareDiscount($x); }, $discounts);
}
public function getDeactivableDiscounts(): array
{
$discounts = $this->getQueryBuilder(true)
->andWhere('date_from >= :date OR date_to <= :date')
->orderBy('position')
->setParameter('date', new \DateTime(), 'datetime')
->execute()->fetchAll();
if (!$discounts) {
return [];
}
return array_map(function ($x) { return $this->prepareDiscount($x); }, $discounts);
}
protected function getQueryBuilder($active = null)
{
$qb = sqlQueryBuilder()->from('global_discounts')
->select('*')
->orderBy('position')
->sendToMaster();
if ($active !== null) {
$qb->andWhere(Operator::equals(['active' => $active ? 1 : 0]));
}
return $qb;
}
private function prepareDiscount($discount)
{
$discount['filter'] = json_decode($discount['filter'], true);
return $discount;
}
}