From 4c8a5b164a85bb3d4feeb89600c7dfbcdc33de10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 5 Aug 2016 14:24:21 +0200 Subject: [PATCH 1/4] [FIX][REF] website_quote: remove broken call to an old onchange website_quote still calls sale_order_line.product_id_change() in old API, giving arguments that are not supported anymore. It does not crash because 'reasons'. However the new onchange does not return values since v9. The call is therefore not necessary anymore and the computation has been adapted accordingly. --- addons/website_quote/models/order.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/addons/website_quote/models/order.py b/addons/website_quote/models/order.py index 25f47f54d47..a40df82af92 100644 --- a/addons/website_quote/models/order.py +++ b/addons/website_quote/models/order.py @@ -205,25 +205,13 @@ class sale_order(osv.osv): lines = [(5,)] quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context) for line in quote_template.quote_line: - res = self.pool.get('sale.order.line').product_id_change(cr, uid, False, - False, line.product_id.id, line.product_uom_qty, line.product_uom_id.id, line.product_uom_qty, - line.product_uom_id.id, line.name, partner, False, True, time.strftime('%Y-%m-%d'), - False, fiscal_position_id, True, context) - data = res.get('value', {}) if pricelist_id: - uom_context = context.copy() - uom_context['uom'] = line.product_uom_id.id + uom_context = dict(context, uom=line.product_uom_id.id) price = pricelist_obj.get_product_price(cr, uid, [pricelist_id], line.product_id, 1, False, context=uom_context) else: price = line.price_unit - if 'tax_id' in data: - data['tax_id'] = [(6, 0, data['tax_id'])] - else: - fpos = (fiscal_position_id and self.pool['account.fiscal.position'].browse(cr, uid, fiscal_position_id)) or False - taxes = fpos.map_tax(line.product_id.product_tmpl_id.taxes_id).ids if fpos else line.product_id.product_tmpl_id.taxes_id.ids - data['tax_id'] = [(6, 0, taxes)] - data.update({ + data = { 'name': line.name, 'price_unit': price, 'discount': line.discount, @@ -234,8 +222,17 @@ class sale_order(osv.osv): 'website_description': line.website_description, 'state': 'draft', 'customer_lead': self._get_customer_lead(cr, uid, line.product_id.product_tmpl_id), - }) + } + + if fiscal_position_id: + fpos = self.pool['account.fiscal.position'].browse(cr, uid, fiscal_position_id) + taxes = fpos.map_tax(line.product_id.product_tmpl_id.taxes_id).ids + else: + taxes = line.product_id.product_tmpl_id.taxes_id.ids + data['tax_id'] = [(6, 0, taxes)] + lines.append((0, 0, data)) + options = [] for option in quote_template.options: if pricelist_id: From 1fe106ef7ae6a1c9b6001e2cb3ebe2ef140bc708 Mon Sep 17 00:00:00 2001 From: "Denis Vermylen (dve)" Date: Thu, 7 Jul 2016 14:02:32 +0200 Subject: [PATCH 2/4] [MOV] website_quote: reorganize addon and split models according to guidelines --- addons/website_quote/__init__.py | 3 + addons/website_quote/__openerp__.py | 13 +- addons/website_quote/controllers/__init__.py | 3 + addons/website_quote/models/__init__.py | 7 +- .../website_quote/models/product_template.py | 12 ++ .../models/{order.py => sale_order.py} | 171 ------------------ addons/website_quote/models/sale_quote.py | 171 ++++++++++++++++++ .../sale_order_reports.xml} | 0 .../sale_order_templates.xml} | 0 .../website_quote_templates.xml} | 0 .../website_quote/views/sale_order_views.xml | 60 ++++++ ...ation_backend.xml => sale_quote_views.xml} | 58 ------ ...tation.xml => website_quote_templates.xml} | 0 13 files changed, 263 insertions(+), 235 deletions(-) create mode 100644 addons/website_quote/models/product_template.py rename addons/website_quote/models/{order.py => sale_order.py} (63%) create mode 100644 addons/website_quote/models/sale_quote.py rename addons/website_quote/{quotation_report.xml => report/sale_order_reports.xml} (100%) rename addons/website_quote/{views/report_saleorder.xml => report/sale_order_templates.xml} (100%) rename addons/website_quote/{views/report_quotation.xml => report/website_quote_templates.xml} (100%) create mode 100644 addons/website_quote/views/sale_order_views.xml rename addons/website_quote/views/{website_quotation_backend.xml => sale_quote_views.xml} (70%) rename addons/website_quote/views/{website_quotation.xml => website_quote_templates.xml} (100%) diff --git a/addons/website_quote/__init__.py b/addons/website_quote/__init__.py index 9f86759e32b..ac0011716f6 100644 --- a/addons/website_quote/__init__.py +++ b/addons/website_quote/__init__.py @@ -1,2 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + import controllers import models diff --git a/addons/website_quote/__openerp__.py b/addons/website_quote/__openerp__.py index f1fc19fac67..7c18b07f0c7 100644 --- a/addons/website_quote/__openerp__.py +++ b/addons/website_quote/__openerp__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. { 'name': 'Online Proposals', 'category': 'Website', @@ -11,12 +13,13 @@ Odoo Sale Quote Roller """, 'depends': ['website', 'sale', 'mail', 'payment', 'website_portal_sale', 'website_mail'], 'data': [ - 'quotation_report.xml', - 'views/website_quotation.xml', - 'views/website_quotation_backend.xml', - 'views/report_saleorder.xml', - 'views/report_quotation.xml', 'data/website_quotation_data.xml', + 'report/sale_order_reports.xml', + 'report/sale_order_templates.xml', + 'report/website_quote_templates.xml', + 'views/sale_order_views.xml', + 'views/sale_quote_views.xml', + 'views/website_quote_templates.xml', 'security/ir.model.access.csv', ], 'demo': [ diff --git a/addons/website_quote/controllers/__init__.py b/addons/website_quote/controllers/__init__.py index 8ee9bae18d9..f48716d3a69 100644 --- a/addons/website_quote/controllers/__init__.py +++ b/addons/website_quote/controllers/__init__.py @@ -1 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + import main diff --git a/addons/website_quote/models/__init__.py b/addons/website_quote/models/__init__.py index 49178edb61d..011bafd821f 100644 --- a/addons/website_quote/models/__init__.py +++ b/addons/website_quote/models/__init__.py @@ -1 +1,6 @@ -import order +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import sale_order +import sale_quote +import product_template diff --git a/addons/website_quote/models/product_template.py b/addons/website_quote/models/product_template.py new file mode 100644 index 00000000000..96f4ad4d0b4 --- /dev/null +++ b/addons/website_quote/models/product_template.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from openerp.osv import osv, fields + +class product_template(osv.Model): + _inherit = "product.template" + + _columns = { + 'website_description': fields.html('Description for the website'), # hack, if website_sale is not installed + 'quote_description': fields.html('Description for the quote'), + } diff --git a/addons/website_quote/models/order.py b/addons/website_quote/models/sale_order.py similarity index 63% rename from addons/website_quote/models/order.py rename to addons/website_quote/models/sale_order.py index a40df82af92..93b8bc922c6 100644 --- a/addons/website_quote/models/order.py +++ b/addons/website_quote/models/sale_order.py @@ -13,100 +13,6 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT from openerp.tools.translate import _, html_translate -class sale_quote_template(osv.osv): - _name = "sale.quote.template" - _description = "Sale Quotation Template" - _columns = { - 'name': fields.char('Quotation Template', required=True), - 'website_description': fields.html('Description', translate=html_translate, sanitize=False), - 'quote_line': fields.one2many('sale.quote.line', 'quote_id', 'Quotation Template Lines', copy=True), - 'note': fields.text('Terms and conditions'), - 'options': fields.one2many('sale.quote.option', 'template_id', 'Optional Products Lines', copy=True), - 'number_of_days': fields.integer('Quotation Duration', help='Number of days for the validity date computation of the quotation'), - 'require_payment': fields.selection([ - (0, 'Not mandatory on website quote validation'), - (1, 'Immediate after website order validation'), - (2, 'Immediate after website order validation and save a token'), - ], 'Payment', help="Require immediate payment by the customer when validating the order from the website quote"), - 'mail_template_id': fields.many2one('mail.template', 'Confirmation Mail', help="This e-mail template will be sent on confirmation. Leave empty to send nothing.") - } - def open_template(self, cr, uid, quote_id, context=None): - return { - 'type': 'ir.actions.act_url', - 'target': 'self', - 'url': '/quote/template/%d' % quote_id[0] - } - - -class sale_quote_line(osv.osv): - _name = "sale.quote.line" - _description = "Quotation Template Lines" - _columns = { - 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale quote lines."), - 'quote_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', required=True, ondelete='cascade', select=True), - 'name': fields.text('Description', required=True, translate=True), - 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True), - 'layout_category_id': fields.many2one('sale.layout_category', string='Section'), - 'website_description': fields.related('product_id', 'product_tmpl_id', 'quote_description', string='Line Description', type='html', translate=True), - 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), - 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), - 'product_uom_qty': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')), - 'product_uom_id': fields.many2one('product.uom', 'Unit of Measure ', required=True), - } - _order = 'sequence, id' - _defaults = { - 'product_uom_qty': 1, - 'discount': 0.0, - 'sequence': 10, - } - def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None): - vals, domain = {}, [] - product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context) - name = product_obj.name - if product_obj.description_sale: - name += '\n' + product_obj.description_sale - vals.update({ - 'price_unit': product_obj.lst_price, - 'product_uom_id': product_obj.uom_id.id, - 'website_description': product_obj and (product_obj.quote_description or product_obj.website_description) or '', - 'name': name, - 'product_uom_id': uom_id or product_obj.uom_id.id, - }) - uom_obj = self.pool.get('product.uom') - if vals['product_uom_id'] != product_obj.uom_id.id: - selected_uom = uom_obj.browse(cr, uid, vals['product_uom_id'], context=context) - new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], vals['price_unit'], selected_uom) - vals['price_unit'] = new_price - if not uom_id: - domain = {'product_uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} - return {'value': vals, 'domain': domain} - - def product_uom_change(self, cr, uid, ids, product, uom_id, context=None): - context = context or {} - if not uom_id: - return {'value': {'price_unit': 0.0, 'uom_id': False}} - return self.on_change_product_id(cr, uid, ids, product, uom_id=uom_id, context=context) - - def _inject_quote_description(self, cr, uid, values, context=None): - values = dict(values or {}) - if not values.get('website_description') and values.get('product_id'): - product = self.pool['product.product'].browse(cr, uid, values['product_id'], context=context) - values['website_description'] = product.quote_description or product.website_description or '' - return values - - def create(self, cr, uid, values, context=None): - values = self._inject_quote_description(cr, uid, values, context) - ret = super(sale_quote_line, self).create(cr, uid, values, context=context) - # hack because create don t make the job for a related field - if values.get('website_description'): - self.write(cr, uid, ret, {'website_description': values['website_description']}, context=context) - return ret - - def write(self, cr, uid, ids, values, context=None): - values = self._inject_quote_description(cr, uid, values, context) - return super(sale_quote_line, self).write(cr, uid, ids, values, context=context) - - class sale_order_line(osv.osv): _inherit = "sale.order.line" _description = "Sales Order Line" @@ -321,74 +227,6 @@ class sale_order(osv.osv): else: return 'form' -class sale_quote_option(osv.osv): - _name = "sale.quote.option" - _description = "Quotation Option" - _columns = { - 'template_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', select=True, required=True), - 'name': fields.text('Description', required=True, translate=True), - 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True), - 'layout_category_id': fields.many2one('sale.layout_category', string='Section'), - 'website_description': fields.html('Option Description', translate=html_translate, sanitize=False), - 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), - 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), - 'uom_id': fields.many2one('product.uom', 'Unit of Measure ', required=True), - 'quantity': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')), - } - _defaults = { - 'quantity': 1, - } - - @api.onchange('product_id') - def _onchange_product_id(self): - if not self.product_id: - return - product = self.product_id - self.price_unit = product.list_price - self.website_description = product.product_tmpl_id.quote_description - self.name = product.name - self.uom_id = product.uom_id - domain = {'uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)]} - return {'domain': domain} - - @api.onchange('uom_id') - def _onchange_product_uom(self): - if not self.product_id: - return - if not self.uom_id: - self.price_unit = 0.0 - return - if self.uom_id.id != self.product_id.uom_id.id: - new_price = self.product_id.uom_id._compute_price(self.price_unit, self.uom_id) - self.price_unit = new_price - - def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None): - vals, domain = {}, [] - product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context) - name = product_obj.name - if product_obj.description_sale: - name += '\n' + product_obj.description_sale - vals.update({ - 'price_unit': product_obj.list_price, - 'website_description': product_obj.product_tmpl_id.quote_description, - 'name': name, - 'uom_id': uom_id or product_obj.uom_id.id, - }) - uom_obj = self.pool.get('product.uom') - if vals['uom_id'] != product_obj.uom_id.id: - selected_uom = uom_obj.browse(cr, uid, vals['uom_id'], context=context) - new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], - vals['price_unit'], selected_uom) - vals['price_unit'] = new_price - if not uom_id: - domain = {'uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} - return {'value': vals, 'domain': domain} - - def product_uom_change(self, cr, uid, ids, product, uom_id, context=None): - if not uom_id: - return {'value': {'price_unit': 0.0, 'uom_id': False}} - return self.on_change_product_id(cr, uid, ids, product, uom_id=uom_id, context=context) - class sale_order_option(osv.osv): _name = "sale.order.option" @@ -492,12 +330,3 @@ class sale_order_option(osv.osv): self.env['sale.order.line']._compute_tax_id() self.env['sale.order.option'].write({'line_id': line}) return {'type':'ir.actions.client', 'tag':'reload'} - - -class product_template(osv.Model): - _inherit = "product.template" - - _columns = { - 'website_description': fields.html('Description for the website', sanitize=False, translate=html_translate), # hack, if website_sale is not installed - 'quote_description': fields.html('Description for the quote', sanitize=False, translate=html_translate), - } diff --git a/addons/website_quote/models/sale_quote.py b/addons/website_quote/models/sale_quote.py new file mode 100644 index 00000000000..1d5883dda9e --- /dev/null +++ b/addons/website_quote/models/sale_quote.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from openerp import api +from openerp.osv import osv, fields + +import openerp.addons.decimal_precision as dp +from openerp.tools.translate import html_translate + + +class sale_quote_template(osv.osv): + _name = "sale.quote.template" + _description = "Sale Quotation Template" + _columns = { + 'name': fields.char('Quotation Template', required=True), + 'website_description': fields.html('Description', translate=html_translate, sanitize=False), + 'quote_line': fields.one2many('sale.quote.line', 'quote_id', 'Quotation Template Lines', copy=True), + 'note': fields.text('Terms and conditions'), + 'options': fields.one2many('sale.quote.option', 'template_id', 'Optional Products Lines', copy=True), + 'number_of_days': fields.integer('Quotation Duration', help='Number of days for the validity date computation of the quotation'), + 'require_payment': fields.selection([ + (0, 'Not mandatory on website quote validation'), + (1, 'Immediate after website order validation'), + (2, 'Immediate after website order validation and save a token'), + ], 'Payment', help="Require immediate payment by the customer when validating the order from the website quote"), + 'mail_template_id': fields.many2one('mail.template', 'Confirmation Mail', help="This e-mail template will be sent on confirmation. Leave empty to send nothing.") + } + def open_template(self, cr, uid, quote_id, context=None): + return { + 'type': 'ir.actions.act_url', + 'target': 'self', + 'url': '/quote/template/%d' % quote_id[0] + } + + +class sale_quote_line(osv.osv): + _name = "sale.quote.line" + _description = "Quotation Template Lines" + _columns = { + 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale quote lines."), + 'quote_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', required=True, ondelete='cascade', select=True), + 'name': fields.text('Description', required=True, translate=True), + 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True), + 'layout_category_id': fields.many2one('sale.layout_category', string='Section'), + 'website_description': fields.related('product_id', 'product_tmpl_id', 'quote_description', string='Line Description', type='html', translate=True), + 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), + 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), + 'product_uom_qty': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')), + 'product_uom_id': fields.many2one('product.uom', 'Unit of Measure ', required=True), + } + _order = 'sequence, id' + _defaults = { + 'product_uom_qty': 1, + 'discount': 0.0, + 'sequence': 10, + } + def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None): + vals, domain = {}, [] + product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context) + name = product_obj.name + if product_obj.description_sale: + name += '\n' + product_obj.description_sale + vals.update({ + 'price_unit': product_obj.lst_price, + 'product_uom_id': product_obj.uom_id.id, + 'website_description': product_obj and (product_obj.quote_description or product_obj.website_description) or '', + 'name': name, + 'product_uom_id': uom_id or product_obj.uom_id.id, + }) + uom_obj = self.pool.get('product.uom') + if vals['product_uom_id'] != product_obj.uom_id.id: + selected_uom = uom_obj.browse(cr, uid, vals['product_uom_id'], context=context) + new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], vals['price_unit'], selected_uom) + vals['price_unit'] = new_price + if not uom_id: + domain = {'product_uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} + return {'value': vals, 'domain': domain} + + def product_uom_change(self, cr, uid, ids, product, uom_id, context=None): + context = context or {} + if not uom_id: + return {'value': {'price_unit': 0.0, 'uom_id': False}} + return self.on_change_product_id(cr, uid, ids, product, uom_id=uom_id, context=context) + + def _inject_quote_description(self, cr, uid, values, context=None): + values = dict(values or {}) + if not values.get('website_description') and values.get('product_id'): + product = self.pool['product.product'].browse(cr, uid, values['product_id'], context=context) + values['website_description'] = product.quote_description or product.website_description or '' + return values + + def create(self, cr, uid, values, context=None): + values = self._inject_quote_description(cr, uid, values, context) + ret = super(sale_quote_line, self).create(cr, uid, values, context=context) + # hack because create don t make the job for a related field + if values.get('website_description'): + self.write(cr, uid, ret, {'website_description': values['website_description']}, context=context) + return ret + + def write(self, cr, uid, ids, values, context=None): + values = self._inject_quote_description(cr, uid, values, context) + return super(sale_quote_line, self).write(cr, uid, ids, values, context=context) + + +class sale_quote_option(osv.osv): + _name = "sale.quote.option" + _description = "Quotation Option" + _columns = { + 'template_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', select=True, required=True), + 'name': fields.text('Description', required=True, translate=True), + 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True), + 'layout_category_id': fields.many2one('sale.layout_category', string='Section'), + 'website_description': fields.html('Option Description', translate=html_translate, sanitize=False), + 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), + 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), + 'uom_id': fields.many2one('product.uom', 'Unit of Measure ', required=True), + 'quantity': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')), + } + _defaults = { + 'quantity': 1, + } + + @api.onchange('product_id') + def _onchange_product_id(self): + if not self.product_id: + return + product = self.product_id + self.price_unit = product.list_price + self.website_description = product.product_tmpl_id.quote_description + self.name = product.name + self.uom_id = product.uom_id + domain = {'uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)]} + return {'domain': domain} + + @api.onchange('uom_id') + def _onchange_product_uom(self): + if not self.product_id: + return + if not self.uom_id: + self.price_unit = 0.0 + return + if self.uom_id.id != self.product_id.uom_id.id: + new_price = self.product_id.uom_id._compute_price(self.price_unit, self.uom_id) + self.price_unit = new_price + + def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None): + vals, domain = {}, [] + product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context) + name = product_obj.name + if product_obj.description_sale: + name += '\n' + product_obj.description_sale + vals.update({ + 'price_unit': product_obj.list_price, + 'website_description': product_obj.product_tmpl_id.quote_description, + 'name': name, + 'uom_id': uom_id or product_obj.uom_id.id, + }) + uom_obj = self.pool.get('product.uom') + if vals['uom_id'] != product_obj.uom_id.id: + selected_uom = uom_obj.browse(cr, uid, vals['uom_id'], context=context) + new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], + vals['price_unit'], selected_uom) + vals['price_unit'] = new_price + if not uom_id: + domain = {'uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} + return {'value': vals, 'domain': domain} + + def product_uom_change(self, cr, uid, ids, product, uom_id, context=None): + if not uom_id: + return {'value': {'price_unit': 0.0, 'uom_id': False}} + return self.on_change_product_id(cr, uid, ids, product, uom_id=uom_id, context=context) diff --git a/addons/website_quote/quotation_report.xml b/addons/website_quote/report/sale_order_reports.xml similarity index 100% rename from addons/website_quote/quotation_report.xml rename to addons/website_quote/report/sale_order_reports.xml diff --git a/addons/website_quote/views/report_saleorder.xml b/addons/website_quote/report/sale_order_templates.xml similarity index 100% rename from addons/website_quote/views/report_saleorder.xml rename to addons/website_quote/report/sale_order_templates.xml diff --git a/addons/website_quote/views/report_quotation.xml b/addons/website_quote/report/website_quote_templates.xml similarity index 100% rename from addons/website_quote/views/report_quotation.xml rename to addons/website_quote/report/website_quote_templates.xml diff --git a/addons/website_quote/views/sale_order_views.xml b/addons/website_quote/views/sale_order_views.xml new file mode 100644 index 00000000000..70561001337 --- /dev/null +++ b/addons/website_quote/views/sale_order_views.xml @@ -0,0 +1,60 @@ + + + + sale.order.form.payment + sale.order + + + +