summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-10-31 16:29:07 +0100
committerChristophe Simonis <chs@odoo.com>2017-10-31 16:29:07 +0100
commit8f1e2044cd9dd0e3d5ab29f7527efdb0a9c7a582 (patch)
treeb531c2fbd3a85855c6691cb707435a3db89162e3 /addons
parentc8b2f5ca9ec0bbb5af06be8f8cf93122d08c41fe (diff)
parent810b6aa7600bad6bba4d0fc67f04ecf4975193d5 (diff)
[MERGE] forward port branch saas-16 up to 810b6aa7600
Diffstat (limited to 'addons')
-rw-r--r--addons/account/models/chart_template.py6
-rw-r--r--addons/account_asset/models/account_asset.py2
-rw-r--r--addons/crm/wizard/base_partner_merge_views.xml2
-rw-r--r--addons/l10n_fr/__init__.py5
-rw-r--r--addons/l10n_fr/__manifest__.py1
-rw-r--r--addons/l10n_lu/__init__.py5
-rw-r--r--addons/l10n_lu/__manifest__.py1
-rw-r--r--addons/l10n_no/__init__.py5
-rw-r--r--addons/l10n_no/__manifest__.py1
-rw-r--r--addons/l10n_pl/__init__.py5
-rw-r--r--addons/l10n_pl/__manifest__.py1
-rw-r--r--addons/l10n_sg/__init__.py5
-rw-r--r--addons/l10n_sg/__manifest__.py1
-rw-r--r--addons/l10n_th/__init__.py5
-rw-r--r--addons/l10n_th/__manifest__.py1
-rw-r--r--addons/l10n_vn/__init__.py5
-rw-r--r--addons/l10n_vn/__manifest__.py3
-rw-r--r--addons/mrp/report/mrp_production_templates.xml3
-rw-r--r--addons/point_of_sale/static/src/js/chrome.js8
-rw-r--r--addons/point_of_sale/static/src/js/db.js8
-rw-r--r--addons/product/models/product.py2
-rw-r--r--addons/sale/models/sale.py2
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js13
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js32
-rw-r--r--addons/website_event/views/event_templates.xml2
-rw-r--r--addons/website_event_track/views/event_track_templates.xml4
-rw-r--r--addons/website_sale/models/website.py5
-rw-r--r--addons/website_slides/views/website_slides_embed.xml4
28 files changed, 115 insertions, 22 deletions
diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py
index 66dc46d7c3d..c86747b194f 100644
--- a/addons/account/models/chart_template.py
+++ b/addons/account/models/chart_template.py
@@ -43,6 +43,12 @@ def migrate_tags_on_taxes(cr, registry):
if len(tax_id.ids) == 1:
tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]})
+def preserve_existing_tags_on_taxes(cr, registry, module):
+ ''' This is a utility function used to preserve existing previous tags during upgrade of the module.'''
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ xml_records = env['ir.model.data'].search([('model', '=', 'account.account.tag'), ('module', 'like', module)])
+ if xml_records:
+ cr.execute("update ir_model_data set noupdate = 't' where id in %s", [tuple(xml_records.ids)])
# ---------------------------------------------------------------
# Account Templates: Account, Tax, Tax Code and chart. + Wizard
diff --git a/addons/account_asset/models/account_asset.py b/addons/account_asset/models/account_asset.py
index 2a4432ace9e..8d4119659f1 100644
--- a/addons/account_asset/models/account_asset.py
+++ b/addons/account_asset/models/account_asset.py
@@ -478,6 +478,8 @@ class AccountAssetDepreciationLine(models.Model):
created_moves = self.env['account.move']
prec = self.env['decimal.precision'].precision_get('Account')
for line in self:
+ if line.move_id:
+ raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.'))
category_id = line.asset_id.category_id
depreciation_date = self.env.context.get('depreciation_date') or line.depreciation_date or fields.Date.context_today(self)
company_currency = line.asset_id.company_id.currency_id
diff --git a/addons/crm/wizard/base_partner_merge_views.xml b/addons/crm/wizard/base_partner_merge_views.xml
index 0918d6ac3a4..259df710ee3 100644
--- a/addons/crm/wizard/base_partner_merge_views.xml
+++ b/addons/crm/wizard/base_partner_merge_views.xml
@@ -56,7 +56,7 @@
You can remove contacts from this list to avoid merging them.
</p>
<group col="2">
- <field name="dst_partner_id" domain="[('id', 'in', partner_ids and partner_ids[0] and partner_ids[0][2] or False)]" attrs="{'required': [('state', '=', 'selection')]}"/>
+ <field name="dst_partner_id" domain="[('id', 'in', partner_ids or False)]" attrs="{'required': [('state', '=', 'selection')]}"/>
</group>
<field name="partner_ids" nolabel="1">
<tree string="Partners">
diff --git a/addons/l10n_fr/__init__.py b/addons/l10n_fr/__init__.py
index 422c6ad09a7..779ab9a056c 100644
--- a/addons/l10n_fr/__init__.py
+++ b/addons/l10n_fr/__init__.py
@@ -4,3 +4,8 @@
# Copyright (c) 2008 JAILLET Simon - CrysaLEAD - www.crysalead.fr
from . import models
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_fr')
diff --git a/addons/l10n_fr/__manifest__.py b/addons/l10n_fr/__manifest__.py
index 3c8fc8c637c..25c75910a00 100644
--- a/addons/l10n_fr/__manifest__.py
+++ b/addons/l10n_fr/__manifest__.py
@@ -45,4 +45,5 @@ configuration of their taxes and fiscal positions manually.
'data/account_reconcile_model_template.xml',
'data/account_chart_template_data.yml',
],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_lu/__init__.py b/addons/l10n_lu/__init__.py
index 67dee8c60db..4ca483f7aff 100644
--- a/addons/l10n_lu/__init__.py
+++ b/addons/l10n_lu/__init__.py
@@ -1,2 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_lu')
diff --git a/addons/l10n_lu/__manifest__.py b/addons/l10n_lu/__manifest__.py
index f7f40c5848a..9fe7e6dfcc9 100644
--- a/addons/l10n_lu/__manifest__.py
+++ b/addons/l10n_lu/__manifest__.py
@@ -44,4 +44,5 @@ Notes:
'data/account.chart.template.csv',
'data/account_chart_template_data.yml',
],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_no/__init__.py b/addons/l10n_no/__init__.py
index 67dee8c60db..52c150be0f0 100644
--- a/addons/l10n_no/__init__.py
+++ b/addons/l10n_no/__init__.py
@@ -1,2 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_no')
diff --git a/addons/l10n_no/__manifest__.py b/addons/l10n_no/__manifest__.py
index ba4208b6b3c..670c1bf55d6 100644
--- a/addons/l10n_no/__manifest__.py
+++ b/addons/l10n_no/__manifest__.py
@@ -20,4 +20,5 @@ Updated for Odoo 9 by Bringsvor Consulting AS <www.bringsvor.com>
'data/account_tax_data.xml',
'data/account_chart_template_data.yml'],
"active": False,
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_pl/__init__.py b/addons/l10n_pl/__init__.py
index 67dee8c60db..6575c176947 100644
--- a/addons/l10n_pl/__init__.py
+++ b/addons/l10n_pl/__init__.py
@@ -1,2 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_pl')
diff --git a/addons/l10n_pl/__manifest__.py b/addons/l10n_pl/__manifest__.py
index dab10c2a1f3..da203009525 100644
--- a/addons/l10n_pl/__manifest__.py
+++ b/addons/l10n_pl/__manifest__.py
@@ -33,4 +33,5 @@ Wewnętrzny numer wersji OpenGLOBE 1.02
'data/res_country_state_data.xml',
'data/account_chart_template_data.yml'
],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_sg/__init__.py b/addons/l10n_sg/__init__.py
index b286495ed4a..e2f7da260d0 100644
--- a/addons/l10n_sg/__init__.py
+++ b/addons/l10n_sg/__init__.py
@@ -2,3 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# Copyright (C) 2014 Tech Receptives (<http://techreceptives.com>).
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_sg')
diff --git a/addons/l10n_sg/__manifest__.py b/addons/l10n_sg/__manifest__.py
index 2df4ef0e928..d05a6c0958e 100644
--- a/addons/l10n_sg/__manifest__.py
+++ b/addons/l10n_sg/__manifest__.py
@@ -33,4 +33,5 @@ After installing this module, the Configuration wizard for accounting is launche
'data/account_tax_data.xml',
'data/account_chart_template_data.yml',
],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_th/__init__.py b/addons/l10n_th/__init__.py
index 67dee8c60db..1b8d7518cd3 100644
--- a/addons/l10n_th/__init__.py
+++ b/addons/l10n_th/__init__.py
@@ -1,2 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_th')
diff --git a/addons/l10n_th/__manifest__.py b/addons/l10n_th/__manifest__.py
index 548cc9dd626..e283dcfaace 100644
--- a/addons/l10n_th/__manifest__.py
+++ b/addons/l10n_th/__manifest__.py
@@ -19,4 +19,5 @@ Thai accounting chart and localization.
'data/l10n_th_chart_data.xml',
'data/account_chart_template_data.yml',
],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/l10n_vn/__init__.py b/addons/l10n_vn/__init__.py
index 34293fdfe8d..490754ae534 100644
--- a/addons/l10n_vn/__init__.py
+++ b/addons/l10n_vn/__init__.py
@@ -2,3 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# This module is Copyright (c) 2009-2013 General Solutions (http://gscom.vn) All Rights Reserved.
+
+
+def _preserve_tag_on_taxes(cr, registry):
+ from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
+ preserve_existing_tags_on_taxes(cr, registry, 'l10n_vn')
diff --git a/addons/l10n_vn/__manifest__.py b/addons/l10n_vn/__manifest__.py
index c945d4726fa..7668c3c8dbe 100644
--- a/addons/l10n_vn/__manifest__.py
+++ b/addons/l10n_vn/__manifest__.py
@@ -28,5 +28,6 @@ with Chart of account under Circular No. 200/2014/TT-BTC
'data/account_data.xml',
'data/account_tax_data.xml',
'data/account_chart_template_data.yml',
- ]
+ ],
+ 'post_init_hook': '_preserve_tag_on_taxes',
}
diff --git a/addons/mrp/report/mrp_production_templates.xml b/addons/mrp/report/mrp_production_templates.xml
index 17adf4858bb..c94536371e0 100644
--- a/addons/mrp/report/mrp_production_templates.xml
+++ b/addons/mrp/report/mrp_production_templates.xml
@@ -18,8 +18,7 @@
</div>
<div class="col-xs-3">
<strong>Product:</strong><br/>
- <span t-field="o.product_id.code"/>
- <span t-field="o.product_id.name"/>
+ <span t-field="o.product_id"/>
</div>
<div class="col-xs-3">
<strong>Quantity:</strong><br/>
diff --git a/addons/point_of_sale/static/src/js/chrome.js b/addons/point_of_sale/static/src/js/chrome.js
index 92c1316fcb7..88ca9e8e4fa 100644
--- a/addons/point_of_sale/static/src/js/chrome.js
+++ b/addons/point_of_sale/static/src/js/chrome.js
@@ -8,6 +8,7 @@ var models = require('point_of_sale.models');
var core = require('web.core');
var ajax = require('web.ajax');
var CrashManager = require('web.CrashManager');
+var BarcodeEvents = require('barcodes.BarcodeEvents').BarcodeEvents;
var _t = core._t;
@@ -606,10 +607,9 @@ var Chrome = PosBaseWidget.extend({
$(window).off();
$('html').off();
$('body').off();
- $(this.$el).parent().off();
- $('document').off();
- $('.oe_web_client').off();
- $('.openerp_webclient_container').off();
+ this.$el.parent().off();
+ // The above lines removed the bindings, but we really need them for the barcode
+ BarcodeEvents.start();
},
build_chrome: function() {
diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js
index caf64ca72e4..e8ec348288b 100644
--- a/addons/point_of_sale/static/src/js/db.js
+++ b/addons/point_of_sale/static/src/js/db.js
@@ -235,10 +235,12 @@ var PosDB = core.Class.extend({
for(var i = 0, len = partners.length; i < len; i++){
partner = partners[i];
- if ( this.partner_write_date &&
+ var local_partner_date = (this.partner_write_date || '').replace(/^(\d{4}-\d{2}-\d{2}) ((\d{2}:?){3})$/, '$1T$2Z');
+ var dist_partner_date = (partner.write_date || '').replace(/^(\d{4}-\d{2}-\d{2}) ((\d{2}:?){3})$/, '$1T$2Z');
+ if ( this.partner_write_date &&
this.partner_by_id[partner.id] &&
- new Date(this.partner_write_date).getTime() + 1000 >=
- new Date(partner.write_date).getTime() ) {
+ new Date(local_partner_date).getTime() + 1000 >=
+ new Date(dist_partner_date).getTime() ) {
// FIXME: The write_date is stored with milisec precision in the database
// but the dates we get back are only precise to the second. This means when
// you read partners modified strictly after time X, you get back partners that were
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index 61704ad44f8..d0aed74bc66 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -542,7 +542,7 @@ class ProductProduct(models.Model):
history = self.env['product.price.history'].search([
('company_id', '=', company_id),
('product_id', 'in', self.ids),
- ('datetime', '<=', date or fields.Datetime.now())], limit=1)
+ ('datetime', '<=', date or fields.Datetime.now())], order='datetime desc,id desc', limit=1)
return history.cost or 0.0
class ProductPackaging(models.Model):
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index c2497b7f2ad..24b35183f68 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -803,7 +803,7 @@ class SaleOrderLine(models.Model):
def create(self, values):
values.update(self._prepare_add_missing_fields(values))
line = super(SaleOrderLine, self).create(values)
- if line.state == 'sale':
+ if line.order_id.state == 'sale':
msg = _("Extra line with %s ") % (line.product_id.display_name,)
line.order_id.message_post(body=msg)
# create an analytic account if at least an expense product
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index f2cacb3327f..ae3080b3b8e 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -534,14 +534,17 @@ var FieldMany2One = AbstractField.extend({
* start/end of the input element. Stops any navigation move event if the
* user is selecting text.
*
- * TODO this is a duplicate of InputField._onNavigationMove, maybe this
- * should be done in a mixin or, better, the m2o field should be an
- * InputField (but this requires some refactoring).
- *
* @private
* @param {OdooEvent} ev
*/
- _onNavigationMove: basicFields.InputField.prototype._onNavigationMove,
+ _onNavigationMove: function (ev) {
+ // TODO Maybe this should be done in a mixin or, better, the m2o field
+ // should be an InputField (but this requires some refactoring).
+ basicFields.InputField.prototype._onNavigationMove.apply(this, arguments);
+ if (this.mode === 'edit' && $(this.$input.autocomplete('widget')).is(':visible')) {
+ ev.stopPropagation();
+ }
+ },
/**
* @private
* @param {OdooEvent} event
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index f21db07f088..fe98eaaeab2 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -572,6 +572,38 @@ QUnit.module('relational_fields', {
form.destroy();
});
+ QUnit.test('many2one field and list navigation', function (assert) {
+ assert.expect(3);
+
+ var list = createView({
+ View: ListView,
+ model: 'partner',
+ data: this.data,
+ arch: '<tree editable="bottom"><field name="trululu"/></tree>',
+ });
+
+ // edit first input, to trigger autocomplete
+ list.$('.o_data_row .o_data_cell').first().click();
+ list.$('.o_data_cell input').val('').trigger('input');
+
+ // press keydown, to select first choice
+ list.$('.o_data_cell input').focus().trigger($.Event('keydown', {
+ which: $.ui.keyCode.DOWN,
+ keyCode: $.ui.keyCode.DOWN,
+ }));
+
+ // we now check that the dropdown is open (and that the focus did not go
+ // to the next line)
+ var $dropdown = list.$('.o_field_many2one input').autocomplete('widget');
+ assert.ok($dropdown.is(':visible'), "dropdown should be visible");
+ assert.ok(list.$('.o_data_row:eq(0)').hasClass('o_selected_row'),
+ 'first data row should still be selected');
+ assert.ok(!list.$('.o_data_row:eq(1)').hasClass('o_selected_row'),
+ 'second data row should not be selected');
+
+ list.destroy();
+ });
+
QUnit.test('standalone many2one field', function (assert) {
assert.expect(3);
var done = assert.async();
diff --git a/addons/website_event/views/event_templates.xml b/addons/website_event/views/event_templates.xml
index e75627f7ee2..714c2f6342d 100644
--- a/addons/website_event/views/event_templates.xml
+++ b/addons/website_event/views/event_templates.xml
@@ -241,6 +241,7 @@
<template id="template_location">
<t t-call="website_event.layout">
+ <div class="oe_structure"/>
<section class="container">
<h1 class="text-center">Event Location</h1>
</section>
@@ -249,6 +250,7 @@
"widget": "contact",
"fields": ["name", "address", "phone", "mobile"]
}'/>
+ <div class="oe_structure"/>
</t>
</template>
diff --git a/addons/website_event_track/views/event_track_templates.xml b/addons/website_event_track/views/event_track_templates.xml
index bb90835df5e..9d5bee401ba 100644
--- a/addons/website_event_track/views/event_track_templates.xml
+++ b/addons/website_event_track/views/event_track_templates.xml
@@ -42,6 +42,7 @@
<template id="agenda">
<t t-call="website_event.layout">
+ <div class="oe_structure"/>
<section class="container">
<h1 class="text-center" t-field="event.name"/>
<div class="form-inline pull-right">
@@ -107,12 +108,14 @@
</tr>
</table>
</section>
+ <div class="oe_structure"/>
</t>
</template>
<template id="tracks">
<t t-call="website_event.event_details">
+ <div class="oe_structure"/>
<div id="left_column">
</div>
<div class="col-md-9">
@@ -151,6 +154,7 @@
</div>
</div>
</div>
+ <div class="oe_structure"/>
</t>
</template>
diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py
index 6cc12e947d4..bdcc5c9f56f 100644
--- a/addons/website_sale/models/website.py
+++ b/addons/website_sale/models/website.py
@@ -77,12 +77,13 @@ class Website(models.Model):
:param bool show_visible: if True, we don't display pricelist where selectable is False (Eg: Code promo)
:returns: pricelist recordset
"""
- website = request and request.website or None
+ website = request and hasattr(request, 'website') and request.website or None
if not website:
if self.env.context.get('website_id'):
website = self.browse(self.env.context['website_id'])
else:
- website = self.search([], limit=1)
+ # In the weird case we are coming from the backend (https://github.com/odoo/odoo/issues/20245)
+ website = len(self) == 1 and self or self.search([], limit=1)
isocountry = request and request.session.geoip and request.session.geoip.get('country_code') or False
partner = self.env.user.partner_id
order_pl = partner.last_website_so_id and partner.last_website_so_id.state == 'draft' and partner.last_website_so_id.pricelist_id
diff --git a/addons/website_slides/views/website_slides_embed.xml b/addons/website_slides/views/website_slides_embed.xml
index c3c77fc676d..72614803325 100644
--- a/addons/website_slides/views/website_slides_embed.xml
+++ b/addons/website_slides/views/website_slides_embed.xml
@@ -59,7 +59,7 @@
<!-- PDF Viewer Body : contains the canvas, the loader, or the image-->
<div id="PDFSlideViewer" style="position:relative;"
t-attf-data-slideid="#{slide.id}"
- t-attf-data-slideurl="/slides/slide/#{slide.id}/pdf_content"
+ t-attf-data-slideurl="/slides/slide/#{slug(slide)}/pdf_content"
t-attf-data-downloadable="#{slide.download_security}"
t-att-data-defaultpage="page">
<t t-if="is_embedded">
@@ -133,7 +133,7 @@
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4 text-center"></div>
</div>
<div class="col-lg-2 col-md-2 col-sm-2 col-xs-2 pull-right text-right">
- <a t-if="slide.download_security and not is_embedded" target="_top" t-attf-href="/slides/slide/#{slide.id}/download" title="Download" id="download">
+ <a t-if="slide.download_security and not is_embedded" target="_top" t-attf-href="/slides/slide/#{slug(slide)}/download" title="Download" id="download">
<i class="fa fa-download fa-2x"></i>
</a>
<span id="fullscreen" title="View fullscreen">