From 1ef5dfbadd97492cb986a672a6725d21de617414 Mon Sep 17 00:00:00 2001 From: Tarek Lokal Date: Sat, 11 Jul 2026 16:17:44 +0200 Subject: [PATCH] feat(spp_starter_sp_mis): bypass registry CRUD restriction via context (#298) Honor bypass_registry_admin_only_crud on res.partner actions so one view can allow non-admin create/edit while the global setting stays on. Co-authored-by: Cursor --- .../static/src/js/registry_restriction.js | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/spp_starter_sp_mis/static/src/js/registry_restriction.js b/spp_starter_sp_mis/static/src/js/registry_restriction.js index 9f41fe02..23758070 100644 --- a/spp_starter_sp_mis/static/src/js/registry_restriction.js +++ b/spp_starter_sp_mis/static/src/js/registry_restriction.js @@ -57,6 +57,11 @@ fetchRestriction(); // Actions to strip from the action menu when restricted const BLOCKED_ACTIONS = ["delete", "archive", "unarchive", "duplicate"]; +function bypassRegistryRestriction(component) { + const context = component.props?.context || {}; + return context.bypass_registry_admin_only_crud === true; +} + /** * Patch FormController to enforce read-only on registry forms when restricted. * @@ -69,6 +74,10 @@ const BLOCKED_ACTIONS = ["delete", "archive", "unarchive", "duplicate"]; patch(FormController.prototype, { setup() { const modelName = this.props.resModel; + if (REGISTRY_MODELS.includes(modelName) && bypassRegistryRestriction(this)) { + super.setup(...arguments); + return; + } // Check synchronous cache BEFORE super.setup() creates the model this._registryRestricted = REGISTRY_MODELS.includes(modelName) && _restrictionResult === true; @@ -153,7 +162,10 @@ patch(FormController.prototype, { get modelParams() { const params = super.modelParams; // Force readonly mode when registry is restricted - if (this._registryRestricted) { + if ( + this._registryRestricted && + !bypassRegistryRestriction(this) + ) { params.config.mode = "readonly"; } return params; @@ -162,7 +174,11 @@ patch(FormController.prototype, { get actionMenuItems() { const menuItems = super.actionMenuItems; - if (this._registryRestricted && REGISTRY_MODELS.includes(this.props.resModel)) { + if ( + this._registryRestricted && + REGISTRY_MODELS.includes(this.props.resModel) && + !bypassRegistryRestriction(this) + ) { if (menuItems.action) { menuItems.action = menuItems.action.filter( (item) => !BLOCKED_ACTIONS.includes(item.key) @@ -185,6 +201,9 @@ patch(ListController.prototype, { if (!REGISTRY_MODELS.includes(modelName)) { return; } + if (bypassRegistryRestriction(this)) { + return; + } this._registryRestricted = false; this._restrictionObserver = null; @@ -247,7 +266,11 @@ patch(ListController.prototype, { get actionMenuItems() { const menuItems = super.actionMenuItems; - if (this._registryRestricted && REGISTRY_MODELS.includes(this.props.resModel)) { + if ( + this._registryRestricted && + REGISTRY_MODELS.includes(this.props.resModel) && + !bypassRegistryRestriction(this) + ) { if (menuItems.action) { menuItems.action = menuItems.action.filter( (item) => !BLOCKED_ACTIONS.includes(item.key)