> */ public function listGroups(): array { $stmt = $this->pdo->query( 'SELECT id, name, code, color_hex, sort_order, is_active, created_at, updated_at FROM order_status_groups ORDER BY sort_order ASC, id ASC' ); $rows = $stmt !== false ? $stmt->fetchAll() : []; return is_array($rows) ? array_values(array_filter($rows, static fn (mixed $row): bool => is_array($row))) : []; } /** * @return array> */ public function listStatuses(): array { $stmt = $this->pdo->query( 'SELECT s.id, s.group_id, g.name AS group_name, g.code AS group_code, g.color_hex AS group_color_hex, s.name, s.code, s.sort_order, s.is_active, s.created_at, s.updated_at FROM order_statuses s INNER JOIN order_status_groups g ON g.id = s.group_id ORDER BY g.sort_order ASC, g.id ASC, s.sort_order ASC, s.id ASC' ); $rows = $stmt !== false ? $stmt->fetchAll() : []; return is_array($rows) ? array_values(array_filter($rows, static fn (mixed $row): bool => is_array($row))) : []; } public function groupExists(int $groupId): bool { $stmt = $this->pdo->prepare('SELECT id FROM order_status_groups WHERE id = :id LIMIT 1'); $stmt->execute(['id' => $groupId]); return (bool) $stmt->fetchColumn(); } /** * @return array|null */ public function findGroupById(int $groupId): ?array { $stmt = $this->pdo->prepare( 'SELECT id, name, code, color_hex, sort_order, is_active, created_at, updated_at FROM order_status_groups WHERE id = :id LIMIT 1' ); $stmt->execute(['id' => $groupId]); $row = $stmt->fetch(); return is_array($row) ? $row : null; } public function existsGroupCode(string $code, int $excludeId = 0): bool { $stmt = $this->pdo->prepare( 'SELECT id FROM order_status_groups WHERE code = :code AND id <> :exclude_id LIMIT 1' ); $stmt->execute([ 'code' => $code, 'exclude_id' => $excludeId, ]); return (bool) $stmt->fetchColumn(); } public function existsStatusCode(string $code, int $excludeId = 0): bool { $stmt = $this->pdo->prepare( 'SELECT id FROM order_statuses WHERE code = :code AND id <> :exclude_id LIMIT 1' ); $stmt->execute([ 'code' => $code, 'exclude_id' => $excludeId, ]); return (bool) $stmt->fetchColumn(); } public function statusExists(int $statusId): bool { $stmt = $this->pdo->prepare('SELECT id FROM order_statuses WHERE id = :id LIMIT 1'); $stmt->execute(['id' => $statusId]); return (bool) $stmt->fetchColumn(); } /** * @return array|null */ public function findStatusById(int $statusId): ?array { $stmt = $this->pdo->prepare( 'SELECT id, group_id, name, code, sort_order, is_active, created_at, updated_at FROM order_statuses WHERE id = :id LIMIT 1' ); $stmt->execute(['id' => $statusId]); $row = $stmt->fetch(); return is_array($row) ? $row : null; } public function createGroup(string $name, string $code, string $colorHex, int $sortOrder, bool $isActive): void { $stmt = $this->pdo->prepare( 'INSERT INTO order_status_groups (name, code, color_hex, sort_order, is_active, created_at, updated_at) VALUES (:name, :code, :color_hex, :sort_order, :is_active, :created_at, :updated_at)' ); $now = date('Y-m-d H:i:s'); $stmt->execute([ 'name' => $name, 'code' => $code, 'color_hex' => $colorHex, 'sort_order' => $sortOrder, 'is_active' => $isActive ? 1 : 0, 'created_at' => $now, 'updated_at' => $now, ]); } public function updateGroup(int $id, string $name, string $code, string $colorHex, bool $isActive): void { $stmt = $this->pdo->prepare( 'UPDATE order_status_groups SET name = :name, code = :code, color_hex = :color_hex, is_active = :is_active, updated_at = :updated_at WHERE id = :id' ); $stmt->execute([ 'id' => $id, 'name' => $name, 'code' => $code, 'color_hex' => $colorHex, 'is_active' => $isActive ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s'), ]); } public function deleteGroup(int $id): void { $stmt = $this->pdo->prepare('DELETE FROM order_status_groups WHERE id = :id'); $stmt->execute(['id' => $id]); } public function createStatus(int $groupId, string $name, string $code, int $sortOrder, bool $isActive): void { $stmt = $this->pdo->prepare( 'INSERT INTO order_statuses (group_id, name, code, sort_order, is_active, created_at, updated_at) VALUES (:group_id, :name, :code, :sort_order, :is_active, :created_at, :updated_at)' ); $now = date('Y-m-d H:i:s'); $stmt->execute([ 'group_id' => $groupId, 'name' => $name, 'code' => $code, 'sort_order' => $sortOrder, 'is_active' => $isActive ? 1 : 0, 'created_at' => $now, 'updated_at' => $now, ]); } public function updateStatus(int $id, int $groupId, string $name, string $code, bool $isActive): void { $stmt = $this->pdo->prepare( 'UPDATE order_statuses SET group_id = :group_id, name = :name, code = :code, is_active = :is_active, updated_at = :updated_at WHERE id = :id' ); $stmt->execute([ 'id' => $id, 'group_id' => $groupId, 'name' => $name, 'code' => $code, 'is_active' => $isActive ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s'), ]); } public function deleteStatus(int $id): void { $stmt = $this->pdo->prepare('DELETE FROM order_statuses WHERE id = :id'); $stmt->execute(['id' => $id]); } public function nextGroupSortOrder(): int { $stmt = $this->pdo->query('SELECT COALESCE(MAX(sort_order), -1) + 1 FROM order_status_groups'); $value = $stmt !== false ? $stmt->fetchColumn() : 0; return max(0, (int) $value); } public function nextStatusSortOrder(int $groupId): int { $stmt = $this->pdo->prepare('SELECT COALESCE(MAX(sort_order), -1) + 1 FROM order_statuses WHERE group_id = :group_id'); $stmt->execute(['group_id' => $groupId]); $value = $stmt->fetchColumn(); return max(0, (int) $value); } /** * @param array $orderedIds */ public function reorderGroups(array $orderedIds): void { if ($orderedIds === []) { return; } $updateStmt = $this->pdo->prepare( 'UPDATE order_status_groups SET sort_order = :sort_order, updated_at = :updated_at WHERE id = :id' ); $this->pdo->beginTransaction(); try { $now = date('Y-m-d H:i:s'); foreach (array_values($orderedIds) as $sortOrder => $groupId) { $id = max(0, (int) $groupId); if ($id <= 0) { continue; } $updateStmt->execute([ 'sort_order' => $sortOrder, 'updated_at' => $now, 'id' => $id, ]); } $this->pdo->commit(); } catch (\Throwable $exception) { if ($this->pdo->inTransaction()) { $this->pdo->rollBack(); } throw $exception; } } /** * @param array $orderedIds */ public function reorderStatusesByGroup(int $groupId, array $orderedIds): void { if ($orderedIds === []) { return; } $updateStmt = $this->pdo->prepare( 'UPDATE order_statuses SET sort_order = :sort_order, updated_at = :updated_at WHERE id = :id AND group_id = :group_id' ); $this->pdo->beginTransaction(); try { $now = date('Y-m-d H:i:s'); foreach (array_values($orderedIds) as $sortOrder => $statusId) { $id = max(0, (int) $statusId); if ($id <= 0) { continue; } $updateStmt->execute([ 'sort_order' => $sortOrder, 'updated_at' => $now, 'id' => $id, 'group_id' => $groupId, ]); } $this->pdo->commit(); } catch (\Throwable $exception) { if ($this->pdo->inTransaction()) { $this->pdo->rollBack(); } throw $exception; } } }