[MERGE] forward port branch 10.0 up to 2198220947

This commit is contained in:
Christophe Simonis
2017-10-18 14:34:32 +02:00
13 changed files with 108 additions and 11 deletions
+8
View File
@@ -264,6 +264,14 @@ class Lead(models.Model):
# ORM override (CRUD, fields_view_get, ...)
# ----------------------------------------
@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
+1 -2
View File
@@ -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),
+1 -1
View File
@@ -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')
+1 -1
View File
@@ -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
+22
View File
@@ -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 () {
@@ -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;
+1
View File
@@ -4,3 +4,4 @@
import sale_order
import sale_quote
import product_template
import ir_model_fields
@@ -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()
+6
View File
@@ -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
@@ -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
+3 -3
View File
@@ -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}" />
+1 -1
View File
@@ -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"
1 id country_id:id name code
534 state_ca_bc ca British Columbia BC
535 state_ca_mb ca Manitoba MB
536 state_ca_nb ca New Brunswick NB
537 state_ca_nl ca Newfoundland Newfoundland and Labrador NL
538 state_ca_nt ca Northwest Territories NT
539 state_ca_ns ca Nova Scotia NS
540 state_ca_nu ca Nunavut NU
@@ -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):