fix: compensatory leave request creation

This commit is contained in:
Mangesh-Khairnar
2019-12-16 16:56:57 +05:30
parent 48a8a40703
commit ce6923ecb6
3 changed files with 167 additions and 65 deletions

View File

@@ -19,4 +19,4 @@ frappe.ui.form.on('Compensatory Leave Request', {
frm.set_df_property('half_day_date', 'reqd', false);
}
}
});
});

View File

@@ -5,9 +5,10 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import date_diff, add_days, getdate
from frappe.utils import date_diff, add_days, getdate, cint
from frappe.model.document import Document
from erpnext.hr.utils import validate_dates, validate_overlap, get_leave_period, get_holidays_for_employee
from erpnext.hr.utils import validate_dates, validate_overlap, get_leave_period, \
get_holidays_for_employee, create_additional_leave_ledger_entry
class CompensatoryLeaveRequest(Document):
@@ -25,16 +26,14 @@ class CompensatoryLeaveRequest(Document):
frappe.throw(_("Leave Type is madatory"))
def validate_attendance(self):
query = """select attendance_date, status
from `tabAttendance` where
attendance_date between %(work_from_date)s and %(work_end_date)s
and docstatus=1 and status = 'Present' and employee=%(employee)s"""
attendance = frappe.get_all('Attendance',
filters={
'attendance_date': ['between', (self.work_from_date, self.work_end_date)],
'status': 'Present',
'docstatus': 1,
'employee': self.employee
}, fields=['attendance_date', 'status'])
attendance = frappe.db.sql(query, {
"work_from_date": self.work_from_date,
"work_end_date": self.work_end_date,
"employee": self.employee
}, as_dict=True)
if len(attendance) < date_diff(self.work_end_date, self.work_from_date) + 1:
frappe.throw(_("You are not present all day(s) between compensatory leave request days"))
@@ -50,13 +49,19 @@ class CompensatoryLeaveRequest(Document):
date_difference -= 0.5
leave_period = get_leave_period(self.work_from_date, self.work_end_date, company)
if leave_period:
leave_allocation = self.exists_allocation_for_period(leave_period)
leave_allocation = self.get_existing_allocation_for_period(leave_period)
if leave_allocation:
leave_allocation.new_leaves_allocated += date_difference
leave_allocation.submit()
leave_allocation.validate()
leave_allocation.db_set("new_leaves_allocated", leave_allocation.total_leaves_allocated)
leave_allocation.db_set("total_leaves_allocated", leave_allocation.total_leaves_allocated)
# generate additional ledger entry for the new compensatory leaves off
create_additional_leave_ledger_entry(leave_allocation, date_difference, add_days(self.work_end_date, 1))
else:
leave_allocation = self.create_leave_allocation(leave_period, date_difference)
self.db_set("leave_allocation", leave_allocation.name)
self.leave_allocation=leave_allocation.name
else:
frappe.throw(_("There is no leave period in between {0} and {1}").format(self.work_from_date, self.work_end_date))
@@ -68,11 +73,16 @@ class CompensatoryLeaveRequest(Document):
leave_allocation = frappe.get_doc("Leave Allocation", self.leave_allocation)
if leave_allocation:
leave_allocation.new_leaves_allocated -= date_difference
if leave_allocation.total_leaves_allocated - date_difference <= 0:
leave_allocation.total_leaves_allocated = 0
leave_allocation.submit()
if leave_allocation.new_leaves_allocated - date_difference <= 0:
leave_allocation.new_leaves_allocated = 0
leave_allocation.validate()
leave_allocation.db_set("new_leaves_allocated", leave_allocation.total_leaves_allocated)
leave_allocation.db_set("total_leaves_allocated", leave_allocation.total_leaves_allocated)
def exists_allocation_for_period(self, leave_period):
# create reverse entry on cancelation
create_additional_leave_ledger_entry(leave_allocation, date_difference * -1, add_days(self.work_end_date, 1))
def get_existing_allocation_for_period(self, leave_period):
leave_allocation = frappe.db.sql("""
select name
from `tabLeave Allocation`
@@ -95,17 +105,18 @@ class CompensatoryLeaveRequest(Document):
def create_leave_allocation(self, leave_period, date_difference):
is_carry_forward = frappe.db.get_value("Leave Type", self.leave_type, "is_carry_forward")
allocation = frappe.new_doc("Leave Allocation")
allocation.employee = self.employee
allocation.employee_name = self.employee_name
allocation.leave_type = self.leave_type
allocation.from_date = add_days(self.work_end_date, 1)
allocation.to_date = leave_period[0].to_date
allocation.new_leaves_allocated = date_difference
allocation.total_leaves_allocated = date_difference
allocation.description = self.reason
if is_carry_forward == 1:
allocation.carry_forward = True
allocation.save(ignore_permissions = True)
allocation = frappe.get_doc(dict(
doctype="Leave Allocation",
employee=self.employee,
employee_name=self.employee_name,
leave_type=self.leave_type,
from_date=add_days(self.work_end_date, 1),
to_date=leave_period[0].to_date,
carry_forward=cint(is_carry_forward),
new_leaves_allocated=date_difference,
total_leaves_allocated=date_difference,
description=self.reason
))
allocation.insert(ignore_permissions=True)
allocation.submit()
return allocation
return allocation

View File

@@ -5,37 +5,128 @@ from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import today, add_months, add_days
from erpnext.hr.doctype.attendance_request.test_attendance_request import get_employee
from erpnext.hr.doctype.leave_period.test_leave_period import create_leave_period
from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on
# class TestCompensatoryLeaveRequest(unittest.TestCase):
# def get_compensatory_leave_request(self):
# return frappe.get_doc('Compensatory Leave Request', dict(
# employee = employee,
# work_from_date = today,
# work_to_date = today,
# reason = 'test'
# )).insert()
#
# def test_creation_of_leave_allocation(self):
# employee = get_employee()
# today = get_today()
#
# compensatory_leave_request = self.get_compensatory_leave_request(today)
#
# before = get_leave_balance(employee, compensatory_leave_request.leave_type)
#
# compensatory_leave_request.submit()
#
# self.assertEqual(get_leave_balance(employee, compensatory_leave_request.leave_type), before + 1)
#
# def test_max_compensatory_leave(self):
# employee = get_employee()
# today = get_today()
#
# compensatory_leave_request = self.get_compensatory_leave_request()
#
# frappe.db.set_value('Leave Type', compensatory_leave_request.leave_type, 'max_leaves_allowed', 0)
#
# self.assertRaises(MaxLeavesLimitCrossed, compensatory_leave_request.submit)
#
# frappe.db.set_value('Leave Type', compensatory_leave_request.leave_type, 'max_leaves_allowed', 10)
#
class TestCompensatoryLeaveRequest(unittest.TestCase):
def setUp(self):
frappe.db.sql(''' delete from `tabCompensatory Leave Request`''')
frappe.db.sql(''' delete from `tabLeave Ledger Entry`''')
frappe.db.sql(''' delete from `tabLeave Allocation`''')
frappe.db.sql(''' delete from `tabAttendance` where attendance_date in {0} '''.format((today(), add_days(today(), -1)))) #nosec
create_leave_period(add_months(today(), -3), add_months(today(), 3), "_Test Company")
create_holiday_list()
employee = get_employee()
employee.holiday_list = "_Test Compensatory Leave"
employee.save()
def test_leave_balance_on_submit(self):
''' check creation of leave allocation on submission of compensatory leave request '''
employee = get_employee()
mark_attendance(employee)
compensatory_leave_request = get_compensatory_leave_request(employee.name)
before = get_leave_balance_on(employee.name, compensatory_leave_request.leave_type, today())
compensatory_leave_request.submit()
self.assertEqual(get_leave_balance_on(employee.name, compensatory_leave_request.leave_type, add_days(today(), 1)), before + 1)
def test_leave_allocation_update_on_submit(self):
employee = get_employee()
mark_attendance(employee, date=add_days(today(), -1))
compensatory_leave_request = get_compensatory_leave_request(employee.name, leave_date=add_days(today(), -1))
compensatory_leave_request.submit()
# leave allocation creation on submit
leaves_allocated = frappe.db.get_value('Leave Allocation', {
'name': compensatory_leave_request.leave_allocation
}, ['total_leaves_allocated'])
self.assertEqual(leaves_allocated, 1)
mark_attendance(employee)
compensatory_leave_request = get_compensatory_leave_request(employee.name)
compensatory_leave_request.submit()
# leave allocation updates on submission of second compensatory leave request
leaves_allocated = frappe.db.get_value('Leave Allocation', {
'name': compensatory_leave_request.leave_allocation
}, ['total_leaves_allocated'])
self.assertEqual(leaves_allocated, 2)
def test_creation_of_leave_ledger_entry_on_submit(self):
''' check creation of leave ledger entry on submission of leave request '''
employee = get_employee()
mark_attendance(employee)
compensatory_leave_request = get_compensatory_leave_request(employee.name)
compensatory_leave_request.submit()
filters = dict(transaction_name=compensatory_leave_request.leave_allocation)
leave_ledger_entry = frappe.get_all('Leave Ledger Entry', fields='*', filters=filters)
self.assertEquals(len(leave_ledger_entry), 1)
self.assertEquals(leave_ledger_entry[0].employee, compensatory_leave_request.employee)
self.assertEquals(leave_ledger_entry[0].leave_type, compensatory_leave_request.leave_type)
self.assertEquals(leave_ledger_entry[0].leaves, 1)
# check reverse leave ledger entry on cancellation
compensatory_leave_request.cancel()
leave_ledger_entry = frappe.get_all('Leave Ledger Entry', fields='*', filters=filters, order_by = 'creation desc')
self.assertEquals(len(leave_ledger_entry), 2)
self.assertEquals(leave_ledger_entry[0].employee, compensatory_leave_request.employee)
self.assertEquals(leave_ledger_entry[0].leave_type, compensatory_leave_request.leave_type)
self.assertEquals(leave_ledger_entry[0].leaves, -1)
def get_compensatory_leave_request(employee, leave_date=today()):
prev_comp_leave_req = frappe.db.get_value('Compensatory Leave Request',
dict(leave_type='Compensatory Off',
work_from_date=leave_date,
work_end_date=leave_date,
employee=employee), 'name')
if prev_comp_leave_req:
return frappe.get_doc('Compensatory Leave Request', prev_comp_leave_req)
return frappe.get_doc(dict(
doctype='Compensatory Leave Request',
employee=employee,
leave_type='Compensatory Off',
work_from_date=leave_date,
work_end_date=leave_date,
reason='test'
)).insert()
def mark_attendance(employee, date=today(), status='Present'):
if not frappe.db.exists(dict(doctype='Attendance', employee=employee.name, attendance_date=date, status='Present')):
attendance = frappe.get_doc({
"doctype": "Attendance",
"employee": employee.name,
"attendance_date": date,
"status": status
})
attendance.save()
attendance.submit()
def create_holiday_list():
if frappe.db.exists("Holiday List", "_Test Compensatory Leave"):
return
holiday_list = frappe.get_doc({
"doctype": "Holiday List",
"from_date": add_months(today(), -3),
"to_date": add_months(today(), 3),
"holidays": [
{
"description": "Test Holiday",
"holiday_date": today()
},
{
"description": "Test Holiday 1",
"holiday_date": add_days(today(), -1)
}
],
"holiday_list_name": "_Test Compensatory Leave"
})
holiday_list.save()