[MERGE] forward port branch saas-11.3 up to 5f419d4ad3

This commit is contained in:
Christophe Simonis
2019-07-25 18:38:32 +02:00
7 changed files with 47 additions and 12 deletions
+5 -1
View File
@@ -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) 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: if self.pricelist_id.discount_policy == 'without_discount' and line.price_unit:
discount = (line.price_unit - price) / line.price_unit * 100 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: else:
price = line.price_unit price = line.price_unit
@@ -53,7 +53,7 @@
<div> <div>
<field name="product_uom_qty" class="oe_inline"/> <field name="product_uom_qty" class="oe_inline"/>
</div> </div>
<field name="price_unit" invisible="1"/> <field name="price_unit"/>
<label for="discount" groups="sale.group_discount_per_so_line"/> <label for="discount" groups="sale.group_discount_per_so_line"/>
<div groups="sale.group_discount_per_so_line"> <div groups="sale.group_discount_per_so_line">
<field name="discount" class="oe_inline"/> %% <field name="discount" class="oe_inline"/> %%
@@ -90,7 +90,7 @@
attrs="{'required': [('display_type', '=', False)]}" attrs="{'required': [('display_type', '=', False)]}"
/> />
<field name="discount" groups="sale.group_discount_per_so_line"/> <field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="price_unit" invisible="1"/> <field name="price_unit"/>
</tree> </tree>
</field> </field>
</page> </page>
@@ -101,7 +101,7 @@
<field name="name"/> <field name="name"/>
<field name="quantity"/> <field name="quantity"/>
<field name="uom_id" groups="uom.group_uom"/> <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"/> <field name="discount" groups="sale.group_discount_per_so_line"/>
</tree> </tree>
</field> </field>
@@ -340,6 +340,9 @@ var SnippetEditor = Widget.extend({
*/ */
_onCloneClick: function (ev) { _onCloneClick: function (ev) {
ev.preventDefault(); ev.preventDefault();
this.trigger_up('snippet_will_be_cloned', {$target: this.$target});
var $clone = this.$target.clone(false); var $clone = this.$target.clone(false);
this.trigger_up('request_history_undo_record', {$target: this.$target}); 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. * Called when the overlay dimensions/positions should be recomputed.
+1 -1
View File
@@ -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') 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_from = fields.Char('Redirect From', required=True)
url_to = fields.Char('Redirect To', 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) active = fields.Boolean(default=True)
sequence = fields.Integer() sequence = fields.Integer()
+22 -1
View File
@@ -20,6 +20,7 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
custom_events: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.custom_events || {}, { custom_events: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.custom_events || {}, {
content_will_be_destroyed: '_onContentWillBeDestroyed', content_will_be_destroyed: '_onContentWillBeDestroyed',
content_was_recreated: '_onContentWasRecreated', content_was_recreated: '_onContentWasRecreated',
snippet_will_be_cloned: '_onSnippetWillBeCloned',
snippet_cloned: '_onSnippetCloned', snippet_cloned: '_onSnippetCloned',
snippet_dropped: '_onSnippetDropped', snippet_dropped: '_onSnippetDropped',
}), }),
@@ -146,9 +147,22 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
$target: ev.data.$target, $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 * 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 * @private
* @param {OdooEvent} ev * @param {OdooEvent} ev
@@ -158,6 +172,13 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
editableMode: true, editableMode: true,
$target: ev.data.$target, $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 * Called when a snippet is dropped in the page. Notifies the WebsiteRoot
+5 -3
View File
@@ -349,9 +349,11 @@ class WebsiteSale(ProductConfiguratorController):
@http.route(['/shop/pricelist'], type='http', auth="public", website=True, sitemap=False) @http.route(['/shop/pricelist'], type='http', auth="public", website=True, sitemap=False)
def pricelist(self, promo, **post): def pricelist(self, promo, **post):
redirect = post.get('r', '/shop/cart') redirect = post.get('r', '/shop/cart')
pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1) # empty promo code is used to reset/remove pricelist (see `sale_get_order()`)
if not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id)): if promo:
return request.redirect("%s?code_not_available=1" % redirect) 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) request.website.sale_get_order(code=promo)
return request.redirect(redirect) return request.redirect(redirect)
+7 -2
View File
@@ -17,7 +17,7 @@ its sub-called methods.
.. code:: python .. code:: python
from odoo.tools.profiler import profile from odoo.tools.misc import profile
[...] [...]
@profile('/temp/prof.profile') @profile('/temp/prof.profile')
@api.multi @api.multi
@@ -37,10 +37,15 @@ A tool called *xdot* will display the resulting graph:
xdot /temp/prof.xdot 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 .. code:: python
from odoo.tools.profiler import profile
[...]
@profile @profile
@api.model @api.model
def mymethod(...): def mymethod(...):