{"record":{"id":"48717e64ae629ef0","repo":"odoo/odoo","slug":"you-can-t-change-the-company-of-an-analytic-accoun","errorCode":null,"errorMessage":"You can't change the company of an analytic account that already has analytic items! It's a recipe for an analytical disaster!","messagePattern":"You can't change the company of an analytic account that already has analytic items! It's a recipe for an analytical disaster!","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"addons/analytic/models/analytic_account.py","lineNumber":102,"sourceCode":"    )\n    credit = fields.Monetary(\n        compute='_compute_debit_credit_balance',\n        string='Credit',\n    )\n\n    currency_id = fields.Many2one(\n        related=\"company_id.currency_id\",\n        string=\"Currency\",\n    )\n\n    @api.constrains('company_id')\n    def _check_company_consistency(self):\n        for company, accounts in groupby(self, lambda account: account.company_id):\n            if company and self.env['account.analytic.line'].sudo().search_count([\n                ('auto_account_id', 'in', [account.id for account in accounts]),\n                '!', ('company_id', 'child_of', company.id),\n            ], limit=1):\n                raise UserError(_(\"You can't change the company of an analytic account that already has analytic items! It's a recipe for an analytical disaster!\"))\n\n    @api.depends('code', 'partner_id')\n    def _compute_display_name(self):\n        for analytic in self:\n            name = analytic.name\n            if analytic.code:\n                name = f'[{analytic.code}] {name}'\n            if analytic.partner_id.commercial_partner_id.name:\n                name = f'{name} - {analytic.partner_id.commercial_partner_id.name}'\n            analytic.display_name = name\n\n    def copy_data(self, default=None):\n        default = dict(default or {})\n        vals_list = super().copy_data(default=default)\n        if 'name' not in default:\n            for account, vals in zip(self, vals_list):\n                vals['name'] = _(\"%s (copy)\", account.name)\n        return vals_list","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/odoo/odoo/blob/1e661df964b1b264c9cef3ab28430d4785be3fda/addons/analytic/models/analytic_account.py#L84-L120","documentation":"A constraint on account.analytic.account.company_id (_check_company_consistency). It blocks changing the company of analytic accounts that already have analytic lines whose company is not a child of the new company, because analytic lines would be left pointing at accounts of a different company.","triggerScenarios":"Calling write({'company_id': new_company_id}) on one or more analytic accounts that have account.analytic.line records via auto_account_id where those lines' company_id is outside the new company subtree. The search_count is done sudo(), so record rules do not shield it.","commonSituations":"Reorganizing a multi-company database (moving analytic accounts to a new company); merging companies; CSV imports or XML data that update company_id on existing analytic accounts.","solutions":["First move or delete the analytic lines referencing the account (or reassign them to a company under the target)","Create a new analytic account in the target company and move postings there instead of changing company_id","If lines are stale/test data, archive or delete them, then retry the company change"],"exampleFix":"// before\nanalytic_account.write({'company_id': new_company_id})\n// after\nlines = env['account.analytic.line'].sudo().search([('auto_account_id', '=', account.id)])\nlines.write({'company_id': new_company_id})  # or reassign\naccount.write({'company_id': new_company_id})","handlingStrategy":"validation","validationCode":"def can_change_company(env, accounts, new_company):\n    return not env['account.analytic.line'].sudo().search_count([\n        ('auto_account_id', 'in', accounts.ids),\n        '!', ('company_id', 'child_of', new_company.id),\n    ], limit=1)","typeGuard":null,"tryCatchPattern":"try:\n    account.write({'company_id': new_co.id})\nexcept UserError:\n    # move lines first, then retry\n    move_analytic_lines(account, new_co)\n    account.write({'company_id': new_co.id})","preventionTips":["Prefer creating a new account in the target company over changing company_id","Always migrate analytic lines together with account company changes"],"tags":["odoo","accounting","analytic","multi-company","constraint"],"backgroundTag":null,"analyzedSha":"1e661df964b1b264c9cef3ab28430d4785be3fda","analyzedAt":"2026-08-15T05:22:16.142Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}