File size: 7,529 Bytes
20adca1
 
 
 
 
 
 
 
1f8ac0c
20adca1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f8ac0c
20adca1
 
 
 
 
 
1f8ac0c
 
 
 
 
 
 
 
 
20adca1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime
from typing import Dict, Any, Optional, List
from ..core.dependencies import get_current_active_user, get_db
from ..db.models import User, ActivityType
from ..services.analytics import staff_analytics
from ..services.staff_reports import staff_reports
from ..services.performance_notifications import performance_notifications
from ..db.schemas import (
    StaffActivityCreate,
    StaffActivityInDB,
    StaffPerformanceReport,
    RealtimeStaffMetrics
)

router = APIRouter()

@router.post("/activity", response_model=Dict[str, Any])
async def record_staff_activity(

    activity: StaffActivityCreate,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Record a staff activity"""
    if not current_user.branch_id:
        raise HTTPException(status_code=400, detail="User is not associated with a branch")
    
    recorded_activity, prev_metrics, new_metrics = await staff_analytics.record_activity(
        user_id=current_user.id,
        branch_id=current_user.branch_id,
        activity_type=activity.activity_type,
        details=activity.details,
        duration=activity.duration
    )

    # Process notifications for the activity
    await performance_notifications.process_activity_notifications(
        user_id=current_user.id,
        branch_id=current_user.branch_id,
        activity=recorded_activity,
        prev_metrics=prev_metrics,
        new_metrics=new_metrics
    )
    
    return {
        "status": "success",
        "activity_id": recorded_activity.id,
        "performance_score": recorded_activity.performance_score
    }

@router.get("/performance", response_model=StaffPerformanceReport)
async def get_staff_performance(

    branch_id: Optional[int] = Query(None, description="Filter by branch ID"),

    user_id: Optional[int] = Query(None, description="Filter by user ID"),

    start_date: Optional[datetime] = Query(None, description="Start date for analysis"),

    end_date: Optional[datetime] = Query(None, description="End date for analysis"),

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Get staff performance metrics"""
    # Check permissions
    if not current_user.is_superuser and (
        (branch_id and branch_id != current_user.branch_id) or
        (user_id and user_id != current_user.id)
    ):
        raise HTTPException(
            status_code=403,
            detail="You can only view performance metrics for your own branch"
        )
    
    # Non-superusers can only view their branch
    if not current_user.is_superuser:
        branch_id = current_user.branch_id
    
    return await staff_analytics.get_staff_performance(
        branch_id=branch_id,
        user_id=user_id,
        start_date=start_date,
        end_date=end_date
    )

@router.get("/metrics/summary")
async def get_performance_summary(

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Get a summary of current user's performance metrics"""
    metrics = await staff_analytics.get_staff_performance(
        user_id=current_user.id,
        branch_id=current_user.branch_id
    )
    
    # Get user's performance data
    user_metrics = next(
        (p for p in metrics["staff_performance"] if p["user_id"] == current_user.id),
        None
    )
    
    if not user_metrics:
        return {
            "message": "No performance metrics available",
            "metrics": None
        }
    
    # Get comparison with branch averages
    comparison = await staff_reports.generate_staff_comparison(
        user_id=current_user.id,
        branch_id=current_user.branch_id
    )
    
    return {
        "metrics": user_metrics["metrics"],
        "comparison": comparison,
        "period": metrics["date_range"]
    }

@router.get("/realtime", response_model=RealtimeStaffMetrics)
async def get_realtime_activity(

    branch_id: Optional[int] = Query(None, description="Filter by branch ID"),

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Get real-time staff activity for the current day"""
    if not current_user.is_superuser and branch_id != current_user.branch_id:
        raise HTTPException(
            status_code=403,
            detail="You can only view real-time activity for your own branch"
        )
    
    today = datetime.utcnow()
    today_start = today.replace(hour=0, minute=0, second=0, microsecond=0)
    
    metrics = await staff_analytics.get_staff_performance(
        branch_id=branch_id or current_user.branch_id,
        start_date=today_start,
        end_date=today
    )
    
    # Calculate real-time metrics
    active_staff = [
        staff for staff in metrics["staff_performance"]
        if staff["metrics"]["total_login_time"] > 0
    ]
    
    total_sales_today = sum(
        staff["metrics"]["total_sales"] for staff in metrics["staff_performance"]
    )
    total_transactions = sum(
        staff["metrics"]["transaction_count"] for staff in metrics["staff_performance"]
    )
    
    return {
        "active_staff_count": len(active_staff),
        "total_sales_today": total_sales_today,
        "total_transactions": total_transactions,
        "staff_metrics": active_staff,
        "last_updated": datetime.utcnow().isoformat()
    }

@router.get("/reports/performance")
async def get_performance_report(

    branch_id: Optional[int] = Query(None, description="Filter by branch ID"),

    start_date: Optional[datetime] = Query(None, description="Start date for report"),

    end_date: Optional[datetime] = Query(None, description="End date for report"),

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Generate comprehensive performance report with insights"""
    # Check permissions
    if not current_user.is_superuser and branch_id != current_user.branch_id:
        raise HTTPException(
            status_code=403,
            detail="You can only view reports for your own branch"
        )
    
    return await staff_reports.generate_performance_report(
        branch_id=branch_id or current_user.branch_id,
        start_date=start_date,
        end_date=end_date
    )

@router.get("/reports/comparison")
async def get_staff_comparison(

    user_id: Optional[int] = Query(None, description="User ID to compare (defaults to current user)"),

    date: Optional[datetime] = Query(None, description="Date for comparison"),

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, Any]:
    """Get performance comparison against branch averages"""
    if not current_user.is_superuser and user_id != current_user.id:
        raise HTTPException(
            status_code=403,
            detail="You can only view your own performance comparison"
        )
    
    return await staff_reports.generate_staff_comparison(
        user_id=user_id or current_user.id,
        branch_id=current_user.branch_id,
        date=date
    )