102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
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)
|