From eea7bbcea7140e50817659f4af32d23a4dc9ae19 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 13:15:13 +0530 Subject: [PATCH 01/10] perf: index most queried fields in Leave Ledger Entry --- .../leave_ledger_entry/leave_ledger_entry.json | 12 ++++++++---- .../doctype/leave_ledger_entry/leave_ledger_entry.py | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json index d74760a5cf8..0ab517fd765 100644 --- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json +++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json @@ -27,7 +27,8 @@ "in_list_view": 1, "in_standard_filter": 1, "label": "Employee", - "options": "Employee" + "options": "Employee", + "search_index": 1 }, { "fetch_from": "employee.employee_name", @@ -57,13 +58,15 @@ "fieldtype": "Link", "in_standard_filter": 1, "label": "Transaction Type", - "options": "DocType" + "options": "DocType", + "search_index": 1 }, { "fieldname": "transaction_name", "fieldtype": "Dynamic Link", "label": "Transaction Name", - "options": "transaction_type" + "options": "transaction_type", + "search_index": 1 }, { "fieldname": "leaves", @@ -123,7 +126,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-01-04 18:47:45.146652", + "modified": "2023-11-17 12:36:36.963697", "modified_by": "Administrator", "module": "HR", "name": "Leave Ledger Entry", @@ -186,5 +189,6 @@ ], "sort_field": "modified", "sort_order": "ASC", + "states": [], "title_field": "employee" } \ No newline at end of file diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py index fed9f770dfc..396e88e8d3a 100644 --- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py +++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py @@ -225,3 +225,7 @@ def expire_carried_forward_allocation(allocation): to_date=allocation.to_date, ) create_leave_ledger_entry(allocation, args) + + +def on_doctype_update(): + frappe.db.add_index("Leave Ledger Entry", ["transaction_type", "transaction_name"]) From 4b8ed0f6aeec314bb87784f9b7ccbdd65456e637 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 13:46:46 +0530 Subject: [PATCH 02/10] fix: use `get_all` instead of `get_list` - query report already filters records based on permissions for link fields - allow employees access to leave balance report by default --- .../employee_leave_balance.json | 40 +++++++++++-------- .../employee_leave_balance.py | 8 ++-- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.json b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.json index 8b47f7e842d..577f6a7b70e 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.json +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.json @@ -1,26 +1,32 @@ { - "add_total_row": 0, - "apply_user_permissions": 1, - "creation": "2013-02-22 15:29:34", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2017-02-24 20:18:04.317397", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Leave Balance", - "owner": "Administrator", - "ref_doctype": "Employee", - "report_name": "Employee Leave Balance", - "report_type": "Script Report", + "add_total_row": 0, + "columns": [], + "creation": "2013-02-22 15:29:34", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 3, + "is_standard": "Yes", + "letterhead": null, + "modified": "2023-11-17 13:28:40.669200", + "modified_by": "Administrator", + "module": "HR", + "name": "Employee Leave Balance", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Employee", + "report_name": "Employee Leave Balance", + "report_type": "Script Report", "roles": [ { "role": "HR User" - }, + }, { "role": "HR Manager" + }, + { + "role": "Employee" } ] } \ No newline at end of file diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 192b255f3e0..fb1d8e2875d 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -85,19 +85,19 @@ def get_columns() -> List[Dict]: def get_data(filters: Filters) -> List: - leave_types = frappe.db.get_list("Leave Type", pluck="name", order_by="name") + leave_types = frappe.get_all("Leave Type", pluck="name", order_by="name") conditions = get_conditions(filters) user = frappe.session.user department_approver_map = get_department_leave_approver_map(filters.department) - active_employees = frappe.get_list( + active_employees = frappe.get_all( "Employee", filters=conditions, fields=["name", "employee_name", "department", "user_id", "leave_approver"], ) - precision = cint(frappe.db.get_single_value("System Settings", "float_precision", cache=True)) + precision = cint(frappe.db.get_single_value("System Settings", "float_precision")) consolidate_leave_types = len(active_employees) > 1 and filters.consolidate_leave_types row = None @@ -188,7 +188,7 @@ def get_conditions(filters: Filters) -> Dict: def get_department_leave_approver_map(department: Optional[str] = None): # get current department and all its child - department_list = frappe.get_list( + department_list = frappe.get_all( "Department", filters={"disabled": 0}, or_filters={"name": department, "parent_department": department}, From 1bd3f4eeefbb8f79a0b225008a4b45bd8197c09a Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 14:38:06 +0530 Subject: [PATCH 03/10] refactor: remove unnecessary approver queries --- .../employee_leave_balance.py | 78 ++++++------------- 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index fb1d8e2875d..0d251b49831 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -86,16 +86,7 @@ def get_columns() -> List[Dict]: def get_data(filters: Filters) -> List: leave_types = frappe.get_all("Leave Type", pluck="name", order_by="name") - conditions = get_conditions(filters) - - user = frappe.session.user - department_approver_map = get_department_leave_approver_map(filters.department) - - active_employees = frappe.get_all( - "Employee", - filters=conditions, - fields=["name", "employee_name", "department", "user_id", "leave_approver"], - ) + active_employees = get_employees(filters) precision = cint(frappe.db.get_single_value("System Settings", "float_precision")) consolidate_leave_types = len(active_employees) > 1 and filters.consolidate_leave_types @@ -110,10 +101,6 @@ def get_data(filters: Filters) -> List: row = frappe._dict({"leave_type": leave_type}) for employee in active_employees: - leave_approvers = department_approver_map.get(employee.department_name, []).append( - employee.leave_approver - ) - if consolidate_leave_types: row = frappe._dict() else: @@ -144,6 +131,27 @@ def get_data(filters: Filters) -> List: return data +def get_employees(filters: Filters) -> list[dict]: + Employee = frappe.qb.DocType("Employee") + query = frappe.qb.from_(Employee).select( + Employee.name, + Employee.employee_name, + Employee.department, + ) + + for field in ["company", "department"]: + if filters.get(field): + query = query.where((getattr(Employee, field) == filters.get(field))) + + if filters.get("employee"): + query = query.where(Employee.name == filters.get("employee")) + + if filters.get("employee_status"): + query = query.where(Employee.status == filters.get("employee_status")) + + return query.run(as_dict=True) + + def get_opening_balance( employee: str, leave_type: str, filters: Filters, carry_forwarded_leaves: float ) -> float: @@ -168,48 +176,6 @@ def get_opening_balance( return opening_balance -def get_conditions(filters: Filters) -> Dict: - conditions = {} - - if filters.employee: - conditions["name"] = filters.employee - - if filters.company: - conditions["company"] = filters.company - - if filters.department: - conditions["department"] = filters.department - - if filters.employee_status: - conditions["status"] = filters.employee_status - - return conditions - - -def get_department_leave_approver_map(department: Optional[str] = None): - # get current department and all its child - department_list = frappe.get_all( - "Department", - filters={"disabled": 0}, - or_filters={"name": department, "parent_department": department}, - pluck="name", - ) - # retrieve approvers list from current department and from its subsequent child departments - approver_list = frappe.get_all( - "Department Approver", - filters={"parentfield": "leave_approvers", "parent": ("in", department_list)}, - fields=["parent", "approver"], - as_list=True, - ) - - approvers = {} - - for k, v in approver_list: - approvers.setdefault(k, []).append(v) - - return approvers - - def get_allocated_and_expired_leaves( from_date: str, to_date: str, employee: str, leave_type: str ) -> Tuple[float, float, float]: From 635c3d54f5ea30c63d30ab95f27808fafa4067ed Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 15:22:49 +0530 Subject: [PATCH 04/10] perf: limit rows to 1 for cf leave expiry query --- erpnext/hr/doctype/leave_application/leave_application.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index d6f8c25b424..d4e3675ac48 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -717,6 +717,7 @@ def get_allocation_expiry_for_cf_leaves( "docstatus": 1, }, fields=["to_date"], + limit=1, ) return expiry[0]["to_date"] if expiry else "" @@ -1017,7 +1018,7 @@ def get_leaves_for_period( if leave_entry.leaves % 1: half_day = 1 half_day_date = frappe.db.get_value( - "Leave Application", {"name": leave_entry.transaction_name}, ["half_day_date"] + "Leave Application", {"name": leave_entry.transaction_name}, "half_day_date" ) leave_days += ( From 461eb7a50de2e3d5381cfc25a9e64a9556a6ace8 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 17:48:44 +0530 Subject: [PATCH 05/10] refactor: rewrite queries with frappe.qb + refactor type hints --- .../leave_allocation/leave_allocation.py | 30 ++++++++++------- .../leave_application/leave_application.py | 32 ++++++++++--------- .../employee_leave_balance.py | 28 +++++++++------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py index ffd6e42f1b0..a445cab7d9f 100755 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py @@ -296,18 +296,24 @@ class LeaveAllocation(Document): def get_previous_allocation(from_date, leave_type, employee): """Returns document properties of previous allocation""" - return frappe.db.get_value( - "Leave Allocation", - filters={ - "to_date": ("<", from_date), - "leave_type": leave_type, - "employee": employee, - "docstatus": 1, - }, - order_by="to_date DESC", - fieldname=["name", "from_date", "to_date", "employee", "leave_type"], - as_dict=1, - ) + Allocation = frappe.qb.DocType("Leave Allocation") + return ( + frappe.qb.from_(Allocation) + .select( + Allocation.name, + Allocation.from_date, + Allocation.to_date, + Allocation.employee, + Allocation.leave_type, + ) + .where( + (Allocation.employee == employee) + & (Allocation.leave_type == leave_type) + & (Allocation.to_date < from_date) + & (Allocation.docstatus == 1) + ) + .orderby(Allocation.to_date, order=frappe.qb.desc) + ).run(as_dict=True) def get_leave_allocation_for_period( diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index d4e3675ac48..daa5205133e 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -706,20 +706,22 @@ def get_allocation_expiry_for_cf_leaves( employee: str, leave_type: str, to_date: str, from_date: str ) -> str: """Returns expiry of carry forward allocation in leave ledger entry""" - expiry = frappe.get_all( - "Leave Ledger Entry", - filters={ - "employee": employee, - "leave_type": leave_type, - "is_carry_forward": 1, - "transaction_type": "Leave Allocation", - "to_date": ["between", (from_date, to_date)], - "docstatus": 1, - }, - fields=["to_date"], - limit=1, - ) - return expiry[0]["to_date"] if expiry else "" + Ledger = frappe.qb.DocType("Leave Ledger Entry") + expiry = ( + frappe.qb.from_(Ledger) + .select(Ledger.to_date) + .where( + (Ledger.employee == employee) + & (Ledger.leave_type == leave_type) + & (Ledger.is_carry_forward == 1) + & (Ledger.transaction_type == "Leave Allocation") + & (Ledger.to_date.between(from_date, to_date)) + & (Ledger.docstatus == 1) + ) + .limit(1) + ).run() + + return expiry[0][0] if expiry else "" @frappe.whitelist() @@ -1018,7 +1020,7 @@ def get_leaves_for_period( if leave_entry.leaves % 1: half_day = 1 half_day_date = frappe.db.get_value( - "Leave Application", {"name": leave_entry.transaction_name}, "half_day_date" + "Leave Application", leave_entry.transaction_name, "half_day_date" ) leave_days += ( diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 0d251b49831..32c4da554ff 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -3,7 +3,6 @@ from itertools import groupby -from typing import Dict, List, Optional, Tuple import frappe from frappe import _ @@ -18,7 +17,7 @@ from erpnext.hr.doctype.leave_application.leave_application import ( Filters = frappe._dict -def execute(filters: Optional[Filters] = None) -> Tuple: +def execute(filters: Filters | None = None) -> tuple: if filters.to_date <= filters.from_date: frappe.throw(_('"From Date" can not be greater than or equal to "To Date"')) @@ -28,7 +27,7 @@ def execute(filters: Optional[Filters] = None) -> Tuple: return columns, data, None, charts -def get_columns() -> List[Dict]: +def get_columns() -> list[dict]: return [ { "label": _("Leave Type"), @@ -84,8 +83,8 @@ def get_columns() -> List[Dict]: ] -def get_data(filters: Filters) -> List: - leave_types = frappe.get_all("Leave Type", pluck="name", order_by="name") +def get_data(filters: Filters) -> list: + leave_types = get_leave_types() active_employees = get_employees(filters) precision = cint(frappe.db.get_single_value("System Settings", "float_precision")) @@ -131,6 +130,13 @@ def get_data(filters: Filters) -> List: return data +def get_leave_types() -> list[str]: + LeaveType = frappe.qb.DocType("Leave Type") + return (frappe.qb.from_(LeaveType).select(LeaveType.name).orderby(LeaveType.name)).run( + pluck="name" + ) + + def get_employees(filters: Filters) -> list[dict]: Employee = frappe.qb.DocType("Employee") query = frappe.qb.from_(Employee).select( @@ -178,7 +184,7 @@ def get_opening_balance( def get_allocated_and_expired_leaves( from_date: str, to_date: str, employee: str, leave_type: str -) -> Tuple[float, float, float]: +) -> tuple[float, float, float]: new_allocation = 0 expired_leaves = 0 carry_forwarded_leaves = 0 @@ -208,9 +214,9 @@ def get_allocated_and_expired_leaves( def get_leave_ledger_entries( from_date: str, to_date: str, employee: str, leave_type: str -) -> List[Dict]: +) -> list[dict]: ledger = frappe.qb.DocType("Leave Ledger Entry") - records = ( + return ( frappe.qb.from_(ledger) .select( ledger.employee, @@ -236,10 +242,8 @@ def get_leave_ledger_entries( ) ).run(as_dict=True) - return records - -def get_chart_data(data: List, filters: Filters) -> Dict: +def get_chart_data(data: list, filters: Filters) -> dict: labels = [] datasets = [] employee_data = data @@ -259,7 +263,7 @@ def get_chart_data(data: List, filters: Filters) -> Dict: return chart -def get_dataset_for_chart(employee_data: List, datasets: List, labels: List) -> List: +def get_dataset_for_chart(employee_data: list, datasets: list, labels: list) -> list: leaves = [] employee_data = sorted(employee_data, key=lambda k: k["employee_name"]) From 9139c14639594b000dd003e9a54b0ffd9d24b68f Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 18:17:32 +0530 Subject: [PATCH 06/10] refactor(Leave Balance Summary report): remove unused department approver queries --- .../employee_leave_balance_summary.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py index 9750ad4e880..c3203493b9e 100644 --- a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py +++ b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py @@ -6,9 +6,6 @@ import frappe from frappe import _ from erpnext.hr.doctype.leave_application.leave_application import get_leave_details -from erpnext.hr.report.employee_leave_balance.employee_leave_balance import ( - get_department_leave_approver_map, -) def execute(filters=None): @@ -54,17 +51,11 @@ def get_data(filters, leave_types): active_employees = frappe.get_all( "Employee", filters=conditions, - fields=["name", "employee_name", "department", "user_id", "leave_approver"], + fields=["name", "employee_name", "department", "user_id"], ) - department_approver_map = get_department_leave_approver_map(filters.get("department")) - data = [] for employee in active_employees: - leave_approvers = department_approver_map.get(employee.department_name, []) - if employee.leave_approver: - leave_approvers.append(employee.leave_approver) - row = [employee.name, employee.employee_name, employee.department] available_leave = get_leave_details(employee.name, filters.date) for leave_type in leave_types: From 6cb8a403392b52e09d901f5b4d10b63e2b61d2f7 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 18:24:36 +0530 Subject: [PATCH 07/10] fix: `get_previous_allocation` return value --- erpnext/hr/doctype/leave_allocation/leave_allocation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py index a445cab7d9f..43ceda875e1 100755 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py @@ -297,7 +297,7 @@ class LeaveAllocation(Document): def get_previous_allocation(from_date, leave_type, employee): """Returns document properties of previous allocation""" Allocation = frappe.qb.DocType("Leave Allocation") - return ( + allocations = ( frappe.qb.from_(Allocation) .select( Allocation.name, @@ -313,8 +313,11 @@ def get_previous_allocation(from_date, leave_type, employee): & (Allocation.docstatus == 1) ) .orderby(Allocation.to_date, order=frappe.qb.desc) + .limit(1) ).run(as_dict=True) + return allocations[0] if allocations else None + def get_leave_allocation_for_period( employee, leave_type, from_date, to_date, exclude_allocation=None From bc1da4678af462b0fccf56e23effd49081731649 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 20:45:34 +0530 Subject: [PATCH 08/10] refactor: retain backward compatible type hints --- .../employee_leave_balance.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 32c4da554ff..7fadc7f643e 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -3,6 +3,7 @@ from itertools import groupby +from typing import Dict, List, Optional, Tuple import frappe from frappe import _ @@ -17,7 +18,7 @@ from erpnext.hr.doctype.leave_application.leave_application import ( Filters = frappe._dict -def execute(filters: Filters | None = None) -> tuple: +def execute(filters: Optional[Filters] = None) -> Tuple: if filters.to_date <= filters.from_date: frappe.throw(_('"From Date" can not be greater than or equal to "To Date"')) @@ -27,7 +28,7 @@ def execute(filters: Filters | None = None) -> tuple: return columns, data, None, charts -def get_columns() -> list[dict]: +def get_columns() -> List[Dict]: return [ { "label": _("Leave Type"), @@ -83,7 +84,7 @@ def get_columns() -> list[dict]: ] -def get_data(filters: Filters) -> list: +def get_data(filters: Filters) -> List: leave_types = get_leave_types() active_employees = get_employees(filters) @@ -130,14 +131,14 @@ def get_data(filters: Filters) -> list: return data -def get_leave_types() -> list[str]: +def get_leave_types() -> List[str]: LeaveType = frappe.qb.DocType("Leave Type") return (frappe.qb.from_(LeaveType).select(LeaveType.name).orderby(LeaveType.name)).run( pluck="name" ) -def get_employees(filters: Filters) -> list[dict]: +def get_employees(filters: Filters) -> List[Dict]: Employee = frappe.qb.DocType("Employee") query = frappe.qb.from_(Employee).select( Employee.name, @@ -184,7 +185,7 @@ def get_opening_balance( def get_allocated_and_expired_leaves( from_date: str, to_date: str, employee: str, leave_type: str -) -> tuple[float, float, float]: +) -> Tuple[float, float, float]: new_allocation = 0 expired_leaves = 0 carry_forwarded_leaves = 0 @@ -214,7 +215,7 @@ def get_allocated_and_expired_leaves( def get_leave_ledger_entries( from_date: str, to_date: str, employee: str, leave_type: str -) -> list[dict]: +) -> List[Dict]: ledger = frappe.qb.DocType("Leave Ledger Entry") return ( frappe.qb.from_(ledger) @@ -243,7 +244,7 @@ def get_leave_ledger_entries( ).run(as_dict=True) -def get_chart_data(data: list, filters: Filters) -> dict: +def get_chart_data(data: List, filters: Filters) -> Dict: labels = [] datasets = [] employee_data = data @@ -263,7 +264,7 @@ def get_chart_data(data: list, filters: Filters) -> dict: return chart -def get_dataset_for_chart(employee_data: list, datasets: list, labels: list) -> list: +def get_dataset_for_chart(employee_data: List, datasets: List, labels: List) -> List: leaves = [] employee_data = sorted(employee_data, key=lambda k: k["employee_name"]) From 958db77cda2e32486298baaac934510fa1fddd14 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 21:11:42 +0530 Subject: [PATCH 09/10] fix: backward compatible query without pluck --- .../report/employee_leave_balance/employee_leave_balance.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 7fadc7f643e..c45cb5849ed 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -133,9 +133,10 @@ def get_data(filters: Filters) -> List: def get_leave_types() -> List[str]: LeaveType = frappe.qb.DocType("Leave Type") - return (frappe.qb.from_(LeaveType).select(LeaveType.name).orderby(LeaveType.name)).run( - pluck="name" + leave_types = (frappe.qb.from_(LeaveType).select(LeaveType.name).orderby(LeaveType.name)).run( + as_dict=True ) + return [leave_type.name for leave_type in leave_types] def get_employees(filters: Filters) -> List[Dict]: From 89c107ea8b5a7b73f953a5bebd765528521a4c0b Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 17 Nov 2023 22:56:42 +0530 Subject: [PATCH 10/10] chore: remove states from json --- erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json index 0ab517fd765..b02e2f18817 100644 --- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json +++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json @@ -189,6 +189,5 @@ ], "sort_field": "modified", "sort_order": "ASC", - "states": [], "title_field": "employee" } \ No newline at end of file