[FIX] sale{,_expense}: bad conversion distr. keys
**Current behavior:**
Trying to post journal entries for an expense report sheet
contianing an expense that has:
A) an associated analytic distribution with
both a Project and Department, and
B) a customer to be re-invoiced (requires the expense
to be for a product which permits this operation),
attempting to post the journal entries for the approved expense
sheet will raise a ValueError.
---
**Expected behavior:**
The entries get posted to their respective accounting journals.
---
Steps to reproduce:
0. Install the Project, Accounting, Sales, Expense apps
and enable analytic accounting in the db settings
1. Create a new expense with:
A) an analytic distribution which has
both available fields filled out, and
B) a category that permits a customer to be re-invoiced
(then enter a customer)
2. Create the report, submit it to the manager, approve it,
then attempt to post the journal entries
3. This should cause the traceback, if the process was blocked
try again after deleting any tax rules in the expense
---
Cause of the issue:
The analytic_distribution field in the hr.expense module is
stored as a dictionary. During the process of recording the
journal entries, the keys are converted from a string to
integers. However, when multiple keys are in the dict, the
conversion is set up improperly and fails.
---
Fix:
Modify the conversion sequence so that multiple dict keys are
accounted for.
---
opw-3663082
closes odoo/odoo#147985
Signed-off-by: John Laterre (jol) <jol@odoo.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user