diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index 0fc05b549bc..5113ac05963 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -3,7 +3,7 @@ from odoo import api, fields, models, _ from odoo.osv import expression from odoo.tools import float_is_zero, pycompat -from odoo.tools import float_compare, float_round +from odoo.tools import float_compare, float_round, float_repr from odoo.tools.misc import formatLang from odoo.exceptions import UserError, ValidationError @@ -606,7 +606,8 @@ class AccountBankStatementLine(models.Model): from_clause = "FROM account_move_line aml JOIN account_account acc ON acc.id = aml.account_id " where_clause = """WHERE aml.company_id = %(company_id)s AND ( - (aml.statement_id IS NULL AND aml.account_id IN %(account_payable_receivable)s) + (aml.statement_id IS NULL AND aml.account_id IN %(account_payable_receivable)s + AND aml.payment_id IS NOT NULL) OR ("""+acc_type+""" AND aml.reconciled = false) )""" @@ -630,7 +631,7 @@ class AccountBankStatementLine(models.Model): precision = st_line_currency and st_line_currency.decimal_places or company_currency.decimal_places params = {'company_id': self.env.user.company_id.id, 'account_payable_receivable': (self.journal_id.default_credit_account_id.id, self.journal_id.default_debit_account_id.id), - 'amount': float_round(amount, precision_digits=precision), + 'amount': float_repr(float_round(amount, precision_digits=precision), precision_digits=precision), 'partner_id': self.partner_id.id, 'excluded_ids': tuple(excluded_ids), 'ref': self.name, @@ -651,9 +652,9 @@ class AccountBankStatementLine(models.Model): # Look for a single move line with the same amount field = currency and 'amount_residual_currency' or 'amount_residual' liquidity_field = currency and 'amount_currency' or amount > 0 and 'debit' or 'credit' - liquidity_amt_clause = currency and '%(amount)s' or 'abs(%(amount)s)' + liquidity_amt_clause = currency and '%(amount)s::numeric' or 'abs(%(amount)s::numeric)' sql_query = self._get_common_sql_query(excluded_ids=excluded_ids) + \ - " AND ("+field+" = %(amount)s OR (acc.internal_type = 'liquidity' AND "+liquidity_field+" = " + liquidity_amt_clause + ")) \ + " AND ("+field+" = %(amount)s::numeric OR (acc.internal_type = 'liquidity' AND "+liquidity_field+" = " + liquidity_amt_clause + ")) \ ORDER BY date_maturity desc, aml.id desc LIMIT 1" self.env.cr.execute(sql_query, params) results = self.env.cr.fetchone() diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index eb2a56aafc3..52b1dbf7f1a 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -474,7 +474,7 @@ class AccountInvoice(models.Model): @api.onchange('invoice_line_ids') def _onchange_invoice_line_ids(self): taxes_grouped = self.get_taxes_values() - tax_lines = self.tax_line_ids.browse([]) + tax_lines = self.tax_line_ids.filtered('manual') for tax in taxes_grouped.values(): tax_lines += tax_lines.new(tax) self.tax_line_ids = tax_lines diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 2ff97a639ce..9680836f15a 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -685,7 +685,7 @@ class AccountMoveLine(models.Model): company_currency = line.account_id.company_id.currency_id ret_line = { 'id': line.id, - 'name': line.name != '/' and line.move_id.name + ': ' + line.name or line.move_id.name, + 'name': line.name and line.name != '/' and line.move_id.name + ': ' + line.name or line.move_id.name, 'ref': line.move_id.ref or '', # For reconciliation between statement transactions and already registered payments (eg. checks) # NB : we don't use the 'reconciled' field because the line we're selecting is not the one that gets reconciled diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index 3c97e697c51..dee6d66a055 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -44,7 +44,7 @@ Customer Code:

-

+
Reference:

diff --git a/addons/base_address_city/models/res_partner.py b/addons/base_address_city/models/res_partner.py index afa5cd759e8..f6fcbf61d42 100644 --- a/addons/base_address_city/models/res_partner.py +++ b/addons/base_address_city/models/res_partner.py @@ -20,6 +20,8 @@ class Partner(models.Model): @api.model def _fields_view_get_address(self, arch): arch = super(Partner, self)._fields_view_get_address(arch) + if not self._context.get('no_address_format'): + return arch # render the partner address accordingly to address_view_id doc = etree.fromstring(arch) for city_node in doc.xpath("//field[@name='city']"): diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 729264e6181..d48ef6e8cd9 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -254,11 +254,13 @@ class Lead(models.Model): self.update(values) @api.constrains('user_id') + @api.multi def _valid_team(self): - if self.user_id: - values = self.with_context(team_id=self.team_id.id)._onchange_user_values(self.user_id.id) - if values: - self.update(values) + for lead in self: + if lead.user_id: + values = lead.with_context(team_id=lead.team_id.id)._onchange_user_values(lead.user_id.id) + if values: + lead.update(values) @api.onchange('state_id') def _onchange_state(self): diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml index f9b44044a2c..eec99576825 100644 --- a/addons/crm/views/crm_lead_views.xml +++ b/addons/crm/views/crm_lead_views.xml @@ -203,7 +203,7 @@ - + - + diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index f990f677436..50e4ba18d6b 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -164,6 +164,7 @@ class PosOrder(models.Model): 'origin': self.name, 'account_id': self.partner_id.property_account_receivable_id.id, 'journal_id': self.session_id.config_id.invoice_journal_id.id, + 'company_id': self.company_id.id, 'type': 'out_invoice', 'reference': self.name, 'partner_id': self.partner_id.id, @@ -859,21 +860,14 @@ class PosOrderLine(models.Model): @api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'product_id') def _compute_amount_line_all(self): for line in self: - currency = line.order_id.pricelist_id.currency_id - taxes = line.tax_ids.filtered(lambda tax: tax.company_id.id == line.order_id.company_id.id) - fiscal_position_id = line.order_id.fiscal_position_id - if fiscal_position_id: - taxes = fiscal_position_id.map_tax(taxes, line.product_id, line.order_id.partner_id) - price = self.env['account.tax']._fix_tax_included_price( - line.price_unit * (1 - (line.discount or 0.0) / 100.0), line.product_id.taxes_id, taxes) - line.price_subtotal = line.price_subtotal_incl = price * line.qty - if taxes: - taxes = taxes.compute_all(price, currency, line.qty, product=line.product_id, partner=line.order_id.partner_id or False) - line.price_subtotal = taxes['total_excluded'] - line.price_subtotal_incl = taxes['total_included'] - - line.price_subtotal = currency.round(line.price_subtotal) - line.price_subtotal_incl = currency.round(line.price_subtotal_incl) + fpos = line.order_id.fiscal_position_id + tax_ids_after_fiscal_position = fpos.map_tax(line.tax_ids, line.product_id, line.order_id.partner_id) if fpos else line.tax_ids + price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) + taxes = tax_ids_after_fiscal_position.compute_all(price, line.order_id.pricelist_id.currency_id, line.qty, product=line.product_id, partner=line.order_id.partner_id) + line.update({ + 'price_subtotal_incl': taxes['total_included'], + 'price_subtotal': taxes['total_excluded'], + }) @api.onchange('product_id') def _onchange_product_id(self): @@ -885,8 +879,10 @@ class PosOrderLine(models.Model): price = self.order_id.pricelist_id.get_product_price( self.product_id, self.qty or 1.0, self.order_id.partner_id) self._onchange_qty() - self.price_unit = price - self.tax_ids = self.product_id.taxes_id + self.tax_ids = self.product_id.taxes_id.filtered(lambda r: not self.company_id or r.company_id == self.company_id) + fpos = self.order_id.fiscal_position_id + tax_ids_after_fiscal_position = fpos.map_tax(self.tax_ids, line.product_id, line.order_id.partner_id) if fpos else self.tax_ids + self.price_unit = self.env['account.tax']._fix_tax_included_price(price, self.product_id.taxes_id, tax_ids_after_fiscal_position) @api.onchange('qty', 'discount', 'price_unit', 'tax_ids') def _onchange_qty(self): diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index d8a48b88801..d10470cb343 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -21,7 +21,7 @@ class ProductTemplate(models.Model): if self._context.get('categ_id') or self._context.get('default_categ_id'): return self._context.get('categ_id') or self._context.get('default_categ_id') category = self.env.ref('product.product_category_all', raise_if_not_found=False) - return category and category.id or False + return category.id if category.type == 'normal' else False def _get_default_uom_id(self): return self.env["product.uom"].search([], limit=1, order='id').id diff --git a/addons/rating/controllers/main.py b/addons/rating/controllers/main.py index c167a980e72..817f26aa79e 100644 --- a/addons/rating/controllers/main.py +++ b/addons/rating/controllers/main.py @@ -28,7 +28,7 @@ class Rating(http.Controller): 'rate_name': rate_names[rate], 'rate': rate }) - @http.route(['/rating///submit_feedback'], type="http", auth="public", method=['post']) + @http.route(['/rating///submit_feedback'], type="http", auth="public", methods=['post']) def submit_rating(self, token, rate, **kwargs): rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index de3c67453a7..42f44d32a03 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -4,3 +4,21 @@ from . import models from . import report from . import wizard + +from functools import partial +import odoo +from odoo import api, SUPERUSER_ID + + + +def uninstall_hook(cr, registry): + def update_dashboard_graph_model(dbname): + db_registry = odoo.modules.registry.Registry.new(dbname) + with api.Environment.manage(), db_registry.cursor() as cr: + env = api.Environment(cr, SUPERUSER_ID, {}) + if 'crm.team' in env: + recs = env['crm.team'].search([]) + for rec in recs: + rec._onchange_team_type() + + cr.after("commit", partial(update_dashboard_graph_model, cr.dbname)) \ No newline at end of file diff --git a/addons/sale/__manifest__.py b/addons/sale/__manifest__.py index f44873daa8e..d1be4a05528 100644 --- a/addons/sale/__manifest__.py +++ b/addons/sale/__manifest__.py @@ -65,6 +65,7 @@ The Dashboard for the Sales Manager will include 'data/sale_demo.xml', 'data/product_product_demo.xml', ], + 'uninstall_hook': "uninstall_hook", 'css': ['static/src/css/sale.css'], 'installable': True, 'auto_install': False, diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index 1d144695f52..eac6318e0d7 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -317,12 +317,15 @@ class Quant(models.Model): # price update + accounting entries adjustments solved_quants._price_update(solving_quant.cost) # merge history (and cost?) - solved_quants.write({ - 'history_ids': [(4, history_move.id) for history_move in solving_quant.history_ids] - }) + solved_quants.write(solving_quant._prepare_history()) solving_quant.with_context(force_unlink=True).unlink() solving_quant = remaining_solving_quant + def _prepare_history(self): + return { + 'history_ids': [(4, history_move.id) for history_move in self.history_ids], + } + @api.multi def _price_update(self, newprice): # TDE note: use ACLs instead of sudoing everything diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 2cd2c2ac7da..5c3fc9f9e50 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1012,6 +1012,8 @@ class Binary(http.Controller): elif status != 200 and download: return request.not_found() + height = int(height) + width = int(width) if content and (width or height): # resize maximum 500*500 if width > 500: diff --git a/addons/web/static/src/js/apps.js b/addons/web/static/src/js/apps.js index b05de1d0756..fa513372269 100644 --- a/addons/web/static/src/js/apps.js +++ b/addons/web/static/src/js/apps.js @@ -59,7 +59,7 @@ var Apps = Widget.extend({ }, destroy: function() { - $(window).off("message.apps"); + $(window).off("message." + this.uniq); if (this.$ifr) { this.$ifr.remove(); this.$ifr = null; @@ -114,10 +114,11 @@ var Apps = Widget.extend({ qs.debug = session.debug; } var u = $.param.querystring(client.origin + "/apps/embed/client", qs); - var css = {width: '100%', height: '400px'}; + var css = {width: '100%', height: '750px'}; self.$ifr = $('