95 lines
3.0 KiB
PHP
95 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KupShop\BonusProgramBundle\Utils\Exchange;
|
|
|
|
use KupShop\BonusProgramBundle\Utils\BonusProvider;
|
|
use KupShop\KupShopBundle\Context\UserContext;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\OrderingBundle\Util\Discount\DiscountGenerator;
|
|
use Query\Operator;
|
|
|
|
class BonusExchangeUtil
|
|
{
|
|
private BonusProvider $bonusProvider;
|
|
private DiscountGenerator $discountGenerator;
|
|
|
|
public function __construct(BonusProvider $bonusProvider, DiscountGenerator $discountGenerator)
|
|
{
|
|
$this->bonusProvider = $bonusProvider;
|
|
$this->discountGenerator = $discountGenerator;
|
|
}
|
|
|
|
public function exchange(int $id, ?int $userId = null): bool
|
|
{
|
|
if (!$userId) {
|
|
if (!($userId = Contexts::get(UserContext::class)->getActiveId())) {
|
|
throw new \InvalidArgumentException('There is no active user neither userId argument was not specified');
|
|
}
|
|
}
|
|
|
|
return sqlGetConnection()->transactional(function () use ($id, $userId) {
|
|
if (!($item = $this->getExchangeItem($id))) {
|
|
throw new \RuntimeException('Bonus program exchange item not found');
|
|
}
|
|
|
|
$userPoints = $this->bonusProvider->getActivePointsAmount($userId);
|
|
if ($userPoints < $item['points']) {
|
|
return false;
|
|
}
|
|
|
|
// generate new coupon for specified user
|
|
$generated = $this->generateUserCoupon($item, (int) $item['id_discount'], (int) $userId);
|
|
|
|
if (($generated['count'] ?? 0) > 0) {
|
|
// subtract points from user
|
|
sqlQueryBuilder()
|
|
->insert('bonus_points')
|
|
->directValues(
|
|
[
|
|
'id_user' => $userId,
|
|
'points' => toDecimal($item['points'])->mul(\DecimalConstants::negativeOne()),
|
|
'date_created' => date('Y-m-d H:i:s'),
|
|
'note' => sprintf(translate_shop('exchangeLogMessage', 'bonus_program'), $item['points'], $item['name']),
|
|
'status' => 'active',
|
|
]
|
|
)->execute();
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
public function getExchangeItem(int $id): ?array
|
|
{
|
|
$item = sqlQueryBuilder()
|
|
->select('*')
|
|
->from('bonus_points_exchange')
|
|
->where(
|
|
Operator::equals(
|
|
[
|
|
'id' => $id,
|
|
'active' => 1,
|
|
]
|
|
)
|
|
)
|
|
->orderBy('id', 'DESC')
|
|
->forUpdate()
|
|
->execute()->fetchAssociative();
|
|
|
|
if (!$item) {
|
|
return null;
|
|
}
|
|
|
|
return $item;
|
|
}
|
|
|
|
protected function generateUserCoupon(array $item, int $discountId, int $userId): array
|
|
{
|
|
return $this->discountGenerator->generateNewCoupons(id_discount: $discountId, userId: $userId);
|
|
}
|
|
}
|