diff --git a/hrms/hr/doctype/leave_application/leave_application.py b/hrms/hr/doctype/leave_application/leave_application.py index 77f94da99a..30c53dc67a 100755 --- a/hrms/hr/doctype/leave_application/leave_application.py +++ b/hrms/hr/doctype/leave_application/leave_application.py @@ -1164,7 +1164,12 @@ def is_lwp(leave_type): @frappe.whitelist() def get_events(start, end, filters=None): - from frappe.desk.reportview import get_filters_cond + import json + + filters = json.loads(filters) + for idx, filter in enumerate(filters): + # taking relevant fields from the list [doctype, fieldname, condition, value, hidden] + filters[idx] = filter[1:-1] events = [] @@ -1178,12 +1183,11 @@ def get_events(start, end, filters=None): employee = "" company = frappe.db.get_value("Global Defaults", None, "default_company") - conditions = get_filters_cond("Leave Application", filters, []) # show department leaves for employee if "Employee" in frappe.get_roles(): add_department_leaves(events, start, end, employee, company) - add_leaves(events, start, end, conditions) + add_leaves(events, start, end, filters) add_block_dates(events, start, end, employee, company) add_holidays(events, start, end, employee, company) @@ -1191,78 +1195,55 @@ def get_events(start, end, filters=None): def add_department_leaves(events, start, end, employee, company): - department = frappe.db.get_value("Employee", employee, "department") - - if not department: - return - - # department leaves - department_employees = frappe.db.sql_list( - """select name from tabEmployee where department=%s - and company=%s""", - (department, company), + if department := frappe.db.get_value("Employee", employee, "department"): + department_employees = frappe.get_list( + "Employee", filters={"department": department, "company": company}, pluck="name" + ) + filters = [["employee", "in", department_employees]] + add_leaves(events, start, end, filters=filters) + + +def add_leaves(events, start, end, filters=None): + if not filters: + filters = [] + filters.extend( + [ + ["from_date", "<=", getdate(end)], + ["to_date", ">=", getdate(start)], + ["status", "in", ["Approved", "Open"]], + ["docstatus", "<", 2], + ] ) - filter_conditions = ' and employee in ("%s")' % '", "'.join(department_employees) - add_leaves(events, start, end, filter_conditions=filter_conditions) - - -def add_leaves(events, start, end, filter_conditions=None): - from frappe.desk.reportview import build_match_conditions - - conditions = [] - - if not cint( - frappe.db.get_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar") - ): - match_conditions = build_match_conditions("Leave Application") - - if match_conditions: - conditions.append(match_conditions) - - query = """SELECT - docstatus, - name, - employee, - employee_name, - leave_type, - from_date, - to_date, - half_day, - status, - color - FROM `tabLeave Application` - WHERE - from_date <= %(end)s AND to_date >= %(start)s <= to_date - AND docstatus < 2 - AND status in ('Approved', 'Open') - """ + fields = [ + "name", + "from_date", + "to_date", + "color", + "docstatus", + "employee_name", + "leave_type", + "(1) as allDay", + "'Leave Application' as doctype", + ] + + show_leaves_of_all_members = frappe.db.get_single_value( + "HR Settings", "show_leaves_of_all_department_members_in_calendar" + ) + if cint(show_leaves_of_all_members): + leave_applications = frappe.get_all("Leave Application", filters=filters, fields=fields) + else: + leave_applications = frappe.get_list("Leave Application", filters=filters, fields=fields) - if conditions: - query += " AND " + " AND ".join(conditions) - - if filter_conditions: - query += filter_conditions - - for d in frappe.db.sql(query, {"start": start, "end": end}, as_dict=True): - e = { - "name": d.name, - "doctype": "Leave Application", - "from_date": d.from_date, - "to_date": d.to_date, - "docstatus": d.docstatus, - "color": d.color, - "all_day": int(not d.half_day), - "title": cstr(d.employee_name) - + f" ({cstr(d.leave_type)})" - + (" " + _("(Half Day)") if d.half_day else ""), - } - if e not in events: - events.append(e) + for d in leave_applications: + d["title"] = f"{d['employee_name']} ({d['leave_type']})" + del d["employee_name"] + del d["leave_type"] + if d not in events: + events.append(d) def add_block_dates(events, start, end, employee, company): - # block days cnt = 0 block_dates = get_applicable_block_dates(start, end, employee, company, all_lists=True) @@ -1274,6 +1255,7 @@ def add_block_dates(events, start, end, employee, company): "to_date": block_date.block_date, "title": _("Leave Blocked") + ": " + block_date.reason, "name": "_" + str(cnt), + "allDay": 1, } ) cnt += 1 @@ -1297,6 +1279,7 @@ def add_holidays(events, start, end, employee, company): "to_date": holiday.holiday_date, "title": _("Holiday") + ": " + cstr(holiday.description), "name": holiday.name, + "allDay": 1, } ) diff --git a/hrms/hr/doctype/leave_block_list/leave_block_list.py b/hrms/hr/doctype/leave_block_list/leave_block_list.py index ce7bb453a7..14c94d8500 100644 --- a/hrms/hr/doctype/leave_block_list/leave_block_list.py +++ b/hrms/hr/doctype/leave_block_list/leave_block_list.py @@ -42,7 +42,6 @@ def get_block_dates_from_date(self, start_date, end_date, days): return date_list -@frappe.whitelist() def get_applicable_block_dates( from_date, to_date, employee=None, company=None, all_lists=False, leave_type=None ): @@ -50,7 +49,7 @@ def get_applicable_block_dates( "Leave Block List Date", filters={ "parent": ["IN", get_applicable_block_lists(employee, company, all_lists, leave_type)], - "block_date": ["BETWEEN", [from_date, to_date]], + "block_date": ["BETWEEN", [getdate(from_date), getdate(to_date)]], }, fields=["block_date", "reason"], ) @@ -59,33 +58,34 @@ def get_applicable_block_dates( def get_applicable_block_lists(employee=None, company=None, all_lists=False, leave_type=None): block_lists = [] + def add_block_list(block_list): + for d in block_list: + if all_lists or not is_user_in_allow_list(d): + block_lists.append(d) + if not employee: employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}) - if not employee: - return [] - if not company: + if not company and employee: company = frappe.db.get_value("Employee", employee, "company") - def add_block_list(block_list): - for d in block_list: - if all_lists or not is_user_in_allow_list(d): - block_lists.append(d) + if company: + # global + conditions = {"applies_to_all_departments": 1, "company": company} + if leave_type: + conditions["leave_type"] = ["IN", (leave_type, "", None)] - # per department - department = frappe.db.get_value("Employee", employee, "department") - if department: - block_list = frappe.db.get_value("Department", department, "leave_block_list") - block_list_leave_type = frappe.db.get_value("Leave Block List", block_list, "leave_type") - if not block_list_leave_type or not leave_type or block_list_leave_type == leave_type: - add_block_list([block_list]) + add_block_list(frappe.db.get_all("Leave Block List", filters=conditions, pluck="name")) - # global - conditions = {"applies_to_all_departments": 1, "company": company} - if leave_type: - conditions["leave_type"] = ["IN", (leave_type, "", None)] + if employee: + # per department + department = frappe.db.get_value("Employee", employee, "department") + if department: + block_list = frappe.db.get_value("Department", department, "leave_block_list") + block_list_leave_type = frappe.db.get_value("Leave Block List", block_list, "leave_type") + if not block_list_leave_type or not leave_type or block_list_leave_type == leave_type: + add_block_list([block_list]) - add_block_list(frappe.db.get_all("Leave Block List", filters=conditions, pluck="name")) return list(set(block_lists)) diff --git a/hrms/payroll/doctype/gratuity/gratuity.js b/hrms/payroll/doctype/gratuity/gratuity.js index 4f311589a3..21d01a24de 100644 --- a/hrms/payroll/doctype/gratuity/gratuity.js +++ b/hrms/payroll/doctype/gratuity/gratuity.js @@ -48,22 +48,18 @@ frappe.ui.form.on('Gratuity', { }); } }, + employee: function (frm) { frm.events.calculate_work_experience_and_amount(frm); }, + gratuity_rule: function (frm) { frm.events.calculate_work_experience_and_amount(frm); }, - calculate_work_experience_and_amount: function (frm) { + calculate_work_experience_and_amount: function (frm) { if (frm.doc.employee && frm.doc.gratuity_rule) { - frappe.call({ - method: "hrms.payroll.doctype.gratuity.gratuity.calculate_work_experience_and_amount", - args: { - employee: frm.doc.employee, - gratuity_rule: frm.doc.gratuity_rule - } - }).then((r) => { + frm.call("calculate_work_experience_and_amount").then((r) => { frm.set_value("current_work_experience", r.message['current_work_experience']); frm.set_value("amount", r.message['amount']); }); diff --git a/hrms/payroll/doctype/gratuity/gratuity.json b/hrms/payroll/doctype/gratuity/gratuity.json index e4a8d5b8ec..6c1927d029 100644 --- a/hrms/payroll/doctype/gratuity/gratuity.json +++ b/hrms/payroll/doctype/gratuity/gratuity.json @@ -60,8 +60,7 @@ "default": "0", "fieldname": "current_work_experience", "fieldtype": "Int", - "label": "Current Work Experience", - "read_only": 1 + "label": "Current Work Experience" }, { "default": "0", @@ -200,7 +199,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-11-09 15:47:13.353555", + "modified": "2024-03-15 02:50:10.282517", "modified_by": "Administrator", "module": "Payroll", "name": "Gratuity", diff --git a/hrms/payroll/doctype/gratuity/gratuity.py b/hrms/payroll/doctype/gratuity/gratuity.py index 06e218b513..63085ef010 100644 --- a/hrms/payroll/doctype/gratuity/gratuity.py +++ b/hrms/payroll/doctype/gratuity/gratuity.py @@ -15,11 +15,26 @@ class Gratuity(AccountsController): def validate(self): - data = calculate_work_experience_and_amount(self.employee, self.gratuity_rule) + data = self.calculate_work_experience_and_amount() self.current_work_experience = data["current_work_experience"] self.amount = data["amount"] self.set_status() + @frappe.whitelist() + def calculate_work_experience_and_amount(self): + rule = get_gratuity_rule_config(self.gratuity_rule) + + if rule.method == "Manual": + current_work_experience = flt(self.current_work_experience) + else: + current_work_experience = calculate_work_experience(self.employee, self.gratuity_rule) or 0 + + gratuity_amount = ( + calculate_gratuity_amount(self.employee, self.gratuity_rule, current_work_experience) or 0 + ) + + return {"current_work_experience": current_work_experience, "amount": gratuity_amount} + def set_status(self, update=False): precision = self.precision("paid_amount") status = None @@ -130,19 +145,21 @@ def set_total_advance_paid(self): self.set_status(update=True) -@frappe.whitelist() -def calculate_work_experience_and_amount(employee, gratuity_rule): - current_work_experience = calculate_work_experience(employee, gratuity_rule) or 0 - gratuity_amount = calculate_gratuity_amount(employee, gratuity_rule, current_work_experience) or 0 - - return {"current_work_experience": current_work_experience, "amount": gratuity_amount} +def get_gratuity_rule_config(gratuity_rule: str) -> dict: + return frappe.db.get_value( + "Gratuity Rule", + gratuity_rule, + [ + "work_experience_calculation_function as method", + "total_working_days_per_year", + "minimum_year_for_gratuity", + ], + as_dict=True, + ) def calculate_work_experience(employee, gratuity_rule): - - total_working_days_per_year, minimum_year_for_gratuity = frappe.db.get_value( - "Gratuity Rule", gratuity_rule, ["total_working_days_per_year", "minimum_year_for_gratuity"] - ) + rule = get_gratuity_rule_config(gratuity_rule) date_of_joining, relieving_date = frappe.db.get_value( "Employee", employee, ["date_of_joining", "relieving_date"] @@ -154,16 +171,13 @@ def calculate_work_experience(employee, gratuity_rule): ) ) - method = frappe.db.get_value( - "Gratuity Rule", gratuity_rule, "work_experience_calculation_function" - ) employee_total_workings_days = calculate_employee_total_workings_days( employee, date_of_joining, relieving_date ) - current_work_experience = employee_total_workings_days / total_working_days_per_year or 1 + current_work_experience = employee_total_workings_days / rule.total_working_days_per_year or 1 current_work_experience = get_work_experience_using_method( - method, current_work_experience, minimum_year_for_gratuity, employee + rule.method, current_work_experience, rule.minimum_year_for_gratuity, employee ) return current_work_experience diff --git a/hrms/payroll/doctype/gratuity_rule/gratuity_rule.json b/hrms/payroll/doctype/gratuity_rule/gratuity_rule.json index ed66dc9a1a..0df1cf38e1 100644 --- a/hrms/payroll/doctype/gratuity_rule/gratuity_rule.json +++ b/hrms/payroll/doctype/gratuity_rule/gratuity_rule.json @@ -63,8 +63,8 @@ "default": "Round off Work Experience", "fieldname": "work_experience_calculation_function", "fieldtype": "Select", - "label": "Work Experience Calculation method", - "options": "Round off Work Experience\nTake Exact Completed Years" + "label": "Work Experience Calculation Method", + "options": "Round off Work Experience\nTake Exact Completed Years\nManual" }, { "default": "365", @@ -93,7 +93,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-01-05 12:36:32.412409", + "modified": "2024-03-15 01:48:52.295003", "modified_by": "Administrator", "module": "Payroll", "name": "Gratuity Rule",