From c8246ce597c72126eaf2c11042b7fd7fcd477347 Mon Sep 17 00:00:00 2001 From: Sujan Adhikari <109404840+Sujanadh@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:57:10 +0545 Subject: [PATCH] feat: endpoint to return count of validated and mapped tasks (#1138) * feat: new endpoint to return count of validated and mapped task * refactor: move to tasks router + use pydantic model * refactor: rename task_activity route --> tasks/activity --------- Co-authored-by: sujanadh Co-authored-by: spwoodcock --- src/backend/app/tasks/tasks_crud.py | 77 +++++++++++++++++++++++++- src/backend/app/tasks/tasks_routes.py | 26 +++++++++ src/backend/app/tasks/tasks_schemas.py | 8 +++ 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/backend/app/tasks/tasks_crud.py b/src/backend/app/tasks/tasks_crud.py index 3b24cd4d44..3345389235 100644 --- a/src/backend/app/tasks/tasks_crud.py +++ b/src/backend/app/tasks/tasks_crud.py @@ -18,7 +18,8 @@ """Logic for FMTM tasks.""" import base64 -from typing import List +from datetime import datetime, timedelta +from typing import List, Optional from fastapi import Depends, HTTPException from geoalchemy2.shape import from_shape @@ -357,3 +358,77 @@ def process_history_entry(history_entry): process_history_entry(history_entry) return tasks + + +def get_task_history( + project_id: int, + end_date: Optional[datetime], + db: Session, +) -> list[db_models.DbTaskHistory]: + """Retrieves the task history records for a specific project. + + Args: + project_id: The ID of the project. + end_date: The end date of the task history + records to retrieve (optional). + db: The database session. + + Returns: + A list of task history records for the specified project. + """ + query = db.query(db_models.DbTaskHistory).filter( + db_models.DbTaskHistory.project_id == project_id + ) + + if end_date: + query = query.filter(db_models.DbTaskHistory.action_date >= end_date) + + return query.all() + + +async def count_validated_and_mapped_tasks( + task_history: list[db_models.DbTaskHistory], end_date: datetime +) -> list[tasks_schemas.TaskHistoryCount]: + """Counts the number of validated and mapped tasks. + + Args: + task_history: The task history records to count. + end_date: The end date of the date range. + + Returns: + A list of dictionaries with following keys: + - 'date': The date in the format 'MM/DD'. + - 'validated': The cumulative count of validated tasks. + - 'mapped': The cumulative count of mapped tasks. + """ + cumulative_counts = {} + results = [] + + current_date = end_date + while current_date <= datetime.now(): + date_str = current_date.strftime("%m/%d") + cumulative_counts = {"date": date_str, "validated": 0, "mapped": 0} + results.append(cumulative_counts) + current_date += timedelta(days=1) + + # Populate cumulative_counts with counts from task_history + for result in task_history: + task_status = result.action_text.split()[5] + date_str = result.action_date.strftime("%m/%d") + entry = next((entry for entry in results if entry["date"] == date_str), None) + + if entry: + if task_status == "VALIDATED": + entry["validated"] += 1 + elif task_status == "MAPPED": + entry["mapped"] += 1 + + total_validated = 0 + total_mapped = 0 + + for entry in results: + total_validated += entry["validated"] + total_mapped += entry["mapped"] + entry.update({"validated": total_validated, "mapped": total_mapped}) + + return results diff --git a/src/backend/app/tasks/tasks_routes.py b/src/backend/app/tasks/tasks_routes.py index 6df1d6f367..bf85659b4c 100644 --- a/src/backend/app/tasks/tasks_routes.py +++ b/src/backend/app/tasks/tasks_routes.py @@ -18,6 +18,7 @@ """Routes for FMTM tasks.""" import json +from datetime import datetime, timedelta from typing import List from fastapi import APIRouter, Depends, File, HTTPException, UploadFile @@ -201,3 +202,28 @@ async def task_features_count( ) return data + + +@router.get("/activity/", response_model=List[tasks_schemas.TaskHistoryCount]) +async def task_activity( + project_id: int, days: int = 10, db: Session = Depends(database.get_db) +): + """Retrieves the validate and mapped task count for a specific project. + + Args: + project_id: The ID of the project. + days: The number of days to consider for the + task activity (default: 10). + db: The database session. + + Returns: + list[TaskHistoryCount]: A list of task history counts. + + """ + end_date = datetime.now() - timedelta(days=days) + task_history = tasks_crud.get_task_history(project_id, end_date, db) + + return await tasks_crud.count_validated_and_mapped_tasks( + task_history, + end_date, + ) diff --git a/src/backend/app/tasks/tasks_schemas.py b/src/backend/app/tasks/tasks_schemas.py index 7be5029ba8..2899e490aa 100644 --- a/src/backend/app/tasks/tasks_schemas.py +++ b/src/backend/app/tasks/tasks_schemas.py @@ -48,6 +48,14 @@ class TaskHistoryOut(TaskHistoryBase): profile_img: Optional[str] +class TaskHistoryCount(BaseModel): + """Task mapping history display.""" + + date: str + validated: int + mapped: int + + class TaskBase(BaseModel): """Core fields for a Task."""