feat(data): add order repository
This commit is contained in:
1 parent
da11a2119a
commit
e2dbd78cc9
1 file changed
+126
@@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bazaar\Repositories;
|
||||||
|
|
||||||
|
use Bazaar\Core\Database;
|
||||||
|
|
||||||
|
final class OrderRepository
|
||||||
|
{
|
||||||
|
public function __construct(private readonly Database $db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(int $userId, int $totalCents, string $currency, int $discountCents = 0, ?string $couponCode = null): int
|
||||||
|
{
|
||||||
|
return $this->db->insert(
|
||||||
|
'INSERT INTO orders (userId, status, totalCents, currency, discountCents, couponCode, createdAt)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||||
|
[$userId, 'pending', $totalCents, $currency, $discountCents, $couponCode, gmdate('c')]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addItem(
|
||||||
|
int $orderId,
|
||||||
|
int $productId,
|
||||||
|
string $productName,
|
||||||
|
int $unitPriceCents,
|
||||||
|
int $quantity,
|
||||||
|
?int $variantId = null,
|
||||||
|
string $variantLabel = ''
|
||||||
|
): void {
|
||||||
|
$this->db->insert(
|
||||||
|
'INSERT INTO orderItems (orderId, productId, productName, unitPriceCents, quantity, variantId, variantLabel)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||||
|
[$orderId, $productId, $productName, $unitPriceCents, $quantity, $variantId, $variantLabel]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find(int $id): ?array
|
||||||
|
{
|
||||||
|
return $this->db->selectOne('SELECT * FROM orders WHERE id = ?', [$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findForUser(int $id, int $userId): ?array
|
||||||
|
{
|
||||||
|
return $this->db->selectOne('SELECT * FROM orders WHERE id = ? AND userId = ?', [$id, $userId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function items(int $orderId): array
|
||||||
|
{
|
||||||
|
return $this->db->select('SELECT * FROM orderItems WHERE orderId = ? ORDER BY id ASC', [$orderId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forUser(int $userId): array
|
||||||
|
{
|
||||||
|
return $this->db->select(
|
||||||
|
'SELECT * FROM orders WHERE userId = ? ORDER BY createdAt DESC, id DESC',
|
||||||
|
[$userId]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all(): array
|
||||||
|
{
|
||||||
|
return $this->db->select(
|
||||||
|
'SELECT o.*, u.email AS userEmail
|
||||||
|
FROM orders o
|
||||||
|
LEFT JOIN users u ON u.id = o.userId
|
||||||
|
ORDER BY o.createdAt DESC, o.id DESC'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setStatus(int $id, string $status, ?string $timestampColumn = null, ?string $stripeSessionId = null): void
|
||||||
|
{
|
||||||
|
$sql = 'UPDATE orders SET status = ?';
|
||||||
|
$bindings = [$status];
|
||||||
|
if ($timestampColumn !== null) {
|
||||||
|
$column = match ($timestampColumn) {
|
||||||
|
'paidAt' => 'paidAt',
|
||||||
|
'fulfilledAt' => 'fulfilledAt',
|
||||||
|
'cancelledAt' => 'cancelledAt',
|
||||||
|
};
|
||||||
|
$sql .= ", {$column} = ?";
|
||||||
|
$bindings[] = gmdate('c');
|
||||||
|
}
|
||||||
|
if ($stripeSessionId !== null) {
|
||||||
|
$sql .= ', stripeSessionId = ?';
|
||||||
|
$bindings[] = $stripeSessionId;
|
||||||
|
}
|
||||||
|
$sql .= ' WHERE id = ?';
|
||||||
|
$bindings[] = $id;
|
||||||
|
$this->db->statement($sql, $bindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByStripeSession(string $sessionId): ?array
|
||||||
|
{
|
||||||
|
return $this->db->selectOne('SELECT * FROM orders WHERE stripeSessionId = ?', [$sessionId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count(): int
|
||||||
|
{
|
||||||
|
return (int) $this->db->scalar('SELECT COUNT(*) FROM orders');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function countByStatus(string $status): int
|
||||||
|
{
|
||||||
|
return (int) $this->db->scalar('SELECT COUNT(*) FROM orders WHERE status = ?', [$status]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revenueCents(): int
|
||||||
|
{
|
||||||
|
return (int) $this->db->scalar(
|
||||||
|
"SELECT COALESCE(SUM(totalCents), 0) FROM orders WHERE status IN ('paid', 'fulfilled')"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recent(int $limit = 5): array
|
||||||
|
{
|
||||||
|
return $this->db->select(
|
||||||
|
'SELECT o.*, u.email AS userEmail
|
||||||
|
FROM orders o
|
||||||
|
LEFT JOIN users u ON u.id = o.userId
|
||||||
|
ORDER BY o.createdAt DESC, o.id DESC
|
||||||
|
LIMIT ?',
|
||||||
|
[$limit]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user