in backend/services/project_service.py [0:0]
def get_contribs_by_day(project_id: int) -> ProjectContribsDTO:
# Validate that project exists
project = ProjectService.get_project_by_id(project_id)
# Fetch all state change with date and task ID
stats = (
TaskHistory.query.with_entities(
TaskHistory.action_text.label("action_text"),
func.DATE(TaskHistory.action_date).label("day"),
TaskHistory.task_id.label("task_id"),
)
.filter(TaskHistory.project_id == project_id)
.filter(
TaskHistory.action == "STATE_CHANGE",
or_(
TaskHistory.action_text == "MAPPED",
TaskHistory.action_text == "VALIDATED",
TaskHistory.action_text == "INVALIDATED",
),
)
.group_by("action_text", "day", "task_id")
.order_by("day")
).all()
contribs_dto = ProjectContribsDTO()
# Filter and store unique dates
dates = list(set(r[1] for r in stats))
dates.sort(
reverse=False
) # Why was this reversed? To have the dates in ascending order
dates_list = []
cumulative_mapped = 0
cumulative_validated = 0
# A hashmap to track task state change updates
tasks = {
"MAPPED": {"total": 0},
"VALIDATED": {"total": 0},
"INVALIDATED": {"total": 0},
}
for date in dates:
dto = ProjectContribDTO(
{
"date": date,
"mapped": 0,
"validated": 0,
"total_tasks": project.total_tasks,
}
)
# s -> ('LOCKED_FOR_MAPPING', datetime.date(2019, 4, 23), 1)
# s[0] -> action, s[1] -> date, s[2] -> task_id
values = [(s[0], s[2]) for s in stats if date == s[1]]
values.sort(reverse=True) # Most recent action comes first
for val in values:
task_id = val[1]
task_status = val[0]
if task_status == "MAPPED":
if task_id not in tasks["MAPPED"]:
tasks["MAPPED"][task_id] = 1
tasks["MAPPED"]["total"] += 1
dto.mapped += 1
elif task_status == "VALIDATED":
if task_id not in tasks["VALIDATED"]:
tasks["VALIDATED"][task_id] = 1
tasks["VALIDATED"]["total"] += 1
dto.validated += 1
if task_id in tasks["INVALIDATED"]:
del tasks["INVALIDATED"][task_id]
tasks["INVALIDATED"]["total"] -= 1
if task_id not in tasks["MAPPED"]:
tasks["MAPPED"][task_id] = 1
tasks["MAPPED"]["total"] += 1
dto.mapped += 1
else:
if task_id not in tasks["INVALIDATED"]:
tasks["INVALIDATED"][task_id] = 1
tasks["INVALIDATED"]["total"] += 1
if task_id in tasks["MAPPED"]:
del tasks["MAPPED"][task_id]
tasks["MAPPED"]["total"] -= 1
if dto.mapped > 0:
dto.mapped -= 1
if task_id in tasks["VALIDATED"]:
del tasks["VALIDATED"][task_id]
tasks["VALIDATED"]["total"] -= 1
if dto.validated > 0:
dto.validated -= 1
cumulative_mapped = tasks["MAPPED"]["total"]
cumulative_validated = tasks["VALIDATED"]["total"]
dto.cumulative_mapped = cumulative_mapped
dto.cumulative_validated = cumulative_validated
dates_list.append(dto)
contribs_dto.stats = dates_list
return contribs_dto