buildFilterQuery( 'SELECT COUNT(*) AS n FROM households h JOIN territories t ON t.id = h.territory_id', $search, $territoryId, $doNotCall ); $row = $this->database->first($sql, $params); return (int) ($row['n'] ?? 0); } /** @return list> */ public function findPaged(int $page, int $perPage, string $search = '', string $territoryId = '', string $doNotCall = ''): array { $offset = ($page - 1) * $perPage; [$where, $params] = $this->buildFilterQuery( 'SELECT h.*, t.name AS territory_name FROM households h JOIN territories t ON t.id = h.territory_id', $search, $territoryId, $doNotCall ); return $this->database->query( $where . ' ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC LIMIT :limit OFFSET :offset', array_merge($params, ['limit' => $perPage, 'offset' => $offset]) ); } /** @return list> */ public function findAllByTerritory(int|string $territoryId): array { return $this->database->query( 'SELECT * FROM households WHERE territory_id = :id ORDER BY street_name ASC, street_number ASC', ['id' => $territoryId] ); } /** @return list> */ public function findAllByTerritories(array $territoryIds): array { if (empty($territoryIds)) { return []; } $placeholders = implode(',', array_fill(0, count($territoryIds), '?')); return $this->database->query( "SELECT h.*, t.name AS territory_name FROM households h JOIN territories t ON t.id = h.territory_id WHERE h.territory_id IN ({$placeholders}) ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC", array_values($territoryIds) ); } public function findWithTerritory(int|string $id): ?array { return $this->database->first( 'SELECT h.*, t.name AS territory_name FROM households h JOIN territories t ON t.id = h.territory_id WHERE h.id = :id', ['id' => $id] ); } /** @return array{string, array} */ private function buildFilterQuery(string $base, string $search, string $territoryId, string $doNotCall): array { $conditions = []; $params = []; if ($search !== '') { $conditions[] = '(h.address LIKE :s OR h.street_name LIKE :s)'; $params['s'] = '%' . $search . '%'; } if ($territoryId !== '') { $conditions[] = 'h.territory_id = :tid'; $params['tid'] = $territoryId; } if ($doNotCall === '1') { $conditions[] = 'h.do_not_call = 1'; } elseif ($doNotCall === '0') { $conditions[] = 'h.do_not_call = 0'; } $sql = $base; if (!empty($conditions)) { $sql .= ' WHERE ' . implode(' AND ', $conditions); } return [$sql, $params]; } }