refactor(fusion_accounting): move security groups to _core, add multi-company session rule
Made-with: Cursor
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Module Category -->
|
||||
<record id="module_category_fusion_accounting" model="ir.module.category">
|
||||
<field name="name">Fusion Accounting AI</field>
|
||||
<field name="sequence">25</field>
|
||||
</record>
|
||||
|
||||
<!-- Groups Privilege -->
|
||||
<record id="res_groups_privilege_fusion_accounting" model="res.groups.privilege">
|
||||
<field name="name">Fusion Accounting AI</field>
|
||||
<field name="category_id" ref="module_category_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- User Group (Staff) -->
|
||||
<record id="group_fusion_accounting_user" model="res.groups">
|
||||
<field name="name">User</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="implied_ids" eval="[(4, ref('account.group_account_user'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Manager Group -->
|
||||
<record id="group_fusion_accounting_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Admin Group -->
|
||||
<record id="group_fusion_accounting_admin" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_manager'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Auto-assign: Accounting users get Fusion AI User, Advisers get Admin -->
|
||||
<record id="account.group_account_user" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
<record id="account.group_account_manager" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_admin'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Record Rules -->
|
||||
<record id="rule_fusion_session_user" model="ir.rule">
|
||||
<field name="name">Fusion Session: Own Sessions</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_session"/>
|
||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_session_manager" model="ir.rule">
|
||||
<field name="name">Fusion Session: All Sessions</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_session"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_fusion_accounting_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_user" model="ir.rule">
|
||||
<field name="name">Fusion History: Own History</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">[('session_id.user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_manager" model="ir.rule">
|
||||
<field name="name">Fusion History: All History</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_fusion_accounting_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Multi-company rules -->
|
||||
<record id="rule_fusion_tool_company" model="ir.rule">
|
||||
<field name="name">Fusion Tool: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_tool"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_rule_company" model="ir.rule">
|
||||
<field name="name">Fusion Rule: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_rule"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_company" model="ir.rule">
|
||||
<field name="name">Fusion History: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -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',
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<field name="domain">bank_reconciliation</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"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"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_auto_reconcile_bank_lines" model="fusion.accounting.tool">
|
||||
<field name="name">auto_reconcile_bank_lines</field>
|
||||
@@ -34,7 +34,7 @@
|
||||
<field name="domain">bank_reconciliation</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"company_id": {"type": "integer"}}}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_apply_reconcile_model" model="fusion.accounting.tool">
|
||||
<field name="name">apply_reconcile_model</field>
|
||||
@@ -43,7 +43,7 @@
|
||||
<field name="domain">bank_reconciliation</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"model_id": {"type": "integer"}, "statement_line_id": {"type": "integer"}}, "required": ["model_id", "statement_line_id"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_unmatch_bank_line" model="fusion.accounting.tool">
|
||||
<field name="name">unmatch_bank_line</field>
|
||||
@@ -52,7 +52,7 @@
|
||||
<field name="domain">bank_reconciliation</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"statement_line_id": {"type": "integer"}}, "required": ["statement_line_id"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_reconcile_suggestions" model="fusion.accounting.tool">
|
||||
<field name="name">get_reconcile_suggestions</field>
|
||||
@@ -119,7 +119,7 @@
|
||||
<field name="domain">hst_management</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {}}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_validate_tax_return" model="fusion.accounting.tool">
|
||||
<field name="name">validate_tax_return</field>
|
||||
@@ -128,7 +128,7 @@
|
||||
<field name="domain">hst_management</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"return_id": {"type": "integer"}}, "required": ["return_id"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
|
||||
<!-- Domain 3: Accounts Receivable -->
|
||||
@@ -163,7 +163,7 @@
|
||||
<field name="domain">accounts_receivable</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"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"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_followup_report" model="fusion.accounting.tool">
|
||||
<field name="name">get_followup_report</field>
|
||||
@@ -180,7 +180,7 @@
|
||||
<field name="domain">accounts_receivable</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["move_line_ids"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_unmatched_payments" model="fusion.accounting.tool">
|
||||
<field name="name">get_unmatched_payments</field>
|
||||
@@ -449,7 +449,7 @@
|
||||
<field name="domain">adp</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["move_line_ids"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_verify_adp_split" model="fusion.accounting.tool">
|
||||
<field name="name">verify_adp_split</field>
|
||||
@@ -483,7 +483,7 @@
|
||||
<field name="domain">adp</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"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"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
|
||||
<!-- Domain 10: Reporting -->
|
||||
@@ -542,7 +542,7 @@
|
||||
<field name="domain">reporting</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"report_ref": {"type": "string"}, "format": {"type": "string", "enum": ["pdf", "xlsx"]}, "date_from": {"type": "string"}, "date_to": {"type": "string"}}, "required": ["report_ref"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
|
||||
<record id="tool_get_invoicing_summary" model="fusion.accounting.tool">
|
||||
@@ -626,7 +626,7 @@
|
||||
<field name="domain">audit</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"move_id": {"type": "integer"}, "flag": {"type": "string"}, "recommendation": {"type": "string"}}, "required": ["move_id"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_audit_status" model="fusion.accounting.tool">
|
||||
<field name="name">get_audit_status</field>
|
||||
@@ -643,7 +643,7 @@
|
||||
<field name="domain">audit</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"status_id": {"type": "integer"}, "status": {"type": "string", "enum": ["todo", "reviewed", "supervised", "anomaly"]}}, "required": ["status_id", "status"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_audit_trail" model="fusion.accounting.tool">
|
||||
<field name="name">get_audit_trail</field>
|
||||
@@ -686,7 +686,7 @@
|
||||
<field name="domain">payroll_management</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"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"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_match_payroll_cheques" model="fusion.accounting.tool">
|
||||
<field name="name">match_payroll_cheques</field>
|
||||
@@ -695,7 +695,7 @@
|
||||
<field name="domain">payroll_management</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"statement_line_id": {"type": "integer"}, "move_line_ids": {"type": "array", "items": {"type": "integer"}}}, "required": ["statement_line_id", "move_line_ids"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_prepare_cra_payment" model="fusion.accounting.tool">
|
||||
<field name="name">prepare_cra_payment</field>
|
||||
@@ -704,7 +704,7 @@
|
||||
<field name="domain">payroll_management</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {"journal_id": {"type": "integer"}, "date": {"type": "string"}, "lines": {"type": "array"}}, "required": ["journal_id", "date", "lines"]}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_generate_t4" model="fusion.accounting.tool">
|
||||
<field name="name">generate_t4</field>
|
||||
@@ -713,7 +713,7 @@
|
||||
<field name="domain">payroll_management</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {}}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_generate_roe" model="fusion.accounting.tool">
|
||||
<field name="name">generate_roe</field>
|
||||
@@ -722,7 +722,7 @@
|
||||
<field name="domain">payroll_management</field>
|
||||
<field name="tier">2</field>
|
||||
<field name="parameters_schema">{"type": "object", "properties": {}}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
<record id="tool_get_payroll_cost_report" model="fusion.accounting.tool">
|
||||
<field name="name">get_payroll_cost_report</field>
|
||||
@@ -823,7 +823,7 @@
|
||||
<field name="domain">bank_reconciliation</field>
|
||||
<field name="tier">3</field>
|
||||
<field name="parameters_schema">{"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."}}}</field>
|
||||
<field name="required_groups">fusion_accounting.group_fusion_accounting_manager</field>
|
||||
<field name="required_groups">fusion_accounting_core.group_fusion_accounting_manager</field>
|
||||
</record>
|
||||
|
||||
<record id="tool_create_expense_entry" model="fusion.accounting.tool">
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Per-user record rules (sessions visible only to the owning user; managers see all) -->
|
||||
<record id="rule_fusion_session_user" model="ir.rule">
|
||||
<field name="name">Fusion Session: Own Sessions</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_session"/>
|
||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('fusion_accounting_core.group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_session_manager" model="ir.rule">
|
||||
<field name="name">Fusion Session: All Sessions</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_session"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('fusion_accounting_core.group_fusion_accounting_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_user" model="ir.rule">
|
||||
<field name="name">Fusion History: Own History</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">[('session_id.user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('fusion_accounting_core.group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_manager" model="ir.rule">
|
||||
<field name="name">Fusion History: All History</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('fusion_accounting_core.group_fusion_accounting_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Multi-company rules -->
|
||||
<record id="rule_fusion_tool_company" model="ir.rule">
|
||||
<field name="name">Fusion Tool: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_tool"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_rule_company" model="ir.rule">
|
||||
<field name="name">Fusion Rule: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_rule"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_fusion_history_company" model="ir.rule">
|
||||
<field name="name">Fusion History: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_match_history"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<!-- NEW (Phase 0): Multi-company rule on session itself
|
||||
(per spec Section 4.2 + existing CLAUDE.md Known Issues) -->
|
||||
<record id="rule_fusion_session_company" model="ir.rule">
|
||||
<field name="name">Fusion Session: Multi-Company</field>
|
||||
<field name="model_id" ref="model_fusion_accounting_session"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -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
|
||||
|
||||
|
@@ -31,10 +31,10 @@
|
||||
<header>
|
||||
<button name="action_approve" string="Approve" type="object"
|
||||
class="btn-primary" invisible="decision != 'pending'"
|
||||
groups="fusion_accounting.group_fusion_accounting_manager"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_manager"/>
|
||||
<button name="action_reject" string="Reject" type="object"
|
||||
class="btn-danger" invisible="decision != 'pending'"
|
||||
groups="fusion_accounting.group_fusion_accounting_manager"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_manager"/>
|
||||
<field name="decision" widget="statusbar"
|
||||
statusbar_visible="pending,approved,rejected,auto"/>
|
||||
</header>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
<!-- Dashboard -->
|
||||
<menuitem id="menu_fusion_dashboard"
|
||||
@@ -34,7 +34,7 @@
|
||||
parent="menu_fusion_accounting_root"
|
||||
action="action_fusion_rule"
|
||||
sequence="40"
|
||||
groups="group_fusion_accounting_manager"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_manager"/>
|
||||
|
||||
<!-- Vendor Tax Profiles -->
|
||||
<menuitem id="menu_fusion_vendor_profiles"
|
||||
@@ -42,7 +42,7 @@
|
||||
parent="menu_fusion_accounting_root"
|
||||
action="action_vendor_tax_profiles"
|
||||
sequence="50"
|
||||
groups="group_fusion_accounting_manager"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_manager"/>
|
||||
|
||||
<!-- Recurring Patterns -->
|
||||
<menuitem id="menu_fusion_recurring_patterns"
|
||||
@@ -50,7 +50,7 @@
|
||||
parent="menu_fusion_accounting_root"
|
||||
action="action_recurring_patterns"
|
||||
sequence="55"
|
||||
groups="group_fusion_accounting_manager"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_manager"/>
|
||||
|
||||
<!-- Configuration (link to settings) -->
|
||||
<menuitem id="menu_fusion_config"
|
||||
@@ -58,5 +58,5 @@
|
||||
parent="menu_fusion_accounting_root"
|
||||
action="account.action_account_config"
|
||||
sequence="90"
|
||||
groups="group_fusion_accounting_admin"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_admin"/>
|
||||
</odoo>
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
<header>
|
||||
<button name="action_demote" string="Demote to Needs Approval" type="object"
|
||||
class="btn-warning" invisible="approval_tier != 'auto'"
|
||||
groups="fusion_accounting.group_fusion_accounting_admin"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_admin"/>
|
||||
<button name="action_rollback" string="Rollback to Previous Version" type="object"
|
||||
class="btn-secondary" invisible="not parent_rule_id"
|
||||
groups="fusion_accounting.group_fusion_accounting_admin"/>
|
||||
groups="fusion_accounting_core.group_fusion_accounting_admin"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Module Category -->
|
||||
<record id="module_category_fusion_accounting" model="ir.module.category">
|
||||
<field name="name">Fusion Accounting</field>
|
||||
<field name="sequence">25</field>
|
||||
</record>
|
||||
|
||||
<!-- Groups Privilege -->
|
||||
<record id="res_groups_privilege_fusion_accounting" model="res.groups.privilege">
|
||||
<field name="name">Fusion Accounting</field>
|
||||
<field name="category_id" ref="module_category_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- User Group (Staff) -->
|
||||
<record id="group_fusion_accounting_user" model="res.groups">
|
||||
<field name="name">User</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="implied_ids" eval="[(4, ref('account.group_account_user'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Manager Group -->
|
||||
<record id="group_fusion_accounting_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Admin Group -->
|
||||
<record id="group_fusion_accounting_admin" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_manager'))]"/>
|
||||
<field name="privilege_id" ref="res_groups_privilege_fusion_accounting"/>
|
||||
</record>
|
||||
|
||||
<!-- Auto-assign: Accounting users get Fusion User; Advisers get Admin -->
|
||||
<record id="account.group_account_user" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_user'))]"/>
|
||||
</record>
|
||||
<record id="account.group_account_manager" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('group_fusion_accounting_admin'))]"/>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user