diff --git a/addons/account/models/account.py b/addons/account/models/account.py index 63d96de9aff..2763c3ededd 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -801,7 +801,7 @@ class AccountTax(models.Model): tag_ids = fields.Many2many('account.account.tag', 'account_tax_account_tag', string='Tags', help="Optional tags you may want to assign for custom reporting") tax_group_id = fields.Many2one('account.tax.group', string="Tax Group", default=_default_tax_group, required=True) # Technical field to make the 'tax_exigibility' field invisible if the same named field is set to false in 'res.company' model - hide_tax_exigibility = fields.Boolean(string='Hide Use Cash Basis Option', related='company_id.tax_exigibility') + hide_tax_exigibility = fields.Boolean(string='Hide Use Cash Basis Option', related='company_id.tax_exigibility', readonly=True) tax_exigibility = fields.Selection( [('on_invoice', 'Based on Invoice'), ('on_payment', 'Based on Payment'), diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 631243e3697..215f9d12878 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1131,7 +1131,7 @@ class AccountMoveLine(models.Model): 'move_id': self.id, 'user_id': self.invoice_id.user_id.id or self._uid, 'partner_id': self.partner_id.id, - 'company_id': self.env.user.company_id.id, + 'company_id': self.analytic_account_id.company_id.id or self.env.user.company_id.id, } def _prepare_analytic_distribution_line(self, distribution): @@ -1154,7 +1154,7 @@ class AccountMoveLine(models.Model): 'ref': self.ref, 'move_id': self.id, 'user_id': self.invoice_id.user_id.id or self._uid, - 'company_id': self.env.user.company_id.id + 'company_id': distribution.account_id.company_id.id or self.env.user.company_id.id, } @api.model diff --git a/addons/account/static/src/js/reconciliation/reconciliation_model.js b/addons/account/static/src/js/reconciliation/reconciliation_model.js index b2c2f5324dc..8c433ba2ce2 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_model.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_model.js @@ -804,6 +804,7 @@ var StatementModel = BasicModel.extend({ model: 'account.tax', method: 'json_friendly_compute_all', args: args, + context: $.extend(self.context || {}, {'round': true}), }) .then(function (result) { _.each(result.taxes, function(tax){ diff --git a/addons/account/wizard/wizard_tax_adjustments.py b/addons/account/wizard/wizard_tax_adjustments.py index 2f188b1abab..51f1936b93b 100644 --- a/addons/account/wizard/wizard_tax_adjustments.py +++ b/addons/account/wizard/wizard_tax_adjustments.py @@ -18,7 +18,7 @@ class TaxAdjustments(models.TransientModel): debit_account_id = fields.Many2one('account.account', string='Debit account', required=True, domain=[('deprecated', '=', False)]) credit_account_id = fields.Many2one('account.account', string='Credit account', required=True, domain=[('deprecated', '=', False)]) amount = fields.Monetary(currency_field='company_currency_id', required=True) - adjustment_type = fields.Selection([('debit', 'Adjustment in favor of the Estate'), ('credit', 'Adjustment in your favor')], string="Adjustment Type", store=False, required=True) + adjustment_type = fields.Selection([('debit', 'Applied on debit journal item'), ('credit', 'Applied on credit journal item')], string="Adjustment Type", store=False, required=True) company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.user.company_id.currency_id) tax_id = fields.Many2one('account.tax', string='Adjustment Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'adjustment')], required=True) diff --git a/addons/account_payment/models/payment.py b/addons/account_payment/models/payment.py index 389cfa206e1..cfc90258289 100644 --- a/addons/account_payment/models/payment.py +++ b/addons/account_payment/models/payment.py @@ -159,7 +159,7 @@ class PaymentTransaction(models.Model): 'currency_id': invoice.currency_id.id, 'partner_id': invoice.partner_id.id, 'partner_country_id': invoice.partner_id.country_id.id, - 'reference': self.get_next_reference(invoice.number), + 'reference': self._get_next_reference(invoice.number, acquirer=acquirer), 'account_invoice_id': invoice.id, } if add_tx_values: diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index b8bdb9787b3..871847cb7b1 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -42,7 +42,6 @@ class AuthSignupHome(Home): template.sudo().with_context( lang=user_sudo.lang, auth_login=werkzeug.url_encode({'auth_login': user_sudo.email}), - password=request.params.get('password') ).send_mail(user_sudo.id, force_send=True) return super(AuthSignupHome, self).web_login(*args, **kw) except UserError as e: diff --git a/addons/auth_signup/data/auth_signup_data.xml b/addons/auth_signup/data/auth_signup_data.xml index 72cb1fa30f0..a58c2d4d9aa 100644 --- a/addons/auth_signup/data/auth_signup_data.xml +++ b/addons/auth_signup/data/auth_signup_data.xml @@ -102,7 +102,6 @@

Your login: ${object.email}
- Your password: ${ctx['password']}

To gain access to your account, you can use the following link: diff --git a/addons/auth_signup/i18n/af.po b/addons/auth_signup/i18n/af.po index e95f0c01e3a..8fe284f2eb6 100644 --- a/addons/auth_signup/i18n/af.po +++ b/addons/auth_signup/i18n/af.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/am.po b/addons/auth_signup/i18n/am.po index 884e96a66f0..7ed08db42cb 100644 --- a/addons/auth_signup/i18n/am.po +++ b/addons/auth_signup/i18n/am.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ar.po b/addons/auth_signup/i18n/ar.po index aec6d4ea4b9..b379535575d 100644 --- a/addons/auth_signup/i18n/ar.po +++ b/addons/auth_signup/i18n/ar.po @@ -115,7 +115,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/auth_signup.pot b/addons/auth_signup/i18n/auth_signup.pot index 3ca1e3ccc53..379775c2600 100644 --- a/addons/auth_signup/i18n/auth_signup.pot +++ b/addons/auth_signup/i18n/auth_signup.pot @@ -102,7 +102,6 @@ msgid "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/bg.po b/addons/auth_signup/i18n/bg.po index 5da9afc881c..96d4cbe6673 100644 --- a/addons/auth_signup/i18n/bg.po +++ b/addons/auth_signup/i18n/bg.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/bs.po b/addons/auth_signup/i18n/bs.po index e30567817fb..72953b3e2fb 100644 --- a/addons/auth_signup/i18n/bs.po +++ b/addons/auth_signup/i18n/bs.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ca.po b/addons/auth_signup/i18n/ca.po index 4154a0f8705..0d58beeaac2 100644 --- a/addons/auth_signup/i18n/ca.po +++ b/addons/auth_signup/i18n/ca.po @@ -134,7 +134,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/cs.po b/addons/auth_signup/i18n/cs.po index bc6da8dee7c..48609ed8491 100644 --- a/addons/auth_signup/i18n/cs.po +++ b/addons/auth_signup/i18n/cs.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/da.po b/addons/auth_signup/i18n/da.po index 3613885ead3..9af60c059ef 100644 --- a/addons/auth_signup/i18n/da.po +++ b/addons/auth_signup/i18n/da.po @@ -111,7 +111,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/de.po b/addons/auth_signup/i18n/de.po index c3fd7bc24bf..21e05ff6e1a 100644 --- a/addons/auth_signup/i18n/de.po +++ b/addons/auth_signup/i18n/de.po @@ -162,7 +162,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/el.po b/addons/auth_signup/i18n/el.po index 527e38d061c..bdd6ddbfdeb 100644 --- a/addons/auth_signup/i18n/el.po +++ b/addons/auth_signup/i18n/el.po @@ -165,7 +165,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" @@ -199,7 +198,6 @@ msgstr "" "

\n" " Email/Όνομα χρήστη: ${object.email}\n" "
\n" -" Κωδικός Πρόσβασης: ${ctx['password']}\n" "

\n" "

\n" " Για να αποκτήσετε πρόσβαση στο λογαριασμό σας, ακολουθήστε τον παρακάτω σύνδεσμο:\n" diff --git a/addons/auth_signup/i18n/en_GB.po b/addons/auth_signup/i18n/en_GB.po index c533eb0e2c3..e9d962451fc 100644 --- a/addons/auth_signup/i18n/en_GB.po +++ b/addons/auth_signup/i18n/en_GB.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es.po b/addons/auth_signup/i18n/es.po index 774a8396e23..3579dd699f2 100644 --- a/addons/auth_signup/i18n/es.po +++ b/addons/auth_signup/i18n/es.po @@ -174,7 +174,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_AR.po b/addons/auth_signup/i18n/es_AR.po index 8013046ee26..52cff67e109 100644 --- a/addons/auth_signup/i18n/es_AR.po +++ b/addons/auth_signup/i18n/es_AR.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_BO.po b/addons/auth_signup/i18n/es_BO.po index 8d0148b3dfe..b1147946e82 100644 --- a/addons/auth_signup/i18n/es_BO.po +++ b/addons/auth_signup/i18n/es_BO.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_CL.po b/addons/auth_signup/i18n/es_CL.po index 5a81f205342..b5a6207ef21 100644 --- a/addons/auth_signup/i18n/es_CL.po +++ b/addons/auth_signup/i18n/es_CL.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_CO.po b/addons/auth_signup/i18n/es_CO.po index b0585f4fa38..9cdb25ddfcb 100644 --- a/addons/auth_signup/i18n/es_CO.po +++ b/addons/auth_signup/i18n/es_CO.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_CR.po b/addons/auth_signup/i18n/es_CR.po index d137efbae8a..2ed09011556 100644 --- a/addons/auth_signup/i18n/es_CR.po +++ b/addons/auth_signup/i18n/es_CR.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_DO.po b/addons/auth_signup/i18n/es_DO.po index 77358762009..5972a4bbd7a 100644 --- a/addons/auth_signup/i18n/es_DO.po +++ b/addons/auth_signup/i18n/es_DO.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_EC.po b/addons/auth_signup/i18n/es_EC.po index fd7782eadce..c8c9bc51c10 100644 --- a/addons/auth_signup/i18n/es_EC.po +++ b/addons/auth_signup/i18n/es_EC.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_PE.po b/addons/auth_signup/i18n/es_PE.po index 9ee0f51c41e..919743b749a 100644 --- a/addons/auth_signup/i18n/es_PE.po +++ b/addons/auth_signup/i18n/es_PE.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_PY.po b/addons/auth_signup/i18n/es_PY.po index 0d37ff54c50..c4dfea726cf 100644 --- a/addons/auth_signup/i18n/es_PY.po +++ b/addons/auth_signup/i18n/es_PY.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/es_VE.po b/addons/auth_signup/i18n/es_VE.po index efbe4c21be1..96b47c37681 100644 --- a/addons/auth_signup/i18n/es_VE.po +++ b/addons/auth_signup/i18n/es_VE.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/et.po b/addons/auth_signup/i18n/et.po index c2d8db1e7dd..e21bd45495d 100644 --- a/addons/auth_signup/i18n/et.po +++ b/addons/auth_signup/i18n/et.po @@ -111,7 +111,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/eu.po b/addons/auth_signup/i18n/eu.po index 9c44dafbd60..035159ebbc5 100644 --- a/addons/auth_signup/i18n/eu.po +++ b/addons/auth_signup/i18n/eu.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/fa.po b/addons/auth_signup/i18n/fa.po index b768510a3af..94919a982a4 100644 --- a/addons/auth_signup/i18n/fa.po +++ b/addons/auth_signup/i18n/fa.po @@ -111,7 +111,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/fi.po b/addons/auth_signup/i18n/fi.po index 1c2f0091215..c2367709374 100644 --- a/addons/auth_signup/i18n/fi.po +++ b/addons/auth_signup/i18n/fi.po @@ -114,7 +114,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/fo.po b/addons/auth_signup/i18n/fo.po index c2b513c1339..47a4304b83d 100644 --- a/addons/auth_signup/i18n/fo.po +++ b/addons/auth_signup/i18n/fo.po @@ -105,7 +105,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/fr.po b/addons/auth_signup/i18n/fr.po index 5d19c895961..345b07411ed 100644 --- a/addons/auth_signup/i18n/fr.po +++ b/addons/auth_signup/i18n/fr.po @@ -168,7 +168,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/fr_CA.po b/addons/auth_signup/i18n/fr_CA.po index 469fd480492..516ffa5ceaa 100644 --- a/addons/auth_signup/i18n/fr_CA.po +++ b/addons/auth_signup/i18n/fr_CA.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/gl.po b/addons/auth_signup/i18n/gl.po index d3ba0b2ac14..7e3f96ee07e 100644 --- a/addons/auth_signup/i18n/gl.po +++ b/addons/auth_signup/i18n/gl.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/he.po b/addons/auth_signup/i18n/he.po index d4adca058c8..5010a56142a 100644 --- a/addons/auth_signup/i18n/he.po +++ b/addons/auth_signup/i18n/he.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/hr.po b/addons/auth_signup/i18n/hr.po index 7ea2aa5a4db..5fe6dfa95cf 100644 --- a/addons/auth_signup/i18n/hr.po +++ b/addons/auth_signup/i18n/hr.po @@ -144,7 +144,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/hu.po b/addons/auth_signup/i18n/hu.po index d88f6f7e87f..242590a5d8c 100644 --- a/addons/auth_signup/i18n/hu.po +++ b/addons/auth_signup/i18n/hu.po @@ -165,7 +165,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/id.po b/addons/auth_signup/i18n/id.po index 6a1a3ff1898..3105d982405 100644 --- a/addons/auth_signup/i18n/id.po +++ b/addons/auth_signup/i18n/id.po @@ -112,7 +112,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/it.po b/addons/auth_signup/i18n/it.po index f590d160d73..4c18b8d3b20 100644 --- a/addons/auth_signup/i18n/it.po +++ b/addons/auth_signup/i18n/it.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ja.po b/addons/auth_signup/i18n/ja.po index 3e28504326f..6824517fdc1 100644 --- a/addons/auth_signup/i18n/ja.po +++ b/addons/auth_signup/i18n/ja.po @@ -165,7 +165,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ka.po b/addons/auth_signup/i18n/ka.po index c484d9eb5ed..f61eb2cd8fb 100644 --- a/addons/auth_signup/i18n/ka.po +++ b/addons/auth_signup/i18n/ka.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/kab.po b/addons/auth_signup/i18n/kab.po index 0dec5bea4da..0e670472029 100644 --- a/addons/auth_signup/i18n/kab.po +++ b/addons/auth_signup/i18n/kab.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ko.po b/addons/auth_signup/i18n/ko.po index d29991121f5..42dba965809 100644 --- a/addons/auth_signup/i18n/ko.po +++ b/addons/auth_signup/i18n/ko.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/lo.po b/addons/auth_signup/i18n/lo.po index e7bb5b2769a..8ae06fffbc2 100644 --- a/addons/auth_signup/i18n/lo.po +++ b/addons/auth_signup/i18n/lo.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/lt.po b/addons/auth_signup/i18n/lt.po index 31c1bc8ff2a..2ff10d5155a 100644 --- a/addons/auth_signup/i18n/lt.po +++ b/addons/auth_signup/i18n/lt.po @@ -112,7 +112,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/lv.po b/addons/auth_signup/i18n/lv.po index 9b1970fc14b..1f493481075 100644 --- a/addons/auth_signup/i18n/lv.po +++ b/addons/auth_signup/i18n/lv.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/mk.po b/addons/auth_signup/i18n/mk.po index 723427f51d1..2bb3dadd211 100644 --- a/addons/auth_signup/i18n/mk.po +++ b/addons/auth_signup/i18n/mk.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/mn.po b/addons/auth_signup/i18n/mn.po index 2ac736ff37e..e2ab4e9d82e 100644 --- a/addons/auth_signup/i18n/mn.po +++ b/addons/auth_signup/i18n/mn.po @@ -105,7 +105,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/nb.po b/addons/auth_signup/i18n/nb.po index e16abb8be70..0732fbeafc3 100644 --- a/addons/auth_signup/i18n/nb.po +++ b/addons/auth_signup/i18n/nb.po @@ -110,7 +110,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ne.po b/addons/auth_signup/i18n/ne.po index 8937826cf50..b05079f39bf 100644 --- a/addons/auth_signup/i18n/ne.po +++ b/addons/auth_signup/i18n/ne.po @@ -105,7 +105,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/nl.po b/addons/auth_signup/i18n/nl.po index 2fae789bf5f..94ba16c4dd4 100644 --- a/addons/auth_signup/i18n/nl.po +++ b/addons/auth_signup/i18n/nl.po @@ -167,7 +167,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" @@ -201,7 +200,6 @@ msgstr "" "

\n" " Uw login: ${object.email}\n" "
\n" -" Uw wachtwoord: ${ctx['password']}\n" "

\n" "

\n" " Om toegang te krijgen tot uw account, kan u de volgende link gebruiken::\n" diff --git a/addons/auth_signup/i18n/nl_BE.po b/addons/auth_signup/i18n/nl_BE.po index 405e872d815..85eb30d00cd 100644 --- a/addons/auth_signup/i18n/nl_BE.po +++ b/addons/auth_signup/i18n/nl_BE.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/pl.po b/addons/auth_signup/i18n/pl.po index fbb0f81860f..314a2b54cb9 100644 --- a/addons/auth_signup/i18n/pl.po +++ b/addons/auth_signup/i18n/pl.po @@ -114,7 +114,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/pt.po b/addons/auth_signup/i18n/pt.po index e1e03417c01..ba4833e46b5 100644 --- a/addons/auth_signup/i18n/pt.po +++ b/addons/auth_signup/i18n/pt.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/pt_BR.po b/addons/auth_signup/i18n/pt_BR.po index 3b2b3c0b29b..0375c301797 100644 --- a/addons/auth_signup/i18n/pt_BR.po +++ b/addons/auth_signup/i18n/pt_BR.po @@ -167,7 +167,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" @@ -201,7 +200,6 @@ msgstr "" "

\n" " Seu login: ${object.email}\n" "
\n" -" Sua senha: ${ctx['password']}\n" "

\n" "

\n" " Para acessar sua conta, você pode acessar o seguinte link:\n" diff --git a/addons/auth_signup/i18n/ro.po b/addons/auth_signup/i18n/ro.po index 70f19bf3768..5178308b08a 100644 --- a/addons/auth_signup/i18n/ro.po +++ b/addons/auth_signup/i18n/ro.po @@ -139,7 +139,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/ru.po b/addons/auth_signup/i18n/ru.po index 64d0fa145bc..8a9cd8d9bae 100644 --- a/addons/auth_signup/i18n/ru.po +++ b/addons/auth_signup/i18n/ru.po @@ -173,7 +173,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sk.po b/addons/auth_signup/i18n/sk.po index 5eb7f676417..5138b206acf 100644 --- a/addons/auth_signup/i18n/sk.po +++ b/addons/auth_signup/i18n/sk.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sl.po b/addons/auth_signup/i18n/sl.po index e887136c172..ffc11c07444 100644 --- a/addons/auth_signup/i18n/sl.po +++ b/addons/auth_signup/i18n/sl.po @@ -105,7 +105,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sq.po b/addons/auth_signup/i18n/sq.po index 164fdf95948..0bcff3b0ad8 100644 --- a/addons/auth_signup/i18n/sq.po +++ b/addons/auth_signup/i18n/sq.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sr.po b/addons/auth_signup/i18n/sr.po index 39bcf501d75..6a1f8a51afb 100644 --- a/addons/auth_signup/i18n/sr.po +++ b/addons/auth_signup/i18n/sr.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sr@latin.po b/addons/auth_signup/i18n/sr@latin.po index 0efb9c4cfda..0a9f5db16b1 100644 --- a/addons/auth_signup/i18n/sr@latin.po +++ b/addons/auth_signup/i18n/sr@latin.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/sv.po b/addons/auth_signup/i18n/sv.po index d3b6c33642c..aa14a9b4a39 100644 --- a/addons/auth_signup/i18n/sv.po +++ b/addons/auth_signup/i18n/sv.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/th.po b/addons/auth_signup/i18n/th.po index 16eaf1167ef..46fe1210082 100644 --- a/addons/auth_signup/i18n/th.po +++ b/addons/auth_signup/i18n/th.po @@ -108,7 +108,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/tr.po b/addons/auth_signup/i18n/tr.po index 00fbe962c82..17d13118d7c 100644 --- a/addons/auth_signup/i18n/tr.po +++ b/addons/auth_signup/i18n/tr.po @@ -171,7 +171,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/uk.po b/addons/auth_signup/i18n/uk.po index 51df9435a86..83cfb0e5b94 100644 --- a/addons/auth_signup/i18n/uk.po +++ b/addons/auth_signup/i18n/uk.po @@ -167,7 +167,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/vi.po b/addons/auth_signup/i18n/vi.po index 4fd58b26cfa..84d5bab21b7 100644 --- a/addons/auth_signup/i18n/vi.po +++ b/addons/auth_signup/i18n/vi.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/zh_CN.po b/addons/auth_signup/i18n/zh_CN.po index db90fbcb26e..bd89431a070 100644 --- a/addons/auth_signup/i18n/zh_CN.po +++ b/addons/auth_signup/i18n/zh_CN.po @@ -140,7 +140,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/i18n/zh_TW.po b/addons/auth_signup/i18n/zh_TW.po index 150c5b36fd4..a92edce19b1 100644 --- a/addons/auth_signup/i18n/zh_TW.po +++ b/addons/auth_signup/i18n/zh_TW.po @@ -109,7 +109,6 @@ msgid "" "

\n" " Your login: ${object.email}\n" "
\n" -" Your password: ${ctx['password']}\n" "

\n" "

\n" " To gain access to your account, you can use the following link:\n" diff --git a/addons/auth_signup/models/res_partner.py b/addons/auth_signup/models/res_partner.py index 9fbcd27872f..17171c645f6 100644 --- a/addons/auth_signup/models/res_partner.py +++ b/addons/auth_signup/models/res_partner.py @@ -32,6 +32,7 @@ class ResPartner(models.Model): signup_url = fields.Char(compute='_compute_signup_url', string='Signup URL') @api.multi + @api.depends('signup_token', 'signup_expiration') def _compute_signup_valid(self): dt = now() for partner in self: diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index f6dd0fbb9d8..b2ffaf67231 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -96,9 +96,10 @@ class SaleOrder(models.Model): taxes_ids = self.fiscal_position_id.map_tax(taxes, carrier.product_id, self.partner_id).ids # Create the sales order line + carrier_name = carrier.product_id.with_context(lang=self.partner_id.lang).name_get()[0][1] values = { 'order_id': self.id, - 'name': carrier.name, + 'name': carrier_name, 'product_uom_qty': 1, 'product_uom': carrier.product_id.uom_id.id, 'product_id': carrier.product_id.id, diff --git a/addons/event/models/event.py b/addons/event/models/event.py index 02b1c1a3489..1dc2ccb60d6 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -220,6 +220,11 @@ class EventEvent(models.Model): else: self.date_end_located = False + @api.onchange('is_online') + def _onchange_is_online(self): + if self.is_online: + self.address_id = False + @api.onchange('event_type_id') def _onchange_type(self): if self.event_type_id: diff --git a/addons/event/models/event_mail.py b/addons/event/models/event_mail.py index 1013f5a083b..680e1d4ba8a 100644 --- a/addons/event/models/event_mail.py +++ b/addons/event/models/event_mail.py @@ -4,7 +4,12 @@ from datetime import datetime from dateutil.relativedelta import relativedelta from odoo import api, fields, models, tools +from odoo.tools import exception_to_unicode +from odoo.tools.translate import _ +import random +import logging +_logger = logging.getLogger(__name__) _INTERVALS = { 'hours': lambda interval: relativedelta(hours=interval), @@ -114,13 +119,52 @@ class EventMailScheduler(models.Model): self.write({'mail_sent': True}) return True + @api.model + def _warn_template_error(self, scheduler, exception): + # We warn ~ once by hour ~ instead of every 10 min if the interval unit is more than 'hours'. + if random.random() < 0.1666 or scheduler.interval_unit in ('now', 'hours'): + ex_s = exception_to_unicode(exception) + try: + event, template = scheduler.event_id, scheduler.template_id + emails = list(set([event.organizer_id.email, event.user_id.email, template.write_uid.email])) + subject = _("WARNING: Event Scheduler Error for event: %s" % event.name) + body = _("""Event Scheduler for: + - Event: %s (%s) + - Scheduled: %s + - Template: %s (%s) + + Failed with error: + - %s + + You receive this email because you are: + - the organizer of the event, + - or the responsible of the event, + - or the last writer of the template.""" + % (event.name, event.id, scheduler.scheduled_date, template.name, template.id, ex_s)) + email = self.env['ir.mail_server'].build_email( + email_from=self.env.user.email, + email_to=emails, + subject=subject, body=body, + ) + self.env['ir.mail_server'].send_email(email) + except Exception as e: + _logger.error("Exception while sending traceback by email: %s.\n Original Traceback:\n%s", e, exception) + pass + @api.model def run(self, autocommit=False): schedulers = self.search([('done', '=', False), ('scheduled_date', '<=', datetime.strftime(fields.datetime.now(), tools.DEFAULT_SERVER_DATETIME_FORMAT))]) for scheduler in schedulers: - scheduler.execute() - if autocommit: - self.env.cr.commit() + try: + with self.env.cr.savepoint(): + scheduler.execute() + except Exception as e: + _logger.exception(e) + self.invalidate_cache() + self._warn_template_error(scheduler, e) + else: + if autocommit: + self.env.cr.commit() return True diff --git a/addons/event/security/ir.model.access.csv b/addons/event/security/ir.model.access.csv index 49d859ad183..ed7ec0e0cc6 100644 --- a/addons/event/security/ir.model.access.csv +++ b/addons/event/security/ir.model.access.csv @@ -5,7 +5,7 @@ access_event_event_portal,event.event.portal,model_event_event,,1,0,0,0 access_event_event_user,event.event.user,model_event_event,event.group_event_user,1,0,0,0 access_event_event_manager,event.event.manager,model_event_event,event.group_event_manager,1,1,1,1 access_event_registration,event.registration,model_event_registration,event.group_event_user,1,1,1,1 -access_event_registration_portal,event.registration,model_event_registration,,1,0,0,0 +access_event_registration_portal,event.registration,model_event_registration,,0,0,0,0 access_event_mail,event.mail,model_event_mail,event.group_event_user,1,0,0,0 access_event_mail_manager,event.mail manager,model_event_mail,event.group_event_manager,1,1,1,1 access_event_mail_registration,event.mail.registration,model_event_mail_registration,event.group_event_user,1,0,0,0 diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index 7a2dcd8a745..6902d8e4743 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -41,7 +41,7 @@ class SaleOrderLine(models.Model): order line has a product_uom_qty attribute that will be the number of registrations linked to this line. This method update existing registrations and create new one for missing one. """ - Registration = self.env['event.registration'] + Registration = self.env['event.registration'].sudo() registrations = Registration.search([('sale_order_line_id', 'in', self.ids), ('state', '!=', 'cancel')]) for so_line in self.filtered('event_id'): existing_registrations = registrations.filtered(lambda self: self.sale_order_line_id.id == so_line.id) diff --git a/addons/hr_attendance/models/hr_employee.py b/addons/hr_attendance/models/hr_employee.py index 3f7eee536cf..e0cec9681bc 100644 --- a/addons/hr_attendance/models/hr_employee.py +++ b/addons/hr_attendance/models/hr_employee.py @@ -54,7 +54,8 @@ class HrEmployee(models.Model): @api.depends('last_attendance_id.check_in', 'last_attendance_id.check_out', 'last_attendance_id') def _compute_attendance_state(self): for employee in self: - employee.attendance_state = employee.last_attendance_id and not employee.last_attendance_id.check_out and 'checked_in' or 'checked_out' + att = employee.last_attendance_id.sudo() + employee.attendance_state = att and not att.check_out and 'checked_in' or 'checked_out' @api.constrains('pin') def _verify_pin(self): diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 57595b2643e..2bfbd27ed1f 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -114,11 +114,6 @@ class HolidaysRequest(models.Model): ('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0."), ] - @api.onchange('employee_id') - def _onchange_employee_id(self): - self.manager_id = self.employee_id and self.employee_id.parent_id - self.department_id = self.employee_id.department_id - @api.multi @api.depends('number_of_days_temp') def _compute_number_of_days(self): @@ -160,7 +155,8 @@ class HolidaysRequest(models.Model): self.department_id = None @api.onchange('employee_id') - def _onchange_employee(self): + def _onchange_employee_id(self): + self.manager_id = self.employee_id and self.employee_id.parent_id if self.holiday_type == 'employee': self.department_id = self.employee_id.department_id diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index ee73147ed3f..1e8e3429206 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -73,6 +73,7 @@ class AccountAnalyticLine(models.Model): if vals.get('project_id') and not vals.get('account_id'): project = self.env['project.project'].browse(vals.get('project_id')) vals['account_id'] = project.analytic_account_id.id + vals['company_id'] = project.analytic_account_id.company_id.id if not project.analytic_account_id.active: raise UserError(_('The project you are timesheeting on is not linked to a active analytic account. Please the project configuration.')) # employee implies user diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py index 12f742231f7..6276aa166ca 100644 --- a/addons/hr_timesheet/models/project.py +++ b/addons/hr_timesheet/models/project.py @@ -154,8 +154,10 @@ class Task(models.Model): # a timesheet must have an analytic account (and a project) if self and not project_id: raise UserError(_('This task must have a project since they are linked to timesheets.')) + account_id = self.env['project.project'].browse(project_id).sudo().analytic_account_id self.sudo().mapped('timesheet_ids').write({ 'project_id': project_id, - 'account_id': self.env['project.project'].browse(project_id).sudo().analytic_account_id.id + 'account_id': account_id.id, + 'company_id': account_id.company_id.id, }) return result diff --git a/addons/http_routing/geoipresolver.py b/addons/http_routing/geoipresolver.py index e95b9318eb2..24bbe723d6d 100644 --- a/addons/http_routing/geoipresolver.py +++ b/addons/http_routing/geoipresolver.py @@ -50,10 +50,10 @@ class GeoIPResolver(object): # Compatibility with Legacy database. # Some ips cannot be located to a specific country. Legacy DB used to locate them in # continent instead of country. Do the same to not change behavior of existing code. - country = r.country if r.country.geoname_id else r.continent + country, attr = (r.country, 'iso_code') if r.country.geoname_id else (r.continent, 'code') return { 'city': r.city.name, - 'country_code': country.iso_code, + 'country_code': getattr(country, attr), 'country_name': country.name, 'region': r.subdivisions[0].iso_code if r.subdivisions else None, 'time_zone': r.location.time_zone, diff --git a/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py b/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py index cf9901281c5..2ec6e172ee1 100644 --- a/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py +++ b/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py @@ -126,7 +126,7 @@ class HrContract(models.Model): @api.depends('commission_on_target') def _compute_warrants_cost(self): for contract in self: - contract.warrants_cost = contract.commission_on_target * 1.326 * 1.05 * 12.0 + contract.warrants_cost = contract.commission_on_target * 1.326 / 1.05 * 12.0 contract.warrant_value_employee = contract.commission_on_target * 1.326 * (1.00 - 0.535) * 12.0 @api.depends('wage', 'fuel_card', 'representation_fees', 'transport_employer_cost', diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 86cd33c67d2..d5df5901608 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -416,8 +416,17 @@ class Message(models.Model): com_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment') note_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note') + # fetch notification status + notif_dict = {} + notifs = self.env['mail.notification'].sudo().search([('mail_message_id', 'in', list(mid for mid in message_tree)), ('is_read', '=', False)]) + for notif in notifs: + mid = notif.mail_message_id.id + if not notif_dict.get(mid): + notif_dict[mid] = {'partner_id': list()} + notif_dict[mid]['partner_id'].append(notif.res_partner_id.id) + for message in message_values: - message['needaction_partner_ids'] = self.env['mail.notification'].sudo().search([('mail_message_id', '=', message['id']), ('is_read', '=', False)]).mapped('res_partner_id').ids + message['needaction_partner_ids'] = notif_dict.get(message['id'], dict()).get('partner_id', []) message['is_note'] = message['subtype_id'] and subtypes_dict[message['subtype_id'][0]]['id'] == note_id message['is_discussion'] = message['subtype_id'] and subtypes_dict[message['subtype_id'][0]]['id'] == com_id message['is_notification'] = message['is_note'] and not message['model'] and not message['res_id'] diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 023077e1859..e32bf8d270d 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1354,7 +1354,13 @@ class MailThread(models.AbstractModel): located in tools. """ if not body: return body, attachments - root = lxml.html.fromstring(body) + try: + root = lxml.html.fromstring(body) + except ValueError: + # In case the email client sent XHTML, fromstring will fail because 'Unicode strings + # with encoding declaration are not supported'. + root = lxml.html.fromstring(body.encode('utf-8')) + postprocessed = False to_remove = [] for node in root.iter(): diff --git a/addons/mail/static/src/js/chatter.js b/addons/mail/static/src/js/chatter.js index dfc041325d9..e48a7c60028 100644 --- a/addons/mail/static/src/js/chatter.js +++ b/addons/mail/static/src/js/chatter.js @@ -184,7 +184,7 @@ var Chatter = Widget.extend({ input_baseline: 14, is_log: options && options.is_log, record_name: this.record_name, - default_body: old_composer && old_composer.$input && old_composer.$input.html(), + default_body: old_composer && old_composer.$input && old_composer.$input.val(), default_mention_selections: old_composer && old_composer.mention_get_listener_selections(), }); this.composer.on('input_focused', this, function () { @@ -247,7 +247,7 @@ var Chatter = Widget.extend({ }).always(function () { // disable widgets in create mode, otherwise enable self.isCreateMode ? self._disableChatter() : self._enableChatter(); - $spinner.remove; + $spinner.remove(); }); }, /** diff --git a/addons/mail/static/src/js/chatter_composer.js b/addons/mail/static/src/js/chatter_composer.js index ad21a16496f..da85f331863 100644 --- a/addons/mail/static/src/js/chatter_composer.js +++ b/addons/mail/static/src/js/chatter_composer.js @@ -212,7 +212,7 @@ var ChatterComposer = composer.BasicComposer.extend({ recipient_done.then(function (partner_ids) { var context = { default_parent_id: self.id, - default_body: utils.get_text2html(self.$input.html()), + default_body: utils.get_text2html(self.$input.val()), default_attachment_ids: _.pluck(self.get('attachment_ids'), 'id'), default_partner_ids: partner_ids, default_is_log: self.options.is_log, diff --git a/addons/mail/static/src/js/composer.js b/addons/mail/static/src/js/composer.js index 8354fe610b5..f89c0382554 100644 --- a/addons/mail/static/src/js/composer.js +++ b/addons/mail/static/src/js/composer.js @@ -7,6 +7,7 @@ var utils = require('mail.utils'); var config = require('web.config'); var core = require('web.core'); var data = require('web.data'); +var dom = require('web.dom'); var session = require('web.session'); var Widget = require('web.Widget'); @@ -29,7 +30,7 @@ var MentionManager = Widget.extend({ events: { "mouseover .o_mention_proposition": "on_hover_mention_proposition", - "click .o_mention_proposition": "_onClickMentionItem", + "click .o_mention_proposition": "on_click_mention_item", }, init: function (parent, options) { @@ -52,6 +53,49 @@ var MentionManager = Widget.extend({ this.$('.o_mention_proposition').removeClass('active'); $elem.addClass('active'); }, + on_click_mention_item: function (event) { + event.preventDefault(); + + var text_input = this.composer.$input.val(); + var id = $(event.currentTarget).data('id'); + var selected_suggestion = _.find(_.flatten(this.get('mention_suggestions')), function (s) { + return s.id === id; + }); + var substitution = selected_suggestion.substitution; + if (!substitution) { // no substitution string given, so use the mention name instead + // replace white spaces with non-breaking spaces to facilitate mentions detection in text + selected_suggestion.name = selected_suggestion.name.replace(/ /g, NON_BREAKING_SPACE); + substitution = this.active_listener.delimiter + selected_suggestion.name; + } + var get_mention_index = function (matches, cursor_position) { + for (var i=0; i 0) { return false; } - var search_str = textVal.substring(delimiter_position, cursorPosition); + var search_str = text_val.substring(delimiter_position, cursor_position); var pattern = "(^"+delimiter+"|(^\\s"+delimiter+"))"; var regex_start = new RegExp(pattern, "g"); search_str = search_str.replace(/^\s\s*|^[\n\r]/g, ''); @@ -203,8 +247,6 @@ var MentionManager = Widget.extend({ /** * Returns the matches (as RexExp.exec does) for the mention in the input text - * - * @private * @param {String} input_text: the text to search matches * @param {Object} listener: the listener for which we want to find a match * @returns {Object[]} matches in the same format as RexExp.exec() @@ -228,32 +270,6 @@ var MentionManager = Widget.extend({ } return result; }, - /** - * Get cursor position in contenteditable div with it's inner html content. - * - * @private - * @return a current cursor position - */ - _getSelectionPositions: function () { - if (window.getSelection && window.getSelection().getRangeAt) { - var range = window.getSelection().getRangeAt(0); - var selectedObj = window.getSelection(); - var rangeCount = 0; - var childNodes = selectedObj.anchorNode.parentNode.childNodes; - for (var i = 0; i < childNodes.length; i++) { - if (childNodes[i] === selectedObj.anchorNode) { - break; - } - if (childNodes[i].outerHTML) - rangeCount += childNodes[i].outerHTML.length; - else if (childNodes[i].nodeType === 3) { - rangeCount += childNodes[i].textContent.length; - } - } - return range.startOffset + rangeCount; - } - return -1; - }, /** * @private * @param {integer} keycode @@ -312,23 +328,9 @@ var MentionManager = Widget.extend({ this.open = false; } }, - /* - * Set cursor position after mention is added. - * @private - * @paran {int} node - id of childnode to set cursor position after it. - */ - _setCursorPosition: function (nodeID) { - var range = document.createRange(); - var selection = window.getSelection(); - range.setStart(document.getElementById(nodeID).nextSibling, 1); - range.collapse(true); - selection.removeAllRanges(); - selection.addRange(range); - this.composer.$input.focus(); - }, - _validate_selection: function (selection, inputMentions) { + _validate_selection: function (selection, input_mentions) { var validated_selection = []; - _.each(inputMentions, function (mention) { + _.each(input_mentions, function (mention) { var validated_mention = _.findWhere(selection, {name: mention.slice(1)}); if (validated_mention) { validated_selection.push(validated_mention); @@ -337,60 +339,15 @@ var MentionManager = Widget.extend({ return validated_selection; }, - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * after click on mention item it set to a contenteditable div with it's new - * cursor postion - * - * @private - * @param {KeyboardEvent} event - to get a current selected mention from - * list and eventlistener. - */ - _onClickMentionItem: function (event) { - event.preventDefault(); - - var textInput = this.composer.$input.html(); - var id = $(event.currentTarget).data('id'); - var selectedSuggestion = _.find(_.flatten(this.get('mention_suggestions')), function (s) { - return s.id === id; + // Cursor position and selection utils + _get_selection_positions: function () { + var el = this.composer.$input.get(0); + return el ? dom.getSelectionRange(el) : {start: 0, end: 0}; + }, + _set_cursor_position: function (pos) { + this.composer.$input.each(function (index, elem) { + dom.setSelectionRange(elem, {start: pos, end: pos}); }); - var substitution = selectedSuggestion.substitution; - if (!substitution) { // no substitution string given, so use the mention name instead - // replace white spaces with non-breaking spaces to facilitate mentions detection in text - selectedSuggestion.name = selectedSuggestion.name.replace(/ /g, NON_BREAKING_SPACE); - substitution = _.escape(this.active_listener.delimiter + selectedSuggestion.name); - } - var getMentionIndex = function (matches, cursorPosition) { - for (var i=0; i" + substitution + " " + textRight; - this.composer.$input.html(newTextInput); - this._setCursorPosition(nodeID); - this.set('mention_suggestions', []); }, }); @@ -398,8 +355,8 @@ var MentionManager = Widget.extend({ var BasicComposer = Widget.extend({ template: "mail.ChatComposer", events: { - "keydown .o_composer_input": "_onKeydown", - "keyup .o_composer_input": "_onKeyup", + "keydown .o_composer_input textarea": "on_keydown", + "keyup .o_composer_input": "on_keyup", "change input.o_input_file": "on_attachment_change", "click .o_composer_button_send": "send_message", "click .o_composer_button_add_attachment": "on_click_add_attachment", @@ -410,7 +367,6 @@ var BasicComposer = Widget.extend({ 'focusout .o_composer_button_emoji': '_onEmojiButtonFocusout', 'focus .o_mail_emoji_container .o_mail_emoji': '_onEmojiImageFocus', 'click .o_mail_emoji_container .o_mail_emoji': '_onEmojiImageClick', - 'input .o_composer_input': '_removeMention', }, // RPCs done to fetch the mention suggestions are throttled with the following value MENTION_THROTTLE: 200, @@ -487,12 +443,12 @@ var BasicComposer = Widget.extend({ this.$attachment_button = this.$(".o_composer_button_add_attachment"); this.$attachments_list = this.$('.o_composer_attachments_list'); - this.$input = this.$('.o_composer_input'); + this.$input = this.$('.o_composer_input textarea'); this.$input.focus(function () { self.trigger('input_focused'); }); - this.$input.html(this.options.default_body); - this.$input.css('min-height', this.options.input_min_height); + this.$input.val(this.options.default_body); + dom.autoresize(this.$input, {parent: this, min_height: this.options.input_min_height}); // Attachments $(window).on(this.fileupload_id, this.on_attachment_loaded); @@ -514,7 +470,7 @@ var BasicComposer = Widget.extend({ // behavior for the chatter composer //Removing unwanted extra spaces from message - var value = _.escape(this.$input.text()).trim(); + var value = _.escape(this.$input.val()).trim(); value = value.replace(/(\r|\n){2,}/g, '

'); value = value.replace(/(\r|\n)/g, '
'); @@ -545,7 +501,7 @@ var BasicComposer = Widget.extend({ clear_composer: function() { // Empty input, selected partners and attachments - this.$input.html(''); + this.$input.val(''); this.mention_manager.reset_selections(); this.set('attachment_ids', []); }, @@ -557,7 +513,7 @@ var BasicComposer = Widget.extend({ getState: function () { return { attachments: this.get('attachment_ids'), - text: this.$input.html(), + text: this.$input.val(), }; }, @@ -572,7 +528,7 @@ var BasicComposer = Widget.extend({ setState: function (state) { this.set('attachment_ids', state.attachments); - this.$input.html(state.text); + this.$input.val(state.text); }, /** @@ -581,18 +537,8 @@ var BasicComposer = Widget.extend({ should_send: function (event) { return !event.shiftKey; }, - /** - * _onKeydown event is triggered when is key is pressed - * - on UP and DOWN arrow is pressed then event prevents it's default - * behaviour if mention manager is open else it break it. - * - on ENTER key is pressed and mention manager is open then event - * prevents it's default behaviour else check if ControlKey is - * pressed or not if yes then it send a message - * - * @private - * @param {KeyboardEvent} event - */ - _onKeydown: function (event) { + + on_keydown: function (event) { switch(event.which) { // UP, DOWN, TAB: prevent moving cursor if navigation in mention propositions case $.ui.keyCode.UP: @@ -617,16 +563,7 @@ var BasicComposer = Widget.extend({ } }, - /** - * _onKeyup event is triggered when key is released. - * on ESCAP key it close the mention suggestion dropdown menu. - * on ENTER key it selects that mention and add to a content editable div. - * on UP or DOWN key it highlights previous or next mention respectively. - * - * @private - * @param {KeyboardEvent} event - */ - _onKeyup: function (event) { + on_keyup: function (event) { switch(event.which) { // ESCAPED KEYS: do nothing case $.ui.keyCode.END: @@ -743,12 +680,6 @@ var BasicComposer = Widget.extend({ attachments: this.get('attachment_ids'), })); }, - // remove mention when user try to edit or remove it. - _removeMention: function (event) { - if (window.getSelection().anchorNode.parentNode.tagName === 'A') { - document.getElementById(window.getSelection().anchorNode.parentNode.id).remove(); - } - }, // Mention mention_fetch_throttled: function (model, method, kwargs) { @@ -834,14 +765,8 @@ var BasicComposer = Widget.extend({ }, // Others - /** - * used to check if contenteditable div is empty or not - * - * @return - it returns length of attachment and trim content of input box - * tp check for empty. - */ is_empty: function () { - return !this.$input.text().trim() && !this.$('.o_attachments').children().length; + return !this.$input.val().trim() && !this.$('.o_attachments').children().length; }, focus: function () { this.$input.focus(); @@ -900,7 +825,7 @@ var BasicComposer = Widget.extend({ if (this.$emojisContainer.parent().length) { this._hideEmojis(); } else { - this.$emojisContainer.appendTo(this.$('.o_composer_container')); + this.$emojisContainer.appendTo(this.$('.o_composer')); } }, /** @@ -924,31 +849,6 @@ var BasicComposer = Widget.extend({ _onEmojiImageFocus: function () { clearTimeout(this._hideEmojisTimeout); }, - /** - * set cursor position at the end in input box - * - * @todo move that kind of code in a utility file. Maybe dom.js - * - * @private - * @param {Element} el - */ - _placeCaretAtEnd: function (el) { - el.focus(); - if (typeof window.getSelection !== "undefined" - && typeof document.createRange !== "undefined") { - var range = document.createRange(); - range.selectNodeContents(el); - range.collapse(false); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - } else if (typeof document.body.createTextRange !== "undefined") { - var textRange = document.body.createTextRange(); - textRange.moveToElementText(el); - textRange.collapse(false); - textRange.select(); - } - }, /** * Called when an emoji is clicked -> adds it in the , focuses the * and closes the emoji panel. @@ -957,8 +857,8 @@ var BasicComposer = Widget.extend({ * @param {Event} ev */ _onEmojiImageClick: function (ev) { - this.$input.html(this.$input.html() + " " + $(ev.currentTarget).data('emoji') + " "); - this._placeCaretAtEnd(this.$input[0]); + this.$input.val(this.$input.val() + " " + $(ev.currentTarget).data('emoji') + " "); + this.$input.focus(); this._hideEmojis(); }, }); diff --git a/addons/mail/static/src/less/composer.less b/addons/mail/static/src/less/composer.less index eb80e9e2691..1686444970d 100644 --- a/addons/mail/static/src/less/composer.less +++ b/addons/mail/static/src/less/composer.less @@ -16,6 +16,7 @@ position: relative; .o-flex(0, 0, auto); .o-flex-display(); + margin: 1px 0; border-top: none; background: @gray-lighter; @@ -23,7 +24,7 @@ position: relative; background: white; - input { + textarea, input { border: none; } } @@ -40,21 +41,9 @@ } .o_composer { - .o_composer_input[contenteditable=true]:empty:before { - content: attr(placeholder); - opacity: 0.4; - } - .o_composer_input { - border: none; - box-shadow: none; - cursor: text; - display: inline-block; - height: 100%; - white-space: pre-wrap; - word-break: break-all; - } - .o_composer_text_field { - padding: 0 0 @o-mail-chatter-gap; + .o_composer_input > textarea { + width: 100%; + resize: none; } .o_composer_mention_dropdown .o_mention_proposition > a { .o-text-overflow(); @@ -83,18 +72,19 @@ color: @odoo-brand-optional; } } - } - .o_mail_emoji_container { - padding: 0 @o-mail-chatter-gap @o-mail-chatter-gap 0; - border: 1px solid @gray-lighter-dark; - background-color: @gray-lighter; + .o_mail_emoji_container { + padding: 0 @o-mail-chatter-gap @o-mail-chatter-gap 0; + border: 1px solid @gray-lighter-dark; + border-width: 1px 0 0 0; + background-color: @gray-lighter; - .o_mail_emoji { - margin: @o-mail-chatter-gap 0 0 @o-mail-chatter-gap; - cursor: pointer; // only in the popover + .o_mail_emoji { + margin: @o-mail-chatter-gap 0 0 @o-mail-chatter-gap; + cursor: pointer; // only in the popover min-width: 20px; min-height: 20px; + } } } @@ -120,13 +110,19 @@ .o_composer { border-radius: 2px; + textarea { + padding-right: @grid-gutter-width; // avoid overlaps betwenn textarea and o_composer_button_full_composer + } + .o_mail_emoji_container { + margin: 0 -@o-mail-chatter-gap; + } } .o_composer, .o_composer_subject { border: 1px solid @gray-lighter-dark; - input { + textarea, input { padding: 0 0 @o-mail-chatter-gap; border: none; } @@ -138,9 +134,6 @@ .o_chatter_composer_tools { border-top: 1px solid @gray-lighter-dark; - @media (max-width: @screen-xs-max) { - margin-top: 10px; - } } &:not(.o_chat_inline_composer) { @@ -159,24 +152,26 @@ &.o_chat_inline_composer { .o_composer_container { - .o-flex(1, 1, auto); + .o-flex(1, 0, auto); } .o_composer { - display: flex; - min-height: 40px; + padding: @o-mail-chatter-gap @o-mail-chatter-gap 0 @o-mail-chatter-gap; border-radius: 2px 0 0 2px; border-right-width: 0; - } - .o_mail_emoji_container { - text-align: right; - border-width: 1px; + + .o_mail_emoji_container { + text-align: right; + border-right-width: 1px; + } } .o_composer_input { + .o-flex-display(); .o-flex-flow(row, wrap); } .o_composer_text_field { - padding: @o-mail-chatter-gap; .o-flex(1, 1, 50%); + margin: 0; + padding: 0; } .o_chatter_composer_tools { .o-flex(0, 1, auto); @@ -188,8 +183,8 @@ .o_chatter_composer_tools { border: none; border-left: 1px solid @gray-lighter-dark; - padding-top: @o-mail-chatter-gap*0.5; padding-left: @o-mail-chatter-gap*0.5; + .o-transform(translateY(-@o-mail-chatter-gap*0.5)); } .o_composer_button_send { @@ -208,26 +203,32 @@ border-top: 1px solid @gray-lighter-dark; width: 100%; } - .o_mail_emoji_container { - .o-position-absolute(auto, 0, 100%, 0); - border-bottom-width: 1px; + .o_composer { + .o_mail_emoji_container { + .o-position-absolute(auto, 0, 100%, 0); + border-bottom-width: 1px; + } } .o_composer_input { - padding: @o-mail-chatter-gap; + .o-flex-display(); .o-flex-flow(row, nowrap); + textarea.o_composer_text_field { + .o-flex(1, 1, auto); + } + .o_chatter_composer_tools { .o-flex(0, 0, auto); } + @media (max-width: @screen-xs-max) { + .o_composer_button_send { + display: inline-block; + } + } } .o_composer_button_send, .o_chatter_avatar { display: none; } - @media (max-width: @screen-xs-max) { - .o_composer_button_send { - display: inline-block; - } - } } } diff --git a/addons/mail/static/src/less/extended_chat_window.less b/addons/mail/static/src/less/extended_chat_window.less index fcf92cf052a..3ae73dee861 100644 --- a/addons/mail/static/src/less/extended_chat_window.less +++ b/addons/mail/static/src/less/extended_chat_window.less @@ -42,14 +42,10 @@ } .o_chatter_composer_tools { .o-position-absolute(@right: 0px, @top: 0px); - - @media (max-width: @screen-xs-max) { - .o-position-absolute(@right: 6px, @top: 0px); - } button { - padding: 8px; + padding: 10px; @media (max-width: @screen-xs-max) { - padding: 7px 6px 0px 6px; + padding: 13px; } &.btn-icon { font-size: 1.3em; diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index 90beedc147f..bb9321a749d 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -8,11 +8,13 @@

-
-
-