From eb79100a30c1815a40402bb2d31b5ecc58d49832 Mon Sep 17 00:00:00 2001 From: iamkhanraheel Date: Mon, 25 May 2026 16:31:55 +0530 Subject: [PATCH 1/3] feat(job_requisition): add duplicate job requisition check with user confirmation before saving --- .../job_requisition/job_requisition.js | 26 +++++++++++++++++++ .../job_requisition/job_requisition.py | 24 +++++------------ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/hrms/hr/doctype/job_requisition/job_requisition.js b/hrms/hr/doctype/job_requisition/job_requisition.js index fd723ac915..39c11557dd 100644 --- a/hrms/hr/doctype/job_requisition/job_requisition.js +++ b/hrms/hr/doctype/job_requisition/job_requisition.js @@ -81,4 +81,30 @@ frappe.ui.form.on("Job Requisition", { frm.page.set_inner_btn_group_as_primary(__("Actions")); } }, + before_save: function (frm) { + frm.trigger("handle_duplicate_check"); + }, + handle_duplicate_check: function (frm) { + if (!frm.is_new() || frm.duplicate_confirmed) return; + frappe.validated = false; + + frm.call("check_duplicate_job_requisition").then((r) => { + if (!r.message) { + frm.duplicate_confirmed = true; + frm.save(); + return; + } + + frappe.confirm( + __( + "A Job Requisition already exists for {0} requested by {1} for the same department.
Do you want to continue?", + [frm.doc.designation.bold(), frm.doc.requested_by.bold()], + ), + () => { + frm.duplicate_confirmed = true; + frm.save(); + }, + ); + }); + }, }); diff --git a/hrms/hr/doctype/job_requisition/job_requisition.py b/hrms/hr/doctype/job_requisition/job_requisition.py index 1660afe290..4f9536da23 100644 --- a/hrms/hr/doctype/job_requisition/job_requisition.py +++ b/hrms/hr/doctype/job_requisition/job_requisition.py @@ -37,11 +37,15 @@ class JobRequisition(Document): # end: auto-generated types def validate(self): - self.validate_duplicates() self.set_time_to_fill() - def validate_duplicates(self): - duplicate = frappe.db.exists( + def set_time_to_fill(self): + if self.status == "Filled" and self.completed_on: + self.time_to_fill = time_diff_in_seconds(self.completed_on, self.posting_date) + + @frappe.whitelist() + def check_duplicate_job_requisition(self): + return frappe.db.exists( "Job Requisition", { "designation": self.designation, @@ -52,20 +56,6 @@ def validate_duplicates(self): }, ) - if duplicate: - frappe.throw( - _("A Job Requisition for {0} requested by {1} already exists: {2}").format( - frappe.bold(self.designation), - frappe.bold(self.requested_by), - get_link_to_form("Job Requisition", duplicate), - ), - title=_("Duplicate Job Requisition"), - ) - - def set_time_to_fill(self): - if self.status == "Filled" and self.completed_on: - self.time_to_fill = time_diff_in_seconds(self.completed_on, self.posting_date) - @frappe.whitelist() def associate_job_opening(self, job_opening: str) -> None: frappe.db.set_value( From dee44d5b3564248024e502f5a5907c0896c75cca Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Wed, 27 May 2026 10:34:57 +0530 Subject: [PATCH 2/3] feat(minor): description field for exemption categories and sub categories. --- .../employee_tax_exemption_category.json | 10 ++++++++-- .../employee_tax_exemption_category.py | 1 + .../employee_tax_exemption_sub_category.json | 10 ++++++++-- .../employee_tax_exemption_sub_category.py | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json b/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json index 3f4a181388..829db29aa2 100644 --- a/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json +++ b/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json @@ -9,7 +9,8 @@ "engine": "InnoDB", "field_order": [ "max_amount", - "is_active" + "is_active", + "description" ], "fields": [ { @@ -23,10 +24,15 @@ "fieldname": "is_active", "fieldtype": "Check", "label": "Is Active" + }, + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" } ], "links": [], - "modified": "2024-03-27 13:09:41.659098", + "modified": "2026-05-27 00:00:00.000000", "modified_by": "Administrator", "module": "Payroll", "name": "Employee Tax Exemption Category", diff --git a/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py b/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py index 135c1b7d99..29ab49e5b4 100644 --- a/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py +++ b/hrms/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py @@ -14,6 +14,7 @@ class EmployeeTaxExemptionCategory(Document): if TYPE_CHECKING: from frappe.types import DF + description: DF.SmallText | None is_active: DF.Check max_amount: DF.Currency # end: auto-generated types diff --git a/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json b/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json index 22218b5637..136d83322c 100644 --- a/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json +++ b/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json @@ -10,7 +10,8 @@ "field_order": [ "exemption_category", "max_amount", - "is_active" + "is_active", + "description" ], "fields": [ { @@ -35,10 +36,15 @@ "fieldname": "is_active", "fieldtype": "Check", "label": "Is Active" + }, + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" } ], "links": [], - "modified": "2024-03-27 13:09:42.420982", + "modified": "2026-05-27 00:00:00.000000", "modified_by": "Administrator", "module": "Payroll", "name": "Employee Tax Exemption Sub Category", diff --git a/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py b/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py index 72ca3d2fc8..79718ee3d1 100644 --- a/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py +++ b/hrms/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py @@ -17,6 +17,7 @@ class EmployeeTaxExemptionSubCategory(Document): if TYPE_CHECKING: from frappe.types import DF + description: DF.SmallText | None exemption_category: DF.Link is_active: DF.Check max_amount: DF.Currency From 4478963eafd979879d57444045db3c634e06f3a4 Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Wed, 27 May 2026 12:21:49 +0530 Subject: [PATCH 3/3] fix: currency format --- .../report/employee_ctc_break_up/employee_ctc_break_up.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hrms/payroll/report/employee_ctc_break_up/employee_ctc_break_up.py b/hrms/payroll/report/employee_ctc_break_up/employee_ctc_break_up.py index 103ac1e2fc..3f571343f8 100644 --- a/hrms/payroll/report/employee_ctc_break_up/employee_ctc_break_up.py +++ b/hrms/payroll/report/employee_ctc_break_up/employee_ctc_break_up.py @@ -4,7 +4,7 @@ import frappe from frappe import _ from frappe.utils import flt, get_link_to_form -from frappe.utils.formatters import format_value +from frappe.utils.formatters import fmt_money from frappe.utils.jinja import render_template from hrms.payroll.doctype.salary_structure.salary_structure import make_salary_slip @@ -201,7 +201,7 @@ def indent_salary_components(self): component["indent"] = 1 def format_currency(self, amount): - return format_value(amount, currency=self.currency) + return fmt_money(amount, precision=2, currency=self.currency) def get_columns(self) -> list[dict]: """Return columns for the report.