diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index 523fad6b108..94df2d0c965 100644 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from ast import literal_eval + from odoo import api, fields, models, _ from odoo.exceptions import ValidationError @@ -38,6 +40,8 @@ class ProjectTask(models.Model): "and if this employee is not in the 'Employee/Sales Order Item Mapping' of the project, the " "timesheet entry will be linked to this sales order item.") 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') + task_to_invoice = fields.Boolean("To invoice", compute='_compute_task_to_invoice', search='_search_task_to_invoice', groups='sales_team.group_sale_salesman_all_leads') @api.depends('project_id.sale_line_id.order_partner_id') def _compute_partner_id(self): @@ -96,3 +100,42 @@ class ProjectTask(models.Model): if partner: return partner return super().rating_get_partner_id() + + @api.depends('sale_order_id.invoice_status', 'sale_order_id.order_line') + def _compute_task_to_invoice(self): + for task in self: + if task.sale_order_id: + task.task_to_invoice = bool(task.sale_order_id.invoice_status not in ('no', 'invoiced')) + else: + task.task_to_invoice = False + + @api.model + def _search_task_to_invoice(self, operator, value): + query = """ + SELECT so.id + FROM sale_order so + WHERE so.invoice_status != 'invoiced' + AND so.invoice_status != 'no' + """ + operator_new = 'inselect' + if(bool(operator == '=') ^ bool(value)): + operator_new = 'not inselect' + return [('sale_order_id', operator_new, (query, ()))] + + def action_create_invoice(self): + # ensure the SO exists before invoicing, then confirm it + so_to_confirm = self.filtered( + lambda task: task.sale_order_id and task.sale_order_id.state in ['draft', 'sent'] + ).mapped('sale_order_id') + so_to_confirm.action_confirm() + + # redirect create invoice wizard (of the Sales Order) + action = self.env.ref('sale.action_view_sale_advance_payment_inv').read()[0] + context = literal_eval(action.get('context', "{}")) + context.update({ + 'active_id': self.sale_order_id.id if len(self) == 1 else False, + 'active_ids': self.mapped('sale_order_id').ids, + 'default_company_id': self.company_id.id, + }) + action['context'] = context + return action diff --git a/addons/sale_project/views/project_task_views.xml b/addons/sale_project/views/project_task_views.xml index 4ccd0f8b9c9..d45fdd10d26 100644 --- a/addons/sale_project/views/project_task_views.xml +++ b/addons/sale_project/views/project_task_views.xml @@ -56,6 +56,22 @@ + + + + + + + + + + Create invoice + + + code + + if records: + action = records.action_create_invoice()