diff --git a/addons/account_asset/models/account_invoice.py b/addons/account_asset/models/account_invoice.py index a6b65b3425e..ea7729fc0f0 100644 --- a/addons/account_asset/models/account_invoice.py +++ b/addons/account_asset/models/account_invoice.py @@ -12,6 +12,16 @@ import odoo.addons.decimal_precision as dp class AccountInvoice(models.Model): _inherit = 'account.invoice' + @api.model + def _refund_cleanup_lines(self, lines): + result = super(AccountInvoice, self)._refund_cleanup_lines(lines) + for i, line in enumerate(lines): + for name, field in line._fields.items(): + if name == 'asset_category_id': + result[i][2][name] = False + break + return result + @api.multi def action_cancel(self): res = super(AccountInvoice, self).action_cancel() diff --git a/addons/base_vat/models/res_partner.py b/addons/base_vat/models/res_partner.py index 1de5c95aeab..69d7204bf9a 100644 --- a/addons/base_vat/models/res_partner.py +++ b/addons/base_vat/models/res_partner.py @@ -18,6 +18,12 @@ from odoo import api, models, _ from odoo.tools.misc import ustr from odoo.exceptions import ValidationError +_eu_country_vat = { + 'GR': 'EL' +} + +_eu_country_vat_inverse = {v: k for k, v in _eu_country_vat.items()} + _ref_vat = { 'at': 'ATU12345675', 'be': 'BE0477472701', @@ -79,6 +85,7 @@ class ResPartner(models.Model): # Foreign companies that trade with non-enterprises in the EU # may have a VATIN starting with "EU" instead of a country code. return True + country_code = _eu_country_vat_inverse.get(country_code, country_code) return bool(self.env['res.country'].search([('code', '=ilike', country_code)])) return check_func(vat_number) @@ -96,6 +103,19 @@ class ResPartner(models.Model): # country code or empty VAT number), so we fall back to the simple check. return self.simple_vat_check(country_code, vat_number) + @api.model + def fix_eu_vat_number(self, country_id, vat): + europe = self.env.ref('base.europe') + country = self.env["res.country"].browse(country_id) + if not europe: + europe = self.env["res.country.group"].search([('name', '=', 'Europe')], limit=1) + if europe and country and country.id in europe.country_ids.ids: + vat = re.sub('[^A-Za-z0-9]', '', vat).upper() + country_code = _eu_country_vat.get(country.code, country.code).upper() + if vat[:2] != country_code: + vat = country_code + vat + return vat + @api.constrains('vat', 'commercial_partner_country_id') def check_vat(self): if self.env.context.get('company_id'): diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index cd90ffd16ed..d79d4bdf8be 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -17,9 +17,9 @@ _logger = logging.getLogger(__name__) # Those are the builtin raspberry pi USB modules, they should # not appear in the list of connected devices. BANNED_DEVICES = set([ - "0424:9514", # Standard Microsystem Corp. Builtin Ethernet module - "1d6b:0002", # Linux Foundation 2.0 root hub - "0424:ec00", # Standard Microsystem Corp. Other Builtin Ethernet module + "0424:9514", # Standard Microsystem Corp. Builtin Ethernet module + "1d6b:0002", # Linux Foundation 2.0 root hub + "0424:ec00", # Standard Microsystem Corp. Other Builtin Ethernet module ]) @@ -106,7 +106,7 @@ class Proxy(http.Controller): device_name = device[device.find('ID')+2:] device_id = device_name.split()[0] if not (device_id in BANNED_DEVICES): - resp+= "
"+device_name+"
\n" + resp+= "
"+device_name+"
\n" count += 1 if count == 0: diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index e176f9314d7..c7080dc306f 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -864,7 +864,8 @@ class SaleOrderLine(models.Model): return price else: from_currency = self.order_id.company_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) + product_price = product[pricelist_item.base] if (pricelist_item and pricelist_item.base != 'pricelist') else product.lst_price + return from_currency.compute(product_price, self.order_id.pricelist_id.currency_id) @api.multi @api.onchange('product_id') diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 6e83180841a..1c4bc697351 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -108,11 +108,13 @@ class SaleOrderLine(models.Model): @api.multi @api.depends('product_id') def _compute_qty_delivered_updateable(self): - for line in self: - if line.product_id.type not in ('consu', 'product'): - super(SaleOrderLine, line)._compute_qty_delivered_updateable() - else: - line.qty_delivered_updateable = False + # prefetch field before filtering + self.mapped('product_id') + # on consumable or stockable products, qty_delivered_updateable defaults + # to False; on other lines use the original computation + lines = self.filtered(lambda line: line.product_id.type not in ('consu', 'product')) + lines = lines.with_prefetch(self._prefetch) + super(SaleOrderLine, lines)._compute_qty_delivered_updateable() @api.onchange('product_id') def _onchange_product_id_set_customer_lead(self): diff --git a/addons/stock/models/stock_pack_operation.py b/addons/stock/models/stock_pack_operation.py index a9116730e5c..80db63ce141 100644 --- a/addons/stock/models/stock_pack_operation.py +++ b/addons/stock/models/stock_pack_operation.py @@ -267,10 +267,10 @@ class PackOperationLot(models.Model): _description = "Lot/Serial number for pack ops" operation_id = fields.Many2one('stock.pack.operation') - qty = fields.Float('Done', default=1.0) + qty = fields.Float('Done', default=1.0, digits=dp.get_precision('Product Unit of Measure')) lot_id = fields.Many2one('stock.production.lot', 'Lot/Serial Number') lot_name = fields.Char('Lot/Serial Number') - qty_todo = fields.Float('To Do', default=0.0) + qty_todo = fields.Float('To Do', default=0.0, digits=dp.get_precision('Product Unit of Measure')) plus_visible = fields.Boolean(compute='_compute_plus_visible', default=True) _sql_constraints = [ diff --git a/addons/web/static/src/less/modal.less b/addons/web/static/src/less/modal.less index 2a0fbb1fa36..2d6c7562fe2 100644 --- a/addons/web/static/src/less/modal.less +++ b/addons/web/static/src/less/modal.less @@ -52,6 +52,8 @@ .modal-body { overflow: auto; + // fix iOS issue https://github.com/scottjehl/Device-Bugs/issues/8 + -webkit-transform: translate3d(0, 0, 0); min-height: 0; &.o_dialog_error { diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 574304216ce..54e82706425 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -200,7 +200,7 @@ - + <link type="image/x-icon" rel="shortcut icon" t-att-href="x_icon or '/web/static/src/img/favicon.ico'"/> diff --git a/addons/web_editor/static/src/js/rte.summernote.js b/addons/web_editor/static/src/js/rte.summernote.js index a3bf079aa30..866d0d68e84 100644 --- a/addons/web_editor/static/src/js/rte.summernote.js +++ b/addons/web_editor/static/src/js/rte.summernote.js @@ -771,7 +771,7 @@ eventHandler.attach = function (oLayoutInfo, options) { * Open Link Dialog on double click on a link/button. * Shows a tooltip on click to say to the user he can double click. */ - create_dblclick_feature("a[href], .btn", function () { + create_dblclick_feature("a[href], a.btn, button.btn", function () { eventHandler.modules.linkDialog.show(oLayoutInfo); }); diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 6fb6ab390fc..3cc5acb29ed 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -481,6 +481,8 @@ class WebsiteSale(http.Controller): # vat validation Partner = request.env['res.partner'] if data.get("vat") and hasattr(Partner, "check_vat"): + if data.get("country_id"): + data["vat"] = Partner.fix_eu_vat_number(data.get("country_id"), data.get("vat")) check_func = request.website.company_id.vat_check_vies and Partner.vies_vat_check or Partner.simple_vat_check vat_country, vat_number = Partner._split_vat(data.get("vat")) if not check_func(vat_country, vat_number): diff --git a/doc/cla/corporate/acsone.md b/doc/cla/corporate/acsone.md index cb97dc6b20d..1060d7ccc02 100644 --- a/doc/cla/corporate/acsone.md +++ b/doc/cla/corporate/acsone.md @@ -25,3 +25,4 @@ Philippe Schmidt philippe.schmidt@acsone.eu https://github.com/phschmidt Stéphane Bidoul stephane.bidoul@acsone.eu https://github.com/sbidoul Thomas Binsfeld thomas.binsfeld@acsone.eu https://github.com/ThomasBinsfeld Benjamin Willig benjamin.willig@acsone.eu https://github.com/benwillig +François Honoré francois.honore@acsone.eu https://github.com/acsonefho diff --git a/doc/cla/corporate/savoirfairelinux.md b/doc/cla/corporate/savoirfairelinux.md index 784518b093e..6dca085c4ce 100644 --- a/doc/cla/corporate/savoirfairelinux.md +++ b/doc/cla/corporate/savoirfairelinux.md @@ -1,4 +1,4 @@ -Canada, France, 2017-05-12 +Canada, France, 2017-10-17 Savoir-faire Linux agrees to the terms of the Odoo Corporate Contributor License Agreement v1.0. @@ -8,17 +8,22 @@ declaration. Signed, -Jérome Boisvert-Chouinard jerome.boisvertchouinard@savoirfairelinux.com https://github.com/jbchouinard +João Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joaoalf List of contributors: Agathe Mollé agathe.molle@savoirfairelinux.com https://github.com/Ehtaga Bruno Joliveau bruno.joliveau@savoirfairelinux.com https://github.com/bjoliveau David Dufresne david.dufresne@savoirfairelinux.com https://github.com/dufresnedavid -Jérome Boisvert-Chouinard jerome.boisvertchouinard@savoirfairelinux.com https://github.com/jbchouinard -Joao Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joaoalf -Julie Moussu julie.mousse@savoirfairelinux.com https://github.com/JulieSFL -Pierre Lamarche pierre.lamarche@savoirfairelinux.com https://github.com/plamarche +Istvan SZALAÏ istvan.szalai@savoirfairelinux.com https://github.com/ventilooo +João Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joaoalf +Julien Jezequel-Breard julien.jezequel-breard@savoirfairelinux.com https://github.com/jjbreard +Quentin Lavallée-Bourdeau quentin.lavallee@savoirfairelinux.com https://github.com/qtiplb +Rim Ben Dhaou rim.bendhaou@savoirfairelinux.com https://github.com/rimbendhaou +Yasmine El Mrini yasmine.elmrini@savoirfairelinux.com https://github.com/yasmineelmrini +Jérome Boisvert-Chouinard jerome.boisvertchouinard@savoirfairelinux.com https://github.com/jbchouinard (up to 2017-10-17) +Julie Moussu julie.mousse@savoirfairelinux.com https://github.com/JulieSFL (up to 2017-10-17) +Pierre Lamarche pierre.lamarche@savoirfairelinux.com https://github.com/plamarche (up to 2017-10-17) David Cormier david.cormier@savoirfairelinux.com https://github.com/cormier (up to 2017-05-12) Davin Baragiotta davin.baragiotta@savoirfairelinux.com https://github.com/giotta (up to 2017-05-12) El Hadji Dem elhadji.dem@savoirfairelinux.com https://github.com/ehdem (up to 2017-05-12) diff --git a/odoo/addons/test_pylint/tests/test_pylint.py b/odoo/addons/test_pylint/tests/test_pylint.py index 38fa4c3d51a..22573c699a2 100644 --- a/odoo/addons/test_pylint/tests/test_pylint.py +++ b/odoo/addons/test_pylint/tests/test_pylint.py @@ -25,6 +25,8 @@ class TestPyLint(TransactionCase): 'E0601', # using variable before assignment 'W0123', # eval used 'W0101', # unreachable code + + 'mixed-indentation', ] def _skip_test(self, reason):