|
- <?php
-
- declare(strict_types=1);
-
- namespace App\Repositories;
-
- use App\Models\Customer;
- use Core\Repository;
-
- class CustomerRepository extends Repository
- {
- protected string $table = 'customer';
- protected string $primaryKey = 'id';
-
- public function count(): int
- {
- $row = $this->database->first('SELECT COUNT(*) AS total FROM customer');
- return (int) ($row['total'] ?? 0);
- }
-
- /** @return list<array<string, mixed>> */
- public function recentWithType(int $limit = 5): array
- {
- return $this->database->query(
- "SELECT TOP ({$limit}) c.id, c.created_at, ct.name AS customer_type_name
- FROM customer c
- INNER JOIN customer_type ct ON c.customer_type_id = ct.id
- ORDER BY c.id DESC"
- );
- }
-
- /** @return list<array<string, mixed>> */
- public function countByType(): array
- {
- return $this->database->query(
- 'SELECT ct.name AS customer_type_name, COUNT(c.id) AS customer_count
- FROM customer_type ct
- LEFT JOIN customer c ON c.customer_type_id = ct.id
- GROUP BY ct.id, ct.name
- ORDER BY customer_count DESC, ct.name ASC'
- );
- }
-
- /** @return list<array<string, mixed>> */
- public function allWithType(): array
- {
- return $this->database->query(
- 'SELECT c.id, c.customer_type_id, c.attribute_values,
- c.created_at, c.updated_at,
- ct.name AS customer_type_name,
- ct.attributes AS customer_type_attributes,
- ct.api_match_field
- FROM customer c
- INNER JOIN customer_type ct ON c.customer_type_id = ct.id
- ORDER BY c.id DESC'
- );
- }
-
- /** @return list<array<string, mixed>> */
- public function allByTypeWithType(int $typeId): array
- {
- return $this->database->query(
- 'SELECT c.id, c.customer_type_id, c.attribute_values,
- c.created_at, c.updated_at,
- ct.name AS customer_type_name,
- ct.attributes AS customer_type_attributes,
- ct.api_match_field
- FROM customer c
- INNER JOIN customer_type ct ON c.customer_type_id = ct.id
- WHERE c.customer_type_id = :type_id
- ORDER BY c.id DESC',
- ['type_id' => $typeId]
- );
- }
-
- public function findWithType(int $id): ?array
- {
- return $this->database->first(
- 'SELECT c.id, c.customer_type_id, c.attribute_values,
- c.created_at, c.updated_at,
- ct.name AS customer_type_name,
- ct.attributes AS customer_type_attributes,
- ct.api_match_field
- FROM customer c
- INNER JOIN customer_type ct ON c.customer_type_id = ct.id
- WHERE c.id = :id',
- ['id' => $id]
- );
- }
-
- /** Returns an existing customer with the same type and attribute values, excluding $excludeId (use for update). */
- public function findDuplicate(int $typeId, string $attributeValuesJson, int $excludeId = 0): ?array
- {
- $sql = 'SELECT TOP (1) c.id, ct.name AS customer_type_name
- FROM customer c
- INNER JOIN customer_type ct ON c.customer_type_id = ct.id
- WHERE c.customer_type_id = :type_id
- AND c.attribute_values = :attribute_values';
- $params = ['type_id' => $typeId, 'attribute_values' => $attributeValuesJson];
-
- if ($excludeId > 0) {
- $sql .= ' AND c.id != :exclude_id';
- $params['exclude_id'] = $excludeId;
- }
-
- return $this->database->first($sql, $params);
- }
-
- /** Used after INSERT to recover the generated id for audit logging. */
- public function findLatestByType(int $typeId): ?array
- {
- return $this->database->first(
- 'SELECT TOP (1) * FROM customer
- WHERE customer_type_id = :type_id
- ORDER BY id DESC',
- ['type_id' => $typeId]
- );
- }
-
- public function create(Customer $customer): bool
- {
- return $this->database->execute(
- 'INSERT INTO customer (customer_type_id, attribute_values)
- VALUES (:customer_type_id, :attribute_values)',
- [
- 'customer_type_id' => $customer->customerTypeId,
- 'attribute_values' => json_encode($customer->attributeValues, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
- ]
- );
- }
-
- public function update(Customer $customer): bool
- {
- return $this->database->execute(
- 'UPDATE customer
- SET customer_type_id = :customer_type_id,
- attribute_values = :attribute_values,
- updated_at = CURRENT_TIMESTAMP
- WHERE id = :id',
- [
- 'customer_type_id' => $customer->customerTypeId,
- 'attribute_values' => json_encode($customer->attributeValues, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
- 'id' => $customer->id,
- ]
- );
- }
- }
|