# Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import models class HrExpense(models.Model): _inherit = "hr.expense" def _compute_analytic_distribution(self): super()._compute_analytic_distribution() if not self.env.context.get('project_id'): expenses_to_recompute = self.env['hr.expense'] prefetch_ids = set() for expense in self.filtered('sale_order_id'): expenses_to_recompute += expense prefetch_ids.update(self.env['analytic.mixin']._get_analytic_account_ids_from_distributions(expense.analytic_distribution)) prefetch_ids.update(self.env['analytic.mixin']._get_analytic_account_ids_from_distributions(expense.sale_order_id.project_id._get_analytic_distribution())) if expenses_to_recompute: analytic_account_model = self.env['account.analytic.account'].with_prefetch(prefetch_ids) for expense in expenses_to_recompute: expense_account_ids = self.env['analytic.mixin']._get_analytic_account_ids_from_distributions(expense.analytic_distribution) project_analytic_distribution = expense.sale_order_id.project_id._get_analytic_distribution() project_account_ids = self.env['analytic.mixin']._get_analytic_account_ids_from_distributions(project_analytic_distribution) project_analytic_distribution_accounts = self.env['account.analytic.account'].browse(project_account_ids) expense_analytic_accounts = analytic_account_model.browse(expense_account_ids) if not any(project_account.root_plan_id in expense_analytic_accounts.root_plan_id for project_account in project_analytic_distribution_accounts): # If it is possible we keep both analytic distributions expense.analytic_distribution = { **(expense.analytic_distribution or {}), **(project_analytic_distribution or {}) } else: # If not we keep the most prioritized one -> project expense.analytic_distribution = expense.sale_order_id.project_id._get_analytic_distribution() or expense.analytic_distribution or {} def action_post(self): """ When creating the move of the expense, if the AA is given in the project of the SO, we take it as reference in the distribution. Otherwise, we create a AA for the project of the SO and set the distribution to it. """ for expense in self: project = expense.sale_order_id.project_id if not project or expense.analytic_distribution: continue if not project.account_id: project._create_analytic_account() expense.analytic_distribution = project._get_analytic_distribution() return super().action_post()