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 9a486d958c0..badca4074d1 100644
--- a/addons/web_editor/static/src/js/editor/snippets.editor.js
+++ b/addons/web_editor/static/src/js/editor/snippets.editor.js
@@ -341,6 +341,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});
@@ -356,7 +359,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 4f9af477383..79b8072b283 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -908,6 +908,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 40da42a82d4..9270afe26af 100644
--- a/addons/website/static/src/js/menu/edit.js
+++ b/addons/website/static/src/js/menu/edit.js
@@ -19,6 +19,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',
}),
@@ -115,9 +116,22 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
$target: ev.data.$target,
});
},
+ /**
+ * 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
@@ -127,6 +141,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_quote/models/sale_order.py b/addons/website_quote/models/sale_order.py
index e5e24874615..789f2514255 100644
--- a/addons/website_quote/models/sale_order.py
+++ b/addons/website_quote/models/sale_order.py
@@ -123,7 +123,11 @@ class SaleOrder(models.Model):
price = self.pricelist_id.with_context(uom=line.product_uom_id.id).get_product_price(line.product_id, line.product_uom_qty, 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/website_quote/views/sale_quote_views.xml b/addons/website_quote/views/sale_quote_views.xml
index 5750dc207c3..1aa75b377ae 100644
--- a/addons/website_quote/views/sale_quote_views.xml
+++ b/addons/website_quote/views/sale_quote_views.xml
@@ -49,7 +49,7 @@