Merge pull request #16871 from rmehta/attendance-from-leave
feat: Pre mark attendance for Leave Application
This commit is contained in:
commit
fc4eefcb22
@ -218,6 +218,39 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "leave_application",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Leave Application",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Leave Application",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -428,7 +461,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-01-30 11:28:13.075959",
|
"modified": "2019-03-08 12:00:14.043535",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Attendance",
|
"name": "Attendance",
|
||||||
|
@ -40,7 +40,8 @@ class Attendance(Document):
|
|||||||
def validate_attendance_date(self):
|
def validate_attendance_date(self):
|
||||||
date_of_joining = frappe.db.get_value("Employee", self.employee, "date_of_joining")
|
date_of_joining = frappe.db.get_value("Employee", self.employee, "date_of_joining")
|
||||||
|
|
||||||
if getdate(self.attendance_date) > getdate(nowdate()):
|
# leaves can be marked for future dates
|
||||||
|
if self.status not in ('On Leave', 'Half Day') and getdate(self.attendance_date) > getdate(nowdate()):
|
||||||
frappe.throw(_("Attendance can not be marked for future dates"))
|
frappe.throw(_("Attendance can not be marked for future dates"))
|
||||||
elif date_of_joining and getdate(self.attendance_date) < getdate(date_of_joining):
|
elif date_of_joining and getdate(self.attendance_date) < getdate(date_of_joining):
|
||||||
frappe.throw(_("Attendance date can not be less than employee's joining date"))
|
frappe.throw(_("Attendance date can not be less than employee's joining date"))
|
||||||
|
@ -117,28 +117,29 @@ class LeaveApplication(Document):
|
|||||||
|
|
||||||
def update_attendance(self):
|
def update_attendance(self):
|
||||||
if self.status == "Approved":
|
if self.status == "Approved":
|
||||||
attendance = frappe.db.sql("""select name from `tabAttendance` where employee = %s\
|
|
||||||
and (attendance_date between %s and %s) and docstatus < 2""",(self.employee, self.from_date, self.to_date), as_dict=1)
|
|
||||||
|
|
||||||
if attendance:
|
|
||||||
for d in attendance:
|
|
||||||
doc = frappe.get_doc("Attendance", d.name)
|
|
||||||
if getdate(self.half_day_date) == doc.attendance_date:
|
|
||||||
status = "Half Day"
|
|
||||||
else:
|
|
||||||
status = "On Leave"
|
|
||||||
frappe.db.sql("""update `tabAttendance` set status = %s, leave_type = %s\
|
|
||||||
where name = %s""",(status, self.leave_type, d.name))
|
|
||||||
|
|
||||||
elif getdate(self.to_date) <= getdate(nowdate()):
|
|
||||||
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
|
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
|
||||||
date = dt.strftime("%Y-%m-%d")
|
date = dt.strftime("%Y-%m-%d")
|
||||||
|
status = "Half Day" if date == self.half_day_date else "On Leave"
|
||||||
|
|
||||||
|
attendance_name = frappe.db.exists('Attendance', dict(employee = self.employee,
|
||||||
|
attenance_date = date, docstatus = ('!=', 2)))
|
||||||
|
|
||||||
|
if attendance_name:
|
||||||
|
# update existing attendance, change absent to on leave
|
||||||
|
doc = frappe.get_doc('Attendance', attendance_name)
|
||||||
|
if doc.status != status:
|
||||||
|
doc.db_set('status', status)
|
||||||
|
doc.db_set('leave_type', self.leave_type)
|
||||||
|
doc.db_set('leave_application', self.name)
|
||||||
|
else:
|
||||||
|
# make new attendance and submit it
|
||||||
doc = frappe.new_doc("Attendance")
|
doc = frappe.new_doc("Attendance")
|
||||||
doc.employee = self.employee
|
doc.employee = self.employee
|
||||||
doc.attendance_date = date
|
doc.attendance_date = date
|
||||||
doc.company = self.company
|
doc.company = self.company
|
||||||
doc.leave_type = self.leave_type
|
doc.leave_type = self.leave_type
|
||||||
doc.status = "Half Day" if date == self.half_day_date else "On Leave"
|
doc.leave_application = self.name
|
||||||
|
doc.status = status
|
||||||
doc.flags.ignore_validate = True
|
doc.flags.ignore_validate = True
|
||||||
doc.insert(ignore_permissions=True)
|
doc.insert(ignore_permissions=True)
|
||||||
doc.submit()
|
doc.submit()
|
||||||
|
@ -7,7 +7,7 @@ import unittest
|
|||||||
|
|
||||||
from erpnext.hr.doctype.leave_application.leave_application import LeaveDayBlockedError, OverlapError, NotAnOptionalHoliday, get_leave_balance_on
|
from erpnext.hr.doctype.leave_application.leave_application import LeaveDayBlockedError, OverlapError, NotAnOptionalHoliday, get_leave_balance_on
|
||||||
from frappe.permissions import clear_user_permissions_for_doctype
|
from frappe.permissions import clear_user_permissions_for_doctype
|
||||||
from frappe.utils import add_days, nowdate, now_datetime
|
from frappe.utils import add_days, nowdate, now_datetime, getdate
|
||||||
|
|
||||||
test_dependencies = ["Leave Allocation", "Leave Block List"]
|
test_dependencies = ["Leave Allocation", "Leave Block List"]
|
||||||
|
|
||||||
@ -67,6 +67,43 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
application.to_date = "2013-01-05"
|
application.to_date = "2013-01-05"
|
||||||
return application
|
return application
|
||||||
|
|
||||||
|
def test_attendance_creation(self):
|
||||||
|
'''check attendance is automatically created on leave approval'''
|
||||||
|
make_allocation_record()
|
||||||
|
application = self.get_application(_test_records[0])
|
||||||
|
application.status = 'Approved'
|
||||||
|
application.from_date = '2018-01-01'
|
||||||
|
application.to_date = '2018-01-03'
|
||||||
|
application.insert()
|
||||||
|
application.submit()
|
||||||
|
|
||||||
|
attendance = frappe.get_all('Attendance', ['name', 'status', 'attendance_date'], dict(leave_application = application.name))
|
||||||
|
|
||||||
|
# attendance created for all 3 days
|
||||||
|
self.assertEqual(len(attendance), 3)
|
||||||
|
|
||||||
|
# all on leave
|
||||||
|
self.assertTrue(all([d.status == 'On Leave' for d in attendance]))
|
||||||
|
|
||||||
|
# dates
|
||||||
|
dates = [d.attendance_date for d in attendance]
|
||||||
|
for d in ('2018-01-01', '2018-01-02', '2018-01-03'):
|
||||||
|
self.assertTrue(getdate(d) in dates)
|
||||||
|
|
||||||
|
def test_overwrite_attendance(self):
|
||||||
|
# employee marked as absent
|
||||||
|
doc = frappe.new_doc("Attendance")
|
||||||
|
doc.employee = '_T-Employee-00001'
|
||||||
|
doc.attendance_date = '2018-01-01'
|
||||||
|
doc.company = '_Test Company'
|
||||||
|
doc.status = 'Absent'
|
||||||
|
doc.flags.ignore_validate = True
|
||||||
|
doc.insert(ignore_permissions=True)
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
# now check if the status has been updated
|
||||||
|
self.test_attendance_creation()
|
||||||
|
|
||||||
def test_block_list(self):
|
def test_block_list(self):
|
||||||
self._clear_roles()
|
self._clear_roles()
|
||||||
|
|
||||||
@ -428,7 +465,7 @@ def make_allocation_record(employee=None, leave_type=None):
|
|||||||
"employee": employee or "_T-Employee-00001",
|
"employee": employee or "_T-Employee-00001",
|
||||||
"leave_type": leave_type or "_Test Leave Type",
|
"leave_type": leave_type or "_Test Leave Type",
|
||||||
"from_date": "2013-01-01",
|
"from_date": "2013-01-01",
|
||||||
"to_date": "2015-12-31",
|
"to_date": "2019-12-31",
|
||||||
"new_leaves_allocated": 30
|
"new_leaves_allocated": 30
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user