sale_management/models/sale_order_template_line.py

115 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class SaleOrderTemplateLine(models.Model):
_name = "sale.order.template.line"
_description = "Quotation Template Line"
_order = 'sale_order_template_id, sequence, id'
_sql_constraints = [
('accountable_product_id_required',
"CHECK(display_type IS NOT NULL OR (product_id IS NOT NULL AND product_uom_id IS NOT NULL))",
"Missing required product and UoM on accountable sale quote line."),
('non_accountable_fields_null',
"CHECK(display_type IS NULL OR (product_id IS NULL AND product_uom_qty = 0 AND product_uom_id IS NULL))",
"Forbidden product, quantity and UoM on non-accountable sale quote line"),
]
sale_order_template_id = fields.Many2one(
comodel_name='sale.order.template',
string='Quotation Template Reference',
index=True, required=True,
ondelete='cascade')
sequence = fields.Integer(
string="Sequence",
help="Gives the sequence order when displaying a list of sale quote lines.",
default=10)
company_id = fields.Many2one(
related='sale_order_template_id.company_id', store=True, index=True)
product_id = fields.Many2one(
comodel_name='product.product',
check_company=True,
domain=lambda self: self._product_id_domain())
name = fields.Text(
string="Description",
compute='_compute_name',
store=True, readonly=False, precompute=True,
required=True,
translate=True)
product_uom_id = fields.Many2one(
comodel_name='uom.uom',
string="Unit of Measure",
compute='_compute_product_uom_id',
store=True, readonly=False, precompute=True,
domain="[('category_id', '=', product_uom_category_id)]")
product_uom_category_id = fields.Many2one(related='product_id.uom_id.category_id')
product_uom_qty = fields.Float(
string='Quantity',
required=True,
digits='Product Unit of Measure',
default=1)
display_type = fields.Selection([
('line_section', "Section"),
('line_note', "Note")], default=False)
#=== COMPUTE METHODS ===#
@api.depends('product_id')
def _compute_name(self):
for option in self:
if not option.product_id:
continue
option.name = option.product_id.get_product_multiline_description_sale()
@api.depends('product_id')
def _compute_product_uom_id(self):
for option in self:
option.product_uom_id = option.product_id.uom_id
#=== CRUD METHODS ===#
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('display_type', self.default_get(['display_type'])['display_type']):
vals.update(product_id=False, product_uom_qty=0, product_uom_id=False)
return super().create(vals_list)
def write(self, values):
if 'display_type' in values and self.filtered(lambda line: line.display_type != values.get('display_type')):
raise UserError(_("You cannot change the type of a sale quote line. Instead you should delete the current line and create a new line of the proper type."))
return super().write(values)
#=== BUSINESS METHODS ===#
@api.model
def _product_id_domain(self):
""" Returns the domain of the products that can be added to the template. """
return [('sale_ok', '=', True)]
def _prepare_order_line_values(self):
""" Give the values to create the corresponding order line.
:return: `sale.order.line` create values
:rtype: dict
"""
self.ensure_one()
return {
'display_type': self.display_type,
'name': self.name,
'product_id': self.product_id.id,
'product_uom_qty': self.product_uom_qty,
'product_uom': self.product_uom_id.id,
'sequence': self.sequence,
}