mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-11 21:51:48 +00:00
Merge pull request #57258 from mihir-kandoi/per-master-company-restriction
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Supplier", {
|
||||
restrict_to_companies(frm) {
|
||||
if (!frm.doc.restrict_to_companies) {
|
||||
frm.set_value("allowed_companies", []);
|
||||
}
|
||||
},
|
||||
|
||||
setup: function (frm) {
|
||||
frm.set_query("allowed_companies", () => ({
|
||||
query: "erpnext.stock.doctype.company_restriction.company_restriction.company_query",
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
"tax_withholding_group",
|
||||
"settings_tab",
|
||||
"company_restrictions_section",
|
||||
"restrict_to_companies",
|
||||
"allowed_companies",
|
||||
"invoice_settings_section",
|
||||
"is_transporter",
|
||||
@@ -430,16 +431,22 @@
|
||||
{
|
||||
"fieldname": "company_restrictions_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Company Restrictions",
|
||||
"description": "If set, this Supplier is only available for transactions in the listed companies. Leave empty for no restriction.",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"label": "Company Restrictions"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "restrict_to_companies",
|
||||
"fieldtype": "Check",
|
||||
"label": "Restrict to Companies",
|
||||
"description": "If checked, this Supplier is only available for transactions in the companies listed below."
|
||||
},
|
||||
{
|
||||
"fieldname": "allowed_companies",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Allowed Companies",
|
||||
"options": "Company Restriction",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"depends_on": "eval:doc.restrict_to_companies",
|
||||
"mandatory_depends_on": "eval:doc.restrict_to_companies"
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_and_address_tab",
|
||||
@@ -578,7 +585,7 @@
|
||||
"link_fieldname": "party"
|
||||
}
|
||||
],
|
||||
"modified": "2026-07-14 21:00:00.000000",
|
||||
"modified": "2026-07-14 23:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier",
|
||||
|
||||
@@ -73,6 +73,7 @@ class Supplier(TransactionBase):
|
||||
primary_address: DF.TextEditor | None
|
||||
release_date: DF.Date | None
|
||||
represents_company: DF.Link | None
|
||||
restrict_to_companies: DF.Check
|
||||
supplier_details: DF.Text | None
|
||||
supplier_group: DF.Link | None
|
||||
supplier_name: DF.Data
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Customer", {
|
||||
restrict_to_companies(frm) {
|
||||
if (!frm.doc.restrict_to_companies) {
|
||||
frm.set_value("allowed_companies", []);
|
||||
}
|
||||
},
|
||||
|
||||
setup: function (frm) {
|
||||
frm.set_query("allowed_companies", () => ({
|
||||
query: "erpnext.stock.doctype.company_restriction.company_restriction.company_query",
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"tax_withholding_category",
|
||||
"settings_tab",
|
||||
"company_restrictions_section",
|
||||
"restrict_to_companies",
|
||||
"allowed_companies",
|
||||
"section_break_ario",
|
||||
"so_required",
|
||||
@@ -516,18 +517,24 @@
|
||||
"label": "Settings"
|
||||
},
|
||||
{
|
||||
"description": "If set, this Customer is only available for transactions in the listed companies. Leave empty for no restriction.",
|
||||
"fieldname": "company_restrictions_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Company Restrictions",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"label": "Company Restrictions"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "restrict_to_companies",
|
||||
"fieldtype": "Check",
|
||||
"label": "Restrict to Companies",
|
||||
"description": "If checked, this Customer is only available for transactions in the companies listed below."
|
||||
},
|
||||
{
|
||||
"fieldname": "allowed_companies",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Allowed Companies",
|
||||
"options": "Company Restriction",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"depends_on": "eval:doc.restrict_to_companies",
|
||||
"mandatory_depends_on": "eval:doc.restrict_to_companies"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
@@ -717,7 +724,7 @@
|
||||
"link_fieldname": "party"
|
||||
}
|
||||
],
|
||||
"modified": "2026-07-14 21:00:00.000000",
|
||||
"modified": "2026-07-14 23:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Customer",
|
||||
|
||||
@@ -99,6 +99,7 @@ class Customer(TransactionBase):
|
||||
primary_address: DF.TextEditor | None
|
||||
prospect_name: DF.Link | None
|
||||
represents_company: DF.Link | None
|
||||
restrict_to_companies: DF.Check
|
||||
sales_team: DF.Table[SalesTeam]
|
||||
so_required: DF.Check
|
||||
supplier_numbers: DF.Table[SupplierNumberAtCustomer]
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
"disable_rounded_total",
|
||||
"disable_in_words",
|
||||
"column_break_hnew",
|
||||
"use_posting_datetime_for_naming_documents",
|
||||
"enable_company_wise_masters"
|
||||
"use_posting_datetime_for_naming_documents"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -93,13 +92,6 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Posting Datetime for Naming Documents"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "When enabled, Supplier, Customer, and Item records can be restricted to specific companies via their <b>Allowed Companies</b> table. Transactions will only show masters configured for the selected company.",
|
||||
"fieldname": "enable_company_wise_masters",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Company-wise Master Filtering"
|
||||
},
|
||||
{
|
||||
"fieldname": "defaults_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -121,7 +113,7 @@
|
||||
"in_create": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2026-07-14 18:30:00.000000",
|
||||
"modified": "2026-07-14 23:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Global Defaults",
|
||||
|
||||
@@ -18,7 +18,6 @@ keydict = {
|
||||
"account_url": "account_url",
|
||||
"disable_rounded_total": "disable_rounded_total",
|
||||
"disable_in_words": "disable_in_words",
|
||||
"enable_company_wise_masters": "enable_company_wise_masters",
|
||||
}
|
||||
|
||||
ROUNDED_TOTAL_DOCTYPES = (
|
||||
@@ -52,7 +51,6 @@ class GlobalDefaults(Document):
|
||||
demo_company: DF.Link | None
|
||||
disable_in_words: DF.Check
|
||||
disable_rounded_total: DF.Check
|
||||
enable_company_wise_masters: DF.Check
|
||||
hide_currency_symbol: DF.Check
|
||||
use_posting_datetime_for_naming_documents: DF.Check
|
||||
# end: auto-generated types
|
||||
|
||||
@@ -26,9 +26,6 @@ class CompanyRestriction(Document):
|
||||
def get_allowed_companies(user, doctype):
|
||||
from frappe.permissions import get_allowed_docs_for_doctype, get_user_permissions
|
||||
|
||||
if not frappe.get_single_value("Global Defaults", "enable_company_wise_masters"):
|
||||
return None
|
||||
|
||||
user_permissions = get_user_permissions(user or frappe.session.user)
|
||||
if "Company" not in user_permissions:
|
||||
return None
|
||||
@@ -45,31 +42,39 @@ def get_permission_query_conditions(user, doctype=None):
|
||||
|
||||
parent = frappe.qb.DocType(doctype)
|
||||
restriction = frappe.qb.DocType("Company Restriction")
|
||||
restriction_rows = (
|
||||
allowed_rows = (
|
||||
frappe.qb.from_(restriction)
|
||||
.select(restriction.name)
|
||||
.where(
|
||||
(restriction.parenttype == doctype)
|
||||
& (restriction.parentfield == "allowed_companies")
|
||||
& (restriction.parent == parent.name)
|
||||
& (restriction.company.isin(allowed_companies))
|
||||
)
|
||||
)
|
||||
allowed_rows = restriction_rows.where(restriction.company.isin(allowed_companies))
|
||||
return Bracket(ExistsCriterion(allowed_rows) | ExistsCriterion(restriction_rows).negate())
|
||||
return Bracket((parent.restrict_to_companies == 0) | ExistsCriterion(allowed_rows))
|
||||
|
||||
|
||||
def has_permission(doc, ptype=None, user=None):
|
||||
if not doc.get("restrict_to_companies"):
|
||||
return True
|
||||
|
||||
allowed_companies = get_allowed_companies(user, doc.doctype)
|
||||
if not allowed_companies:
|
||||
return True
|
||||
|
||||
companies = [row.company for row in doc.get("allowed_companies") or []]
|
||||
if not companies:
|
||||
return True
|
||||
return any(company in allowed_companies for company in companies)
|
||||
return any(row.company in allowed_companies for row in doc.get("allowed_companies") or [])
|
||||
|
||||
|
||||
def validate_allowed_companies(doc):
|
||||
if not doc.get("restrict_to_companies"):
|
||||
doc.set("allowed_companies", [])
|
||||
elif not doc.get("allowed_companies") and not doc.flags.ignore_mandatory:
|
||||
frappe.throw(
|
||||
_("Allowed Companies is required when Restrict to Companies is checked"),
|
||||
frappe.MandatoryError,
|
||||
)
|
||||
|
||||
if doc.flags.ignore_permissions:
|
||||
return
|
||||
|
||||
|
||||
@@ -60,6 +60,12 @@ frappe.ui.form.on("Item", {
|
||||
erpnext.utils.confirm_negative_stock(frm);
|
||||
},
|
||||
|
||||
restrict_to_companies(frm) {
|
||||
if (!frm.doc.restrict_to_companies) {
|
||||
frm.set_value("allowed_companies", []);
|
||||
}
|
||||
},
|
||||
|
||||
setup: function (frm) {
|
||||
frm.set_query("allowed_companies", () => ({
|
||||
query: "erpnext.stock.doctype.company_restriction.company_restriction.company_query",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"column_break_wugd",
|
||||
"over_billing_allowance",
|
||||
"company_restrictions_section",
|
||||
"restrict_to_companies",
|
||||
"allowed_companies",
|
||||
"section_break_11",
|
||||
"brand",
|
||||
@@ -1089,16 +1090,22 @@
|
||||
{
|
||||
"fieldname": "company_restrictions_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Company Restrictions",
|
||||
"description": "If set, this Item is only available for transactions in the listed companies. Leave empty for no restriction.",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"label": "Company Restrictions"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "restrict_to_companies",
|
||||
"fieldtype": "Check",
|
||||
"label": "Restrict to Companies",
|
||||
"description": "If checked, this Item is only available for transactions in the companies listed below."
|
||||
},
|
||||
{
|
||||
"fieldname": "allowed_companies",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Allowed Companies",
|
||||
"options": "Company Restriction",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.enable_company_wise_masters)"
|
||||
"depends_on": "eval:doc.restrict_to_companies",
|
||||
"mandatory_depends_on": "eval:doc.restrict_to_companies"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-tag",
|
||||
@@ -1106,7 +1113,7 @@
|
||||
"image_field": "image",
|
||||
"links": [],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2026-07-14 21:00:00.000000",
|
||||
"modified": "2026-07-14 23:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item",
|
||||
|
||||
@@ -134,6 +134,7 @@ class Item(Document):
|
||||
quality_inspection_template: DF.Link | None
|
||||
reorder_levels: DF.Table[ItemReorder]
|
||||
retain_sample: DF.Check
|
||||
restrict_to_companies: DF.Check
|
||||
safety_stock: DF.Float
|
||||
sales_tax_withholding_category: DF.Link | None
|
||||
sales_uom: DF.Link | None
|
||||
|
||||
Reference in New Issue
Block a user