diff options
| -rw-r--r-- | addons/sale_management/models/sale_order.py | 6 | ||||
| -rw-r--r-- | addons/sale_management/views/sale_order_template_views.xml | 6 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/editor/snippets.editor.js | 5 | ||||
| -rw-r--r-- | addons/website/models/website.py | 2 | ||||
| -rw-r--r-- | addons/website/static/src/js/menu/edit.js | 23 | ||||
| -rw-r--r-- | addons/website_sale/controllers/main.py | 8 | ||||
| -rw-r--r-- | doc/howtos/profilecode.rst | 9 |
7 files changed, 47 insertions, 12 deletions
diff --git a/addons/sale_management/models/sale_order.py b/addons/sale_management/models/sale_order.py index 6a95dfeaeeb..1b8562b1c54 100644 --- a/addons/sale_management/models/sale_order.py +++ b/addons/sale_management/models/sale_order.py @@ -72,7 +72,11 @@ class SaleOrder(models.Model): price = self.pricelist_id.with_context(uom=line.product_uom_id.id).get_product_price(line.product_id, 1, False) if self.pricelist_id.discount_policy == 'without_discount' and line.price_unit: discount = (line.price_unit - price) / line.price_unit * 100 - price = line.price_unit + # negative discounts (= surcharge) are included in the display price + if discount < 0: + discount = 0 + else: + price = line.price_unit else: price = line.price_unit diff --git a/addons/sale_management/views/sale_order_template_views.xml b/addons/sale_management/views/sale_order_template_views.xml index 2260c7e2b0e..a95654e03d8 100644 --- a/addons/sale_management/views/sale_order_template_views.xml +++ b/addons/sale_management/views/sale_order_template_views.xml @@ -53,7 +53,7 @@ <div> <field name="product_uom_qty" class="oe_inline"/> </div> - <field name="price_unit" invisible="1"/> + <field name="price_unit"/> <label for="discount" groups="sale.group_discount_per_so_line"/> <div groups="sale.group_discount_per_so_line"> <field name="discount" class="oe_inline"/> %% @@ -90,7 +90,7 @@ attrs="{'required': [('display_type', '=', False)]}" /> <field name="discount" groups="sale.group_discount_per_so_line"/> - <field name="price_unit" invisible="1"/> + <field name="price_unit"/> </tree> </field> </page> @@ -101,7 +101,7 @@ <field name="name"/> <field name="quantity"/> <field name="uom_id" groups="uom.group_uom"/> - <field name="price_unit" invisible="1"/> + <field name="price_unit"/> <field name="discount" groups="sale.group_discount_per_so_line"/> </tree> </field> diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 51beb939648..776d9992bb7 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -340,6 +340,9 @@ var SnippetEditor = Widget.extend({ */ _onCloneClick: function (ev) { ev.preventDefault(); + + this.trigger_up('snippet_will_be_cloned', {$target: this.$target}); + var $clone = this.$target.clone(false); this.trigger_up('request_history_undo_record', {$target: this.$target}); @@ -355,7 +358,7 @@ var SnippetEditor = Widget.extend({ } }, }); - this.trigger_up('snippet_cloned', {$target: $clone}); + this.trigger_up('snippet_cloned', {$target: $clone, $origin: this.$target}); }, /** * Called when the overlay dimensions/positions should be recomputed. diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 295d6484df5..a5f4202e4a2 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -1331,6 +1331,6 @@ class WebsiteRedirect(models.Model): type = fields.Selection([('301', 'Moved permanently (301)'), ('302', 'Moved temporarily (302)')], string='Redirection Type', required=True, default='301') url_from = fields.Char('Redirect From', required=True) url_to = fields.Char('Redirect To', required=True) - website_id = fields.Many2one('website', 'Website') + website_id = fields.Many2one('website', 'Website', ondelete='cascade') active = fields.Boolean(default=True) sequence = fields.Integer() diff --git a/addons/website/static/src/js/menu/edit.js b/addons/website/static/src/js/menu/edit.js index a3015a78a6a..6591b51738d 100644 --- a/addons/website/static/src/js/menu/edit.js +++ b/addons/website/static/src/js/menu/edit.js @@ -20,6 +20,7 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ custom_events: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.custom_events || {}, { content_will_be_destroyed: '_onContentWillBeDestroyed', content_was_recreated: '_onContentWasRecreated', + snippet_will_be_cloned: '_onSnippetWillBeCloned', snippet_cloned: '_onSnippetCloned', snippet_dropped: '_onSnippetDropped', }), @@ -147,8 +148,21 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ }); }, /** + * Called when a snippet is about to be cloned in the page. Notifies the + * WebsiteRoot that is should destroy the animations for this snippet. + * + * @private + * @param {OdooEvent} ev + */ + _onSnippetWillBeCloned: function (ev) { + this.trigger_up('animation_stop_demand', { + $target: ev.data.$target, + }); + }, + /** * Called when a snippet is cloned in the page. Notifies the WebsiteRoot - * that is should start the animations for this snippet. + * that is should start the animations for this snippet and the snippet it + * was cloned from. * * @private * @param {OdooEvent} ev @@ -158,6 +172,13 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ editableMode: true, $target: ev.data.$target, }); + // TODO: remove in saas-12.5, undefined $origin will restart #wrapwrap + if (ev.data.$origin) { + this.trigger_up('animation_start_demand', { + editableMode: true, + $target: ev.data.$origin, + }); + } }, /** * Called when a snippet is dropped in the page. Notifies the WebsiteRoot diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 0d11c1856d9..dbd12ecb48d 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -349,9 +349,11 @@ class WebsiteSale(ProductConfiguratorController): @http.route(['/shop/pricelist'], type='http', auth="public", website=True, sitemap=False) def pricelist(self, promo, **post): redirect = post.get('r', '/shop/cart') - pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1) - if not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id)): - return request.redirect("%s?code_not_available=1" % redirect) + # empty promo code is used to reset/remove pricelist (see `sale_get_order()`) + if promo: + pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1) + if (not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id))): + return request.redirect("%s?code_not_available=1" % redirect) request.website.sale_get_order(code=promo) return request.redirect(redirect) diff --git a/doc/howtos/profilecode.rst b/doc/howtos/profilecode.rst index ed6d2640648..d21c1f3891c 100644 --- a/doc/howtos/profilecode.rst +++ b/doc/howtos/profilecode.rst @@ -17,7 +17,7 @@ its sub-called methods. .. code:: python - from odoo.tools.profiler import profile + from odoo.tools.misc import profile [...] @profile('/temp/prof.profile') @api.multi @@ -37,10 +37,15 @@ A tool called *xdot* will display the resulting graph: xdot /temp/prof.xdot -The profiler can be also used without saving data in a file: +Log a method +============ + +Another profiler can be used to log statistics on a method: .. code:: python + from odoo.tools.profiler import profile + [...] @profile @api.model def mymethod(...): |
