From 7ac01991e571fb7e0e8a5125703b429d843ccc9c Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 00:14:36 -0400 Subject: [PATCH] refactor(fusion_accounting): move security groups to _core, add multi-company session rule Made-with: Cursor --- fusion_accounting/security/security.xml | 94 ------------------- fusion_accounting_ai/__manifest__.py | 1 + .../controllers/chat_controller.py | 10 +- .../data/tool_definitions.xml | 38 ++++---- .../migrations/19.0.1.0.0/post-migration.py | 38 ++++++-- .../fusion_accounting_ai_security.xml | 58 ++++++++++++ .../security/ir.model.access.csv | 36 +++---- .../views/match_history_views.xml | 4 +- fusion_accounting_ai/views/menus.xml | 10 +- fusion_accounting_ai/views/rule_views.xml | 4 +- fusion_accounting_core/__manifest__.py | 1 + .../migrations/19.0.1.0.0/post-migration.py | 48 ++++++++++ .../security/fusion_accounting_security.xml | 46 +++++++++ 13 files changed, 237 insertions(+), 151 deletions(-) delete mode 100644 fusion_accounting/security/security.xml create mode 100644 fusion_accounting_ai/security/fusion_accounting_ai_security.xml create mode 100644 fusion_accounting_core/migrations/19.0.1.0.0/post-migration.py create mode 100644 fusion_accounting_core/security/fusion_accounting_security.xml diff --git a/fusion_accounting/security/security.xml b/fusion_accounting/security/security.xml deleted file mode 100644 index 25c3c297..00000000 --- a/fusion_accounting/security/security.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Fusion Accounting AI - 25 - - - - - Fusion Accounting AI - - - - - - User - 10 - - - - - - - Manager - 20 - - - - - - - Administrator - 30 - - - - - - - - - - - - - - - Fusion Session: Own Sessions - - [('user_id', '=', user.id)] - - - - - Fusion Session: All Sessions - - [(1, '=', 1)] - - - - - Fusion History: Own History - - [('session_id.user_id', '=', user.id)] - - - - - Fusion History: All History - - [(1, '=', 1)] - - - - - - Fusion Tool: Multi-Company - - ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] - - - - Fusion Rule: Multi-Company - - ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] - - - - Fusion History: Multi-Company - - ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] - - diff --git a/fusion_accounting_ai/__manifest__.py b/fusion_accounting_ai/__manifest__.py index e524cb74..ab54bffa 100644 --- a/fusion_accounting_ai/__manifest__.py +++ b/fusion_accounting_ai/__manifest__.py @@ -30,6 +30,7 @@ Built by Nexa Systems Inc. }, 'data': [ 'security/ir.model.access.csv', + 'security/fusion_accounting_ai_security.xml', 'data/cron.xml', 'data/tool_definitions.xml', 'data/default_rules.xml', diff --git a/fusion_accounting_ai/controllers/chat_controller.py b/fusion_accounting_ai/controllers/chat_controller.py index a3c6214c..b1acb10b 100644 --- a/fusion_accounting_ai/controllers/chat_controller.py +++ b/fusion_accounting_ai/controllers/chat_controller.py @@ -13,7 +13,7 @@ class FusionAccountingChatController(http.Controller): """S1-S3: Verify the current user owns the session.""" if session.user_id.id != request.env.user.id: # Allow managers to access any session - if not request.env.user.has_group('fusion_accounting.group_fusion_accounting_manager'): + if not request.env.user.has_group('fusion_accounting_core.group_fusion_accounting_manager'): return {'error': 'Access denied: you do not own this session'} return None @@ -55,7 +55,7 @@ class FusionAccountingChatController(http.Controller): @http.route('/fusion_accounting/approve', type='jsonrpc', auth='user') def approve_action(self, match_history_id, **kwargs): - if not request.env.user.has_group('fusion_accounting.group_fusion_accounting_manager'): + if not request.env.user.has_group('fusion_accounting_core.group_fusion_accounting_manager'): return {'error': 'Insufficient permissions to approve actions'} agent = request.env['fusion.accounting.agent'] result = agent.approve_action(int(match_history_id)) @@ -63,7 +63,7 @@ class FusionAccountingChatController(http.Controller): @http.route('/fusion_accounting/reject', type='jsonrpc', auth='user') def reject_action(self, match_history_id, reason='', **kwargs): - if not request.env.user.has_group('fusion_accounting.group_fusion_accounting_manager'): + if not request.env.user.has_group('fusion_accounting_core.group_fusion_accounting_manager'): return {'error': 'Insufficient permissions to reject actions'} agent = request.env['fusion.accounting.agent'] result = agent.reject_action(int(match_history_id), reason) @@ -103,7 +103,7 @@ class FusionAccountingChatController(http.Controller): @http.route('/fusion_accounting/approve_all', type='jsonrpc', auth='user') def approve_all(self, match_history_ids, **kwargs): - if not request.env.user.has_group('fusion_accounting.group_fusion_accounting_manager'): + if not request.env.user.has_group('fusion_accounting_core.group_fusion_accounting_manager'): return {'error': 'Insufficient permissions to approve actions'} agent = request.env['fusion.accounting.agent'] results = [] @@ -119,7 +119,7 @@ class FusionAccountingChatController(http.Controller): @http.route('/fusion_accounting/reject_all', type='jsonrpc', auth='user') def reject_all(self, match_history_ids, reason='', **kwargs): - if not request.env.user.has_group('fusion_accounting.group_fusion_accounting_manager'): + if not request.env.user.has_group('fusion_accounting_core.group_fusion_accounting_manager'): return {'error': 'Insufficient permissions to reject actions'} agent = request.env['fusion.accounting.agent'] results = [] diff --git a/fusion_accounting_ai/data/tool_definitions.xml b/fusion_accounting_ai/data/tool_definitions.xml index 55a5cad9..ec81f941 100644 --- a/fusion_accounting_ai/data/tool_definitions.xml +++ b/fusion_accounting_ai/data/tool_definitions.xml @@ -25,7 +25,7 @@ bank_reconciliation 3 {"type": "object", "properties": {"statement_line_id": {"type": "integer", "description": "Bank statement line ID"}, "move_line_ids": {"type": "array", "items": {"type": "integer"}, "description": "Journal item IDs to match"}}, "required": ["statement_line_id", "move_line_ids"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager auto_reconcile_bank_lines @@ -34,7 +34,7 @@ bank_reconciliation 3 {"type": "object", "properties": {"company_id": {"type": "integer"}}} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager apply_reconcile_model @@ -43,7 +43,7 @@ bank_reconciliation 3 {"type": "object", "properties": {"model_id": {"type": "integer"}, "statement_line_id": {"type": "integer"}}, "required": ["model_id", "statement_line_id"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager unmatch_bank_line @@ -52,7 +52,7 @@ bank_reconciliation 3 {"type": "object", "properties": {"statement_line_id": {"type": "integer"}}, "required": ["statement_line_id"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_reconcile_suggestions @@ -119,7 +119,7 @@ hst_management 2 {"type": "object", "properties": {}} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager validate_tax_return @@ -128,7 +128,7 @@ hst_management 3 {"type": "object", "properties": {"return_id": {"type": "integer"}}, "required": ["return_id"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager @@ -163,7 +163,7 @@ accounts_receivable 2 {"type": "object", "properties": {"partner_id": {"type": "integer"}, "send_email": {"type": "boolean"}, "print_letter": {"type": "boolean"}, "email_subject": {"type": "string"}, "body": {"type": "string"}}, "required": ["partner_id"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_followup_report @@ -180,7 +180,7 @@ accounts_receivable 3 {"type": "object", "properties": {"move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["move_line_ids"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_unmatched_payments @@ -449,7 +449,7 @@ adp 3 {"type": "object", "properties": {"move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["move_line_ids"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager verify_adp_split @@ -483,7 +483,7 @@ adp 3 {"type": "object", "properties": {"invoices": {"type": "array", "items": {"type": "object", "properties": {"invoice_number": {"type": "string"}, "amount": {"type": "number"}}, "required": ["invoice_number", "amount"]}, "description": "List of invoices with number and payment amount"}, "payment_date": {"type": "string", "description": "Payment date from remittance (YYYY-MM-DD)"}, "journal_id": {"type": "integer", "description": "Bank journal ID (default 50 = Scotia Current)"}}, "required": ["invoices", "payment_date"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager @@ -542,7 +542,7 @@ reporting 2 {"type": "object", "properties": {"report_ref": {"type": "string"}, "format": {"type": "string", "enum": ["pdf", "xlsx"]}, "date_from": {"type": "string"}, "date_to": {"type": "string"}}, "required": ["report_ref"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager @@ -626,7 +626,7 @@ audit 2 {"type": "object", "properties": {"move_id": {"type": "integer"}, "flag": {"type": "string"}, "recommendation": {"type": "string"}}, "required": ["move_id"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_audit_status @@ -643,7 +643,7 @@ audit 2 {"type": "object", "properties": {"status_id": {"type": "integer"}, "status": {"type": "string", "enum": ["todo", "reviewed", "supervised", "anomaly"]}}, "required": ["status_id", "status"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_audit_trail @@ -686,7 +686,7 @@ payroll_management 3 {"type": "object", "properties": {"journal_id": {"type": "integer"}, "date": {"type": "string"}, "ref": {"type": "string"}, "lines": {"type": "array", "items": {"type": "object", "properties": {"account_id": {"type": "integer"}, "name": {"type": "string"}, "debit": {"type": "number"}, "credit": {"type": "number"}, "partner_id": {"type": "integer"}}}}}, "required": ["journal_id", "date", "lines"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager match_payroll_cheques @@ -695,7 +695,7 @@ payroll_management 3 {"type": "object", "properties": {"statement_line_id": {"type": "integer"}, "move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["statement_line_id", "move_line_ids"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager prepare_cra_payment @@ -704,7 +704,7 @@ payroll_management 3 {"type": "object", "properties": {"journal_id": {"type": "integer"}, "date": {"type": "string"}, "lines": {"type": "array"}}, "required": ["journal_id", "date", "lines"]} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager generate_t4 @@ -713,7 +713,7 @@ payroll_management 2 {"type": "object", "properties": {}} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager generate_roe @@ -722,7 +722,7 @@ payroll_management 2 {"type": "object", "properties": {}} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager get_payroll_cost_report @@ -823,7 +823,7 @@ bank_reconciliation 3 {"type": "object", "properties": {"journal_id": {"type": "integer", "description": "Bank journal ID (default 50)"}, "line_ids": {"type": "array", "items": {"type": "integer"}, "description": "Optional: specific bank line IDs to reconcile. If empty, reconciles all matching payroll cheques."}}} - fusion_accounting.group_fusion_accounting_manager + fusion_accounting_core.group_fusion_accounting_manager diff --git a/fusion_accounting_ai/migrations/19.0.1.0.0/post-migration.py b/fusion_accounting_ai/migrations/19.0.1.0.0/post-migration.py index 409d3ac8..8386592f 100644 --- a/fusion_accounting_ai/migrations/19.0.1.0.0/post-migration.py +++ b/fusion_accounting_ai/migrations/19.0.1.0.0/post-migration.py @@ -61,7 +61,31 @@ AI_NAME_LIKE = ( ) +# Group/category/privilege xml-ids that moved from 'fusion_accounting' to +# 'fusion_accounting_core' in Phase 0 (Task 16). Both _core and _ai +# post-migrations run this same UPDATE — whichever runs first wins, the other +# is a no-op. We reassign these here too so that if _ai happens to upgrade +# first (before _core's own post-migration has had a chance to run) the groups +# are still rehomed correctly. +CORE_SECURITY_NAMES = ( + 'module_category_fusion_accounting', + 'res_groups_privilege_fusion_accounting', + 'group_fusion_accounting_user', + 'group_fusion_accounting_manager', + 'group_fusion_accounting_admin', +) + + def migrate(cr, version): + # Step 0: Reassign security groups/category/privilege to fusion_accounting_core. + cr.execute(""" + UPDATE ir_model_data + SET module = 'fusion_accounting_core' + WHERE module = 'fusion_accounting' + AND name = ANY(%s) + """, (list(CORE_SECURITY_NAMES),)) + moved_to_core = cr.rowcount + # Step 1: Delete orphan rows that conflict with an already-existing row in # fusion_accounting_ai (data-load artifact). The new row is the survivor. cr.execute(""" @@ -76,7 +100,7 @@ def migrate(cr, version): """, (list(AI_MODEL_PREFIXES), list(AI_NAME_LIKE))) deleted_conflicts = cr.rowcount - # Step 2: Reassign the non-conflicting orphans. + # Step 2: Reassign the non-conflicting orphans to fusion_accounting_ai. cr.execute(""" UPDATE ir_model_data SET module = 'fusion_accounting_ai' @@ -86,12 +110,14 @@ def migrate(cr, version): OR name LIKE ANY(%s) ) """, (list(AI_MODEL_PREFIXES), list(AI_NAME_LIKE))) - moved = cr.rowcount + moved_to_ai = cr.rowcount _logger.info( - "fusion_accounting_ai post-migration: deleted %d conflicting orphans, " - "reassigned %d ir_model_data rows from module='fusion_accounting' " - "to module='fusion_accounting_ai'", + "fusion_accounting_ai post-migration: reassigned %d security rows to " + "fusion_accounting_core, deleted %d conflicting AI orphans, reassigned " + "%d ir_model_data rows from module='fusion_accounting' to " + "module='fusion_accounting_ai'", + moved_to_core, deleted_conflicts, - moved, + moved_to_ai, ) diff --git a/fusion_accounting_ai/security/fusion_accounting_ai_security.xml b/fusion_accounting_ai/security/fusion_accounting_ai_security.xml new file mode 100644 index 00000000..e3cc66cc --- /dev/null +++ b/fusion_accounting_ai/security/fusion_accounting_ai_security.xml @@ -0,0 +1,58 @@ + + + + + Fusion Session: Own Sessions + + [('user_id', '=', user.id)] + + + + + Fusion Session: All Sessions + + [(1, '=', 1)] + + + + + Fusion History: Own History + + [('session_id.user_id', '=', user.id)] + + + + + Fusion History: All History + + [(1, '=', 1)] + + + + + + Fusion Tool: Multi-Company + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + + Fusion Rule: Multi-Company + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + + Fusion History: Multi-Company + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + + + Fusion Session: Multi-Company + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + diff --git a/fusion_accounting_ai/security/ir.model.access.csv b/fusion_accounting_ai/security/ir.model.access.csv index 81cbe5d6..441b9863 100644 --- a/fusion_accounting_ai/security/ir.model.access.csv +++ b/fusion_accounting_ai/security/ir.model.access.csv @@ -1,19 +1,19 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_fusion_session_user,fusion.accounting.session.user,model_fusion_accounting_session,group_fusion_accounting_user,1,1,1,0 -access_fusion_session_admin,fusion.accounting.session.admin,model_fusion_accounting_session,group_fusion_accounting_admin,1,1,1,1 -access_fusion_history_user,fusion.accounting.match.history.user,model_fusion_accounting_match_history,group_fusion_accounting_user,1,0,0,0 -access_fusion_history_manager,fusion.accounting.match.history.manager,model_fusion_accounting_match_history,group_fusion_accounting_manager,1,1,1,0 -access_fusion_history_admin,fusion.accounting.match.history.admin,model_fusion_accounting_match_history,group_fusion_accounting_admin,1,1,1,1 -access_fusion_rule_user,fusion.accounting.rule.user,model_fusion_accounting_rule,group_fusion_accounting_user,1,0,0,0 -access_fusion_rule_manager,fusion.accounting.rule.manager,model_fusion_accounting_rule,group_fusion_accounting_manager,1,1,1,0 -access_fusion_rule_admin,fusion.accounting.rule.admin,model_fusion_accounting_rule,group_fusion_accounting_admin,1,1,1,1 -access_fusion_tool_user,fusion.accounting.tool.user,model_fusion_accounting_tool,group_fusion_accounting_user,1,0,0,0 -access_fusion_tool_admin,fusion.accounting.tool.admin,model_fusion_accounting_tool,group_fusion_accounting_admin,1,1,1,1 -access_fusion_dashboard_user,fusion.accounting.dashboard.user,model_fusion_accounting_dashboard,group_fusion_accounting_user,1,1,1,1 -access_fusion_rule_wizard_manager,fusion.accounting.rule.wizard.manager,model_fusion_accounting_rule_wizard,group_fusion_accounting_manager,1,1,1,1 -access_fusion_recurring_pattern_user,fusion.recurring.pattern.user,model_fusion_recurring_pattern,group_fusion_accounting_user,1,0,0,0 -access_fusion_recurring_pattern_manager,fusion.recurring.pattern.manager,model_fusion_recurring_pattern,group_fusion_accounting_manager,1,1,1,0 -access_fusion_recurring_pattern_admin,fusion.recurring.pattern.admin,model_fusion_recurring_pattern,group_fusion_accounting_admin,1,1,1,1 -access_fusion_vendor_profile_user,fusion.vendor.tax.profile.user,model_fusion_vendor_tax_profile,group_fusion_accounting_user,1,0,0,0 -access_fusion_vendor_profile_manager,fusion.vendor.tax.profile.manager,model_fusion_vendor_tax_profile,group_fusion_accounting_manager,1,1,1,0 -access_fusion_vendor_profile_admin,fusion.vendor.tax.profile.admin,model_fusion_vendor_tax_profile,group_fusion_accounting_admin,1,1,1,1 +access_fusion_session_user,fusion.accounting.session.user,model_fusion_accounting_session,fusion_accounting_core.group_fusion_accounting_user,1,1,1,0 +access_fusion_session_admin,fusion.accounting.session.admin,model_fusion_accounting_session,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 +access_fusion_history_user,fusion.accounting.match.history.user,model_fusion_accounting_match_history,fusion_accounting_core.group_fusion_accounting_user,1,0,0,0 +access_fusion_history_manager,fusion.accounting.match.history.manager,model_fusion_accounting_match_history,fusion_accounting_core.group_fusion_accounting_manager,1,1,1,0 +access_fusion_history_admin,fusion.accounting.match.history.admin,model_fusion_accounting_match_history,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 +access_fusion_rule_user,fusion.accounting.rule.user,model_fusion_accounting_rule,fusion_accounting_core.group_fusion_accounting_user,1,0,0,0 +access_fusion_rule_manager,fusion.accounting.rule.manager,model_fusion_accounting_rule,fusion_accounting_core.group_fusion_accounting_manager,1,1,1,0 +access_fusion_rule_admin,fusion.accounting.rule.admin,model_fusion_accounting_rule,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 +access_fusion_tool_user,fusion.accounting.tool.user,model_fusion_accounting_tool,fusion_accounting_core.group_fusion_accounting_user,1,0,0,0 +access_fusion_tool_admin,fusion.accounting.tool.admin,model_fusion_accounting_tool,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 +access_fusion_dashboard_user,fusion.accounting.dashboard.user,model_fusion_accounting_dashboard,fusion_accounting_core.group_fusion_accounting_user,1,1,1,1 +access_fusion_rule_wizard_manager,fusion.accounting.rule.wizard.manager,model_fusion_accounting_rule_wizard,fusion_accounting_core.group_fusion_accounting_manager,1,1,1,1 +access_fusion_recurring_pattern_user,fusion.recurring.pattern.user,model_fusion_recurring_pattern,fusion_accounting_core.group_fusion_accounting_user,1,0,0,0 +access_fusion_recurring_pattern_manager,fusion.recurring.pattern.manager,model_fusion_recurring_pattern,fusion_accounting_core.group_fusion_accounting_manager,1,1,1,0 +access_fusion_recurring_pattern_admin,fusion.recurring.pattern.admin,model_fusion_recurring_pattern,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 +access_fusion_vendor_profile_user,fusion.vendor.tax.profile.user,model_fusion_vendor_tax_profile,fusion_accounting_core.group_fusion_accounting_user,1,0,0,0 +access_fusion_vendor_profile_manager,fusion.vendor.tax.profile.manager,model_fusion_vendor_tax_profile,fusion_accounting_core.group_fusion_accounting_manager,1,1,1,0 +access_fusion_vendor_profile_admin,fusion.vendor.tax.profile.admin,model_fusion_vendor_tax_profile,fusion_accounting_core.group_fusion_accounting_admin,1,1,1,1 diff --git a/fusion_accounting_ai/views/match_history_views.xml b/fusion_accounting_ai/views/match_history_views.xml index e8e52ae1..a1c38b2e 100644 --- a/fusion_accounting_ai/views/match_history_views.xml +++ b/fusion_accounting_ai/views/match_history_views.xml @@ -31,10 +31,10 @@
diff --git a/fusion_accounting_ai/views/menus.xml b/fusion_accounting_ai/views/menus.xml index 15cb292f..7a1dc508 100644 --- a/fusion_accounting_ai/views/menus.xml +++ b/fusion_accounting_ai/views/menus.xml @@ -5,7 +5,7 @@ name="Fusion AI" parent="accountant.menu_accounting" sequence="8" - groups="group_fusion_accounting_user"/> + groups="fusion_accounting_core.group_fusion_accounting_user"/> + groups="fusion_accounting_core.group_fusion_accounting_manager"/> + groups="fusion_accounting_core.group_fusion_accounting_manager"/> + groups="fusion_accounting_core.group_fusion_accounting_manager"/> + groups="fusion_accounting_core.group_fusion_accounting_admin"/> diff --git a/fusion_accounting_ai/views/rule_views.xml b/fusion_accounting_ai/views/rule_views.xml index 85af9d0e..60139a29 100644 --- a/fusion_accounting_ai/views/rule_views.xml +++ b/fusion_accounting_ai/views/rule_views.xml @@ -27,10 +27,10 @@
diff --git a/fusion_accounting_core/__manifest__.py b/fusion_accounting_core/__manifest__.py index 1d1f9de0..95479c45 100644 --- a/fusion_accounting_core/__manifest__.py +++ b/fusion_accounting_core/__manifest__.py @@ -24,6 +24,7 @@ Built by Nexa Systems Inc. 'maintainer': 'Nexa Systems Inc.', 'depends': ['account', 'mail'], 'data': [ + 'security/fusion_accounting_security.xml', 'security/ir.model.access.csv', ], 'installable': True, diff --git a/fusion_accounting_core/migrations/19.0.1.0.0/post-migration.py b/fusion_accounting_core/migrations/19.0.1.0.0/post-migration.py new file mode 100644 index 00000000..5564954a --- /dev/null +++ b/fusion_accounting_core/migrations/19.0.1.0.0/post-migration.py @@ -0,0 +1,48 @@ +"""Reassign security group/category/privilege xml-ids from the old module name. + +Pre-Phase-0, the three fusion security groups (user, manager, admin), the +module category and the privilege all lived in module='fusion_accounting'. +Post-Phase-0 (Task 16) they moved into module='fusion_accounting_core'. + +Odoo loads the XML from the new location on upgrade, but the existing +ir_model_data rows still reference the old module. This script rewrites them. + +Both fusion_accounting_core and fusion_accounting_ai ship an equivalent +UPDATE — whichever post-migration runs first wins the rehoming, the other +is a no-op. This redundancy protects the common case where the two modules +are upgraded in either order (as well as the case where only one is +installed in a given database). + +Idempotent: running it a second time matches zero rows. +""" + +import logging + +_logger = logging.getLogger(__name__) + + +CORE_SECURITY_NAMES = ( + 'module_category_fusion_accounting', + 'res_groups_privilege_fusion_accounting', + 'group_fusion_accounting_user', + 'group_fusion_accounting_manager', + 'group_fusion_accounting_admin', +) + + +def migrate(cr, version): + cr.execute( + """ + UPDATE ir_model_data + SET module = 'fusion_accounting_core' + WHERE module = 'fusion_accounting' + AND name = ANY(%s) + """, + (list(CORE_SECURITY_NAMES),), + ) + moved = cr.rowcount + _logger.info( + "fusion_accounting_core post-migration: reassigned %d security rows " + "from module='fusion_accounting' to module='fusion_accounting_core'", + moved, + ) diff --git a/fusion_accounting_core/security/fusion_accounting_security.xml b/fusion_accounting_core/security/fusion_accounting_security.xml new file mode 100644 index 00000000..59953d9c --- /dev/null +++ b/fusion_accounting_core/security/fusion_accounting_security.xml @@ -0,0 +1,46 @@ + + + + + Fusion Accounting + 25 + + + + + Fusion Accounting + + + + + + User + 10 + + + + + + + Manager + 20 + + + + + + + Administrator + 30 + + + + + + + + + + + +