Merge pull request #4088 from anandpdoshi/address-contact-permissions
Apply permissions on address and contact based on permissions of Customer, Supplier
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 7d40d85..a747510 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -93,6 +93,16 @@
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission"
}
+permission_query_conditions = {
+ "Contact": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_contact",
+ "Address": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_address"
+}
+
+has_permission = {
+ "Contact": "erpnext.utilities.address_and_contact.has_permission",
+ "Address": "erpnext.utilities.address_and_contact.has_permission"
+}
+
dump_report_map = "erpnext.startup.report_data_map.data_map"
before_tests = "erpnext.setup.utils.before_tests"
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 640a79e..1191c47 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -37,40 +37,3 @@
"Sales Partner": "Selling",
"Brand": "Selling"
});
-
-frappe.desk_home_buttons.push({label:"<i class='icon-facetime-video'></i> "+ __("Learn"),
- route:"Module/Learn"})
-
-frappe.desk_home_flows.push({
- title: __("Selling"),
- sequence: [
- {title: __("Opportunity"), route:"List/Opportunity"},
- {title: __("Quotation"), route:"List/Quotation"},
- {title: __("Sales Order"), route:"List/Sales Order"},
- {title: __("Delivery Note"), route:"List/Delivery Note"},
- {title: __("Sales Invoice"), route:"List/Sales Invoice"},
- {title: __("Payment"), route:"List/Journal Entry"},
- ]
- });
-
-frappe.desk_home_flows.push({
- title: __("Buying"),
- sequence: [
- {title: __("Material Request"), route:"List/Material Request"},
- {title: __("Supplier Quotation"), route:"List/Supplier Quotation"},
- {title: __("Purchase Order"), route:"List/Purchase Order"},
- {title: __("Purchase Receipt"), route:"List/Purchase Receipt"},
- {title: __("Purchase Invoice"), route:"List/Purchase Invoice"},
- {title: __("Payment"), route:"List/Journal Entry"},
- ]
- });
-
-frappe.desk_home_flows.push({
- title: __("Manufacturing"),
- sequence: [
- {title: __("BOM"), route:"List/BOM"},
- {title: __("Production Planning Tool"), route:"Form/Production Planning Tool"},
- {title: __("Production Order"), route:"List/Production Order"},
- {title: __("Stock Entry"), route:"List/Stock Entry"},
- ]
- });
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
index d386d67..9341adf 100644
--- a/erpnext/utilities/address_and_contact.py
+++ b/erpnext/utilities/address_and_contact.py
@@ -17,3 +17,68 @@
doc.get("__onload").contact_list = frappe.get_all("Contact",
fields="*", filters={key: doc.name},
order_by="is_primary_contact desc, modified desc")
+
+def has_permission(doc, ptype, user):
+ links = get_permitted_and_not_permitted_links(doc.doctype)
+ if not links.get("not_permitted_links"):
+ # optimization: don't determine permissions based on link fields
+ return True
+
+ # True if any one is True or all are empty
+ names = []
+ for df in (links.get("permitted_links") + links.get("not_permitted_links")):
+ doctype = df.options
+ name = doc.get(df.fieldname)
+
+ names.append(name)
+
+ if name and frappe.has_permission(doctype, ptype, doc=name):
+ return True
+
+ if not any(names):
+ return True
+
+ else:
+ return False
+
+def get_permission_query_conditions_for_contact(user):
+ return get_permission_query_conditions("Contact")
+
+def get_permission_query_conditions_for_address(user):
+ return get_permission_query_conditions("Address")
+
+def get_permission_query_conditions(doctype):
+ links = get_permitted_and_not_permitted_links(doctype)
+
+ if not links.get("not_permitted_links"):
+ # when everything is permitted, don't add additional condition
+ return ""
+
+ else:
+ conditions = []
+
+ for df in links.get("permitted_links"):
+ # like ifnull(customer, '')!='' or ifnull(supplier, '')!=''
+ conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
+
+ return "( " + " or ".join(conditions) + " )"
+
+def get_permitted_and_not_permitted_links(doctype):
+ permitted_links = []
+ not_permitted_links = []
+
+ meta = frappe.get_meta(doctype)
+
+ for df in meta.get_link_fields():
+ if df.options not in ("Customer", "Supplier", "Sales Partner"):
+ continue
+
+ if frappe.has_permission(df.options):
+ permitted_links.append(df)
+ else:
+ not_permitted_links.append(df)
+
+ return {
+ "permitted_links": permitted_links,
+ "not_permitted_links": not_permitted_links
+ }