tanshu
10dbe6663d
Credit Salary works!! Refresh router created, now need to use it in angular Errors should now show up in the frontend.
102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
from calendar import monthrange
|
|
from datetime import datetime, date
|
|
|
|
from fastapi import APIRouter, Depends, Security, Body, HTTPException, status
|
|
from sqlalchemy import or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ..core.session import get_first_day, get_last_day
|
|
from ..schemas.auth import UserToken
|
|
from ..core.security import get_current_active_user as get_user
|
|
from ..db.session import SessionLocal
|
|
from ..models.master import Account, Employee, AttendanceType
|
|
from ..models.voucher import Voucher, Journal, VoucherType, Attendance
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# Dependency
|
|
def get_db() -> Session:
|
|
try:
|
|
db = SessionLocal()
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.post("")
|
|
def credit_salary(
|
|
month: str = Body(..., embed=True),
|
|
db: Session = Depends(get_db),
|
|
user: UserToken = Security(get_user, scopes=["attendance"]),
|
|
):
|
|
month = datetime.strptime(month, "%d-%b-%Y").date()
|
|
|
|
start_date = get_first_day(month)
|
|
finish_date = get_last_day(month)
|
|
voucher = Voucher(
|
|
date=finish_date,
|
|
narration="Auto Generated Salary Entry",
|
|
user_id=user.id_,
|
|
type_=VoucherType.by_name("Journal"),
|
|
posted=True,
|
|
poster_id=user.id_,
|
|
)
|
|
db.add(voucher)
|
|
for item in salary_journals(start_date, finish_date, db):
|
|
voucher.journals.append(item)
|
|
db.add(item)
|
|
db.commit()
|
|
return {"message": "Salary Entry created"}
|
|
|
|
|
|
def salary_journals(start_date: date, finish_date: date, db: Session):
|
|
days = monthrange(start_date.year, start_date.month)[1]
|
|
amount = 0
|
|
journals = []
|
|
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()
|
|
)
|
|
for employee in employees:
|
|
att = (
|
|
db.query(Attendance)
|
|
.filter(Attendance.employee_id == employee.id)
|
|
.filter(Attendance.date >= start_date)
|
|
.filter(Attendance.date <= finish_date)
|
|
.filter(Attendance.is_valid == True)
|
|
.all()
|
|
)
|
|
att = sum(map(lambda x: AttendanceType.by_id(x.attendance_type).value, att))
|
|
att = round(att * employee.salary / days)
|
|
if att != 0:
|
|
amount += att
|
|
journals.append(
|
|
Journal(
|
|
amount=att,
|
|
debit=-1,
|
|
account_id=employee.id,
|
|
cost_centre_id=employee.cost_centre_id,
|
|
)
|
|
)
|
|
salary = db.query(Account).filter(Account.id == Account.salary_id()).first()
|
|
if amount == 0:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail="No salaries to credit",
|
|
)
|
|
journals.append(
|
|
Journal(
|
|
amount=amount,
|
|
debit=1,
|
|
account_id=salary.id,
|
|
cost_centre_id=salary.cost_centre_id,
|
|
)
|
|
)
|
|
return journals
|