[IMP] sale_project : add create invoice server action to project

The possibility to create invoices from project tasks was being
introduced in industry_fsm_sale. This moves the server action to
sale_project.

Task-2191253

closes odoo/odoo#45650

Related: odoo/enterprise#8530
Related: odoo/upgrade#808
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
jdoutreloux
2020-03-10 10:17:55 +00:00
parent 724e0e498d
commit 69b1e1a052
2 changed files with 59 additions and 0 deletions
+43
View File
@@ -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
@@ -56,6 +56,22 @@
<xpath expr="//field[@name='stage_id']" position="before">
<field name="sale_order_id" string="Sale Order" filter_domain="['|', ('sale_order_id', 'ilike', self), ('sale_line_id', 'ilike', self)]"/>
</xpath>
<filter name="inactive" position="before">
<filter string="To Invoice" name="to_invoice" domain="[('task_to_invoice', '=', True)]" groups="sales_team.group_sale_salesman" />
<separator/>
</filter>
</field>
</record>
<!-- To invoice batch action -->
<record id="project_task_server_action_batch_invoice" model="ir.actions.server">
<field name="name">Create invoice</field>
<field name="model_id" ref="project.model_project_task"/>
<field name="binding_model_id" ref="project.model_project_task"/>
<field name="state">code</field>
<field name="code">
if records:
action = records.action_create_invoice()
</field>
</record>