File size: 5,220 Bytes
fcf8749
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""
Phase 2 Driver-facing API endpoints.
Handles driver operations: assignments, stats, deliveries, feedback, swaps, issues.
"""

from datetime import date as date_type

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from uuid import UUID

from app.database import get_db
from app.schemas.driver_api import (
    TodayAssignmentResponse,
    DriverStatsWindowResponse,
    DeliveryLogRequest,
    DeliveryLogResponse,
    RouteSwapRequestCreate,
    RouteSwapRequestResponse,
    StopIssueRequest,
    StopIssueResponse,
)
from app.services.driver_service import (
    get_today_assignment,
    get_driver_stats,
    log_delivery,
    create_route_swap_request,
    create_stop_issue,
)

router = APIRouter(tags=["Driver"])


@router.get(
    "/assignments/today",
    response_model=TodayAssignmentResponse,
    summary="Get today's assignment",
    description="Fetch the driver's assignment for the given date with full stop details.",
)
async def get_assignment_today(
    driver_id: UUID = Query(..., description="Driver UUID"),
    target_date: date_type = Query(default=None, description="Date (defaults to today)"),
    db: AsyncSession = Depends(get_db),
) -> TodayAssignmentResponse:
    """Get driver's assignment for today or specified date."""
    actual_date = target_date or date_type.today()
    
    result = await get_today_assignment(db, driver_id, actual_date)
    
    if not result:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="No assignment found for driver on given date",
        )
    
    return result


@router.get(
    "/drivers/{driver_id}/stats",
    response_model=DriverStatsWindowResponse,
    summary="Get driver stats",
    description="Get driver statistics over a time window.",
)
async def get_driver_stats_endpoint(
    driver_id: UUID,
    window_days: int = Query(default=7, ge=1, le=90, description="Days to look back"),
    db: AsyncSession = Depends(get_db),
) -> DriverStatsWindowResponse:
    """Get driver stats over time window."""
    result = await get_driver_stats(db, driver_id, window_days)
    
    if not result:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Driver not found",
        )
    
    return result


@router.post(
    "/deliveries/log",
    response_model=DeliveryLogResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Log delivery",
    description="Log a delivery attempt at a stop.",
)
async def log_delivery_endpoint(
    request: DeliveryLogRequest,
    db: AsyncSession = Depends(get_db),
) -> DeliveryLogResponse:
    """Log a delivery at a stop."""
    try:
        result = await log_delivery(
            db=db,
            assignment_id=request.assignment_id,
            route_id=request.route_id,
            driver_id=request.driver_id,
            stop_order=request.stop_order,
            status=request.status,
            issue_type=request.issue_type,
            package_id=request.package_id,
            photo_url=request.photo_url,
            signature_data=request.signature_data,
            notes=request.notes,
        )
        await db.commit()
        return result
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )


@router.post(
    "/route_swap_requests",
    response_model=RouteSwapRequestResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Request route swap",
    description="Submit a route swap request.",
)
async def create_route_swap_endpoint(
    request: RouteSwapRequestCreate,
    db: AsyncSession = Depends(get_db),
) -> RouteSwapRequestResponse:
    """Create a route swap request."""
    try:
        result = await create_route_swap_request(
            db=db,
            from_driver_id=request.from_driver_id,
            assignment_id=request.assignment_id,
            reason=request.reason,
            to_driver_id=request.to_driver_id,
            preferred_date=request.preferred_date,
        )
        await db.commit()
        return result
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )


@router.post(
    "/stop_issues",
    response_model=StopIssueResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Report stop issue",
    description="Report an issue at a specific stop.",
)
async def create_stop_issue_endpoint(
    request: StopIssueRequest,
    db: AsyncSession = Depends(get_db),
) -> StopIssueResponse:
    """Create a stop issue report."""
    try:
        result = await create_stop_issue(
            db=db,
            assignment_id=request.assignment_id,
            route_id=request.route_id,
            driver_id=request.driver_id,
            stop_order=request.stop_order,
            issue_type=request.issue_type,
            notes=request.notes,
        )
        await db.commit()
        return result
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )