TorbatYar/backend/services/delivery/app/specifications/fleet.py
Mortezakoohjani 72077908f1 feat(delivery): deploy backend phases 10.2-10.8 through settlement
Ship fleet, availability, pricing, dispatch, routing, tracking, and settlement on delivery-service 0.10.8.0 with migrations and phase tests green.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 21:01:23 +03:30

104 lines
3.7 KiB
Python

"""Fleet query specifications — Phase 10.2."""
from __future__ import annotations
from dataclasses import dataclass
from uuid import UUID
from sqlalchemy import Select, asc, desc, or_
from sqlalchemy.sql import ColumnElement
from app.models.fleet import Fleet, Vehicle, VehicleType
from app.models.types import FleetStatus, VehicleStatus
FLEET_SORT = frozenset({"created_at", "updated_at", "code", "name", "status"})
VT_SORT = frozenset({"created_at", "updated_at", "code", "name"})
VEHICLE_SORT = frozenset({"created_at", "updated_at", "code", "status"})
@dataclass(frozen=True, slots=True)
class FleetListSpec:
status: FleetStatus | None = None
organization_id: UUID | None = None
hub_id: UUID | None = None
q: str | None = None
sort_by: str = "created_at"
sort_dir: str = "desc"
def filter_clauses(self) -> list[ColumnElement]:
clauses: list[ColumnElement] = []
if self.status is not None:
clauses.append(Fleet.status == self.status)
if self.organization_id is not None:
clauses.append(Fleet.organization_id == self.organization_id)
if self.hub_id is not None:
clauses.append(Fleet.hub_id == self.hub_id)
if self.q:
term = f"%{self.q.strip()}%"
clauses.append(or_(Fleet.code.ilike(term), Fleet.name.ilike(term)))
return clauses
def apply(self, stmt: Select) -> Select:
clauses = self.filter_clauses()
if clauses:
stmt = stmt.where(*clauses)
sort_key = self.sort_by if self.sort_by in FLEET_SORT else "created_at"
column = getattr(Fleet, sort_key)
order = desc(column) if self.sort_dir.lower() != "asc" else asc(column)
return stmt.order_by(order)
@dataclass(frozen=True, slots=True)
class VehicleTypeListSpec:
q: str | None = None
sort_by: str = "created_at"
sort_dir: str = "desc"
def filter_clauses(self) -> list[ColumnElement]:
clauses: list[ColumnElement] = []
if self.q:
term = f"%{self.q.strip()}%"
clauses.append(
or_(VehicleType.code.ilike(term), VehicleType.name.ilike(term))
)
return clauses
def apply(self, stmt: Select) -> Select:
clauses = self.filter_clauses()
if clauses:
stmt = stmt.where(*clauses)
sort_key = self.sort_by if self.sort_by in VT_SORT else "created_at"
column = getattr(VehicleType, sort_key)
order = desc(column) if self.sort_dir.lower() != "asc" else asc(column)
return stmt.order_by(order)
@dataclass(frozen=True, slots=True)
class VehicleListSpec:
fleet_id: UUID | None = None
status: VehicleStatus | None = None
q: str | None = None
sort_by: str = "created_at"
sort_dir: str = "desc"
def filter_clauses(self) -> list[ColumnElement]:
clauses: list[ColumnElement] = []
if self.fleet_id is not None:
clauses.append(Vehicle.fleet_id == self.fleet_id)
if self.status is not None:
clauses.append(Vehicle.status == self.status)
if self.q:
term = f"%{self.q.strip()}%"
clauses.append(
or_(Vehicle.code.ilike(term), Vehicle.plate_number.ilike(term))
)
return clauses
def apply(self, stmt: Select) -> Select:
clauses = self.filter_clauses()
if clauses:
stmt = stmt.where(*clauses)
sort_key = self.sort_by if self.sort_by in VEHICLE_SORT else "created_at"
column = getattr(Vehicle, sort_key)
order = desc(column) if self.sort_dir.lower() != "asc" else asc(column)
return stmt.order_by(order)