Merge pull request #39525 from rohitwaghchaure/fixed-auto-mr-email-with-user-permissions-issue
fix: email list for auto reorder material request
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index 3e44049..48397a3 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -774,6 +774,62 @@
self.assertEqual(mr.per_ordered, 100)
self.assertEqual(existing_requested_qty, current_requested_qty)
+ def test_auto_email_users_with_company_user_permissions(self):
+ from erpnext.stock.reorder_item import get_email_list
+
+ comapnywise_users = {
+ "_Test Company": "test_auto_email_@example.com",
+ "_Test Company 1": "test_auto_email_1@example.com",
+ }
+
+ permissions = []
+
+ for company, user in comapnywise_users.items():
+ if not frappe.db.exists("User", user):
+ frappe.get_doc(
+ {
+ "doctype": "User",
+ "email": user,
+ "first_name": user,
+ "send_notifications": 0,
+ "enabled": 1,
+ "user_type": "System User",
+ "roles": [{"role": "Purchase Manager"}],
+ }
+ ).insert(ignore_permissions=True)
+
+ if not frappe.db.exists(
+ "User Permission", {"user": user, "allow": "Company", "for_value": company}
+ ):
+ perm_doc = frappe.get_doc(
+ {
+ "doctype": "User Permission",
+ "user": user,
+ "allow": "Company",
+ "for_value": company,
+ "apply_to_all_doctypes": 1,
+ }
+ ).insert(ignore_permissions=True)
+
+ permissions.append(perm_doc)
+
+ comapnywise_mr_list = frappe._dict({})
+ mr1 = make_material_request()
+ comapnywise_mr_list.setdefault(mr1.company, []).append(mr1.name)
+
+ mr2 = make_material_request(
+ company="_Test Company 1", warehouse="Stores - _TC1", cost_center="Main - _TC1"
+ )
+ comapnywise_mr_list.setdefault(mr2.company, []).append(mr2.name)
+
+ for company, mr_list in comapnywise_mr_list.items():
+ emails = get_email_list(company)
+
+ self.assertTrue(comapnywise_users[company] in emails)
+
+ for perm in permissions:
+ perm.delete()
+
def get_in_transit_warehouse(company):
if not frappe.db.exists("Warehouse Type", "Transit"):
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 1f5f41a..276531a 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -145,6 +145,7 @@
mr.log_error("Unable to create material request")
+ company_wise_mr = frappe._dict({})
for request_type in material_requests:
for company in material_requests[request_type]:
try:
@@ -206,17 +207,19 @@
mr.submit()
mr_list.append(mr)
+ company_wise_mr.setdefault(company, []).append(mr)
+
except Exception:
_log_exception(mr)
- if mr_list:
+ if company_wise_mr:
if getattr(frappe.local, "reorder_email_notify", None) is None:
frappe.local.reorder_email_notify = cint(
frappe.db.get_single_value("Stock Settings", "reorder_email_notify")
)
if frappe.local.reorder_email_notify:
- send_email_notification(mr_list)
+ send_email_notification(company_wise_mr)
if exceptions_list:
notify_errors(exceptions_list)
@@ -224,20 +227,56 @@
return mr_list
-def send_email_notification(mr_list):
+def send_email_notification(company_wise_mr):
"""Notify user about auto creation of indent"""
- email_list = frappe.db.sql_list(
- """select distinct r.parent
- from `tabHas Role` r, tabUser p
- where p.name = r.parent and p.enabled = 1 and p.docstatus < 2
- and r.role in ('Purchase Manager','Stock Manager')
- and p.name not in ('Administrator', 'All', 'Guest')"""
+ for company, mr_list in company_wise_mr.items():
+ email_list = get_email_list(company)
+
+ if not email_list:
+ continue
+
+ msg = frappe.render_template("templates/emails/reorder_item.html", {"mr_list": mr_list})
+
+ frappe.sendmail(
+ recipients=email_list, subject=_("Auto Material Requests Generated"), message=msg
+ )
+
+
+def get_email_list(company):
+ users = get_comapny_wise_users(company)
+ user_table = frappe.qb.DocType("User")
+ role_table = frappe.qb.DocType("Has Role")
+
+ query = (
+ frappe.qb.from_(user_table)
+ .inner_join(role_table)
+ .on(user_table.name == role_table.parent)
+ .select(user_table.email)
+ .where(
+ (role_table.role.isin(["Purchase Manager", "Stock Manager"]))
+ & (user_table.name.notin(["Administrator", "All", "Guest"]))
+ & (user_table.enabled == 1)
+ & (user_table.docstatus < 2)
+ )
)
- msg = frappe.render_template("templates/emails/reorder_item.html", {"mr_list": mr_list})
+ if users:
+ query = query.where(user_table.name.isin(users))
- frappe.sendmail(recipients=email_list, subject=_("Auto Material Requests Generated"), message=msg)
+ emails = query.run(as_dict=True)
+
+ return list(set([email.email for email in emails]))
+
+
+def get_comapny_wise_users(company):
+ users = frappe.get_all(
+ "User Permission",
+ filters={"allow": "Company", "for_value": company, "apply_to_all_doctypes": 1},
+ fields=["user"],
+ )
+
+ return [user.user for user in users]
def notify_errors(exceptions_list):