diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index b1bcb28e12e..54206ceba5a 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -240,9 +240,9 @@ class ResPartner(models.Model): LEFT JOIN account_move_line aml ON aml.partner_id = partner.id RIGHT JOIN account_account acc ON aml.account_id = acc.id WHERE acc.internal_type = %s - AND NOT acc.deprecated + AND NOT acc.deprecated AND acc.company_id = %s GROUP BY partner.id - HAVING %s * COALESCE(SUM(aml.amount_residual), 0) ''' + operator + ''' %s''', (account_type, sign, operand)) + HAVING %s * COALESCE(SUM(aml.amount_residual), 0) ''' + operator + ''' %s''', (account_type, self.env.user.company_id.id, sign, operand)) res = self._cr.fetchall() if not res: return [('id', '=', '0')] diff --git a/addons/l10n_fr_fec/wizard/account_fr_fec.py b/addons/l10n_fr_fec/wizard/account_fr_fec.py index 24e35187736..90b5288c71a 100644 --- a/addons/l10n_fr_fec/wizard/account_fr_fec.py +++ b/addons/l10n_fr_fec/wizard/account_fr_fec.py @@ -308,7 +308,7 @@ class AccountFrFec(models.TransientModel): TO_CHAR(am.date, 'YYYYMMDD') AS PieceDate, CASE WHEN aml.name IS NULL OR aml.name = '' THEN '/' WHEN aml.name SIMILAR TO '[\t|\s|\n]*' THEN '/' - ELSE replace(replace(replace(aml.name, '|', '/'), '\t', ''), '\n', '') END AS EcritureLib, + ELSE replace(replace(replace(replace(aml.name, '|', '/'), '\t', ''), '\n', ''), '\r', '') END AS EcritureLib, replace(CASE WHEN aml.debit = 0 THEN '0,00' ELSE to_char(aml.debit, '000000000000000D99') END, '.', ',') AS Debit, replace(CASE WHEN aml.credit = 0 THEN '0,00' ELSE to_char(aml.credit, '000000000000000D99') END, '.', ',') AS Credit, CASE WHEN rec.name IS NULL THEN '' ELSE rec.name END AS EcritureLet, diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index b5ac7da464d..e1b0ee682fa 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -1707,8 +1707,11 @@ exports.Orderline = Backbone.Model.extend({ }, _compute_all: function(tax, base_amount, quantity) { if (tax.amount_type === 'fixed') { - var sign_base_amount = base_amount >= 0 ? 1 : -1; - return (Math.abs(tax.amount) * sign_base_amount) * quantity; + var sign_base_amount = Math.sign(base_amount) || 1; + // Since base amount has been computed with quantity + // we take the abs of quantity + // Same logic as bb72dea98de4dae8f59e397f232a0636411d37ce + return tax.amount * sign_base_amount * Math.abs(quantity); } if ((tax.amount_type === 'percent' && !tax.price_include) || (tax.amount_type === 'division' && tax.price_include)){ return base_amount * tax.amount / 100; diff --git a/addons/pos_discount/static/src/js/discount.js b/addons/pos_discount/static/src/js/discount.js index 771992bb01b..70fbdd17d7a 100644 --- a/addons/pos_discount/static/src/js/discount.js +++ b/addons/pos_discount/static/src/js/discount.js @@ -42,10 +42,16 @@ var DiscountButton = screens.ActionButtonWidget.extend({ } // Add discount + // We add the price as manually set to avoid recomputation when changing customer. var discount = - pc / 100.0 * order.get_total_with_tax(); if( discount < 0 ){ - order.add_product(product, { price: discount }); + order.add_product(product, { + price: discount, + extras: { + price_manually_set: true, + }, + }); } }, }); diff --git a/addons/purchase/models/stock.py b/addons/purchase/models/stock.py index 794e7401486..616f5b8f09f 100644 --- a/addons/purchase/models/stock.py +++ b/addons/purchase/models/stock.py @@ -46,7 +46,12 @@ class StockMove(models.Model): if line.product_uom.id != line.product_id.uom_id.id: price_unit *= line.product_uom.factor / line.product_id.uom_id.factor if order.currency_id != order.company_id.currency_id: - price_unit = order.currency_id.with_context(date=self.date or order.date_approve).compute(price_unit, order.company_id.currency_id, round=False) + # DO NOT FORWARD-PORT! ONLY FOR V11!!! + # The date must be today, and not the date of the move since the move move is still + # in assigned state. However, the move date is the scheduled date until move is + # done, then date of actual move processing. See: + # https://github.com/odoo/odoo/blob/2f789b6863407e63f90b3a2d4cc3be09815f7002/addons/stock/models/stock_move.py#L36 + price_unit = order.currency_id.with_context(date=fields.Date.context_today(self)).compute(price_unit, order.company_id.currency_id, round=False) return price_unit return super(StockMove, self)._get_price_unit() diff --git a/addons/purchase/tests/test_stockvaluation.py b/addons/purchase/tests/test_stockvaluation.py index 9c3c191ac5e..8eeedf1353f 100644 --- a/addons/purchase/tests/test_stockvaluation.py +++ b/addons/purchase/tests/test_stockvaluation.py @@ -771,12 +771,12 @@ class TestStockValuationWithCOA(AccountingTestCase): 'company_id': company.id, }) - # To allow testing validation of PO + # To allow testing validation of PO and Delivery + today = date_po def _today(*args, **kwargs): - return date_po - # To allow testing validation of Delivery + return today def _now(*args, **kwargs): - return date_delivery + ' 01:00:00' + return today + ' 01:00:00' patchers = [ patch('odoo.fields.Date.context_today', _today), @@ -805,13 +805,17 @@ class TestStockValuationWithCOA(AccountingTestCase): line_product_avg = po.order_line.filtered(lambda l: l.product_id == product_avg) + today = date_delivery picking = po.picking_ids (picking.move_lines .filtered(lambda l: l.purchase_line_id == line_product_avg) .write({'quantity_done': 1.0})) picking.button_validate() + # 1 Units received at rate 0.7 = 42.86 + self.assertAlmostEqual(product_avg.standard_price, 42.86) + today = date_invoice inv = self.env['account.invoice'].create({ 'type': 'in_invoice', 'date_invoice': date_invoice, diff --git a/addons/web_editor/static/src/js/editor/summernote.js b/addons/web_editor/static/src/js/editor/summernote.js index 74f14e46374..f3d895c1b76 100644 --- a/addons/web_editor/static/src/js/editor/summernote.js +++ b/addons/web_editor/static/src/js/editor/summernote.js @@ -2283,7 +2283,7 @@ $.summernote.pluginEvents.backColor = function (event, editor, layoutInfo, backC options.onCreateLink = function (sLinkUrl) { if (sLinkUrl.indexOf('mailto:') === 0 || sLinkUrl.indexOf('tel:') === 0) { - // pass + sLinkUrl = sLinkUrl.replace(/^tel:([0-9]+)$/, 'tel://$1'); } else if (sLinkUrl.indexOf('@') !== -1 && sLinkUrl.indexOf(':') === -1) { sLinkUrl = 'mailto:' + sLinkUrl; } else if (sLinkUrl.indexOf('://') === -1 && sLinkUrl[0] !== '/' diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js index d1a5a905651..e621cae3692 100644 --- a/addons/web_editor/static/src/js/widgets/widgets.js +++ b/addons/web_editor/static/src/js/widgets/widgets.js @@ -926,7 +926,7 @@ var VideoWidget = MediaWidget.extend({ return {errorCode: 0}; } - var autoplay = options.autoplay ? '?autoplay=1' : '?autoplay=0'; + var autoplay = options.autoplay ? '?autoplay=1&mute=1' : '?autoplay=0'; if (ytMatch && ytMatch[2].length === 11) { $video.attr('src', '//www.youtube' + (ytMatch[1] || '') + '.com/embed/' + ytMatch[2] + autoplay); @@ -955,7 +955,8 @@ var VideoWidget = MediaWidget.extend({ $video.attr('src', $video.attr('src') + '&rel=0'); } if (options.loop && (ytMatch || vimMatch)) { - $video.attr('src', $video.attr('src') + '&loop=1'); + var videoSrc = _.str.sprintf('%s&loop=1', $video.attr('src')); + $video.attr('src', ytMatch ? _.str.sprintf('%s&playlist=%s', videoSrc, ytMatch[2]) : videoSrc); } if (options.hide_controls && (ytMatch || dmMatch)) { $video.attr('src', $video.attr('src') + '&controls=0'); diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml index dab833bce06..3ae7c983bb6 100644 --- a/addons/web_editor/static/src/xml/editor.xml +++ b/addons/web_editor/static/src/xml/editor.xml @@ -202,7 +202,11 @@ Options