167 lines
4.7 KiB
PHP
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;
|
|
}
|
|
}
|