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,
|
||||
"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",
|
||||
|
@ -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"))
|
||||
|
@ -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)
|
||||
|
||||
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)):
|
||||
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.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()
|
||||
|
@ -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
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user