[IMP] sale_project: link project analytic account to invoice
Previously when a user added products to a task, when invoicing the customer, in default case, no analytic account was defined on the invoice line generated for the sale order line. With this commit, we define a default analytic account based on the information of the sale order line. If the sale order line has a generated task or project associated to it, we set the project analytic account. If the sale order line is used on tasks or projects which all use the same analytic account, then the invoice line created will take this unique analytic account as default value. If a sale order line is used in distinct project or tasks from distinct project, then no default analytic account is defined. PR : #70527 task-2458135
This commit is contained in:
committed by
Laurent Stukkens (LTU)
parent
2915a939a8
commit
d4a0bcaa5a
@@ -12,7 +12,7 @@ class Project(models.Model):
|
||||
|
||||
sale_line_id = fields.Many2one(
|
||||
'sale.order.line', 'Sales Order Item', copy=False,
|
||||
compute="_compute_sale_line_id", store=True, readonly=False,
|
||||
compute="_compute_sale_line_id", store=True, readonly=False, index=True,
|
||||
domain="[('is_service', '=', True), ('is_expense', '=', False), ('state', 'in', ['sale', 'done']), ('order_partner_id', '=?', partner_id), '|', ('company_id', '=', False), ('company_id', '=', company_id)]",
|
||||
help="Sales order item to which the project is linked. Link the timesheet entry to the sales order item defined on the project. "
|
||||
"Only applies on tasks without sale order item defined, and if the employee is not in the 'Employee/Sales Order Item Mapping' of the project.")
|
||||
@@ -61,7 +61,7 @@ class ProjectTask(models.Model):
|
||||
sale_order_id = fields.Many2one('sale.order', 'Sales Order', compute='_compute_sale_order_id', store=True, help="Sales order to which the task is linked.")
|
||||
sale_line_id = fields.Many2one(
|
||||
'sale.order.line', 'Sales Order Item', domain="[('company_id', '=', company_id), ('is_service', '=', True), ('order_partner_id', 'child_of', commercial_partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done'])]",
|
||||
compute='_compute_sale_line', recursive=True, store=True, readonly=False, copy=False, tracking=True,
|
||||
compute='_compute_sale_line', recursive=True, store=True, readonly=False, copy=False, tracking=True, index=True,
|
||||
help="Sales Order Item to which the time spent on this task will be added, in order to be invoiced to your customer.")
|
||||
project_sale_order_id = fields.Many2one('sale.order', string="Project's sale order", related='project_id.sale_order_id')
|
||||
invoice_count = fields.Integer("Number of invoices", related='sale_order_id.invoice_count')
|
||||
|
||||
@@ -353,3 +353,24 @@ class SaleOrderLine(models.Model):
|
||||
project = map_so_project[so_line.order_id.id]
|
||||
if not so_line.task_id:
|
||||
so_line._timesheet_create_task(project=project)
|
||||
|
||||
def _prepare_invoice_line(self, **optional_values):
|
||||
"""
|
||||
If the sale order line isn't linked to a sale order which already have a default analytic account,
|
||||
this method allows to retrieve the analytic account which is linked to project or task directly linked
|
||||
to this sale order line, or the analytic account of the project which uses this sale order line, if it exists.
|
||||
"""
|
||||
values = super(SaleOrderLine, self)._prepare_invoice_line(**optional_values)
|
||||
if not values['analytic_account_id']:
|
||||
if self.project_id.analytic_account_id:
|
||||
values['analytic_account_id'] = self.project_id.analytic_account_id
|
||||
elif self.task_id.project_id.analytic_account_id:
|
||||
values['analytic_account_id'] = self.task_id.project_id.analytic_account_id
|
||||
elif self.is_service and not self.is_expense:
|
||||
project_analytic_account_id = self.env['project.project'].read_group([
|
||||
'|', ('sale_line_id', '=', self.id), ('task_ids.sale_line_id', '=', self.id)
|
||||
], ['analytic_account_id'], ['analytic_account_id'])
|
||||
analytic_account_ids = {rec['analytic_account_id'][0] for rec in project_analytic_account_id}
|
||||
if len(analytic_account_ids) == 1:
|
||||
values['analytic_account_id'] = analytic_account_ids.pop()
|
||||
return values
|
||||
|
||||
Reference in New Issue
Block a user