110 lines
4.6 KiB
Python
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
|