diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 63aff0fc7ef..f4ff433bf71 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -1558,11 +1558,21 @@ var ReceiptScreenWidget = ScreenWidget.extend({ }; }, print_web: function() { - if($.browser.safari){ + if ($.browser.safari) { document.execCommand('print', false, null); - } - else{ - window.print(); + } else { + try { + window.print(); + } catch(err) { + if (navigator.userAgent.toLowerCase().indexOf("android") > -1) { + this.gui.show_popup('error',{ + 'title':_t('Printing is not supported on some android browsers'), + 'body': _t('Printing is not supported on some android browsers due to no default printing protocol is available. It is possible to print your tickets by making use of an IoT Box.'), + }); + } else { + throw err; + } + } } this.pos.get_order()._printed = true; }, diff --git a/addons/report_intrastat/report/report_intrastat_report.py b/addons/report_intrastat/report/report_intrastat_report.py index 012fd84ea1b..1ca5dfb4bec 100644 --- a/addons/report_intrastat/report/report_intrastat_report.py +++ b/addons/report_intrastat/report/report_intrastat_report.py @@ -36,12 +36,12 @@ class ReportIntrastat(models.Model): intrastat.id as intrastat_id, upper(inv_country.code) as code, sum(case when inv_line.price_unit is not null - then inv_line.price_unit * inv_line.quantity + then inv_line.price_unit * (1.0 - coalesce(inv_line.discount, 0.0) / 100.0) * inv_line.quantity else 0 end) as value, sum( - case when uom.category_id != puom.category_id then (pt.weight * inv_line.quantity) - else (pt.weight * inv_line.quantity * uom.factor) end + case when uom.category_id != puom.category_id then (coalesce(nullif(pp.weight, 0), pt.weight) * inv_line.quantity) + else (coalesce(nullif(pp.weight, 0), pt.weight) * inv_line.quantity * uom.factor) end ) as weight, sum( case when uom.category_id != puom.category_id then inv_line.quantity diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index 133494dc184..c15a985c29a 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -5,7 +5,7 @@ from odoo.addons import decimal_precision as dp from odoo.tools import pycompat from odoo.tools.translate import html_translate -from odoo.tools import float_is_zero +from odoo.tools import float_compare class ProductStyle(models.Model): @@ -199,8 +199,14 @@ class Product(models.Model): for p, p2 in pycompat.izip(self, self2): taxes = partner.property_account_position_id.map_tax(p.sudo().taxes_id.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 + # We must convert the price_without_pricelist in the same currency than the + # website_price, otherwise the comparison doesn't make sense. Moreover, we show a price + # difference only if the website price is lower + price_without_pricelist = p.list_price + if company_id.currency_id != pricelist.currency_id: + price_without_pricelist = company_id.currency_id.compute(price_without_pricelist, pricelist.currency_id) + price_without_pricelist = taxes.compute_all(price_without_pricelist, pricelist.currency_id)[ret] + p.website_price_difference = True if float_compare(price_without_pricelist, p.website_price, precision_rounding=pricelist.currency_id.rounding) > 0 else False 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.js b/addons/website_sale/static/src/js/website_sale.js index 3e55dac396e..6c508eba48b 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -90,7 +90,7 @@ odoo.define('website_sale.website_sale', function (require) { var product_ids = []; var product_dom = $(event.target).closest(".js_product").find("ul.js_add_cart_variants"); var qty = $(event.target).closest('form').find('input[name="add_qty"]').val(); - if (!product_dom.length) { + if (!product_dom.length || $('body').hasClass('editor_enable')) { // if variants in list view, update variant price based on quantity var $list_products = $(event.target).closest('.js_product').find('.js_product_change'); if ($list_products.length) { @@ -145,7 +145,7 @@ odoo.define('website_sale.website_sale', function (require) { $(oe_website_sale).on("change", ".oe_cart input.js_quantity[data-product-id]", function () { var $input = $(this); - if ($input.data('update_change')) { + if ($input.data('update_change') || $('body').hasClass('editor_enable')) { return; } var value = parseInt($input.val() || 0, 10); @@ -214,6 +214,9 @@ odoo.define('website_sale.website_sale', function (require) { // hack to add and remove from cart with json $(oe_website_sale).on('click', 'a.js_add_cart_json', function (ev) { + if ($('body').hasClass('editor_enable')) { + return; + } ev.preventDefault(); var $link = $(ev.currentTarget); var $input = $link.parent().find("input"); diff --git a/odoo/addons/base/res/ir_property.py b/odoo/addons/base/res/ir_property.py index 8c789f1f4bf..ddf8696a627 100644 --- a/odoo/addons/base/res/ir_property.py +++ b/odoo/addons/base/res/ir_property.py @@ -63,9 +63,9 @@ class Property(models.Model): @api.multi def _update_values(self, values): - value = values.pop('value', None) - if not value: + if 'value' not in values: return values + value = values.pop('value') prop = None type_ = values.get('type') @@ -81,7 +81,9 @@ class Property(models.Model): raise UserError(_('Invalid type')) if field == 'value_reference': - if isinstance(value, models.BaseModel): + if not value: + value = False + elif isinstance(value, models.BaseModel): value = '%s,%d' % (value._name, value.id) elif isinstance(value, pycompat.integer_types): field_id = values.get('fields_id') 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 80f35b1426e..83a359ac951 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -633,6 +633,12 @@ class TestFields(common.TransactionCase): self.assertEqual(record.sudo(user1).tag_id, tag0.browse()) self.assertEqual(record.sudo(user2).tag_id, tag0) + record.sudo(user1).foo = False + record.invalidate_cache() + self.assertEqual(record.sudo(user0).foo, 'main') + self.assertEqual(record.sudo(user1).foo, False) + self.assertEqual(record.sudo(user2).foo, 'default') + # create company record and attribute company_record = self.env['test_new_api.company'].create({'foo': 'ABC'}) attribute_record = self.env['test_new_api.company.attr'].create({ diff --git a/odoo/models.py b/odoo/models.py index 3266a763977..dda229cd226 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -852,6 +852,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): # avoid broken transaction) and keep going cr.execute('ROLLBACK TO SAVEPOINT model_load_save') except Exception as e: + _logger.exception("Error while loading record") message = (_(u'Unknown error during import:') + u' %s: %s' % (type(e), e)) moreinfo = _('Resolve other errors first') messages.append(dict(info, type='error', message=message, moreinfo=moreinfo))