summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/crm/models/crm_lead.py8
-rw-r--r--addons/point_of_sale/static/src/js/models.js3
-rw-r--r--addons/sale/models/sale.py2
-rw-r--r--addons/stock/models/stock_move.py2
-rw-r--r--addons/web_editor/static/src/js/rte.js22
-rw-r--r--addons/web_editor/static/src/less/web_editor.common.less4
-rw-r--r--addons/website_quote/models/__init__.py1
-rw-r--r--addons/website_quote/models/ir_model_fields.py35
-rw-r--r--addons/website_sale/models/product.py6
-rw-r--r--addons/website_sale/static/src/js/website_sale_payment.js4
-rw-r--r--addons/website_sale/views/templates.xml6
-rw-r--r--odoo/addons/base/res/res.country.state.csv2
-rw-r--r--odoo/addons/test_new_api/tests/test_new_fields.py24
13 files changed, 108 insertions, 11 deletions
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index 5aa384f3ae3..a85fb466c90 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -265,6 +265,14 @@ class Lead(models.Model):
# ----------------------------------------
@api.model
+ def name_create(self, name):
+ res = super(Lead, self).name_create(name)
+
+ # update the probability of the lead if the stage is set to update it automatically
+ self.browse(res[0])._onchange_stage_id()
+ return res
+
+ @api.model
def create(self, vals):
# set up context used to find the lead's sales channel which is needed
# to correctly set the default stage_id
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 27281342cde..043188b6393 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1475,7 +1475,7 @@ exports.Orderline = Backbone.Model.extend({
var recompute_base = function(base_amount, fixed_amount, percent_amount){
if(fixed_amount === 0.0 && percent_amount === 0.0)
return base_amount;
- return round_pr((base_amount - fixed_amount) / (1.0 + percent_amount / 100.0), currency_rounding);
+ return (base_amount - fixed_amount) / (1.0 + percent_amount / 100.0);
}
// 4) Iterate the taxes in the reversed sequence order to retrieve the initial base of the computation.
@@ -1529,7 +1529,6 @@ exports.Orderline = Backbone.Model.extend({
taxes_vals.push(tax_vals);
});
-
return {
taxes: taxes_vals,
total_excluded: round_pr(total_excluded, currency_rounding_bak),
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index 79899961997..e176f9314d7 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -864,7 +864,7 @@ class SaleOrderLine(models.Model):
return price
else:
from_currency = self.order_id.company_id.currency_id
- return from_currency.compute(product[pricelist_item.base], self.order_id.pricelist_id.currency_id)
+ return from_currency.compute(pricelist_item and product[pricelist_item.base] or product.lst_price, self.order_id.pricelist_id.currency_id)
@api.multi
@api.onchange('product_id')
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 30c988954d7..3c359c93b25 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -971,7 +971,7 @@ class StockMove(models.Model):
self._propagate_split(new_move, qty)
# returning the first element of list returned by action_confirm is ok because we checked it wouldn't be exploded (and
# thus the result of action_confirm should always be a list of 1 element length)
- new_move.action_confirm()
+ new_move = new_move.action_confirm()
# TDE FIXME: due to action confirm change
return new_move.id
diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js
index c7dc268251d..13eb568f9b7 100644
--- a/addons/web_editor/static/src/js/rte.js
+++ b/addons/web_editor/static/src/js/rte.js
@@ -578,6 +578,28 @@ var RTE = Widget.extend({
_.defer(function () {
self.historyRecordUndo($target, 'activate', true);
});
+
+ // To Fix Google Chrome Tripleclick Issue, which selects the ending
+ // whitespace characters (so Tripleclicking then typing text will remove
+ // the whole paragraph instead of its content).
+ // http://stackoverflow.com/questions/38467334/why-does-google-chrome-always-add-space-after-selected-text
+ if ($.browser.chrome === true && event.originalEvent.detail === 3) {
+ var currentSelection = range.create();
+ if (currentSelection.sc.parentNode === currentSelection.ec) {
+ _selectSC(currentSelection);
+ } else if (currentSelection.eo === 0) {
+ var $hasNext = $(currentSelection.sc).parent();
+ while (!$hasNext.next().length && !$hasNext.is('body')) {
+ $hasNext = $hasNext.parent();
+ }
+ if ($hasNext.next()[0] === currentSelection.ec) {
+ _selectSC(currentSelection);
+ }
+ }
+ }
+ function _selectSC(selection) {
+ range.create(selection.sc, selection.so, selection.sc, selection.sc.length).select();
+ }
},
editable: function () {
diff --git a/addons/web_editor/static/src/less/web_editor.common.less b/addons/web_editor/static/src/less/web_editor.common.less
index 9cef6b8e32f..7a6dc37da3a 100644
--- a/addons/web_editor/static/src/less/web_editor.common.less
+++ b/addons/web_editor/static/src/less/web_editor.common.less
@@ -24,7 +24,9 @@ html, body {
/* ----- GENERIC LAYOUTING HELPERS ---- */
/* table */
#wrapwrap, .o_editable {
- table.table {
+ // Only style editor-made tables (shop/portal/... tables are not supposed to
+ // use table-bordered...)
+ table.table.table-bordered {
table-layout: fixed;
td {
min-width: 20px;
diff --git a/addons/website_quote/models/__init__.py b/addons/website_quote/models/__init__.py
index 011bafd821f..a83051f5a10 100644
--- a/addons/website_quote/models/__init__.py
+++ b/addons/website_quote/models/__init__.py
@@ -4,3 +4,4 @@
import sale_order
import sale_quote
import product_template
+import ir_model_fields
diff --git a/addons/website_quote/models/ir_model_fields.py b/addons/website_quote/models/ir_model_fields.py
new file mode 100644
index 00000000000..55643edfe0d
--- /dev/null
+++ b/addons/website_quote/models/ir_model_fields.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+
+# !! Attention, this is a hack of a hack, do not try this at home !!
+# This is done because website_quote defines the website_description
+# field which is also defined by website_sale, but these two modules
+# are independent of each other, the part of the ORM that generates
+# xmlids does not support this case therefore it only creates a single
+# pair of xmlids for whichever module is installed first, therefore
+# when uninstalling any of the two modules the website_descripion field
+# will be deleted from the db and the other module won't be able to
+# use this field, resulting in a crash and data-loss.
+# See opw-776464 for more details.
+#
+# This is hotfixed by overriding the unlink method so as to not delete
+# the website_description field if website_quote is uninstalled, it's
+# an ugly hack but it works and big changes can't be done to the ORM
+# in stable versions, Odoo v12+ will properly fix this
+
+
+class IrModelFields(models.Model):
+ _inherit = "ir.model.fields"
+
+ @api.multi
+ def unlink(self):
+ # Prevent the deletion of the field "website_description"
+ self = self.filtered(
+ lambda rec: not (
+ rec.model in ('product.product', 'product.template') and
+ rec.name == 'website_description'
+ )
+ )
+ return super(IrModelFields, self).unlink()
diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py
index 6c50e86c2b1..8d33629e927 100644
--- a/addons/website_sale/models/product.py
+++ b/addons/website_sale/models/product.py
@@ -3,6 +3,7 @@
from odoo import api, fields, models, tools, _
import odoo.addons.decimal_precision as dp
from odoo.tools.translate import html_translate
+from odoo.tools import float_is_zero
class ProductStyle(models.Model):
@@ -139,6 +140,7 @@ class ProductTemplate(models.Model):
website_price = fields.Float('Website price', compute='_website_price', digits=dp.get_precision('Product Price'))
website_public_price = fields.Float('Website public price', compute='_website_price', digits=dp.get_precision('Product Price'))
+ website_price_difference = fields.Boolean('Website price difference', compute='_website_price')
def _website_price(self):
# First filter out the ones that have no variant:
@@ -148,6 +150,7 @@ class ProductTemplate(models.Model):
for template, product in zip(self, self.mapped('product_variant_id')):
template.website_price = product.website_price
template.website_public_price = product.website_public_price
+ template.website_price_difference = product.website_price_difference
def _default_website_sequence(self):
self._cr.execute("SELECT MIN(website_sequence) FROM %s" % self._table)
@@ -188,6 +191,7 @@ class Product(models.Model):
website_price = fields.Float('Website price', compute='_website_price', digits=dp.get_precision('Product Price'))
website_public_price = fields.Float('Website public price', compute='_website_price', digits=dp.get_precision('Product Price'))
+ website_price_difference = fields.Boolean('Website price difference', compute='_website_price')
def _website_price(self):
qty = self._context.get('quantity', 1.0)
@@ -204,6 +208,8 @@ class Product(models.Model):
for p, p2 in zip(self, self2):
taxes = partner.property_account_position_id.map_tax(p.taxes_id.sudo().filtered(lambda x: x.company_id == company_id))
p.website_price = taxes.compute_all(p2.price, pricelist.currency_id, quantity=qty, product=p2, partner=partner)[ret]
+ price_without_pricelist = taxes.compute_all(p.list_price, pricelist.currency_id)[ret]
+ p.website_price_difference = False if float_is_zero(price_without_pricelist - p.website_price, precision_rounding=pricelist.currency_id.rounding) else True
p.website_public_price = taxes.compute_all(p2.lst_price, quantity=qty, product=p2, partner=partner)[ret]
@api.multi
diff --git a/addons/website_sale/static/src/js/website_sale_payment.js b/addons/website_sale/static/src/js/website_sale_payment.js
index 526145bba8d..8923483fb61 100644
--- a/addons/website_sale/static/src/js/website_sale_payment.js
+++ b/addons/website_sale/static/src/js/website_sale_payment.js
@@ -6,10 +6,10 @@ var ajax = require('web.ajax');
$(document).ready(function () {
// If option is enable
if ($("#checkbox_cgv").length) {
- var enabling_button = function() {
+ $("#checkbox_cgv").change(function() {
$("div.oe_sale_acquirer_button").find('input, button').prop("disabled", !this.checked);
};
- $("#checkbox_cgv").click(enabling_button).each(enabling_button);
+ $('#checkbox_cgv').trigger('change');
}
// When choosing an acquirer, display its Pay Now button
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 39881863c45..f18aa0c31a8 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -102,7 +102,7 @@
</h5>
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" class="product_price" t-if="product.product_variant_ids">
<b>
- <t t-if="(compute_currency(product.lst_price) - product.website_price ) &gt; 0.01 and website.get_current_pricelist().discount_policy=='without_discount'">
+ <t t-if="product.website_price_difference and website.get_current_pricelist().discount_policy=='without_discount'">
<del class="text-danger mr8" style="white-space: nowrap;" t-esc="compute_currency(product.website_public_price)" t-options="{'widget': 'monetary', 'display_currency': website.get_current_pricelist().currency_id, 'from_currency': website.currency_id}" />
</t>
@@ -593,7 +593,7 @@
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" class="product_price mt16">
<h4 class="oe_price_h4 css_editable_mode_hidden">
<span class="text-danger oe_default_price" style="text-decoration: line-through; white-space: nowrap;"
- t-esc="compute_currency(product.website_public_price)" t-options="{'widget': 'monetary', 'display_currency': website.get_current_pricelist().currency_id, 'from_currency': website.currency_id}" t-att-style="'text-decoration: line-through; white-space: nowrap; ' + '' if (compute_currency(product.lst_price) - product.website_price) &gt; 0.01 and website.get_current_pricelist().discount_policy == 'without_discount' else 'display: none;'"
+ t-esc="compute_currency(product.website_public_price)" t-options="{'widget': 'monetary', 'display_currency': website.get_current_pricelist().currency_id, 'from_currency': website.currency_id}" t-att-style="'text-decoration: line-through; white-space: nowrap; ' + '' if product.website_price_difference and website.get_current_pricelist().discount_policy == 'without_discount' else 'display: none;'"
/>
<b class="oe_price" style="white-space: nowrap;" t-esc="product.website_price" t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
<span itemprop="price" style="display:none;" t-esc="product.website_price"/>
@@ -1003,7 +1003,7 @@
<div class="text-muted hidden-xs" t-field="product.description_sale" />
</td>
<td class='td-price'>
- <t t-if="(compute_currency(product.lst_price) - product.website_price) &gt; 0.01 and website.get_current_pricelist().discount_policy=='without_discount'">
+ <t t-if="product.website_price_difference and website.get_current_pricelist().discount_policy=='without_discount'">
<del class="text-danger mr8" style="white-space: nowrap;" t-field="product.lst_price" t-options="{'widget': 'monetary','from_currency': product.currency_id, 'display_currency': website.currency_id}" />
</t>
<span t-field="product.website_price" style="white-space: nowrap;" t-options="{'widget': 'monetary','display_currency': website.currency_id}" />
diff --git a/odoo/addons/base/res/res.country.state.csv b/odoo/addons/base/res/res.country.state.csv
index d87a1318daa..c48ed49141d 100644
--- a/odoo/addons/base/res/res.country.state.csv
+++ b/odoo/addons/base/res/res.country.state.csv
@@ -534,7 +534,7 @@ state_ca_ab,ca,"Alberta","AB"
state_ca_bc,ca,"British Columbia","BC"
state_ca_mb,ca,"Manitoba","MB"
state_ca_nb,ca,"New Brunswick","NB"
-state_ca_nl,ca,"Newfoundland","NL"
+state_ca_nl,ca,"Newfoundland and Labrador","NL"
state_ca_nt,ca,"Northwest Territories","NT"
state_ca_ns,ca,"Nova Scotia","NS"
state_ca_nu,ca,"Nunavut","NU"
diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py
index dc5b9936c7a..df8f7ba4f2d 100644
--- a/odoo/addons/test_new_api/tests/test_new_fields.py
+++ b/odoo/addons/test_new_api/tests/test_new_fields.py
@@ -721,6 +721,30 @@ class TestFields(common.TransactionCase):
self.assertEqual(len(discussion.important_messages), 2)
self.assertEqual(len(discussion.very_important_messages), 2)
+ def test_70_x2many_write(self):
+ discussion = self.env.ref('test_new_api.discussion_0')
+ Message = self.env['test_new_api.message']
+ # There must be 3 messages, 0 important
+ self.assertEqual(len(discussion.messages), 3)
+ self.assertEqual(len(discussion.important_messages), 0)
+ self.assertEqual(len(discussion.very_important_messages), 0)
+ discussion.important_messages = [(0, 0, {
+ 'body': 'What is the answer?',
+ 'important': True,
+ })]
+ # There must be 4 messages, 1 important
+ self.assertEqual(len(discussion.messages), 4)
+ self.assertEqual(len(discussion.important_messages), 1)
+ self.assertEqual(len(discussion.very_important_messages), 1)
+ discussion.very_important_messages |= Message.new({
+ 'body': '42',
+ 'important': True,
+ })
+ # There must be 5 messages, 2 important
+ self.assertEqual(len(discussion.messages), 5)
+ self.assertEqual(len(discussion.important_messages), 2)
+ self.assertEqual(len(discussion.very_important_messages), 2)
+
class TestHtmlField(common.TransactionCase):