From d9a585bdad456af2e5ce5872420a9659844c2a4e Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Mon, 12 Feb 2018 16:02:57 +0530 Subject: [PATCH] Leave workflow patch fixes (#12823) * modified patch for leave application workflow * removed leave approval field from leave application doctype * fetch lwp and attendance only if workflow field exists * modified test cases * modified files with leave application * docstatus draft for rejected applications * modified leave application calendar * test fixed * run patch only if any record exists --- erpnext/demo/user/hr.py | 4 +- .../patient_appointment.py | 2 +- erpnext/hr/doctype/attendance/attendance.py | 2 +- .../leave_application/leave_application.js | 18 +-- .../leave_application/leave_application.json | 94 +------------ .../leave_application/leave_application.py | 77 ++--------- .../leave_application_calendar.js | 2 +- .../leave_application_list.js | 6 +- .../test_leave_application.js | 5 +- .../test_leave_application.py | 123 +----------------- erpnext/hr/doctype/salary_slip/salary_slip.py | 1 - erpnext/patches.txt | 2 +- .../v10_0/workflow_leave_application.py | 67 +++++++++- erpnext/setup/install.py | 53 -------- 14 files changed, 85 insertions(+), 371 deletions(-) diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index e59c3eeffe..d61aa4e6a0 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -172,7 +172,6 @@ def make_leave_application(): "from_date": frappe.flags.current_date, "to_date": to_date, "leave_type": allocated_leave.leave_type, - "status": "Approved" }) try: leave_application.insert() @@ -191,8 +190,9 @@ def mark_attendance(): "employee": employee.name, "attendance_date": attendance_date }) + leave = frappe.db.sql("""select name from `tabLeave Application` - where employee = %s and %s between from_date and to_date and workflow_state = 'Approved' + where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee.name, attendance_date)) if leave: diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index 0a96820362..90d4d0ea20 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -103,7 +103,7 @@ def get_availability_data(date, physician): # Check if He/She on Leave leave_record = frappe.db.sql("""select half_day from `tabLeave Application` - where employee = %s and %s between from_date and to_date and status = 'Approved' + where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: diff --git a/erpnext/hr/doctype/attendance/attendance.py b/erpnext/hr/doctype/attendance/attendance.py index fd7344a495..7b04f7dbae 100644 --- a/erpnext/hr/doctype/attendance/attendance.py +++ b/erpnext/hr/doctype/attendance/attendance.py @@ -21,7 +21,7 @@ class Attendance(Document): def check_leave_record(self): leave_record = frappe.db.sql("""select leave_type, half_day from `tabLeave Application` - where employee = %s and %s between from_date and to_date and workflow_state = 'Approved' + where employee = %s and %s between from_date and to_date and docstatus = 1""", (self.employee, self.attendance_date), as_dict=True) if leave_record: if leave_record[0].half_day: diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js index c2d8326320..2e6e4515b1 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.js +++ b/erpnext/hr/doctype/leave_application/leave_application.js @@ -10,15 +10,6 @@ frappe.ui.form.on("Leave Application", { frm.set_value("posting_date", frappe.datetime.get_today()); } - frm.set_query("leave_approver", function() { - return { - query: "erpnext.hr.doctype.leave_application.leave_application.get_approvers", - filters: { - employee: frm.doc.employee - } - }; - }); - frm.set_query("employee", erpnext.queries.employee); }, @@ -29,14 +20,11 @@ frappe.ui.form.on("Leave Application", { refresh: function(frm) { if (frm.is_new()) { - frm.set_value("workflow_state", "Open"); frm.trigger("calculate_total_days"); } - }, - - leave_approver: function(frm) { - if(frm.doc.leave_approver){ - frm.set_value("leave_approver_name", frappe.user.full_name(frm.doc.leave_approver)); + cur_frm.set_intro(""); + if(frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) { + frm.set_intro(__("Fill the form and save it")); } }, diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json index 88b5a554fc..2435d06979 100644 --- a/erpnext/hr/doctype/leave_application/leave_application.json +++ b/erpnext/hr/doctype/leave_application/leave_application.json @@ -427,96 +427,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_15", - "fieldtype": "Column Break", - "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, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "leave_approver", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Leave Approver", - "length": 0, - "no_copy": 0, - "options": "User", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "leave_approver_name", - "fieldtype": "Read Only", - "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 Approver Name", - "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, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -736,7 +646,7 @@ "issingle": 0, "istable": 0, "max_attachments": 3, - "modified": "2018-01-22 12:10:40.757274", + "modified": "2018-02-12 13:10:05.766762", "modified_by": "Administrator", "module": "HR", "name": "Leave Application", @@ -885,7 +795,7 @@ "submit": 0, "write": 1 } - ], + ], "quick_entry": 0, "read_only": 0, "read_only_onload": 0, diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index 5be44af1e3..22fd0e5f98 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -21,17 +21,10 @@ class AttendanceAlreadyMarkedError(frappe.ValidationError): pass from frappe.model.document import Document class LeaveApplication(Document): def get_feed(self): - return _("{0}: From {0} of type {1}").format(self.workflow_state, self.employee_name, self.leave_type) + return _("{0}: From {0} of type {1}").format(self.employee_name, self.leave_type) def validate(self): - if self.get("__islocal"): self.workflow_state = 'Open' - if not getattr(self, "__islocal", None) and frappe.db.exists(self.doctype, self.name): - self.previous_doc = frappe.get_value(self.doctype, self.name, "leave_approver", as_dict=True) - else: - self.previous_doc = None - set_employee_name(self) - self.validate_dates() self.validate_balance_leaves() self.validate_leave_overlap() @@ -39,22 +32,12 @@ class LeaveApplication(Document): self.show_block_day_warning() self.validate_block_days() self.validate_salary_processed_days() - self.validate_leave_approver() self.validate_attendance() - def on_update(self): - if (not self.previous_doc and self.leave_approver) or (self.previous_doc and \ - self.workflow_state == "Open" and self.previous_doc.leave_approver != self.leave_approver): - # notify leave approver about creation - self.notify_leave_approver() - def on_submit(self): self.validate_back_dated_application() - # notify leave applier about approval - self.notify_employee(self.workflow_state) - def on_cancel(self): # notify leave applier about cancellation self.notify_employee("cancelled") @@ -128,7 +111,7 @@ class LeaveApplication(Document): block_dates = get_applicable_block_dates(self.from_date, self.to_date, self.employee, self.company) - if block_dates and self.workflow_state == "Approved": + if block_dates and self.docstatus == 1: frappe.throw(_("You are not authorized to approve leaves on Block Dates"), LeaveDayBlockedError) def validate_balance_leaves(self): @@ -143,7 +126,7 @@ class LeaveApplication(Document): self.leave_balance = get_leave_balance_on(self.employee, self.leave_type, self.from_date, consider_all_leaves_in_the_allocation_period=True) - if self.workflow_state != "Rejected" and self.leave_balance < self.total_leave_days: + if self.leave_balance < self.total_leave_days: if frappe.db.get_value("Leave Type", self.leave_type, "allow_negative"): frappe.msgprint(_("Note: There is not enough leave balance for Leave Type {0}") .format(self.leave_type)) @@ -160,7 +143,7 @@ class LeaveApplication(Document): select name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date from `tabLeave Application` - where employee = %(employee)s and docstatus < 2 and workflow_state in ("Open", "Approved") + where employee = %(employee)s and docstatus < 2 and to_date >= %(from_date)s and from_date <= %(to_date)s and name != %(name)s""", { "employee": self.employee, @@ -190,7 +173,6 @@ class LeaveApplication(Document): leave_count_on_half_day_date = frappe.db.sql("""select count(name) from `tabLeave Application` where employee = %(employee)s and docstatus < 2 - and workflow_state in ("Open", "Approved") and half_day = 1 and half_day_date = %(half_day_date)s and name != %(name)s""", { @@ -206,23 +188,6 @@ class LeaveApplication(Document): if max_days and self.total_leave_days > cint(max_days): frappe.throw(_("Leave of type {0} cannot be longer than {1}").format(self.leave_type, max_days)) - def validate_leave_approver(self): - employee = frappe.get_doc("Employee", self.employee) - leave_approvers = [l.leave_approver for l in employee.get("leave_approvers")] - - if len(leave_approvers) and self.leave_approver not in leave_approvers: - frappe.throw(_("Leave approver must be one of {0}") - .format(comma_or(leave_approvers)), InvalidLeaveApproverError) - - elif self.leave_approver and not frappe.db.sql("""select name from `tabHas Role` - where parent=%s and role='Leave Approver'""", self.leave_approver): - frappe.throw(_("{0} ({1}) must have role 'Leave Approver'")\ - .format(get_fullname(self.leave_approver), self.leave_approver), InvalidLeaveApproverError) - - elif self.docstatus==1 and len(leave_approvers) and self.leave_approver != frappe.session.user: - frappe.throw(_("Only the selected Leave Approver can submit this Leave Application"), - LeaveApproverIdentityError) - def validate_attendance(self): attendance = frappe.db.sql("""select name from `tabAttendance` where employee = %s and (attendance_date between %s and %s) and status = "Present" and docstatus = 1""", @@ -231,7 +196,7 @@ class LeaveApplication(Document): frappe.throw(_("Attendance for employee {0} is already marked for this day").format(self.employee), AttendanceAlreadyMarkedError) - def notify_employee(self, workflow_state): + def notify_employee(self): employee = frappe.get_doc("Employee", self.employee) if not employee.user_id: return @@ -246,19 +211,15 @@ class LeaveApplication(Document): message += "Leave Type: {leave_type}".format(leave_type=self.leave_type)+"
" message += "From Date: {from_date}".format(from_date=self.from_date)+"
" message += "To Date: {to_date}".format(to_date=self.to_date)+"
" - message += "Status: {workflow_state}".format(workflow_state=_(workflow_state)) return message self.notify({ # for post in messages "message": _get_message(url=True), "message_to": employee.user_id, - "subject": (_("Leave Application") + ": %s - %s") % (self.name, _(workflow_state)) + "subject": (_("Leave Application") + ": %s - %s") % (self.name) }) - def notify_leave_approver(self): - employee = frappe.get_doc("Employee", self.employee) - def _get_message(url=False): name = self.name employee_name = cstr(employee.employee_name) @@ -275,7 +236,6 @@ class LeaveApplication(Document): self.notify({ # for post in messages "message": _get_message(url=True), - "message_to": self.leave_approver, # for email "subject": (_("New Leave Application") + ": %s - " + _("Employee") + ": %s") % (self.name, cstr(employee.employee_name)) @@ -320,23 +280,6 @@ class LeaveApplication(Document): # Arrey! pass -@frappe.whitelist() -def get_approvers(doctype, txt, searchfield, start, page_len, filters): - if not filters.get("employee"): - frappe.throw(_("Please select Employee Record first.")) - - employee_user = frappe.get_value("Employee", filters.get("employee"), "user_id") - - approvers_list = frappe.db.sql("""select user.name, user.first_name, user.last_name from - tabUser user, `tabEmployee Leave Approver` approver where - approver.parent = %s - and user.name like %s - and approver.leave_approver=user.name""", (filters.get("employee"), "%" + txt + "%")) - - if not approvers_list: - approvers_list = get_approver_list(employee_user) - return approvers_list - @frappe.whitelist() def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None): number_of_days = 0 @@ -371,7 +314,7 @@ def get_approved_leaves_for_period(employee, leave_type, from_date, to_date): select employee, leave_type, from_date, to_date, total_leave_days from `tabLeave Application` where employee=%(employee)s and leave_type=%(leave_type)s - and workflow_state="Approved" and docstatus=1 + and docstatus=1 and (from_date between %(from_date)s and %(to_date)s or to_date between %(from_date)s and %(to_date)s or (from_date < %(from_date)s and to_date > %(to_date)s)) @@ -471,11 +414,10 @@ def add_department_leaves(events, start, end, employee, company): def add_leaves(events, start, end, match_conditions=None): query = """select name, from_date, to_date, employee_name, half_day, - workflow_state, employee, docstatus + employee, docstatus from `tabLeave Application` where from_date <= %(end)s and to_date >= %(start)s <= to_date - and docstatus < 2 - and workflow_state!="Rejected" """ + and docstatus < 2""" if match_conditions: query += match_conditions @@ -485,7 +427,6 @@ def add_leaves(events, start, end, match_conditions=None): "doctype": "Leave Application", "from_date": d.from_date, "to_date": d.to_date, - "workflow_state": d.workflow_state, "title": cstr(d.employee_name) + \ (d.half_day and _(" (Half Day)") or ""), "docstatus": d.docstatus diff --git a/erpnext/hr/doctype/leave_application/leave_application_calendar.js b/erpnext/hr/doctype/leave_application/leave_application_calendar.js index b06b40f38e..0286f30064 100644 --- a/erpnext/hr/doctype/leave_application/leave_application_calendar.js +++ b/erpnext/hr/doctype/leave_application/leave_application_calendar.js @@ -7,7 +7,7 @@ frappe.views.calendar["Leave Application"] = { "end": "to_date", "id": "name", "title": "title", - "workflow_state": "workflow_state", + "docstatus": 1 }, options: { header: { diff --git a/erpnext/hr/doctype/leave_application/leave_application_list.js b/erpnext/hr/doctype/leave_application/leave_application_list.js index 7798ae7d3d..d7588da4dd 100644 --- a/erpnext/hr/doctype/leave_application/leave_application_list.js +++ b/erpnext/hr/doctype/leave_application/leave_application_list.js @@ -1,7 +1,3 @@ frappe.listview_settings['Leave Application'] = { - add_fields: ["workflow_state", "leave_type", "employee", "employee_name", "total_leave_days", "from_date", "to_date"], - get_indicator: function(doc) { - return [__(doc.workflow_state), frappe.utils.guess_colour(doc.workflow_state), - "workflow_state,=," + doc.workflow_state]; - } + add_fields: ["leave_type", "employee", "employee_name", "total_leave_days", "from_date", "to_date"] }; diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.js b/erpnext/hr/doctype/leave_application/test_leave_application.js index 6d51b71057..6d7b6a7058 100644 --- a/erpnext/hr/doctype/leave_application/test_leave_application.js +++ b/erpnext/hr/doctype/leave_application/test_leave_application.js @@ -16,7 +16,6 @@ QUnit.test("Test: Leave application [HR]", function (assert) { {to_date: leave_date}, {half_day: 1}, {employee: employee.message.name}, - {leave_approver: "Administrator"}, {follow_via_email: 0} ]); }, @@ -36,8 +35,8 @@ QUnit.test("Test: Leave application [HR]", function (assert) { () => frappe.set_route("List", "Leave Application", "List"), () => frappe.timeout(1), // // check approved application in list - () => assert.deepEqual(["Test Employee 1", "Approved"], [cur_list.data[0].employee_name, cur_list.data[0].workflow_state]), - // "leave for correct employee is approved"), + () => assert.deepEqual(["Test Employee 1", 1], [cur_list.data[0].employee_name, cur_list.data[0].docstatus]), + // "leave for correct employee is submitted"), () => done() ]); }); \ No newline at end of file diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py index b2f6054057..520d7c9703 100644 --- a/erpnext/hr/doctype/leave_application/test_leave_application.py +++ b/erpnext/hr/doctype/leave_application/test_leave_application.py @@ -103,7 +103,6 @@ class TestLeaveApplication(unittest.TestCase): application = self.get_application(_test_records[0]) application.insert() - application.workflow_state = "Approved" self.assertRaises(LeaveDayBlockedError, application.submit) frappe.set_user("test1@example.com") @@ -127,11 +126,9 @@ class TestLeaveApplication(unittest.TestCase): make_allocation_record() application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.insert() application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" self.assertRaises(OverlapError, application.insert) def test_overlap_with_half_day_1(self): @@ -148,14 +145,12 @@ class TestLeaveApplication(unittest.TestCase): # leave from 1-5, half day on 3rd application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.half_day = 1 application.half_day_date = "2013-01-03" application.insert() # Apply again for a half day leave on 3rd application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.from_date = "2013-01-03" application.to_date = "2013-01-03" application.half_day = 1 @@ -164,7 +159,6 @@ class TestLeaveApplication(unittest.TestCase): # Apply again for a half day leave on 3rd application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.from_date = "2013-01-03" application.to_date = "2013-01-03" application.half_day = 1 @@ -186,12 +180,10 @@ class TestLeaveApplication(unittest.TestCase): # leave from 1-5, no half day application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.insert() # Apply again for a half day leave on 1st application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.half_day = 1 application.half_day_date = application.from_date @@ -211,14 +203,12 @@ class TestLeaveApplication(unittest.TestCase): # leave from 1-5, half day on 5th application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.half_day = 1 application.half_day_date = "2013-01-05" application.insert() # Apply leave from 4-7, half day on 5th application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.from_date = "2013-01-04" application.to_date = "2013-01-07" application.half_day = 1 @@ -228,7 +218,6 @@ class TestLeaveApplication(unittest.TestCase): # Apply leave from 5-7, half day on 5th application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" application.from_date = "2013-01-05" application.to_date = "2013-01-07" application.half_day = 1 @@ -246,7 +235,6 @@ class TestLeaveApplication(unittest.TestCase): make_allocation_record(employee="_T-Employee-0002") application = self.get_application(_test_records[1]) - application.leave_approver = "test@example.com" frappe.db.set_value("Leave Block List", "_Test Leave Block List", "applies_to_all_departments", 1) @@ -257,7 +245,6 @@ class TestLeaveApplication(unittest.TestCase): application.insert() frappe.set_user("test@example.com") - application.workflow_state = "Approved" # clear permlevel access cache on change user del application._has_access_to @@ -267,114 +254,6 @@ class TestLeaveApplication(unittest.TestCase): frappe.db.set_value("Leave Block List", "_Test Leave Block List", "applies_to_all_departments", 0) - def test_leave_approval(self): - self._clear_roles() - - from frappe.utils.user import add_role - add_role("test@example.com", "Employee") - add_role("test1@example.com", "HR User") - add_role("test1@example.com", "Leave Approver") - add_role("test2@example.com", "Leave Approver") - - self._test_leave_approval_basic_case() - self._test_leave_approval_invalid_leave_approver_insert() - self._test_leave_approval_invalid_leave_approver_submit() - self._test_leave_approval_valid_leave_approver_insert() - - def _test_leave_approval_basic_case(self): - self._clear_applications() - - self._add_employee_leave_approver("_T-Employee-0001", "test1@example.com") - - # create leave application as Employee - frappe.set_user("test@example.com") - - make_allocation_record() - - application = self.get_application(_test_records[0]) - application.leave_approver = "test1@example.com" - application.insert() - - # submit leave application by Leave Approver - frappe.set_user("test1@example.com") - application.workflow_state = "Approved" - del application._has_access_to - application.submit() - self.assertEqual(frappe.db.get_value("Leave Application", application.name, - "docstatus"), 1) - - def _test_leave_approval_invalid_leave_approver_insert(self): - from erpnext.hr.doctype.leave_application.leave_application import InvalidLeaveApproverError - - self._clear_applications() - - # add a different leave approver in the employee's list - # should raise exception if not a valid leave approver - self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com") - self._remove_employee_leave_approver("_T-Employee-0001", "test1@example.com") - - make_allocation_record() - - application = self.get_application(_test_records[0]) - frappe.set_user("test@example.com") - - application.leave_approver = "test1@example.com" - self.assertRaises(InvalidLeaveApproverError, application.insert) - - frappe.db.sql("""delete from `tabEmployee Leave Approver` where parent=%s""", - "_T-Employee-0001") - - def _test_leave_approval_invalid_leave_approver_submit(self): - self._clear_applications() - self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com") - - # create leave application as employee - # but submit as invalid leave approver - should raise exception - frappe.set_user("test@example.com") - - make_allocation_record() - - application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" - application.insert() - frappe.set_user("test1@example.com") - del application._has_access_to - application.workflow_state = "Approved" - - from erpnext.hr.doctype.leave_application.leave_application import LeaveApproverIdentityError - self.assertRaises(LeaveApproverIdentityError, application.submit) - - frappe.db.sql("""delete from `tabEmployee Leave Approver` where parent=%s""", - "_T-Employee-0001") - - def _test_leave_approval_valid_leave_approver_insert(self): - self._clear_applications() - self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com") - - original_department = frappe.db.get_value("Employee", "_T-Employee-0001", "department") - frappe.db.set_value("Employee", "_T-Employee-0001", "department", None) - - frappe.set_user("test@example.com") - - make_allocation_record() - - application = self.get_application(_test_records[0]) - application.leave_approver = "test2@example.com" - application.insert() - - # change to valid leave approver and try to submit leave application - frappe.set_user("test2@example.com") - application.workflow_state = "Approved" - del application._has_access_to - application.submit() - self.assertEqual(frappe.db.get_value("Leave Application", application.name, - "docstatus"), 1) - - frappe.db.sql("""delete from `tabEmployee Leave Approver` where parent=%s""", - "_T-Employee-0001") - - frappe.db.set_value("Employee", "_T-Employee-0001", "department", original_department) - def make_allocation_record(employee=None, leave_type=None): frappe.db.sql("delete from `tabLeave Allocation`") @@ -388,4 +267,4 @@ def make_allocation_record(employee=None, leave_type=None): }) allocation.insert(ignore_permissions=True) - allocation.submit() + allocation.submit() \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index 878c6b433a..da2598ff93 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -300,7 +300,6 @@ class SalarySlip(TransactionBase): where t2.name = t1.leave_type and t2.is_lwp = 1 and t1.docstatus = 1 - and t1.workflow_state = 'Approved' and t1.employee = %(employee)s and CASE WHEN t2.include_holiday != 1 THEN %(dt)s not in ('{0}') and %(dt)s between from_date and to_date WHEN t2.include_holiday THEN %(dt)s between from_date and to_date diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 4f86799e1a..69d8a4752c 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -489,7 +489,7 @@ erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france erpnext.patches.v10_0.update_assessment_plan erpnext.patches.v10_0.update_assessment_result erpnext.patches.v10_0.added_extra_gst_custom_field -erpnext.patches.v10_0.workflow_leave_application #2018-01-24 +erpnext.patches.v10_0.workflow_leave_application #2018-01-24 #2018-02-02 #2018-02-08 erpnext.patches.v10_0.set_default_payment_terms_based_on_company erpnext.patches.v10_0.update_sales_order_link_to_purchase_order erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 diff --git a/erpnext/patches/v10_0/workflow_leave_application.py b/erpnext/patches/v10_0/workflow_leave_application.py index 8a68f891c4..0d3340264e 100644 --- a/erpnext/patches/v10_0/workflow_leave_application.py +++ b/erpnext/patches/v10_0/workflow_leave_application.py @@ -3,11 +3,66 @@ from __future__ import unicode_literals import frappe -from erpnext.setup.install import leave_application_workflow def execute(): - frappe.reload_doc("hr", "doctype", "leave_application") - frappe.reload_doc("workflow", "doctype", "workflow") - leave_application_workflow() - if frappe.db.has_column("Leave Application", "status"): - frappe.db.sql("""update `tabLeave Application` set workflow_state = status""") + if frappe.db.a_row_exists("Leave Application"): + frappe.reload_doc("hr", "doctype", "leave_application") + frappe.reload_doc("workflow", "doctype", "workflow") + states = {'Approved': 'Success', 'Rejected': 'Danger', 'Open': 'Warning'} + + for state, style in states.items(): + if not frappe.db.exists("Workflow State", state): + frappe.get_doc({ + 'doctype': 'Workflow State', + 'workflow_state_name': state, + 'style': style + }).insert(ignore_permissions=True) + + for action in ['Approve', 'Reject']: + if not frappe.db.exists("Workflow Action", action): + frappe.get_doc({ + 'doctype': 'Workflow Action', + 'workflow_action_name': action + }).insert(ignore_permissions=True) + + if not frappe.db.exists("Workflow", "Leave Approval"): + frappe.get_doc({ + 'doctype': 'Workflow', + 'workflow_name': 'Leave Approval', + 'document_type': 'Leave Application', + 'is_active': 1, + 'workflow_state_field': 'workflow_state', + 'states': [{ + "state": 'Open', + "doc_status": 0, + "allow_edit": 'Employee' + }, { + "state": 'Approved', + "doc_status": 1, + "allow_edit": 'Leave Approver' + }, { + "state": 'Rejected', + "doc_status": 0, + "allow_edit": 'Leave Approver' + }], + 'transitions': [{ + "state": 'Open', + "action": 'Approve', + "next_state": 'Approved', + "allowed": 'Leave Approver' + }, + { + "state": 'Open', + "action": 'Reject', + "next_state": 'Rejected', + "allowed": 'Leave Approver' + }] + }).insert(ignore_permissions=True) + + if frappe.db.has_column("Leave Application", "status"): + frappe.db.sql("""update `tabLeave Application` set workflow_state = status""") + + if frappe.db.has_column("Leave Application", "workflow_state"): + frappe.db.sql("""update `tabWorkflow Document State` set doc_status = 0 where parent = "Leave Approval" \ + and state = "Rejected" and doc_status = 1""") + frappe.db.sql("""update `tabLeave Application` set docstatus = 0 where workflow_state = "Rejected" and docstatus = 1""") diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index 2cc280ff67..81f909aa84 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -12,7 +12,6 @@ default_mail_footer = """
ERPNext
""" def after_install(): - leave_application_workflow() frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert() set_single_defaults() create_compact_item_print_custom_field() @@ -20,58 +19,6 @@ def after_install(): add_all_roles_to("Administrator") frappe.db.commit() -def leave_application_workflow(): - states = {'Approved': 'Success', 'Rejected': 'Danger', 'Open': 'Warning'} - - for state, style in states.items(): - if not frappe.db.exists("Workflow State", state): - frappe.get_doc({ - 'doctype': 'Workflow State', - 'workflow_state_name': state, - 'style': style - }).insert(ignore_permissions=True) - - for action in ['Approve', 'Reject']: - if not frappe.db.exists("Workflow Action", action): - frappe.get_doc({ - 'doctype': 'Workflow Action', - 'workflow_action_name': action - }).insert(ignore_permissions=True) - - if not frappe.db.exists("Workflow", "Leave Approval"): - frappe.get_doc({ - 'doctype': 'Workflow', - 'workflow_name': 'Leave Approval', - 'document_type': 'Leave Application', - 'is_active': 1, - 'workflow_state_field': 'workflow_state', - 'states': [{ - "state": 'Open', - "doc_status": 0, - "allow_edit": 'Employee' - }, { - "state": 'Approved', - "doc_status": 1, - "allow_edit": 'Leave Approver' - }, { - "state": 'Rejected', - "doc_status": 1, - "allow_edit": 'Leave Approver' - }], - 'transitions': [{ - "state": 'Open', - "action": 'Approve', - "next_state": 'Approved', - "allowed": 'Leave Approver' - }, - { - "state": 'Open', - "action": 'Reject', - "next_state": 'Rejected', - "allowed": 'Leave Approver' - }] - }).insert(ignore_permissions=True) - def check_setup_wizard_not_completed(): if frappe.db.get_default('desktop:home_page') == 'desktop': print()