[FIX] sale_project : set project's aa on sol

Steps :
Create a Project (P) :
	> Analytic Account : AA
Create a Product (A) :
	> Product Type : Service
	> Create on Order : Task
	> Project : P
Create a Product (B) :
	> Product Type : Consumable
Create and confirm a Quotation :
	> SOL > Product : A
Go to the Task consequently created.
Add B to the products.
Go back to the Quotation and create invoice.

Issue :
See Invoice Lines:
	> INVL(A)'s analytic account is AA.
	> INVL(B)'s is not set.

Cause :
To set the aa on the SOL, we use
SOL.task_id._get_task_analytic_account_id(),
which returns the task's aa or its project's.
Yet we do that only if the task has an aa.

Fix :
Call the method. If it returns something, set it on SOL.

opw-2817811

closes odoo/odoo#89660

X-original-commit: 9e7bf074c346c35325e14e14422f2d860d0db74e
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
Signed-off-by: Xavier <xbo@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-04-26 12:22:08 +02:00
parent 1d21c78946
commit c3c5c5ae72
2 changed files with 48 additions and 2 deletions
@@ -307,8 +307,9 @@ class SaleOrderLine(models.Model):
"""
values = super(SaleOrderLine, self)._prepare_invoice_line(**optional_values)
if not values.get('analytic_account_id'):
if self.task_id.analytic_account_id:
values['analytic_account_id'] = self.task_id._get_task_analytic_account_id().id
task_analytic_account = self.task_id._get_task_analytic_account_id() if self.task_id else False
if task_analytic_account:
values['analytic_account_id'] = task_analytic_account.id
elif self.project_id.analytic_account_id:
values['analytic_account_id'] = self.project_id.analytic_account_id.id
elif self.is_service and not self.is_expense:
@@ -640,3 +640,48 @@ class TestSaleService(TestCommonSaleTimesheet):
tasks = self.project_global.task_ids
for task in tasks:
self.assertEqual(task.planned_hours, planned_hours_for_uom[task.sale_line_id.name])
def test_add_product_analytic_account(self):
""" When we have a project with an analytic account and we add a product to the task,
the consequent invoice line should have the same analytic account as the project.
"""
# Ensure the SO has no analytic account to give to its SOLs
self.assertFalse(self.sale_order.analytic_account_id)
Product = self.env['product.product']
SaleOrderLine = self.env['sale.order.line']
# Create a SO with a service that creates a task
product_create = Product.create({
'name': 'Product that creates the task',
'type': 'service',
'service_type': 'timesheet',
'project_id': self.project_global.id,
'service_tracking': 'task_global_project',
})
sale_order_line_create = SaleOrderLine.create({
'order_id': self.sale_order.id,
'name': product_create.name,
'product_id': product_create.id,
'product_uom_qty': 5,
'product_uom': product_create.uom_id.id,
'price_unit': product_create.list_price,
})
self.sale_order.action_confirm()
# Add a SOL with a task_id to mimmic the "Add a product" flow on the task
product_add = Product.create({'name': 'Product added on task'})
SaleOrderLine.create({
'order_id': self.sale_order.id,
'name': product_add.name,
'product_id': product_add.id,
'product_uom_qty': 5,
'product_uom': product_add.uom_id.id,
'price_unit': product_add.list_price,
'task_id': sale_order_line_create.task_id.id,
})
self.sale_order._create_invoices()
# Check that the resulting invoice line and the project have the same analytic account
invoice_line = self.sale_order.invoice_ids.line_ids.filtered(lambda line: line.product_id == product_add)
self.assertEqual(invoice_line.analytic_account_id, self.project_global.analytic_account_id,
"SOL's analytic account should be the same as the project's")