Files
esun3d/app/code/Esun/Reward/Model/ReservationManager.php
T
2026-09-15 10:35:56 +08:00

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]); }
}