diff --git a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.js b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.js index bb57562988..1baa1e04e3 100644 --- a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.js +++ b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.js @@ -10,5 +10,13 @@ frappe.ui.form.on('Compensatory Leave Request', { } }; }); + }, + half_day: function(frm) { + if(frm.doc.half_day == 1){ + frm.set_df_property('half_day_date', 'reqd', true); + } + else{ + frm.set_df_property('half_day_date', 'reqd', false); + } } }); diff --git a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.json b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.json index 9d2a966165..be309cd196 100644 --- a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.json +++ b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.json @@ -43,7 +43,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -77,7 +77,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -87,39 +87,40 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "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": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "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, + "fetch_from": "employee.department", + "fieldname": "department", + "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": "Department", + "length": 0, + "no_copy": 0, + "options": "Department", + "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, "fieldname": "work_from_date", "fieldtype": "Date", "hidden": 0, @@ -142,7 +143,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -174,7 +175,72 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "half_day", + "fieldtype": "Check", + "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": "Half Day", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "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, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "half_day", + "fieldname": "half_day_date", + "fieldtype": "Date", + "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": "Half Day Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -205,7 +271,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -238,7 +304,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -270,7 +336,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -303,7 +369,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { @@ -335,7 +401,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 } ], @@ -349,7 +415,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-05-25 12:02:05.585184", + "modified": "2018-06-20 17:32:40.735664", "modified_by": "Administrator", "module": "HR", "name": "Compensatory Leave Request", @@ -442,4 +508,4 @@ "title_field": "employee_name", "track_changes": 1, "track_seen": 0 -} +} \ No newline at end of file diff --git a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.py b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.py index 6a67d47fd4..bc4a1b4034 100644 --- a/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.py +++ b/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.py @@ -5,33 +5,72 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import date_diff, add_days +from frappe.utils import date_diff, add_days, getdate from frappe.model.document import Document -from erpnext.hr.utils import validate_dates, validate_overlap, get_leave_period +from erpnext.hr.utils import validate_dates, validate_overlap, get_leave_period, get_holidays_for_employee class CompensatoryLeaveRequest(Document): def validate(self): validate_dates(self, self.work_from_date, self.work_end_date) + if self.half_day: + if not self.half_day_date: + frappe.throw(_("Half Day Date is mandatory")) + if not getdate(self.work_from_date)<=getdate(self.half_day_date)<=getdate(self.work_end_date): + frappe.throw(_("Half Day Date should be in between Work From Date and Work End Date")) validate_overlap(self, self.work_from_date, self.work_end_date) + self.validate_holidays() + self.validate_attendance() + if not self.leave_type: + 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.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")) + + def validate_holidays(self): + holidays = get_holidays_for_employee(self.employee, self.work_from_date, self.work_end_date) + if len(holidays) < date_diff(self.work_end_date, self.work_from_date) + 1: + frappe.throw(_("Compensatory leave request days not in valid holidays")) def on_submit(self): - if not self.leave_type: - frappe.throw(_("Please select a leave type to submit the request")) - else: - company = frappe.db.get_value("Employee", self.employee, "company") - date_difference = date_diff(self.work_end_date, self.work_from_date) + 1 - 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) - if leave_allocation: - leave_allocation.new_leaves_allocated += date_difference - leave_allocation.submit() - else: - leave_allocation = self.create_leave_allocation(leave_period, date_difference) - self.db_set("leave_allocation", leave_allocation.name) + company = frappe.db.get_value("Employee", self.employee, "company") + date_difference = date_diff(self.work_end_date, self.work_from_date) + 1 + if self.half_day: + 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) + if leave_allocation: + leave_allocation.new_leaves_allocated += date_difference + leave_allocation.submit() else: - frappe.throw(_("There is no leave period in between {0} and {1}").format(self.work_from_date, self.work_end_date)) + leave_allocation = self.create_leave_allocation(leave_period, date_difference) + self.db_set("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)) + + def on_cancel(self): + if self.leave_allocation: + date_difference = date_diff(self.work_end_date, self.work_from_date) + 1 + if self.half_day: + date_difference -= 0.5 + 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() def exists_allocation_for_period(self, leave_period): leave_allocation = frappe.db.sql(""" diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py index 7cffa4c5b1..dc270dba41 100755 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py @@ -92,7 +92,7 @@ class LeaveAllocation(Document): self.total_leaves_allocated = flt(self.carry_forwarded_leaves) + flt(self.new_leaves_allocated) - if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave"): + if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave") and not frappe.db.get_value("Leave Type", self.leave_type, "is_compensatory"): frappe.throw(_("Total leaves allocated is mandatory for Leave Type {0}".format(self.leave_type))) def validate_total_leaves_allocated(self):