141 lines
4.1 KiB
Python
141 lines
4.1 KiB
Python
from datetime import date, datetime, timedelta
|
|
|
|
import brewman.schemas.voucher as schemas
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Request, Security, status
|
|
from sqlalchemy import or_
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ..core.security import get_current_active_user as get_user
|
|
from ..core.session import get_date, set_date
|
|
from ..db.session import SessionLocal
|
|
from ..models.master import Employee
|
|
from ..models.voucher import Attendance
|
|
from ..routers.fingerprint import get_prints
|
|
from ..schemas.auth import UserToken
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# Dependency
|
|
def get_db() -> Session:
|
|
try:
|
|
db = SessionLocal()
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("", response_model=schemas.Attendance)
|
|
def attendance_blank(
|
|
request: Request, user: UserToken = Security(get_user, scopes=["attendance"])
|
|
):
|
|
return {"date": get_date(request.session), "body": []}
|
|
|
|
|
|
@router.get("/{date_}", response_model=schemas.Attendance)
|
|
def attendance_date(
|
|
date_: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
user: UserToken = Security(get_user, scopes=["attendance"]),
|
|
):
|
|
set_date(date_, request.session)
|
|
return {
|
|
"date": date_,
|
|
"body": attendance_date_report(datetime.strptime(date_, "%d-%b-%Y"), db),
|
|
}
|
|
|
|
|
|
def attendance_date_report(date_: date, db: Session):
|
|
body = []
|
|
employees = (
|
|
db.query(Employee)
|
|
.filter(Employee.joining_date <= date_)
|
|
.filter(
|
|
or_(
|
|
Employee.is_active,
|
|
Employee.leaving_date >= date_,
|
|
)
|
|
)
|
|
.order_by(Employee.cost_centre_id)
|
|
.order_by(Employee.designation)
|
|
.order_by(Employee.name)
|
|
.all()
|
|
)
|
|
for item in employees:
|
|
att = (
|
|
db.query(Attendance)
|
|
.filter(Attendance.employee_id == item.id)
|
|
.filter(Attendance.date == date_)
|
|
.filter(Attendance.is_valid == True)
|
|
.first()
|
|
)
|
|
att = 0 if att is None else att.attendance_type
|
|
|
|
prints, hours_worked, full_day = get_prints(item.id, date_, db)
|
|
body.append(
|
|
schemas.AttendanceItem(
|
|
id=item.id,
|
|
code=item.code,
|
|
name=item.name,
|
|
designation=item.designation,
|
|
department=item.cost_centre.name,
|
|
attendanceType=schemas.AttendanceType(id=att),
|
|
prints=prints,
|
|
hoursWorked=hours_worked,
|
|
fullDay=full_day,
|
|
)
|
|
)
|
|
return body
|
|
|
|
|
|
@router.post("/{date_}", response_model=schemas.Attendance)
|
|
def save(
|
|
date_: str,
|
|
data: schemas.Attendance,
|
|
db: Session = Depends(get_db),
|
|
user: UserToken = Security(get_user, scopes=["attendance"]),
|
|
):
|
|
try:
|
|
att_date = datetime.strptime(date_, "%d-%b-%Y").date()
|
|
for item in data.body:
|
|
if item.attendance_type.id_ != 0:
|
|
attendance = Attendance(
|
|
employee_id=item.id_,
|
|
date=att_date,
|
|
attendance_type=item.attendance_type.id_,
|
|
user_id=user.id_,
|
|
)
|
|
attendance.create(db)
|
|
db.commit()
|
|
return {"date": date_, "body": attendance_date_report(att_date, db)}
|
|
except SQLAlchemyError as e:
|
|
db.rollback()
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(e),
|
|
)
|
|
except Exception:
|
|
db.rollback()
|
|
raise
|
|
|
|
|
|
def date_range(start: date, stop: date, step=timedelta(days=1), inclusive=False):
|
|
# inclusive=False to behave like range by default
|
|
if step.days > 0:
|
|
while start < stop:
|
|
yield start
|
|
start = start + step
|
|
# not +=! don't modify object passed in if it's mutable
|
|
# since this function is not restricted to
|
|
# only types from datetime module
|
|
elif step.days < 0:
|
|
while start > stop:
|
|
yield start
|
|
start = start + step
|
|
if inclusive and start == stop:
|
|
yield start
|