140 lines
3.9 KiB
PHP
140 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace KupShop\BonusProgramBundle\Utils;
|
|
|
|
use Doctrine\DBAL\Exception;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Context\UserContext;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\KupShopBundle\Util\Price\Price;
|
|
use KupShop\OrderDiscountBundle\Util\DiscountManager;
|
|
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class BonusProvider
|
|
{
|
|
#[Required]
|
|
public DiscountManager $discountManager;
|
|
|
|
#[Required]
|
|
public PurchaseUtil $purchaseUtil;
|
|
|
|
public function __construct(
|
|
protected readonly UserContext $userContext,
|
|
protected readonly ContextManager $contextManager,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function getActivePointsAmount(int|\User|null $user): int
|
|
{
|
|
if ($user === null) {
|
|
return 0;
|
|
}
|
|
|
|
$contexts = [];
|
|
if ($user instanceof \User) {
|
|
$contexts[UserContext::class] = $user;
|
|
}
|
|
|
|
return $this->contextManager->activateContexts(
|
|
$contexts,
|
|
fn () => $this->handleFetchActivePointsAmount(is_int($user) ? $user : $user->id),
|
|
);
|
|
}
|
|
|
|
public function getActivePointsValue(\User $user): ?Price
|
|
{
|
|
if (!($points = $this->getActivePointsAmount($user))) {
|
|
return null;
|
|
}
|
|
|
|
if (!($actions = $this->getBonusProgramActions())) {
|
|
return null;
|
|
}
|
|
|
|
$currencyContext = Contexts::get(CurrencyContext::class);
|
|
|
|
$action = reset($actions);
|
|
|
|
if (!($pointValue = ($action['data']['discount'] ?? null))) {
|
|
return null;
|
|
}
|
|
|
|
$pointCurrency = $action['data']['unit'] ?? $currencyContext->getDefaultId();
|
|
|
|
$pointsValue = toDecimal($pointValue)->mul(toDecimal($points));
|
|
|
|
return new Price(
|
|
$pointsValue,
|
|
$currencyContext->getOrDefault($pointCurrency),
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
* @throws \Exception
|
|
*/
|
|
protected function handleFetchActivePointsAmount(int $userId): int
|
|
{
|
|
$result = sqlQueryBuilder()
|
|
->select('SUM(points)')
|
|
->from('bonus_points')
|
|
->where(\Query\Operator::equals(['id_user' => $userId, 'status' => 'active']))
|
|
->execute()->fetchColumn();
|
|
|
|
return $result ? (int) $result : 0;
|
|
}
|
|
|
|
public function getPointsHistory($id_user, $spec = null)
|
|
{
|
|
$qb = sqlQueryBuilder()
|
|
->select('bp.*, o.order_no')
|
|
->from('bonus_points', 'bp')
|
|
->leftJoin('bp', 'orders', 'o', 'bp.id_order = o.id')
|
|
->where(\Query\Operator::equals(['bp.id_user' => $id_user]))
|
|
->orderBy('bp.date_created', 'DESC');
|
|
|
|
if ($spec) {
|
|
$qb->andWhere($spec);
|
|
}
|
|
|
|
return array_map(
|
|
function ($x) {
|
|
$x['data'] = json_decode($x['data'] ?: '', true) ?: [];
|
|
|
|
return $x;
|
|
},
|
|
$qb->execute()->fetchAllAssociative()
|
|
);
|
|
}
|
|
|
|
public function getPointsHistoryCount($id_user)
|
|
{
|
|
$qb = sqlQueryBuilder()
|
|
->select('COUNT(*) count')
|
|
->from('bonus_points', 'bp')
|
|
->where(\Query\Operator::equals(['bp.id_user' => $id_user]));
|
|
|
|
return $qb->execute()->fetchOne();
|
|
}
|
|
|
|
private function getBonusProgramActions(): array
|
|
{
|
|
$purchaseState = $this->purchaseUtil->getEmptyPurchaseState();
|
|
$actions = $purchaseState->getActions();
|
|
if (is_null($actions)) {
|
|
$this->discountManager->setPurchaseState($purchaseState);
|
|
$actions = $this->discountManager->getCurrentActions();
|
|
$purchaseState->setActions($actions);
|
|
$this->purchaseUtil->persistPurchaseState($purchaseState, true);
|
|
}
|
|
|
|
return $actions['bonus_program'] ?? [];
|
|
}
|
|
}
|