from odoo import api, fields, models, _ from odoo.exceptions import UserError class SaveAsTemplateWizard(models.TransientModel): _name = 'sale.order.save.template.wizard' _description = 'Save Sale Order as Template' sale_order_id = fields.Many2one( 'sale.order', string='Sale Order', required=True, readonly=True, ) template_name = fields.Char( string='Template Name', required=True, ) note = fields.Html( string='Terms and Conditions', ) number_of_days = fields.Integer( string='Quotation Duration (days)', help='Number of days for the validity of quotations using this template.', ) @api.onchange('sale_order_id') def _onchange_sale_order_id(self): if self.sale_order_id: self.template_name = _('Template from %s', self.sale_order_id.name) def action_save_as_template(self): """Create a sale.order.template from the linked sale order.""" self.ensure_one() order = self.sale_order_id if not order.order_line: raise UserError(_('Cannot create a template from an order with no lines.')) # Build template line values from sale order lines template_line_vals = [] for sequence, line in enumerate(order.order_line, start=1): vals = { 'sequence': sequence * 10, } if line.display_type == 'line_section': vals.update({ 'display_type': 'line_section', 'name': line.name or '', }) elif line.display_type == 'line_note': vals.update({ 'display_type': 'line_note', 'name': line.name or '', }) else: vals.update({ 'product_id': line.product_id.id, 'name': line.name or line.product_id.name, 'product_uom_qty': line.product_uom_qty, 'product_uom_id': line.product_uom_id.id if line.product_uom_id else False, }) template_line_vals.append((0, 0, vals)) # Create the template template_vals = { 'name': self.template_name, 'sale_order_template_line_ids': template_line_vals, } if self.note: template_vals['note'] = self.note if self.number_of_days: template_vals['number_of_days'] = self.number_of_days template = self.env['sale.order.template'].create(template_vals) # Return action to open the created template return { 'name': _('Quotation Template'), 'type': 'ir.actions.act_window', 'res_model': 'sale.order.template', 'res_id': template.id, 'view_mode': 'form', 'target': 'current', }