diff --git a/addons/account/data/email_template_data_invoice.xml b/addons/account/data/email_template_data_invoice.xml index f3df57f1153..e94b240ae22 100644 --- a/addons/account/data/email_template_data_invoice.xml +++ b/addons/account/data/email_template_data_invoice.xml @@ -72,13 +72,13 @@ from ${object.company_id.name}. % set record = ctx.get('record') % set company = record and record.company_id or user.company_id - +
- +
@@ -96,7 +96,7 @@ from ${object.company_id.name}.
- +
${object.body | safe} @@ -109,7 +109,7 @@ from ${object.company_id.name}.
- +
diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index 6dba7ca9f8d..3a03b519e06 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -61,7 +61,6 @@ class Partner(models.Model): website_url = 'http://%s' % user.company_id.website if not user.company_id.website.lower().startswith(('http:', 'https:')) else user.company_id.website else: website_url = False - company_name = user.company_id.name model_name = False if message.model: @@ -81,9 +80,15 @@ class Partner(models.Model): if message.res_id and message.model in self.env: record = self.env[message.model].browse(message.res_id) + company = user.company_id; + if record and hasattr(record, 'company_id'): + company = record.company_id; + company_name = company.name; + return { 'signature': signature, 'website_url': website_url, + 'company': company, 'company_name': company_name, 'model_name': model_name, 'record': record, diff --git a/addons/mail/wizard/email_template_preview_view.xml b/addons/mail/wizard/email_template_preview_view.xml index 7d5cd1cb6d6..67068f5dc84 100644 --- a/addons/mail/wizard/email_template_preview_view.xml +++ b/addons/mail/wizard/email_template_preview_view.xml @@ -28,6 +28,9 @@ +
+
diff --git a/addons/product/models/product.py b/addons/product/models/product.py index d7a550e47f6..0d146fcd4e0 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -307,7 +307,8 @@ class ProductProduct(models.Model): for value in product.attribute_value_ids: if value.attribute_id in attributes: raise ValidationError(_('Error! It is not allowed to choose more than one value for a given attribute.')) - attributes |= value.attribute_id + if value.attribute_id.create_variant: + attributes |= value.attribute_id return True @api.onchange('uom_id', 'uom_po_id') diff --git a/addons/sale/data/mail_template_data.xml b/addons/sale/data/mail_template_data.xml index e8bd4ef7b79..630c8313ab0 100644 --- a/addons/sale/data/mail_template_data.xml +++ b/addons/sale/data/mail_template_data.xml @@ -66,13 +66,13 @@ from ${object.company_id.name}. % set record = ctx.get('record') % set company = record and record.company_id or user.company_id -
${company.name}
diff --git a/addons/account/models/account.py b/addons/account/models/account.py index b1d405a1a4f..787122492db 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -798,7 +798,7 @@ class AccountTax(models.Model): # (145 - 15) / (1.0 + ((10 + 20) / 100.0)) = 130 / 1.3 = 100 if fixed_amount == 0.0 and percent_amount == 0.0: return base_amount - return round((base_amount - fixed_amount) / (1.0 + percent_amount / 100.0), prec) + return (base_amount - fixed_amount) / (1.0 + percent_amount / 100.0) base = round(price_unit * quantity, prec) @@ -862,7 +862,7 @@ class AccountTax(models.Model): 'id': tax.id, 'name': tax.with_context(**{'lang': partner.lang} if partner else {}).name, 'amount': sign * tax_amount, - 'base': sign * tax_base, + 'base': round(sign * tax_base, prec), 'sequence': tax.sequence, 'account_id': tax.account_id.id, 'refund_account_id': tax.refund_account_id.id, @@ -873,7 +873,7 @@ class AccountTax(models.Model): 'taxes': taxes_vals, 'total_excluded': sign * (currency.round(total_excluded) if round_total else total_excluded), 'total_included': sign * (currency.round(total_included) if round_total else total_included), - 'base': sign * base, + 'base': round(sign * base, prec), } @api.model diff --git a/addons/account/tests/test_tax.py b/addons/account/tests/test_tax.py index 5ea51d3077d..b39d36f7bf3 100644 --- a/addons/account/tests/test_tax.py +++ b/addons/account/tests/test_tax.py @@ -28,6 +28,12 @@ class TestTax(AccountTestUsers): 'amount': 10, 'sequence': 3, }) + self.percent_tax_bis = self.tax_model.create({ + 'name': "Percent tax bis", + 'amount_type': 'percent', + 'amount': 21, + 'sequence': 3, + }) self.division_tax = self.tax_model.create({ 'name': "Division tax", 'amount_type': 'division', @@ -172,6 +178,21 @@ class TestTax(AccountTestUsers): ], res_percent ) + self.percent_tax_bis.price_include = True + self.percent_tax_bis.include_base_amount = True + res_percent = self.percent_tax_bis.compute_all(7.0) + self._check_compute_all_results( + 7.0, # 'base' + 7.0, # 'total_included' + 5.79, # 'total_excluded' + [ + # base , amount | seq | amount | incl | incl_base + # --------------------------------------------------- + (5.79, 1.21), # | 3 | 21% | t | t + # --------------------------------------------------- + ], + res_percent + ) def test_tax_sequence_normalized_set(self): self.division_tax.sequence = 1 diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py index aa3f4e69b5c..a5a888f51a2 100644 --- a/addons/auth_oauth/controllers/main.py +++ b/addons/auth_oauth/controllers/main.py @@ -6,6 +6,7 @@ import logging import json +import werkzeug.urls import werkzeug.utils from werkzeug.exceptions import BadRequest @@ -148,7 +149,11 @@ class OAuthController(http.Controller): url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu - return login_and_redirect(*credentials, redirect_url=url) + resp = login_and_redirect(*credentials, redirect_url=url) + # Since /web is hardcoded, verify user has right to land on it + if werkzeug.urls.url_parse(resp.location).path == '/web' and not request.env.user.has_group('base.group_user'): + resp.location = '/' + return resp except AttributeError: # auth_signup is not installed _logger.error("auth_signup not installed on database %s: oauth sign up cancelled." % (dbname,)) diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index 6db20b0f592..13796164757 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -71,6 +71,7 @@ % if ctx.get('has_button_access'):
@@ -110,7 +111,7 @@ % endif
- ${user.company_id.name} + ${company.name}
+
- +
@@ -90,7 +90,7 @@ from ${object.company_id.name}.
- +
${object.body | safe} @@ -103,7 +103,7 @@ from ${object.company_id.name}.
- +
${company.name}
diff --git a/addons/website_sale/models/__init__.py b/addons/website_sale/models/__init__.py index a40ad2379a6..a54c1194068 100644 --- a/addons/website_sale/models/__init__.py +++ b/addons/website_sale/models/__init__.py @@ -4,3 +4,4 @@ import product import sale_order import crm_team import res_config +import ir_model_fields diff --git a/addons/website_sale/models/ir_model_fields.py b/addons/website_sale/models/ir_model_fields.py new file mode 100644 index 00000000000..e109ab809b5 --- /dev/null +++ b/addons/website_sale/models/ir_model_fields.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models + +# !! Attention, this is a hack of a hack, do not try this at home !! +# This is done because website_sale defines the website_description +# field which is also defined by website_quote, but these two modules +# are independent of each other, the part of the ORM that generates +# xmlids does not support this case therefore it only creates a single +# pair of xmlids for whichever module is installed first, therefore +# when uninstalling any of the two modules the website_descripion field +# will be deleted from the db and the other module won't be able to +# use this field, resulting in a crash and data-loss. +# See opw-776464 for more details. +# +# This is hotfixed by overriding the unlink method so as to not delete +# the website_description field if website_sale is uninstalled, it's +# an ugly hack but it works and big changes can't be done to the ORM +# in stable versions, Odoo v12+ will properly fix this + + +class IrModelFields(models.Model): + _inherit = "ir.model.fields" + + @api.multi + def unlink(self): + # Prevent the deletion of the field "website_description" + self = self.filtered( + lambda rec: not ( + rec.model in ('product.product', 'product.template') and + rec.name == 'website_description' + ) + ) + return super(IrModelFields, self).unlink()