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