diff --git a/addons/sale/models/account_move_line.py b/addons/sale/models/account_move_line.py index 3c45dc1ffbc..3020463ee2d 100644 --- a/addons/sale/models/account_move_line.py +++ b/addons/sale/models/account_move_line.py @@ -155,12 +155,15 @@ class AccountMoveLine(models.Model): for move_line in self: if move_line.analytic_distribution: distribution_json = move_line.analytic_distribution - sale_order = self.env['sale.order'].search([('analytic_account_id', 'in', list(int(account_id) for account_id in distribution_json.keys())), + account_ids = [int(account_id) for key in distribution_json.keys() for account_id in key.split(',')] + + sale_order = self.env['sale.order'].search([('analytic_account_id', 'in', account_ids), ('state', '=', 'sale')], order='create_date ASC', limit=1) if sale_order: mapping[move_line.id] = sale_order else: - sale_order = self.env['sale.order'].search([('analytic_account_id', 'in', list(int(account_id) for account_id in distribution_json.keys()))], order='create_date ASC', limit=1) + sale_order = self.env['sale.order'].search([('analytic_account_id', 'in', account_ids)], + order='create_date ASC', limit=1) mapping[move_line.id] = sale_order # map of AAL index with the SO on which it needs to be reinvoiced. Maybe be None if no SO found diff --git a/addons/sale_expense/tests/test_sale_expense.py b/addons/sale_expense/tests/test_sale_expense.py index 084ba03f1c1..4081e7baef6 100644 --- a/addons/sale_expense/tests/test_sale_expense.py +++ b/addons/sale_expense/tests/test_sale_expense.py @@ -1,5 +1,5 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import Command +from odoo import Command, fields from odoo.addons.hr_expense.tests.common import TestExpenseCommon from odoo.addons.sale.tests.common import TestSaleCommon from odoo.tests import tagged @@ -97,3 +97,55 @@ class TestSaleExpense(TestExpenseCommon, TestSaleCommon): # both expenses should be invoiced inv = so._create_invoices() self.assertEqual(inv.amount_untaxed, 621.5 + (prod_exp_2.list_price * 100.0), 'Sale Expense: invoicing of expense is wrong') + + def test_expense_multi_id_analytic_distribution(self): + """ + Test conversion of analytic_distribution dict into account numbers when a hr.expense.sheet containing + a hr.expense with an analytic_distribution having 2+ account ids + """ + expensed_product = self.env['product.product'].create({ + 'name': 'test product', + 'can_be_expensed': True, + 'detailed_type': 'service', + 'invoice_policy': 'order', + 'standard_price': 100, + 'expense_policy': 'cost', + }) + + sale_order = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'order_line': [Command.create({'product_id': self.product_b.id})], + }) + sale_order.action_confirm() + sale_order._create_invoices() + + analytic_account_3 = self.env['account.analytic.account'].create({ + 'name': 'analytic_account_3', + 'plan_id': self.analytic_plan.id, + }) + + expense_sheet = self.env['hr.expense.sheet'].create({ + 'name': 'Test Expense Report', + 'employee_id': self.expense_employee.id, + 'company_id': self.company_data['company'].id, + 'expense_line_ids': [Command.create({ + 'employee_id': self.expense_employee.id, + 'product_id': expensed_product.id, + 'quantity': 1000.00, + 'date': fields.Date.today(), + 'company_id': self.company_data['company'].id, + 'currency_id': self.company_data['currency'].id, + 'analytic_distribution': { + f'{self.analytic_account_1.id},{self.analytic_account_2.id}': 60, + f'{analytic_account_3.id}': 40, + }, + 'sale_order_id': sale_order.id, + })], + }) + expense_sheet.action_submit_sheet() + expense_sheet.action_approve_expense_sheets() + expense_sheet.action_sheet_move_create() + + self.assertTrue(self.env['account.move'].search([('expense_sheet_id', '=', expense_sheet.id)], limit=1))