Merge pull request #16871 from rmehta/attendance-from-leave

feat: Pre mark attendance for Leave Application
This commit is contained in:
Rushabh Mehta 2019-03-22 12:41:47 +05:30 committed by GitHub
commit fc4eefcb22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 19 deletions

View File

@ -218,6 +218,39 @@
"translatable": 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_in_quick_entry": 0,
@ -428,7 +461,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-01-30 11:28:13.075959",
"modified": "2019-03-08 12:00:14.043535",
"modified_by": "Administrator",
"module": "HR",
"name": "Attendance",

View File

@ -40,7 +40,8 @@ class Attendance(Document):
def validate_attendance_date(self):
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"))
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"))

View File

@ -117,28 +117,29 @@ class LeaveApplication(Document):
def update_attendance(self):
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)
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
date = dt.strftime("%Y-%m-%d")
status = "Half Day" if date == self.half_day_date else "On Leave"
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))
attendance_name = frappe.db.exists('Attendance', dict(employee = self.employee,
attenance_date = date, docstatus = ('!=', 2)))
elif getdate(self.to_date) <= getdate(nowdate()):
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
date = dt.strftime("%Y-%m-%d")
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.employee = self.employee
doc.attendance_date = date
doc.company = self.company
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.insert(ignore_permissions=True)
doc.submit()

View File

@ -7,7 +7,7 @@ import unittest
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.utils import add_days, nowdate, now_datetime
from frappe.utils import add_days, nowdate, now_datetime, getdate
test_dependencies = ["Leave Allocation", "Leave Block List"]
@ -67,6 +67,43 @@ class TestLeaveApplication(unittest.TestCase):
application.to_date = "2013-01-05"
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):
self._clear_roles()
@ -428,7 +465,7 @@ def make_allocation_record(employee=None, leave_type=None):
"employee": employee or "_T-Employee-00001",
"leave_type": leave_type or "_Test Leave Type",
"from_date": "2013-01-01",
"to_date": "2015-12-31",
"to_date": "2019-12-31",
"new_leaves_allocated": 30
})