diff --git a/addons/account/models/account_analytic_account.py b/addons/account/models/account_analytic_account.py index 9334690a8d3..a80a2f5e9ef 100644 --- a/addons/account/models/account_analytic_account.py +++ b/addons/account/models/account_analytic_account.py @@ -41,10 +41,16 @@ class AccountAnalyticAccount(models.Model): def action_view_invoice(self): self.ensure_one() + query = self.env['account.move.line']._search([('move_id.move_type', 'in', self.env['account.move'].get_sale_types())]) + query.order = None + query.add_where('analytic_distribution ? %s', [str(self.id)]) + query_string, query_param = query.select('DISTINCT move_id') + self._cr.execute(query_string, query_param) + move_ids = [line.get('move_id') for line in self._cr.dictfetchall()] result = { "type": "ir.actions.act_window", "res_model": "account.move", - "domain": [('line_ids.analytic_distribution_stored_char', '=ilike', f'%"{self.id}":%'), ('move_type', 'in', self.env['account.move'].get_sale_types())], + "domain": [('id', 'in', move_ids)], "context": {"create": False}, "name": "Customer Invoices", 'view_mode': 'tree,form', @@ -53,10 +59,16 @@ class AccountAnalyticAccount(models.Model): def action_view_vendor_bill(self): self.ensure_one() + query = self.env['account.move.line']._search([('move_id.move_type', 'in', self.env['account.move'].get_purchase_types())]) + query.order = None + query.add_where('analytic_distribution ? %s', [str(self.id)]) + query_string, query_param = query.select('DISTINCT move_id') + self._cr.execute(query_string, query_param) + move_ids = [line.get('move_id') for line in self._cr.dictfetchall()] result = { "type": "ir.actions.act_window", "res_model": "account.move", - "domain": [('line_ids.analytic_distribution_stored_char', '=ilike', f'%"{self.id}":%'), ('move_type', 'in', self.env['account.move'].get_purchase_types())], + "domain": [('id', 'in', move_ids)], "context": {"create": False}, "name": "Vendor Bills", 'view_mode': 'tree,form', diff --git a/addons/account/models/account_move_line.py b/addons/account/models/account_move_line.py index c1aca329d27..a82511bed55 100644 --- a/addons/account/models/account_move_line.py +++ b/addons/account/models/account_move_line.py @@ -15,7 +15,7 @@ INTEGRITY_HASH_LINE_FIELDS = ('debit', 'credit', 'account_id', 'partner_id') class AccountMoveLine(models.Model): _name = "account.move.line" - _inherit = 'analytic.mixin' + _inherit = "analytic.mixin" _description = "Journal Item" _order = "date desc, move_name desc, sequence, id" _check_company_auto = True @@ -352,6 +352,9 @@ class AccountMoveLine(models.Model): comodel_name='account.analytic.line', inverse_name='move_line_id', string='Analytic lines', ) + analytic_distribution = fields.Json( + inverse="_inverse_analytic_distribution", + ) # add the inverse function used to trigger the creation/update of the analytic lines accordingly (field originally defined in the analytic mixin) # === Early Pay fields === # discount_date = fields.Date( @@ -1071,10 +1074,10 @@ class AccountMoveLine(models.Model): line.term_key = False @api.depends('account_id', 'partner_id', 'product_id') - def _compute_analytic_distribution_stored_char(self): + def _compute_analytic_distribution(self): for line in self: if line.display_type == 'product' or not line.move_id.is_invoice(include_receipts=True): - distribution = self.env['account.analytic.distribution.model']._get_distributionjson({ + distribution = self.env['account.analytic.distribution.model']._get_distribution({ "product_id": line.product_id.id, "product_categ_id": line.product_id.categ_id.id, "partner_id": line.partner_id.id, @@ -1082,8 +1085,7 @@ class AccountMoveLine(models.Model): "account_prefix": line.account_id.code, "company_id": line.company_id.id, }) - line.analytic_distribution_stored_char = distribution or line.analytic_distribution_stored_char - line._compute_analytic_distribution() + line.analytic_distribution = distribution or line.analytic_distribution # ------------------------------------------------------------------------- # INVERSE METHODS @@ -1125,7 +1127,6 @@ class AccountMoveLine(models.Model): @api.onchange('analytic_distribution') def _inverse_analytic_distribution(self): """ Unlink and recreate analytic_lines when modifying the distribution.""" - super()._inverse_analytic_distribution() lines_to_modify = self.env['account.move.line'].browse([ line.id for line in self if line.parent_state == "posted" ]) @@ -2365,7 +2366,6 @@ class AccountMoveLine(models.Model): def _prepare_analytic_lines(self): self.ensure_one() analytic_line_vals = [] - self._compute_analytic_distribution() if self.analytic_distribution: # distribution_on_each_plan corresponds to the proportion that is distributed to each plan to be able to # give the real amount when we achieve a 100% distribution diff --git a/addons/account/models/account_move_line_tax_details.py b/addons/account/models/account_move_line_tax_details.py index 9b0254eeb01..11b4b8c20d2 100644 --- a/addons/account/models/account_move_line_tax_details.py +++ b/addons/account/models/account_move_line_tax_details.py @@ -182,8 +182,8 @@ class AccountMoveLine(models.Model): ) AND ( NOT tax.analytic - OR (base_line.analytic_distribution_stored_char IS NULL AND account_move_line.analytic_distribution_stored_char IS NULL) - OR base_line.analytic_distribution_stored_char = account_move_line.analytic_distribution_stored_char + OR (base_line.analytic_distribution IS NULL AND account_move_line.analytic_distribution IS NULL) + OR base_line.analytic_distribution = account_move_line.analytic_distribution ) LEFT JOIN affecting_base_tax_ids tax_line_tax_ids ON tax_line_tax_ids.id = account_move_line.id JOIN affecting_base_tax_ids base_line_tax_ids ON base_line_tax_ids.id = base_line.id diff --git a/addons/account/tests/test_account_analytic.py b/addons/account/tests/test_account_analytic.py index 18eb98ce5cb..02f7d2a2054 100644 --- a/addons/account/tests/test_account_analytic.py +++ b/addons/account/tests/test_account_analytic.py @@ -21,10 +21,12 @@ class TestAccountAnalyticAccount(AccountTestInvoicingCommon): cls.analytic_account_a = cls.env['account.analytic.account'].create({ 'name': 'analytic_account_a', 'plan_id': cls.default_plan.id, + 'company_id': False, }) cls.analytic_account_b = cls.env['account.analytic.account'].create({ 'name': 'analytic_account_b', 'plan_id': cls.default_plan.id, + 'company_id': False, }) def create_invoice(self, partner, product): @@ -123,7 +125,7 @@ class TestAccountAnalyticAccount(AccountTestInvoicingCommon): # Partner and product match, score 2 invoice = self.create_invoice(self.partner_a, self.product_a) - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_b.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_b.id): 100}) # Match the partner but not the product, score 0 invoice = self.create_invoice(self.partner_a, self.product_b) @@ -131,7 +133,7 @@ class TestAccountAnalyticAccount(AccountTestInvoicingCommon): # Product match, score 1 invoice = self.create_invoice(self.partner_b, self.product_a) - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_a.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_a.id): 100}) # No rule match with the product, score 0 invoice = self.create_invoice(self.partner_b, self.product_b) @@ -141,10 +143,12 @@ class TestAccountAnalyticAccount(AccountTestInvoicingCommon): """Test that the distribution is recomputed if and only if it is needed when changing the partner.""" self.env['account.analytic.distribution.model'].create([{ 'partner_id': self.partner_a.id, - 'analytic_distribution': {self.analytic_account_a.id: 100} + 'analytic_distribution': {self.analytic_account_a.id: 100}, + 'company_id': False, }, { 'partner_id': self.partner_b.id, - 'analytic_distribution': {self.analytic_account_b.id: 100} + 'analytic_distribution': {self.analytic_account_b.id: 100}, + 'company_id': False, }]) invoice = self.create_invoice(self.env['res.partner'], self.product_a) @@ -153,27 +157,27 @@ class TestAccountAnalyticAccount(AccountTestInvoicingCommon): # A model is found, set the new values invoice.partner_id = self.partner_a - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_a.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_a.id): 100}) # A model is found, set the new values invoice.partner_id = self.partner_b - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_b.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_b.id): 100}) # No model is found, don't change previously set values invoice.partner_id = invoice.company_id.partner_id - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_b.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_b.id): 100}) # No model is found, don't change previously set values invoice.partner_id = False - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_b.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_b.id): 100}) # It manual value is not erased in form view when saving with Form(invoice) as invoice_form: invoice_form.partner_id = self.partner_a with invoice_form.invoice_line_ids.edit(0) as line_form: - self.assertEqual(line_form.analytic_distribution, {self.analytic_account_a.id: 100}) + self.assertEqual(line_form.analytic_distribution, {str(self.analytic_account_a.id): 100}) line_form.analytic_distribution = {self.analytic_account_b.id: 100} - self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {self.analytic_account_b.id: 100}) + self.assertEqual(invoice.invoice_line_ids.analytic_distribution, {str(self.analytic_account_b.id): 100}) def test_mandatory_plan_validation(self): invoice = self.create_invoice(self.partner_b, self.product_a) diff --git a/addons/account/tests/test_account_move_out_invoice.py b/addons/account/tests/test_account_move_out_invoice.py index f6f0e12823b..d5c742ed818 100644 --- a/addons/account/tests/test_account_move_out_invoice.py +++ b/addons/account/tests/test_account_move_out_invoice.py @@ -1173,7 +1173,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'code': 'TEST' }) - analytic_distribution = {analytic_account.id: 100} + analytic_distribution = {str(analytic_account.id): 100.00} move_form = Form(self.invoice) with move_form.invoice_line_ids.edit(0) as line_form: @@ -1291,7 +1291,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'code': 'TEST1' }) - analytic_distribution = {analytic_account.id: 100} + analytic_distribution = {str(analytic_account.id): 100.00} self.invoice.write({'invoice_line_ids': [(1, self.invoice.invoice_line_ids.ids[0], { 'analytic_distribution': analytic_distribution, diff --git a/addons/account/tests/test_templates_consistency.py b/addons/account/tests/test_templates_consistency.py index f37cc317891..c139044e585 100644 --- a/addons/account/tests/test_templates_consistency.py +++ b/addons/account/tests/test_templates_consistency.py @@ -78,7 +78,7 @@ class AccountingTestTemplConsistency(TransactionCase): ) # lines self.check_fields_consistency('account.reconcile.model.line.template', 'account.reconcile.model.line', exceptions=['chart_template_id']) - self.check_fields_consistency('account.reconcile.model.line', 'account.reconcile.model.line.template', exceptions=['company_id', 'journal_id', 'analytic_distribution_stored_char', 'amount']) + self.check_fields_consistency('account.reconcile.model.line', 'account.reconcile.model.line.template', exceptions=['company_id', 'journal_id', 'analytic_distribution', 'amount']) def test_account_group_fields(self): '''Test fields consistency for ('account.group', 'account.group.template') diff --git a/addons/account/views/account_move_views.xml b/addons/account/views/account_move_views.xml index 6235d49e0e1..3a5b5e386fe 100644 --- a/addons/account/views/account_move_views.xml +++ b/addons/account/views/account_move_views.xml @@ -70,7 +70,6 @@ - @@ -187,7 +186,6 @@ - - -