29 lines
2.1 KiB
PHP
29 lines
2.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Reward\Model;
|
|
|
|
use Magento\Framework\App\ResourceConnection;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
|
|
class ReservationManager
|
|
{
|
|
public function __construct(private readonly ResourceConnection $resource, private readonly BalanceManager $balances) {}
|
|
public function reserve(int $customerId, int $websiteId, int $quoteId, int $points): void
|
|
{
|
|
$connection = $this->resource->getConnection(); $table = $this->resource->getTableName('esun_reward_reservation');
|
|
$connection->beginTransaction();
|
|
try {
|
|
$accountTable = $this->resource->getTableName('esun_reward_account');
|
|
$connection->insertOnDuplicate($accountTable, ['customer_id' => $customerId, 'website_id' => $websiteId], []);
|
|
$account = $connection->fetchRow($connection->select()->from($accountTable)->where('customer_id = ?', $customerId)->where('website_id = ?', $websiteId)->forUpdate(true));
|
|
$otherReserved = (int)$connection->fetchOne($connection->select()->from($table, ['SUM(points)'])->where('customer_id = ?', $customerId)->where('status = ?', 'active')->where('quote_id != ?', $quoteId)->where('expires_at IS NULL OR expires_at > ?', date('Y-m-d H:i:s')));
|
|
if ($points > max(0, (int)$account['balance'] - $otherReserved)) { throw new LocalizedException(__('You do not have enough available reward points.')); }
|
|
if ($points <= 0) { $connection->delete($table, ['quote_id = ?' => $quoteId]); }
|
|
else { $connection->insertOnDuplicate($table, ['customer_id' => $customerId, 'quote_id' => $quoteId, 'points' => $points, 'status' => 'active', 'expires_at' => date('Y-m-d H:i:s', time() + 86400)], ['customer_id', 'points', 'status', 'expires_at']); }
|
|
$connection->commit();
|
|
} catch (\Throwable $e) { if ($connection->getTransactionLevel() > 0) { $connection->rollBack(); } throw $e; }
|
|
}
|
|
public function markUsed(int $quoteId): void { $this->resource->getConnection()->update($this->resource->getTableName('esun_reward_reservation'), ['status' => 'used'], ['quote_id = ?' => $quoteId]); }
|
|
}
|