From 623239d3f717f0af04cd9f8fd1f74607778ad4e3 Mon Sep 17 00:00:00 2001 From: HarryPaulo Date: Mon, 11 Sep 2023 18:14:38 -0300 Subject: [PATCH 1/2] feat: created "based on" Item Group to specify a different percentage for each item group --- .../authorization_control.py | 25 ++++++++++++------- .../authorization_rule/authorization_rule.js | 10 ++++++++ .../authorization_rule.json | 8 +++--- .../authorization_rule/authorization_rule.py | 1 + 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py index 5e77c6fa816e..80d8c9f85a57 100644 --- a/erpnext/setup/doctype/authorization_control/authorization_control.py +++ b/erpnext/setup/doctype/authorization_control/authorization_control.py @@ -10,7 +10,7 @@ class AuthorizationControl(TransactionBase): - def get_appr_user_role(self, det, doctype_name, total, based_on, condition, item, company): + def get_appr_user_role(self, det, doctype_name, total, based_on, condition, master_name, company): amt_list, appr_users, appr_roles = [], [], [] users, roles = "", "" if det: @@ -47,11 +47,11 @@ def get_appr_user_role(self, det, doctype_name, total, based_on, condition, item frappe.msgprint(_("Not authroized since {0} exceeds limits").format(_(based_on))) frappe.throw(_("Can be approved by {0}").format(comma_or(appr_roles + appr_users))) - def validate_auth_rule(self, doctype_name, total, based_on, cond, company, item=""): + def validate_auth_rule(self, doctype_name, total, based_on, cond, company, master_name=""): chk = 1 add_cond1, add_cond2 = "", "" - if based_on == "Itemwise Discount": - add_cond1 += " and master_name = " + frappe.db.escape(cstr(item)) + if based_on in ["Itemwise Discount", "Item Group wise Discount"]: + add_cond1 += " and master_name = " + frappe.db.escape(cstr(master_name)) itemwise_exists = frappe.db.sql( """select value from `tabAuthorization Rule` where transaction = %s and value <= %s @@ -71,11 +71,11 @@ def validate_auth_rule(self, doctype_name, total, based_on, cond, company, item= if itemwise_exists: self.get_appr_user_role( - itemwise_exists, doctype_name, total, based_on, cond + add_cond1, item, company + itemwise_exists, doctype_name, total, based_on, cond + add_cond1, master_name, company ) chk = 0 if chk == 1: - if based_on == "Itemwise Discount": + if based_on in ["Itemwise Discount", "Item Group wise Discount"]: add_cond2 += " and ifnull(master_name,'') = ''" appr = frappe.db.sql( @@ -95,7 +95,7 @@ def validate_auth_rule(self, doctype_name, total, based_on, cond, company, item= (doctype_name, total, based_on), ) - self.get_appr_user_role(appr, doctype_name, total, based_on, cond + add_cond2, item, company) + self.get_appr_user_role(appr, doctype_name, total, based_on, cond + add_cond2, master_name, company) def bifurcate_based_on_type(self, doctype_name, total, av_dis, based_on, doc_obj, val, company): add_cond = "" @@ -123,6 +123,12 @@ def bifurcate_based_on_type(self, doctype_name, total, av_dis, based_on, doc_obj self.validate_auth_rule( doctype_name, t.discount_percentage, based_on, add_cond, company, t.item_code ) + elif based_on == "Item Group wise Discount": + if doc_obj: + for t in doc_obj.get("items"): + self.validate_auth_rule( + doctype_name, t.discount_percentage, based_on, add_cond, company, t.item_group + ) else: self.validate_auth_rule(doctype_name, auth_value, based_on, add_cond, company) @@ -148,6 +154,7 @@ def validate_approving_authority(self, doctype_name, company, total, doc_obj="") "Average Discount", "Customerwise Discount", "Itemwise Discount", + "Item Group wise Discount", ] # Check for authorization set for individual user @@ -166,7 +173,7 @@ def validate_approving_authority(self, doctype_name, company, total, doc_obj="") # Remove user specific rules from global authorization rules for r in based_on: - if r in final_based_on and r != "Itemwise Discount": + if r in final_based_on and not r in ["Itemwise Discount", "Item Group wise Discount"]: final_based_on.remove(r) # Check for authorization set on particular roles @@ -194,7 +201,7 @@ def validate_approving_authority(self, doctype_name, company, total, doc_obj="") # Remove role specific rules from global authorization rules for r in based_on: - if r in final_based_on and r != "Itemwise Discount": + if r in final_based_on and not r in ["Itemwise Discount", "Item Group wise Discount"]: final_based_on.remove(r) # Check for global authorization diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.js b/erpnext/setup/doctype/authorization_rule/authorization_rule.js index 3f6afcae7f51..f00ed3ecd0da 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.js +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.js @@ -12,6 +12,9 @@ frappe.ui.form.on("Authorization Rule", { } else if(frm.doc.based_on==="Itemwise Discount") { unhide_field("master_name"); frm.set_value("customer_or_item", "Item"); + } else if(frm.doc.based_on==="Item Group wise Discount") { + unhide_field("master_name"); + frm.set_value("customer_or_item", "Item Group"); } else { frm.set_value("customer_or_item", ""); frm.set_value("master_name", ""); @@ -81,6 +84,13 @@ cur_frm.fields_dict['master_name'].get_query = function(doc) { doctype: "Item", query: "erpnext.controllers.queries.item_query" } + else if (doc.based_on==="Item Group wise Discount") + return { + doctype: "Item Group", + filters: { + "is_group": 0 + } + } else return { filters: [ diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.json b/erpnext/setup/doctype/authorization_rule/authorization_rule.json index d3b8887c37b6..d750c7bb182f 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.json +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.json @@ -46,7 +46,7 @@ "label": "Based On", "oldfieldname": "based_on", "oldfieldtype": "Select", - "options": "\nGrand Total\nAverage Discount\nCustomerwise Discount\nItemwise Discount\nNot Applicable", + "options": "\nGrand Total\nAverage Discount\nCustomerwise Discount\nItemwise Discount\nItem Group wise Discount\nNot Applicable", "reqd": 1 }, { @@ -54,14 +54,14 @@ "fieldtype": "Select", "hidden": 1, "label": "Customer or Item", - "options": "Customer\nItem", + "options": "Customer\nItem\nItem Group", "read_only": 1 }, { "fieldname": "master_name", "fieldtype": "Dynamic Link", "in_list_view": 1, - "label": "Customer / Item Name", + "label": "Customer / Item / Item Group", "oldfieldname": "master_name", "oldfieldtype": "Link", "options": "customer_or_item" @@ -162,7 +162,7 @@ "icon": "fa fa-shield", "idx": 1, "links": [], - "modified": "2022-07-01 11:19:45.643991", + "modified": "2023-09-11 10:29:02.863193", "modified_by": "Administrator", "module": "Setup", "name": "Authorization Rule", diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.py b/erpnext/setup/doctype/authorization_rule/authorization_rule.py index 44bd826fc6e4..b7823a183ea2 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.py +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.py @@ -47,6 +47,7 @@ def validate_rule(self): "Average Discount", "Customerwise Discount", "Itemwise Discount", + "Item Group wise Discount", ]: frappe.throw( _("Cannot set authorization on basis of Discount for {0}").format(self.transaction) From da54ab5b3daa8d2de51277238044061b46c54111 Mon Sep 17 00:00:00 2001 From: HarryPaulo Date: Tue, 12 Sep 2023 09:43:11 -0300 Subject: [PATCH 2/2] fix: linters --- .../doctype/authorization_control/authorization_control.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py index 80d8c9f85a57..fd5a2012c7da 100644 --- a/erpnext/setup/doctype/authorization_control/authorization_control.py +++ b/erpnext/setup/doctype/authorization_control/authorization_control.py @@ -95,7 +95,9 @@ def validate_auth_rule(self, doctype_name, total, based_on, cond, company, maste (doctype_name, total, based_on), ) - self.get_appr_user_role(appr, doctype_name, total, based_on, cond + add_cond2, master_name, company) + self.get_appr_user_role( + appr, doctype_name, total, based_on, cond + add_cond2, master_name, company + ) def bifurcate_based_on_type(self, doctype_name, total, av_dis, based_on, doc_obj, val, company): add_cond = ""