brewman/brewman/brewman/routers/attendance_report.py

94 lines
2.7 KiB
Python

import csv
import io
from datetime import date, datetime
from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse
from sqlalchemy import or_
from sqlalchemy.orm import Session
from ..db.session import SessionLocal
from ..models.master import AttendanceType, Employee
from ..models.voucher import Attendance
from .attendance import date_range
router = APIRouter()
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("")
def get_report(
s: str = None,
f: str = None,
db: Session = Depends(get_db),
# user: UserToken = Security(get_user, scopes=["attendance"]) ## removed as jwt headers are a pain in the ass
):
try:
output = io.StringIO()
attendance_record(
datetime.strptime(s, "%d-%b-%Y"),
datetime.strptime(f, "%d-%b-%Y"),
output,
db,
)
headers = {
"Content-Disposition": "attachment; filename = 'attendance-record.csv'"
}
output.seek(0)
return StreamingResponse(output, media_type="text/csv", headers=headers)
finally:
pass
# output.close()
def attendance_record(start_date: date, finish_date: date, output, db: Session):
header = ["Code", "Name", "Designation", "Department", "Salary", "Points"]
for date_ in date_range(start_date, finish_date, inclusive=True):
header.append(date_.strftime("%d-%b"))
not_set = AttendanceType.by_id(0)
employees = (
db.query(Employee)
.filter(Employee.joining_date <= finish_date)
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))
.order_by(Employee.cost_centre_id)
.order_by(Employee.designation)
.order_by(Employee.name)
.all()
)
writer = csv.writer(output)
writer.writerow(header)
for employee in employees:
row_display = [
employee.code,
employee.name,
employee.designation,
employee.cost_centre.name,
employee.salary,
employee.points,
]
row_value = ["", "", "", "", employee.salary, employee.points]
for date_ in date_range(start_date, finish_date, inclusive=True):
att = (
db.query(Attendance)
.filter(Attendance.employee_id == employee.id)
.filter(Attendance.date == date_)
.filter(Attendance.is_valid == True)
.first()
)
att = not_set if att is None else AttendanceType.by_id(att.attendance_type)
row_display.append(att.name)
row_value.append(att.value)
writer.writerow(row_display)
writer.writerow(row_value)