94 lines
2.7 KiB
Python
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)
|