feat: add on_leave status to reporting progress + week_leaves stat
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from sqlalchemy import select, func
|
from sqlalchemy import select, func, and_
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
from app.models.customer import Customer
|
from app.models.customer import Customer
|
||||||
@@ -10,6 +10,7 @@ from app.models.work_plan import WorkPlan
|
|||||||
from app.models.mini_business import MiniBusiness
|
from app.models.mini_business import MiniBusiness
|
||||||
from app.models.key_visit import KeyVisit
|
from app.models.key_visit import KeyVisit
|
||||||
from app.models.daily_note import DailyNote
|
from app.models.daily_note import DailyNote
|
||||||
|
from app.models.leave import Leave
|
||||||
from app.utils.timezone import today_cst
|
from app.utils.timezone import today_cst
|
||||||
|
|
||||||
|
|
||||||
@@ -41,11 +42,19 @@ async def get_dashboard_stats(db: AsyncSession, reference_date: date | None = No
|
|||||||
select(func.count(KeyVisit.id))
|
select(func.count(KeyVisit.id))
|
||||||
)).scalar() or 0
|
)).scalar() or 0
|
||||||
|
|
||||||
|
# Week leave count — distinct managers on leave this week
|
||||||
|
leaves_count = (await db.execute(
|
||||||
|
select(func.count(func.distinct(Leave.manager_id))).where(
|
||||||
|
and_(Leave.start_date <= sunday, Leave.end_date >= monday)
|
||||||
|
)
|
||||||
|
)).scalar() or 0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"week_visits": visits_count,
|
"week_visits": visits_count,
|
||||||
"work_plans": plans_count,
|
"work_plans": plans_count,
|
||||||
"mini_business": mini_biz_count,
|
"mini_business": mini_biz_count,
|
||||||
"key_visits": key_visit_count,
|
"key_visits": key_visit_count,
|
||||||
|
"week_leaves": leaves_count,
|
||||||
"week_start": str(monday),
|
"week_start": str(monday),
|
||||||
"week_end": str(sunday),
|
"week_end": str(sunday),
|
||||||
}
|
}
|
||||||
@@ -69,24 +78,43 @@ async def get_reporting_progress(db: AsyncSession, reference_date: date | None =
|
|||||||
)
|
)
|
||||||
visit_map = {str(uid): cnt for uid, cnt in visits_result.all()}
|
visit_map = {str(uid): cnt for uid, cnt in visits_result.all()}
|
||||||
|
|
||||||
|
# Query leave records for today — build a set of managers on leave
|
||||||
|
today = today_cst()
|
||||||
|
leaves_result = await db.execute(
|
||||||
|
select(Leave).where(and_(
|
||||||
|
Leave.start_date <= today,
|
||||||
|
Leave.end_date >= today,
|
||||||
|
))
|
||||||
|
)
|
||||||
|
on_leave_today = {str(r.manager_id): r for r in leaves_result.scalars().all()}
|
||||||
|
|
||||||
progress = []
|
progress = []
|
||||||
for m in reporters:
|
for m in reporters:
|
||||||
count = visit_map.get(str(m.id), 0)
|
count = visit_map.get(str(m.id), 0)
|
||||||
# Calculate expected working days (Mon-Fri)
|
# Calculate expected working days (Mon-Fri)
|
||||||
days_passed = min((date.today() - monday).days + 1, 5)
|
days_passed = min((date.today() - monday).days + 1, 5)
|
||||||
expected = days_passed # At least 1 visit per working day
|
expected = days_passed # At least 1 visit per working day
|
||||||
|
|
||||||
|
mid = str(m.id)
|
||||||
|
leave = on_leave_today.get(mid)
|
||||||
|
|
||||||
progress.append({
|
progress.append({
|
||||||
"manager_id": str(m.id),
|
"manager_id": mid,
|
||||||
"manager_name": m.name,
|
"manager_name": m.name,
|
||||||
"department": m.department,
|
"department": m.department,
|
||||||
"visit_count": count,
|
"visit_count": count,
|
||||||
"expected": expected,
|
"expected": expected,
|
||||||
"completed": count >= expected,
|
"completed": count >= expected,
|
||||||
"has_reported_today": False, # Will be set below
|
"has_reported_today": False, # Will be set below
|
||||||
|
"on_leave": leave is not None,
|
||||||
|
"leave_info": {
|
||||||
|
"leave_type": leave.leave_type,
|
||||||
|
"start_date": str(leave.start_date),
|
||||||
|
"end_date": str(leave.end_date),
|
||||||
|
} if leave else None,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Check today's reporting — visits OR daily notes
|
# Check today's reporting — visits OR daily notes
|
||||||
today = today_cst()
|
|
||||||
today_visits = await db.execute(
|
today_visits = await db.execute(
|
||||||
select(Visit.manager_id).where(Visit.visit_date == today)
|
select(Visit.manager_id).where(Visit.visit_date == today)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user