changes
This commit is contained in:
2
fusion_templates/__init__.py
Normal file
2
fusion_templates/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import models
|
||||
from . import wizard
|
||||
22
fusion_templates/__manifest__.py
Normal file
22
fusion_templates/__manifest__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
'name': 'Fusion Templates',
|
||||
'version': '19.0.1.0.0',
|
||||
'summary': 'Save any sale order as a reusable quotation template',
|
||||
'description': """
|
||||
Adds a "Save as Template" option in the gear menu on sale orders
|
||||
that creates a quotation template from the current order,
|
||||
preserving all product lines, sections, and notes.
|
||||
""",
|
||||
'category': 'Sales/Sales',
|
||||
'author': 'Fusion',
|
||||
'license': 'LGPL-3',
|
||||
'depends': ['sale_management'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/save_as_template_wizard_views.xml',
|
||||
'views/sale_order_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'auto_install': False,
|
||||
}
|
||||
1
fusion_templates/models/__init__.py
Normal file
1
fusion_templates/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import sale_order
|
||||
19
fusion_templates/models/sale_order.py
Normal file
19
fusion_templates/models/sale_order.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from odoo import models
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = 'sale.order'
|
||||
|
||||
def action_save_as_template(self):
|
||||
"""Open wizard to save this sale order as a quotation template."""
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': 'Save as Template',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'sale.order.save.template.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_sale_order_id': self.id,
|
||||
},
|
||||
}
|
||||
2
fusion_templates/security/ir.model.access.csv
Normal file
2
fusion_templates/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_save_template_wizard,sale.order.save.template.wizard,model_sale_order_save_template_wizard,sale_management.group_sale_order_template,1,1,1,1
|
||||
|
14
fusion_templates/views/sale_order_views.xml
Normal file
14
fusion_templates/views/sale_order_views.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Gear menu action only -->
|
||||
<record id="action_save_as_template_server" model="ir.actions.server">
|
||||
<field name="name">Save as Template</field>
|
||||
<field name="model_id" ref="sale.model_sale_order"/>
|
||||
<field name="binding_model_id" ref="sale.model_sale_order"/>
|
||||
<field name="binding_view_types">form</field>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = record.action_save_as_template()</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
1
fusion_templates/wizard/__init__.py
Normal file
1
fusion_templates/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import save_as_template_wizard
|
||||
88
fusion_templates/wizard/save_as_template_wizard.py
Normal file
88
fusion_templates/wizard/save_as_template_wizard.py
Normal file
@@ -0,0 +1,88 @@
|
||||
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',
|
||||
}
|
||||
24
fusion_templates/wizard/save_as_template_wizard_views.xml
Normal file
24
fusion_templates/wizard/save_as_template_wizard_views.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="save_as_template_wizard_form" model="ir.ui.view">
|
||||
<field name="name">sale.order.save.template.wizard.form</field>
|
||||
<field name="model">sale.order.save.template.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Save as Template">
|
||||
<group>
|
||||
<field name="sale_order_id" invisible="1"/>
|
||||
<field name="template_name" placeholder="e.g. Standard IT Equipment Package"/>
|
||||
<field name="number_of_days"/>
|
||||
<field name="note" placeholder="Optional terms and conditions..."/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_save_as_template"
|
||||
type="object"
|
||||
string="Save Template"
|
||||
class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user