Files
brewman/brewman/views/services/voucher/salary_deduction.py

110 lines
4.6 KiB
Python

import datetime
from decimal import Decimal
from math import ceil
import uuid
from brewman.models import DBSession
from brewman.models.master import LedgerBase, Employee
from brewman.models.operations import journals_valid
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Journal, Voucher, VoucherType, SalaryDeduction
from brewman.views.services.session import get_last_day
__author__ = 'tanshu'
def salary_deduction_create_voucher(json, user):
dt = get_last_day(datetime.datetime.strptime(json['Date'], '%d-%b-%Y'))
days_in_month = dt.day
voucher = Voucher(date=dt, user_id=user.id, type=VoucherType.by_id(12))
DBSession.add(voucher)
exp, total = 0, 0
for item in json['SalaryDeductions']:
item_exp, item_total = add_salary_deduction(item, days_in_month, voucher)
exp += item_exp
total += item_total
ledger = LedgerBase.by_id(LedgerBase.esi_pf_expense())
journal = Journal(amount=exp, debit=1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id)
DBSession.add(journal)
voucher.journals.append(journal)
ledger = LedgerBase.by_id(LedgerBase.esi_pf_payable())
journal = Journal(amount=total, debit=-1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id)
DBSession.add(journal)
voucher.journals.append(journal)
journals_valid(voucher)
return voucher
def salary_deduction_update_voucher(voucher, json, user):
dt = get_last_day(datetime.datetime.strptime(json['Date'], '%d-%b-%Y'))
if dt != voucher.date.date():
raise ValidationError("Date Cannot be changed for Salary Deduction voucher!")
days_in_month = voucher.date.day
voucher.user_id = user.id
voucher.posted = False
voucher.last_edit_date = datetime.datetime.utcnow()
newDeductions = json['SalaryDeductions']
exp, total, journals = 0, 0, []
for i in range(len(voucher.salary_deductions), 0, -1):
item = voucher.salary_deductions[i - 1]
found = False
for i in range(len(newDeductions), 0, -1):
j = newDeductions[i - 1]
if 'SalaryDeductionID' in j and item.id == uuid.UUID(j['SalaryDeductionID']):
journals.append(item.journal.id)
exp += item.esi_er + item.pf_er
total += item.esi_ee + item.pf_ee + item.esi_er + item.pf_er
newDeductions.remove(j)
break
if not found:
voucher.salary_deductions.remove(item)
voucher.journals.remove(item.journal)
for j in newDeductions:
item_exp, item_total = add_salary_deduction(j, days_in_month, voucher)
exp += item_exp
total += item_total
journal = [i for i in voucher.journals if i.ledger_id == LedgerBase.esi_pf_expense()]
journal = journal[0]
journal.amount = exp
journal = [i for i in voucher.journals if i.ledger_id == LedgerBase.esi_pf_payable()]
journal = journal[0]
journal.amount = total
journals_valid(voucher)
return voucher
def add_salary_deduction(item, days_in_month, voucher):
ledger = Employee.by_id(uuid.UUID(item['Journal']['Ledger']['LedgerID']))
gross_salary = int(item['GrossSalary'])
days_worked = int(item['DaysWorked'])
esi_ee, esi_er, esi_both = esi_contribution(gross_salary, days_worked, days_in_month)
pf_ee, pf_er, pf_both = pf_contribution(gross_salary, days_worked, days_in_month)
journal = Journal(amount=esi_ee + pf_ee, debit=1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id)
sd = SalaryDeduction(journal=journal, gross_salary=gross_salary, days_worked=days_worked, esi_ee=esi_ee,
pf_ee=pf_ee, esi_er=esi_er, pf_er=pf_er)
voucher.journals.append(journal)
voucher.salary_deductions.append(sd)
DBSession.add(journal)
DBSession.add(sd)
return esi_er + pf_er, esi_both + pf_both
def esi_contribution(gross_salary, days_worked, days_in_month):
limit = 15000
employee_rate = .0175
employer_rate = .0475
employee = 0 if gross_salary > limit else ceil(employee_rate * gross_salary * days_worked / days_in_month)
employer = 0 if gross_salary > limit else ceil(employer_rate * gross_salary * days_worked / days_in_month)
return employee, employer, employee + employer
def pf_contribution(gross_salary, days_worked, days_in_month):
limit = 6500
employee_rate = .12
employer_rate = .12 + .011 + .005 + .0001
employee = 0 if gross_salary > limit else ceil(employee_rate * gross_salary * days_worked / days_in_month)
employer = 0 if gross_salary > limit else ceil(employer_rate * gross_salary * days_worked / days_in_month)
return employee, employer, employee + employer