This commit is contained in:
gsinghpal
2026-05-16 13:18:52 -04:00
parent 191a9c82be
commit 9ebf89bde2
1080 changed files with 0 additions and 1197 deletions

View File

@@ -0,0 +1,5 @@
from . import ir_module_module
from . import res_users
from . import account_move
from . import account_reconcile_model
from . import account_bank_statement_line

View File

@@ -0,0 +1,15 @@
"""Shared-field-ownership for account.bank.statement.line.
Enterprise's account_accountant adds cron_last_check (timestamp of the last
auto-reconcile cron run for the line). By declaring it here with the same
schema, fusion_accounting_core becomes a co-owner so the column persists
when account_accountant uninstalls.
"""
from odoo import fields, models
class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line"
cron_last_check = fields.Datetime(copy=False)

View File

@@ -0,0 +1,56 @@
"""Shared-field-ownership declarations for account.move.
Per the roadmap (Section 3.3), these fields exist in Odoo Enterprise's
account_accountant module. By declaring them here with identical schemas
and identical relation tables, fusion_accounting_core becomes a co-owner.
When Enterprise uninstalls, Odoo's module registry sees fusion still owns
the fields and preserves the columns / relation tables, so the data
(deferred revenue links, signing user, etc.) survives uninstall.
The fields here have NO compute methods, NO defaults beyond what Enterprise
provides, NO views. They're pure schema-preservation declarations. Any
business logic that operates on these fields lives in Enterprise (when
present) or in a future fusion sub-module that opts to own that behavior.
"""
from odoo import fields, models
class AccountMove(models.Model):
_inherit = "account.move"
deferred_move_ids = fields.Many2many(
comodel_name='account.move',
relation='account_move_deferred_rel',
column1='original_move_id',
column2='deferred_move_id',
copy=False,
string="Deferred Entries",
)
deferred_original_move_ids = fields.Many2many(
comodel_name='account.move',
relation='account_move_deferred_rel',
column1='deferred_move_id',
column2='original_move_id',
copy=False,
string="Original Invoices",
)
deferred_entry_type = fields.Selection(
selection=[
('expense', 'Deferred Expense'),
('revenue', 'Deferred Revenue'),
],
copy=False,
string="Deferred Entry Type",
)
signing_user = fields.Many2one(
comodel_name='res.users',
copy=False,
string="Signing User",
)
payment_state_before_switch = fields.Char(
copy=False,
string="Payment State Before Switch",
)

View File

@@ -0,0 +1,17 @@
"""Shared-field-ownership for account.reconcile.model.
Mirrors the single field Enterprise's account_accountant adds to the
Community account.reconcile.model: created_automatically.
"""
from odoo import fields, models
class AccountReconcileModel(models.Model):
_inherit = "account.reconcile.model"
created_automatically = fields.Boolean(
default=False,
copy=False,
string="Created Automatically",
)

View File

@@ -0,0 +1,55 @@
from odoo import api, models
# Modules considered "Odoo Enterprise accounting" for the purpose of feature gating.
# A client is "on Enterprise" if any of these are installed; fusion_accounting_*
# replacement modules will hide their menus when Enterprise is present (replace mode
# vs. augment mode is configurable in Settings).
ENTERPRISE_ACCOUNTING_MODULES = (
'account_accountant',
'account_reports',
'accountant',
)
class IrModuleModule(models.Model):
_inherit = "ir.module.module"
@api.model
def _fusion_is_enterprise_accounting_installed(self):
"""True if any Odoo Enterprise accounting module is installed in this DB."""
return bool(self.sudo().search_count([
('name', 'in', list(ENTERPRISE_ACCOUNTING_MODULES)),
('state', '=', 'installed'),
]))
@api.model
def _fusion_is_module_installed(self, module_name):
"""True if a specific module is installed."""
return bool(self.sudo().search_count([
('name', '=', module_name),
('state', '=', 'installed'),
]))
def button_immediate_install(self):
"""Recompute the coexistence group after install state changes."""
result = super().button_immediate_install()
self.env['res.users']._fusion_recompute_coexistence_group()
return result
def button_immediate_uninstall(self):
"""Recompute the coexistence group after uninstall state changes.
The MRO chains into fusion_accounting_migration's override (which runs
the safety guard before calling super); we recompute only after the
whole chain completes.
"""
result = super().button_immediate_uninstall()
self.env['res.users']._fusion_recompute_coexistence_group()
return result
def module_uninstall(self):
"""Recompute the coexistence group after the lower-level uninstall."""
result = super().module_uninstall()
self.env['res.users']._fusion_recompute_coexistence_group()
return result

View File

@@ -0,0 +1,53 @@
"""Coexistence group membership recomputation."""
from odoo import api, models
class ResUsers(models.Model):
_inherit = "res.users"
@api.model
def _fusion_recompute_coexistence_group(self):
"""Maintain the two coexistence groups based on Enterprise presence.
- ``group_fusion_show_when_enterprise_absent``: members = all internal
users when NO Enterprise accounting module is installed. Used to
unhide Fusion menus that would conflict with Enterprise UIs.
- ``group_fusion_show_when_enterprise_present``: members = all internal
users when AT LEAST ONE Enterprise accounting module IS installed.
Used to hide migration/transitional UIs once Enterprise has been
uninstalled (so the user doesn't see "Migrate from Enterprise" with
nothing to migrate).
The two groups are mutually exclusive at any moment in time, but a
user can transition between them as Enterprise modules are installed
or uninstalled. Idempotent; safe to call multiple times.
Called from ir.module.module.button_immediate_install / uninstall
overrides.
"""
absent_group = self.env.ref(
'fusion_accounting_core.group_fusion_show_when_enterprise_absent',
raise_if_not_found=False,
)
present_group = self.env.ref(
'fusion_accounting_core.group_fusion_show_when_enterprise_present',
raise_if_not_found=False,
)
if not absent_group and not present_group:
return
enterprise_installed = self.env['ir.module.module']._fusion_is_enterprise_accounting_installed()
all_internal = self.sudo().search([('share', '=', False)])
if enterprise_installed:
if absent_group:
absent_group.sudo().write({'user_ids': [(5, 0, 0)]})
if present_group:
present_group.sudo().write({'user_ids': [(6, 0, all_internal.ids)]})
else:
if absent_group:
absent_group.sudo().write({'user_ids': [(6, 0, all_internal.ids)]})
if present_group:
present_group.sudo().write({'user_ids': [(5, 0, 0)]})