diff --git a/hrms/hr/doctype/leave_allocation/leave_allocation.py b/hrms/hr/doctype/leave_allocation/leave_allocation.py index 85298cbfe6..9b0719d92b 100755 --- a/hrms/hr/doctype/leave_allocation/leave_allocation.py +++ b/hrms/hr/doctype/leave_allocation/leave_allocation.py @@ -283,6 +283,7 @@ def set_total_leaves_allocated(self): 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") + and not frappe.db.get_value("Leave Type", self.leave_type, "allow_negative") ): frappe.throw(_("Total leaves allocated is mandatory for Leave Type {0}").format(self.leave_type)) diff --git a/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py index 91689c96be..2b58c4c388 100644 --- a/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py @@ -147,7 +147,11 @@ def create_leave_allocation(self, annual_allocation, leave_details, date_of_join else [] ) - if new_leaves_allocated == 0 and not leave_details.is_earned_leave: + if ( + new_leaves_allocated == 0 + and not leave_details.is_earned_leave + and not leave_details.allow_negative + ): text = _( "Leave allocation is skipped for {0}, because number of leaves to be allocated is 0." ).format(frappe.bold(leave_details.name)) @@ -507,6 +511,7 @@ def get_leave_type_details(): "is_lwp", "is_earned_leave", "is_compensatory", + "allow_negative", "allocate_on_day", "is_carry_forward", "expire_carry_forwarded_leaves_after_days", diff --git a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py index 703b91cad7..9cf6bc17dd 100644 --- a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py @@ -258,6 +258,8 @@ def test_skip_zero_allocation_leaves(self): sick = create_leave_type( leave_type_name="_Test Sick Leave", non_encashable_leaves=0, max_leaves_allowed=2 ) + sick.allow_negative = 1 + sick.save() casual = create_leave_type( leave_type_name="_Test Casual Leave", non_encashable_leaves=0, max_leaves_allowed=12 ) @@ -304,17 +306,18 @@ def test_skip_zero_allocation_leaves(self): fields=["content"], ) - self.assertEqual(len(comments), 2) + self.assertEqual(len(comments), 1) self.assertIn(casual.name, comments[0]["content"]) - self.assertIn(sick.name, comments[1]["content"]) allocations = frappe.get_all( "Leave Allocation", filters={"leave_policy_assignment": assignment.name}, - fields=["leave_type", "new_leaves_allocated"], + fields=["leave_type", "new_leaves_allocated", "total_leaves_allocated"], ) + allocations = {allocation["leave_type"]: allocation for allocation in allocations} - self.assertEqual(allocations[0]["leave_type"], compoff.name) - self.assertEqual(allocations[0]["new_leaves_allocated"], 3) - self.assertEqual(allocations[1]["leave_type"], annual.name) - self.assertEqual(allocations[1]["new_leaves_allocated"], 3) + self.assertEqual(allocations[sick.name]["new_leaves_allocated"], 0) + self.assertEqual(allocations[sick.name]["total_leaves_allocated"], 0) + self.assertEqual(allocations[compoff.name]["new_leaves_allocated"], 3) + self.assertEqual(allocations[annual.name]["new_leaves_allocated"], 3) + self.assertNotIn(casual.name, allocations) diff --git a/hrms/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py b/hrms/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py index 6858e270da..9321f6a051 100644 --- a/hrms/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py +++ b/hrms/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py @@ -4,6 +4,8 @@ import frappe from frappe import _ +from frappe.query_builder import DocType +from frappe.query_builder.functions import Extract import erpnext @@ -65,28 +67,26 @@ def get_columns(filters): def get_conditions(filters): - conditions = [""] + SalarySlip = DocType("Salary Slip") + filter_clauses = [] if filters.get("department"): - conditions.append("department = '%s' " % (filters["department"])) - + filter_clauses.append(SalarySlip.department == filters["department"]) if filters.get("branch"): - conditions.append("branch = '%s' " % (filters["branch"])) - + filter_clauses.append(SalarySlip.branch == filters["branch"]) if filters.get("company"): - conditions.append("company = '%s' " % (filters["company"])) - + filter_clauses.append(SalarySlip.company == filters["company"]) if filters.get("month"): - conditions.append("month(start_date) = '%s' " % (filters["month"])) - + filter_clauses.append(Extract("month", SalarySlip.start_date) == int(filters["month"])) if filters.get("year"): - conditions.append("year(start_date) = '%s' " % (filters["year"])) + filter_clauses.append(Extract("year", SalarySlip.start_date) == int(filters["year"])) - return " and ".join(conditions) + return filter_clauses def get_data(filters): - data = [] + SalarySlip = DocType("Salary Slip") + filter_clauses = get_conditions(filters) fields = ["employee", "branch", "bank_name", "bank_ac_no", "salary_mode"] if erpnext.get_region() == "India": @@ -108,16 +108,19 @@ def get_data(filters): }, ) - conditions = get_conditions(filters) + base_where = SalarySlip.docstatus == 1 + for clause in filter_clauses: + base_where = base_where & clause - entry = frappe.db.sql( - """ select employee, employee_name, gross_pay, net_pay - from `tabSalary Slip` - where docstatus = 1 %s """ - % (conditions), - as_dict=1, + entry = ( + frappe.qb.from_(SalarySlip) + .select(SalarySlip.employee, SalarySlip.employee_name, SalarySlip.gross_pay, SalarySlip.net_pay) + .where(base_where) + .run(as_dict=True) ) + data = [] + for d in entry: employee = { "branch": employee_data_dict.get(d.employee).get("branch"), diff --git a/hrms/public/js/erpnext/employee.js b/hrms/public/js/erpnext/employee.js index 99550db019..65d795935a 100644 --- a/hrms/public/js/erpnext/employee.js +++ b/hrms/public/js/erpnext/employee.js @@ -27,6 +27,11 @@ frappe.ui.form.on("Employee", { }); } frm.set_df_property("holiday_list", "hidden", 1); + + // hide naming series field based on hr settings + frappe.db.get_single_value("HR Settings", "emp_created_by").then((value) => { + frm.toggle_display("naming_series", value === "Naming Series"); + }); }, date_of_birth(frm) {