132 lines
6.0 KiB
Python
132 lines
6.0 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 ValidationError
|
|
|
|
|
|
class SaleOrderTemplate(models.Model):
|
|
_name = "sale.order.template"
|
|
_description = "Quotation Template"
|
|
|
|
active = fields.Boolean(
|
|
default=True,
|
|
help="If unchecked, it will allow you to hide the quotation template without removing it.")
|
|
company_id = fields.Many2one(comodel_name='res.company')
|
|
|
|
name = fields.Char(string="Quotation Template", required=True)
|
|
note = fields.Html(string="Terms and conditions", translate=True)
|
|
|
|
mail_template_id = fields.Many2one(
|
|
comodel_name='mail.template',
|
|
string="Confirmation Mail",
|
|
domain=[('model', '=', 'sale.order')],
|
|
help="This e-mail template will be sent on confirmation. Leave empty to send nothing.")
|
|
number_of_days = fields.Integer(
|
|
string="Quotation Duration",
|
|
help="Number of days for the validity date computation of the quotation")
|
|
|
|
require_signature = fields.Boolean(
|
|
string="Online Signature",
|
|
compute='_compute_require_signature',
|
|
store=True, readonly=False,
|
|
help="Request a online signature to the customer in order to confirm orders automatically.")
|
|
require_payment = fields.Boolean(
|
|
string="Online Payment",
|
|
compute='_compute_require_payment',
|
|
store=True, readonly=False,
|
|
help="Request an online payment to the customer in order to confirm orders automatically.")
|
|
prepayment_percent = fields.Float(
|
|
string="Prepayment percentage",
|
|
compute="_compute_prepayment_percent",
|
|
store=True, readonly=False,
|
|
help="The percentage of the amount needed to be paid to confirm quotations.")
|
|
|
|
sale_order_template_line_ids = fields.One2many(
|
|
comodel_name='sale.order.template.line', inverse_name='sale_order_template_id',
|
|
string="Lines",
|
|
copy=True)
|
|
sale_order_template_option_ids = fields.One2many(
|
|
comodel_name='sale.order.template.option', inverse_name='sale_order_template_id',
|
|
string="Optional Products",
|
|
copy=True)
|
|
journal_id = fields.Many2one(
|
|
'account.journal', string="Invoicing Journal",
|
|
domain=[('type', '=', 'sale')], company_dependent=True, check_company=True,
|
|
help="If set, SO with this template will invoice in this journal; "
|
|
"otherwise the sales journal with the lowest sequence is used.")
|
|
|
|
#=== COMPUTE METHODS ===#
|
|
|
|
@api.depends('company_id')
|
|
def _compute_require_signature(self):
|
|
for order in self:
|
|
order.require_signature = (order.company_id or order.env.company).portal_confirmation_sign
|
|
|
|
@api.depends('company_id')
|
|
def _compute_require_payment(self):
|
|
for order in self:
|
|
order.require_payment = (order.company_id or order.env.company).portal_confirmation_pay
|
|
|
|
@api.depends('company_id', 'require_payment')
|
|
def _compute_prepayment_percent(self):
|
|
for template in self:
|
|
template.prepayment_percent = (
|
|
template.company_id or template.env.company
|
|
).prepayment_percent
|
|
|
|
#=== ONCHANGE METHODS ===#
|
|
|
|
@api.onchange('prepayment_percent')
|
|
def _onchange_prepayment_percent(self):
|
|
for template in self:
|
|
if not template.prepayment_percent:
|
|
template.require_payment = False
|
|
|
|
#=== CONSTRAINT METHODS ===#
|
|
|
|
@api.constrains('company_id', 'sale_order_template_line_ids', 'sale_order_template_option_ids')
|
|
def _check_company_id(self):
|
|
for template in self:
|
|
companies = template.mapped('sale_order_template_line_ids.product_id.company_id') | template.mapped('sale_order_template_option_ids.product_id.company_id')
|
|
if len(companies) > 1:
|
|
raise ValidationError(_("Your template cannot contain products from multiple companies."))
|
|
elif companies and companies != template.company_id:
|
|
raise ValidationError(_(
|
|
"Your template contains products from company %(product_company)s whereas your template belongs to company %(template_company)s. \n Please change the company of your template or remove the products from other companies.",
|
|
product_company=', '.join(companies.mapped('display_name')),
|
|
template_company=template.company_id.display_name,
|
|
))
|
|
|
|
@api.constrains('prepayment_percent')
|
|
def _check_prepayment_percent(self):
|
|
for template in self:
|
|
if template.require_payment and not (0 < template.prepayment_percent <= 1.0):
|
|
raise ValidationError(_("Prepayment percentage must be a valid percentage."))
|
|
|
|
#=== CRUD METHODS ===#
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
records = super().create(vals_list)
|
|
records._update_product_translations()
|
|
return records
|
|
|
|
def write(self, vals):
|
|
if 'active' in vals and not vals.get('active'):
|
|
companies = self.env['res.company'].sudo().search([('sale_order_template_id', 'in', self.ids)])
|
|
companies.sale_order_template_id = None
|
|
result = super().write(vals)
|
|
self._update_product_translations()
|
|
return result
|
|
|
|
def _update_product_translations(self):
|
|
languages = self.env['res.lang'].search([('active', '=', 'true')])
|
|
for lang in languages:
|
|
for line in self.sale_order_template_line_ids:
|
|
if line.name == line.product_id.get_product_multiline_description_sale():
|
|
line.with_context(lang=lang.code).name = line.product_id.with_context(lang=lang.code).get_product_multiline_description_sale()
|
|
for option in self.sale_order_template_option_ids:
|
|
if option.name == option.product_id.get_product_multiline_description_sale():
|
|
option.with_context(lang=lang.code).name = option.product_id.with_context(lang=lang.code).get_product_multiline_description_sale()
|