forked from Mapan/odoo17e
108 lines
4.8 KiB
Python
108 lines
4.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from collections import defaultdict
|
|
|
|
from odoo import api, models, fields, _
|
|
from odoo.tools import float_is_zero
|
|
|
|
class SaleOrder(models.Model):
|
|
_inherit = ['sale.order']
|
|
|
|
task_id = fields.Many2one('project.task', string="Task", help="Task from which this quotation have been created")
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
orders = super().create(vals)
|
|
for sale_order in orders:
|
|
if sale_order.task_id:
|
|
message = _("Extra Quotation Created: %s", sale_order._get_html_link())
|
|
sale_order.task_id.message_post(body=message)
|
|
return orders
|
|
|
|
@api.returns('mail.message', lambda value: value.id)
|
|
def message_post(self, **kwargs):
|
|
if self.env.context.get('fsm_no_message_post'):
|
|
return False
|
|
return super().message_post(**kwargs)
|
|
|
|
def action_confirm(self):
|
|
res = super().action_confirm()
|
|
for sale_order in self:
|
|
if sale_order.task_id:
|
|
message = _("This Sales Order has been created from Task: %s", sale_order.task_id._get_html_link())
|
|
sale_order.message_post(body=message)
|
|
return res
|
|
|
|
def _get_product_catalog_record_lines(self, product_ids):
|
|
"""
|
|
Accessing the catalog from the smart button of a "field service" should compute
|
|
the content of the catalog related to that field service rather than the content
|
|
of the catalog related to the sale order containing that "field service".
|
|
"""
|
|
task_id = self.env.context.get('fsm_task_id')
|
|
if task_id:
|
|
grouped_lines = defaultdict(lambda: self.env['sale.order.line'])
|
|
for line in self.order_line:
|
|
if line.task_id.id == task_id and line.product_id.id in product_ids:
|
|
grouped_lines[line.product_id] |= line
|
|
return grouped_lines
|
|
return super()._get_product_catalog_record_lines(product_ids)
|
|
|
|
|
|
class SaleOrderLine(models.Model):
|
|
_inherit = ['sale.order.line']
|
|
|
|
delivered_price_subtotal = fields.Monetary(compute='_compute_delivered_amount', string='Delivered Subtotal')
|
|
delivered_price_tax = fields.Float(compute='_compute_delivered_amount', string='Delivered Total Tax')
|
|
delivered_price_total = fields.Monetary(compute='_compute_delivered_amount', string='Delivered Total')
|
|
|
|
@api.depends('qty_delivered', 'discount', 'price_unit', 'tax_id')
|
|
def _compute_delivered_amount(self):
|
|
"""
|
|
Compute the amounts of the SO line for delivered quantity.
|
|
"""
|
|
for line in self:
|
|
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
|
taxes = line.tax_id.compute_all(price, line.order_id.currency_id, line.qty_delivered, product=line.product_id, partner=line.order_id.partner_shipping_id)
|
|
line.delivered_price_tax = sum(t.get('amount', 0.0) for t in taxes.get('taxes', []))
|
|
line.delivered_price_total = taxes['total_included']
|
|
line.delivered_price_subtotal = taxes['total_excluded']
|
|
|
|
def _timesheet_create_task_prepare_values(self, project):
|
|
res = super(SaleOrderLine, self)._timesheet_create_task_prepare_values(project)
|
|
if project.is_fsm:
|
|
res.update({'partner_id': self.order_id.partner_shipping_id.id})
|
|
return res
|
|
|
|
def _timesheet_create_project_prepare_values(self):
|
|
"""Generate project values"""
|
|
values = super(SaleOrderLine, self)._timesheet_create_project_prepare_values()
|
|
if self.product_id.project_template_id.is_fsm:
|
|
values.pop('sale_line_id', False)
|
|
return values
|
|
|
|
def _compute_invoice_status(self):
|
|
sol_from_task_without_amount = self.filtered(
|
|
lambda sol:
|
|
sol.task_id.is_fsm
|
|
and float_is_zero(sol.price_unit, precision_rounding=sol.currency_id.rounding)
|
|
and sol.invoice_status in (None, 'to_invoice')
|
|
)
|
|
sol_from_task_without_amount.invoice_status = 'no'
|
|
super(SaleOrderLine, self - sol_from_task_without_amount)._compute_invoice_status()
|
|
|
|
@api.depends('price_unit')
|
|
def _compute_qty_to_invoice(self):
|
|
sol_from_task_without_amount = self.filtered(
|
|
lambda sol:
|
|
sol.task_id.is_fsm
|
|
and float_is_zero(sol.price_unit, precision_rounding=sol.currency_id.rounding)
|
|
)
|
|
sol_from_task_without_amount.qty_to_invoice = 0.0
|
|
super(SaleOrderLine, self - sol_from_task_without_amount)._compute_qty_to_invoice()
|
|
|
|
def action_add_from_catalog(self):
|
|
if len(self.task_id) == 1 and self.task_id.allow_material:
|
|
return self.task_id.action_fsm_view_material()
|
|
return super().action_add_from_catalog()
|