84 lines
3.6 KiB
Python
84 lines
3.6 KiB
Python
import datetime
|
|
import uuid
|
|
from decimal import Decimal
|
|
from pyramid.security import authenticated_userid
|
|
from pyramid.view import view_config
|
|
from sqlalchemy import or_, func
|
|
import transaction
|
|
from ....models import DBSession
|
|
from ....models.auth import User
|
|
from ....models.master import Employee, AttendanceType, Ledger
|
|
from ....models.validation_exception import TryCatchFunction
|
|
from ....models.voucher import Voucher, VoucherType, Attendance, Journal
|
|
from ..session import get_first_day, get_last_day
|
|
|
|
__author__ = 'tanshu'
|
|
|
|
|
|
@view_config(request_method='POST', route_name='api_credit_service_charge', renderer='json', permission='Attendance')
|
|
@TryCatchFunction
|
|
def credit_sc(request):
|
|
user = User.by_id(uuid.UUID(authenticated_userid(request)))
|
|
month = datetime.datetime.strptime(request.json_body['Month'], '%d-%b-%Y')
|
|
credit_date = datetime.datetime.strptime(request.json_body['CreditDate'], '%d-%b-%Y')
|
|
|
|
amount = balance(month)
|
|
start_date = get_first_day(month)
|
|
finish_date = get_last_day(month)
|
|
voucher = Voucher(date=credit_date, narration='Auto Generated Service Charge Entry', user_id=user.id,
|
|
type=VoucherType.by_name('Journal'), posted=True, poster_id=user.id)
|
|
DBSession.add(voucher)
|
|
for item in service_charge_journals(amount, start_date, finish_date):
|
|
voucher.journals.append(item)
|
|
DBSession.add(item)
|
|
transaction.commit()
|
|
return {'message': 'Salary Entry created'}
|
|
|
|
|
|
def service_charge_journals(amount, start_date, finish_date):
|
|
amount = amount * Decimal(.7) * Decimal(.9)
|
|
total_points = 0
|
|
details = []
|
|
finish_date = finish_date + datetime.timedelta(1)
|
|
journals = []
|
|
employees = DBSession().query(Employee) \
|
|
.filter(Employee.joining_date <= finish_date) \
|
|
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date)) \
|
|
.order_by(Employee.costcenter_id).order_by(Employee.designation).order_by(Employee.name).all()
|
|
for employee in employees:
|
|
if employee.service_points != 0:
|
|
att = DBSession.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))
|
|
points = Decimal(att) * employee.service_points
|
|
if points != 0:
|
|
total_points += points
|
|
details.append({'Employee': employee, 'Points': points})
|
|
if total_points == 0:
|
|
raise ValueError("There is no data to credit service charges")
|
|
point_value = round(amount / total_points, 2)
|
|
amount = 0
|
|
for item in details:
|
|
ee = item['Employee']
|
|
employee_amount = round(point_value * item['Points'])
|
|
journal = Journal(amount=employee_amount, debit=-1, ledger_id=ee.id, cost_center_id=ee.costcenter_id)
|
|
journals.append(journal)
|
|
amount += employee_amount
|
|
sc = Ledger.by_id(uuid.UUID(Ledger.service_charge()['LedgerID']))
|
|
journals.append(Journal(amount=amount, debit=1, ledger_id=sc.id, cost_center_id=sc.costcenter_id))
|
|
return journals
|
|
|
|
|
|
def balance(date):
|
|
amount = DBSession.query(func.sum(Journal.amount * Journal.debit)) \
|
|
.join(Journal.voucher) \
|
|
.filter(Voucher.date < date + datetime.timedelta(1)) \
|
|
.filter(Voucher.type != VoucherType.by_name('Issue').id) \
|
|
.filter(Journal.ledger_id == uuid.UUID(Ledger.service_charge()['LedgerID'])) \
|
|
.scalar()
|
|
return 0 if amount is None else amount * -1
|