from collections import defaultdict from datetime import datetime, timedelta from time import time from fastapi import APIRouter from app import mongo from app.utils.response_util import response router = APIRouter() @router.post("/get-records", tags=[""]) async def get_time_tracking_records(params: dict): start_time = time() input_date = datetime.strptime(params["date"], "%Y-%m-%dT%H:%M:%S.%f") month_start = input_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0) next_month = (month_start.replace(day=28) + timedelta(days=4)).replace(day=1) users = await mongo.users_collection.find({}, {"_id": False}).to_list(length=None) users_by_id = { user["id"]: user for user in users } records = await mongo.time_tracking_collection.find({ "date": { "$gte": month_start.strftime("%Y-%m-%dT00:00:00.000"), "$lt": next_month.strftime("%Y-%m-%dT00:00:00.000") } }, {"_id": False}).to_list(length=None) grouped = defaultdict(list) for record in records: user = users_by_id.get(record["userId"]) if not user: continue pay_rate = await mongo.pay_rates_collection.find_one( {"id": user.get("payRate", {}).get("id")}, {"_id": False} ) total_hours = record.get("hours", 0.0) total_amount = 0.0 if pay_rate and pay_rate["payrollScheme"]["key"] == "hourly": overtime_threshold = pay_rate.get("overtimeThreshold", 0) base_hours = min(total_hours, overtime_threshold) overtime_hours = max(total_hours - overtime_threshold, 0) base_rate = pay_rate.get("baseRate", 0) overtime_rate = pay_rate.get("overtimeRate", base_rate) total_amount = round(base_hours * base_rate + overtime_hours * overtime_rate, 2) grouped[record["userId"]].append({ "date": record["date"].split("T")[0], "hours": total_hours, "amount": total_amount }) result = [] for user_id, data in grouped.items(): user = await mongo.users_collection.find_one({"id": user_id}, {"_id": False}) result.append({ "user": user, "userId": user_id, "data": data }) return response({ "records": result, "ok": True }, start_time=start_time) @router.post("/update-record", tags=[""]) async def update_time_tracking_record(params: dict): start_time = time() user_id = params["userId"] new_hours = params["hours"] date = params["date"] user = await mongo.users_collection.find_one({"id": user_id}, {"_id": False}) pay_rate = await mongo.pay_rates_collection.find_one( {"id": user.get("payRate", {}).get("id")}, {"_id": False} ) await mongo.time_tracking_collection.update_one( {"date": date, "userId": user_id}, {"$set": {"hours": new_hours}}, upsert=True ) return response({ "ok": True }, start_time=start_time)