summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
Diffstat (limited to 'addons')
-rw-r--r--addons/account/models/account_account.py12
-rw-r--r--addons/account/models/account_bank_statement.py41
-rw-r--r--addons/account/models/account_journal.py12
-rw-r--r--addons/account/models/account_move.py27
-rw-r--r--addons/account/models/account_partial_reconcile.py2
-rw-r--r--addons/account/models/account_payment.py4
-rw-r--r--addons/account/models/account_tax.py2
-rw-r--r--addons/account/models/chart_template.py2
-rw-r--r--addons/account/models/company.py2
-rw-r--r--addons/account/models/res_bank.py2
-rw-r--r--addons/account/models/sequence_mixin.py2
-rw-r--r--addons/account/wizard/account_accrual_accounting.py2
-rw-r--r--addons/account/wizard/account_move_reversal.py4
-rw-r--r--addons/account/wizard/account_transfer_wizard.py4
-rw-r--r--addons/auth_signup/models/res_partner.py4
-rw-r--r--addons/auth_signup/models/res_users.py4
-rw-r--r--addons/base_address_extended/models/res_partner.py4
-rw-r--r--addons/base_gengo/wizard/base_gengo_translations.py2
-rw-r--r--addons/base_import/models/base_import.py6
-rw-r--r--addons/base_import_module/controllers/main.py2
-rw-r--r--addons/base_import_module/models/ir_module.py2
-rw-r--r--addons/base_sparse_field/models/models.py4
-rw-r--r--addons/base_vat/models/res_partner.py14
-rw-r--r--addons/calendar/models/calendar_event.py38
-rw-r--r--addons/calendar/models/calendar_recurrence.py10
-rw-r--r--addons/calendar_sms/models/calendar.py2
-rw-r--r--addons/crm/models/crm_lead.py6
-rw-r--r--addons/delivery/models/sale_order.py2
-rw-r--r--addons/delivery/models/stock_picking.py8
-rw-r--r--addons/event/models/event_ticket.py2
-rw-r--r--addons/fetchmail/models/fetchmail.py2
-rw-r--r--addons/gamification/models/challenge.py12
-rw-r--r--addons/gamification/models/goal.py16
-rw-r--r--addons/google_calendar/models/calendar.py18
-rw-r--r--addons/google_calendar/models/res_users.py2
-rw-r--r--addons/hr/models/hr_plan.py12
-rw-r--r--addons/hr_contract/models/hr_contract.py2
-rw-r--r--addons/hr_expense/wizard/hr_expense_sheet_register_payment.py9
-rw-r--r--addons/hr_fleet/controllers/main.py7
-rw-r--r--addons/hr_holidays/models/hr_leave.py55
-rw-r--r--addons/hr_holidays/models/hr_leave_allocation.py24
-rw-r--r--addons/hr_recruitment/models/hr_recruitment.py2
-rw-r--r--addons/hr_skills/models/hr_skills.py4
-rw-r--r--addons/hr_timesheet/models/project.py7
-rw-r--r--addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py2
-rw-r--r--addons/iap/models/iap.py2
-rw-r--r--addons/im_livechat/models/mail_channel.py2
-rw-r--r--addons/l10n_ar/models/account_move.py12
-rw-r--r--addons/l10n_ar/models/res_partner.py6
-rw-r--r--addons/l10n_fr_fec/wizard/account_fr_fec.py2
-rw-r--r--addons/l10n_fr_pos_cert/models/pos.py2
-rw-r--r--addons/l10n_fr_pos_cert/models/res_company.py4
-rw-r--r--addons/l10n_id_efaktur/models/account_move.py2
-rw-r--r--addons/l10n_it_edi/models/account_edi_format.py4
-rw-r--r--addons/l10n_it_edi/models/account_invoice.py2
-rw-r--r--addons/l10n_latam_invoice_document/models/account_move.py2
-rw-r--r--addons/mail/controllers/main.py2
-rw-r--r--addons/mail/models/mail_activity.py4
-rw-r--r--addons/mail/models/mail_blacklist.py2
-rw-r--r--addons/mail/models/mail_channel.py6
-rw-r--r--addons/mail/models/mail_render_mixin.py2
-rw-r--r--addons/mail/models/mail_template.py6
-rw-r--r--addons/mail/models/mail_thread.py28
-rw-r--r--addons/mail/models/mail_thread_blacklist.py4
-rw-r--r--addons/mail/wizard/invite.py2
-rw-r--r--addons/maintenance/models/maintenance.py2
-rw-r--r--addons/mass_mailing/models/mailing.py4
-rw-r--r--addons/mass_mailing_sms/models/mailing_mailing.py2
-rw-r--r--addons/mass_mailing_sms/wizard/mailing_sms_test.py2
-rw-r--r--addons/mass_mailing_sms/wizard/sms_composer.py2
-rw-r--r--addons/mrp/models/mrp_bom.py12
-rw-r--r--addons/mrp/models/mrp_production.py16
-rw-r--r--addons/mrp/models/mrp_workorder.py18
-rw-r--r--addons/mrp/wizard/change_production_qty.py6
-rw-r--r--addons/payment_sips/models/payment.py2
-rw-r--r--addons/payment_stripe/models/payment.py6
-rw-r--r--addons/phone_validation/models/mail_thread_phone.py4
-rw-r--r--addons/phone_validation/tools/phone_validation.py6
-rw-r--r--addons/point_of_sale/models/pos_config.py4
-rw-r--r--addons/point_of_sale/models/pos_order.py6
-rw-r--r--addons/point_of_sale/models/pos_payment.py2
-rw-r--r--addons/portal/controllers/mail.py2
-rw-r--r--addons/portal/controllers/portal.py8
-rw-r--r--addons/portal/models/mail_thread.py6
-rw-r--r--addons/pos_adyen/models/pos_config.py2
-rw-r--r--addons/pos_mercury/models/pos_mercury_transaction.py2
-rw-r--r--addons/product/models/product_pricelist.py4
-rw-r--r--addons/product/models/product_template.py2
-rw-r--r--addons/project/models/project.py4
-rw-r--r--addons/purchase/models/purchase.py20
-rw-r--r--addons/purchase_requisition/models/purchase_requisition.py4
-rw-r--r--addons/purchase_stock/models/purchase.py6
-rw-r--r--addons/repair/models/repair.py4
-rw-r--r--addons/resource/models/resource.py2
-rw-r--r--addons/sale/controllers/portal.py2
-rw-r--r--addons/sale/models/account_invoice.py2
-rw-r--r--addons/sale/models/payment.py2
-rw-r--r--addons/sale/models/sale.py11
-rw-r--r--addons/sale_coupon/models/coupon.py6
-rw-r--r--addons/sale_coupon/models/coupon_program.py6
-rw-r--r--addons/sale_management/models/sale_order.py7
-rw-r--r--addons/sale_management/models/sale_order_template.py6
-rw-r--r--addons/sale_stock/models/sale_order.py8
-rw-r--r--addons/sale_timesheet/models/project.py2
-rw-r--r--addons/sales_team/models/crm_team.py4
-rw-r--r--addons/sms/models/sms_template.py4
-rw-r--r--addons/sms/wizard/sms_composer.py4
-rw-r--r--addons/snailmail_account/wizard/account_invoice_send.py2
-rw-r--r--addons/stock/models/product.py6
-rw-r--r--addons/stock/models/stock_move.py2
-rw-r--r--addons/stock/models/stock_move_line.py2
-rw-r--r--addons/stock/models/stock_quant.py4
-rw-r--r--addons/stock/models/stock_rule.py2
-rw-r--r--addons/stock/models/stock_warehouse.py2
-rw-r--r--addons/stock/wizard/stock_picking_return.py2
-rw-r--r--addons/stock_account/models/product.py16
-rw-r--r--addons/stock_account/wizard/stock_valuation_layer_revaluation.py32
-rw-r--r--addons/stock_landed_costs/models/stock_landed_cost.py4
-rw-r--r--addons/web/controllers/main.py4
-rw-r--r--addons/website/models/website.py8
-rw-r--r--addons/website/models/website_visitor.py2
-rw-r--r--addons/website_blog/models/website.py4
-rw-r--r--addons/website_blog/models/website_blog.py2
-rw-r--r--addons/website_crm_partner_assign/wizard/crm_forward_to_partner.py2
-rw-r--r--addons/website_forum/models/forum.py48
-rw-r--r--addons/website_livechat/models/mail_channel.py2
-rw-r--r--addons/website_sale/models/product_image.py2
-rw-r--r--addons/website_sale/models/sale_order.py4
-rw-r--r--addons/website_sale_stock/controllers/main.py6
-rw-r--r--addons/website_slides/controllers/main.py4
-rw-r--r--addons/website_slides/models/slide_channel.py2
-rw-r--r--addons/website_slides/models/slide_question.py4
-rw-r--r--addons/website_slides/models/slide_slide.py2
133 files changed, 549 insertions, 343 deletions
diff --git a/addons/account/models/account_account.py b/addons/account/models/account_account.py
index 68a903b2760..1622338baf2 100644
--- a/addons/account/models/account_account.py
+++ b/addons/account/models/account_account.py
@@ -42,7 +42,7 @@ class AccountAccount(models.Model):
def _check_reconcile(self):
for account in self:
if account.internal_type in ('receivable', 'payable') and account.reconcile == False:
- raise ValidationError(_('You cannot have a receivable/payable account that is not reconcilable. (account code: %s)') % account.code)
+ raise ValidationError(_('You cannot have a receivable/payable account that is not reconcilable. (account code: %s)', account.code))
@api.constrains('user_type_id')
def _check_user_type_id(self):
@@ -52,7 +52,7 @@ class AccountAccount(models.Model):
if res.get('company_id_count', 0) >= 2:
account_unaffected_earnings = self.search([('company_id', '=', res['company_id'][0]),
('user_type_id', '=', data_unaffected_earnings.id)])
- raise ValidationError(_('You cannot have more than one account with "Current Year Earnings" as type. (accounts: %s)') % [a.code for a in account_unaffected_earnings])
+ raise ValidationError(_('You cannot have more than one account with "Current Year Earnings" as type. (accounts: %s)', [a.code for a in account_unaffected_earnings]))
name = fields.Char(string="Account Name", required=True, index=True)
currency_id = fields.Many2one('res.currency', string='Account Currency',
@@ -147,7 +147,11 @@ class AccountAccount(models.Model):
if res:
account = self.env['account.account'].browse(res[0])
journal = self.env['account.journal'].browse(res[1])
- raise ValidationError(_("The foreign currency set on the journal '%s' and the account '%s' must be the same.") % (journal.display_name, account.display_name))
+ raise ValidationError(_(
+ "The foreign currency set on the journal '%(journal)s' and the account '%(account)s' must be the same.",
+ journal=journal.display_name,
+ account=account.display_name
+ ))
@api.constrains('company_id')
def _check_company_consistency(self):
@@ -445,7 +449,7 @@ class AccountAccount(models.Model):
if partner_prop_acc:
account_name = partner_prop_acc.get_by_record().display_name
raise UserError(
- _('You cannot remove/deactivate the account %s which is set on a customer or vendor.') % account_name
+ _('You cannot remove/deactivate the account %s which is set on a customer or vendor.', account_name)
)
return super(AccountAccount, self).unlink()
diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py
index 71d6f336dac..502d91c563b 100644
--- a/addons/account/models/account_bank_statement.py
+++ b/addons/account/models/account_bank_statement.py
@@ -75,7 +75,7 @@ class AccountBankStmtCashWizard(models.Model):
def name_get(self):
result = []
for cashbox in self:
- result.append((cashbox.id, _("%s")%(cashbox.total)))
+ result.append((cashbox.id, str(cashbox.total)))
return result
@api.model_create_multi
@@ -294,29 +294,34 @@ class AccountBankStatement(models.Model):
for stmt in self:
if not stmt.currency_id.is_zero(stmt.difference):
if stmt.journal_type == 'cash':
- if stmt.difference < 0.0:
- account = stmt.journal_id.loss_account_id
- name = _('Loss')
- else:
- # statement.difference > 0.0
- account = stmt.journal_id.profit_account_id
- name = _('Profit')
- if not account:
- raise UserError(_('Please go on the %s journal and define a %s Account. This account will be used to record cash difference.') % (stmt.journal_id.name, name))
-
st_line_vals = {
'statement_id': stmt.id,
'journal_id': stmt.journal_id.id,
'amount': stmt.difference,
- 'payment_ref': _("Cash difference observed during the counting (%s)") % name,
'date': stmt.date,
}
- self.env['account.bank.statement.line'].with_context(counterpart_account_id=account.id).create(st_line_vals)
+
+ if stmt.difference < 0.0:
+ if not stmt.journal_id.loss_account_id:
+ raise UserError(_('Please go on the %s journal and define a Loss Account. This account will be used to record cash difference.', stmt.journal_id.name))
+
+ st_line_vals['payment_ref'] = _("Cash difference observed during the counting (Loss)")
+ self.env['account.bank.statement.line'].with_context(counterpart_account_id=stmt.journal_id.loss_account_id).create(st_line_vals)
+ else:
+ # statement.difference > 0.0
+ if not stmt.journal_id.profit_account_id:
+ raise UserError(_('Please go on the %s journal and define a Profit Account. This account will be used to record cash difference.', stmt.journal_id.name))
+
+ st_line_vals['payment_ref'] = _("Cash difference observed during the counting (Profit)")
+ self.env['account.bank.statement.line'].with_context(counterpart_account_id=stmt.journal_id.profit_account_id).create(st_line_vals)
else:
balance_end_real = formatLang(self.env, stmt.balance_end_real, currency_obj=stmt.currency_id)
balance_end = formatLang(self.env, stmt.balance_end, currency_obj=stmt.currency_id)
- raise UserError(_('The ending balance is incorrect !\nThe expected balance (%s) is different from the computed one. (%s)')
- % (balance_end_real, balance_end))
+ raise UserError(_(
+ 'The ending balance is incorrect !\nThe expected balance (%(real_balance)s) is different from the computed one (%(computed_balance)s).',
+ real_balance=balance_end_real,
+ computed_balance=balance_end
+ ))
return True
def unlink(self):
@@ -392,13 +397,13 @@ class AccountBankStatement(models.Model):
for statement in self:
# Chatter.
- statement.message_post(body=_('Statement %s confirmed.') % statement.name)
+ statement.message_post(body=_('Statement %s confirmed.', statement.name))
# Bank statement report.
if statement.journal_id.type == 'bank':
content, content_type = self.env.ref('account.action_report_account_statement')._render(statement.id)
self.env['ir.attachment'].create({
- 'name': statement.name and _("Bank Statement %s.pdf") % statement.name or _("Bank Statement.pdf"),
+ 'name': statement.name and _("Bank Statement %s.pdf", statement.name) or _("Bank Statement.pdf"),
'type': 'binary',
'datas': base64.encodebytes(content),
'res_model': statement._name,
@@ -873,7 +878,7 @@ class AccountBankStatementLine(models.Model):
if st_line.currency_id.is_zero(st_line.amount):
raise ValidationError(_("The amount of a statement line can't be equal to zero."))
if st_line.foreign_currency_id == st_line.currency_id:
- raise ValidationError(_("The foreign currency must be different than the journal one: %s") % st_line.currency_id.name)
+ raise ValidationError(_("The foreign currency must be different than the journal one: %s", st_line.currency_id.name))
if st_line.foreign_currency_id and st_line.foreign_currency_id.is_zero(st_line.amount_currency):
raise ValidationError(_("The amount in foreign currency must be set if the amount is not equal to zero."))
if not st_line.foreign_currency_id and st_line.amount_currency:
diff --git a/addons/account/models/account_journal.py b/addons/account/models/account_journal.py
index db72d23f5f0..f424d2fb738 100644
--- a/addons/account/models/account_journal.py
+++ b/addons/account/models/account_journal.py
@@ -213,11 +213,11 @@ class AccountJournal(models.Model):
for journal in self:
if journal.type == 'bank' and journal.bank_account_id:
if journal.bank_account_id.company_id and journal.bank_account_id.company_id != journal.company_id:
- raise ValidationError(_('The bank account of a bank journal must belong to the same company (%s).') % journal.company_id.name)
+ raise ValidationError(_('The bank account of a bank journal must belong to the same company (%s).', journal.company_id.name))
# A bank account can belong to a customer/supplier, in which case their partner_id is the customer/supplier.
# Or they are part of a bank journal and their partner_id must be the company's partner_id.
if journal.bank_account_id.partner_id != journal.company_id.partner_id:
- raise ValidationError(_('The holder of a journal\'s bank account must be the company (%s).') % journal.company_id.name)
+ raise ValidationError(_('The holder of a journal\'s bank account must be the company (%s).', journal.company_id.name))
@api.constrains('company_id')
def _check_company_consistency(self):
@@ -270,7 +270,11 @@ class AccountJournal(models.Model):
''', [tuple(accounts.ids)])
res = self._cr.fetchone()
if res:
- raise ValidationError(_("The account %s can't be shared between multiple journals: %s") % (res[0], ', '.join(res[1])))
+ raise ValidationError(_(
+ "The account %(account_name)s can't be shared between multiple journals: %(journals)s",
+ account_name=res[0],
+ journals=', '.join(res[1])
+ ))
@api.constrains('type', 'default_credit_account_id', 'default_debit_account_id')
def _check_type_default_credit_account_id_type(self):
@@ -365,7 +369,7 @@ class AccountJournal(models.Model):
journal_entry = self.env['account.move'].search([('journal_id', '=', self.id), ('state', '=', 'posted'), ('secure_sequence_number', '!=', 0)], limit=1)
if len(journal_entry) > 0:
field_string = self._fields['restrict_mode_hash_table'].get_description(self.env)['string']
- raise UserError(_("You cannot modify the field %s of a journal that already has accounting entries.") % field_string)
+ raise UserError(_("You cannot modify the field %s of a journal that already has accounting entries.", field_string))
result = super(AccountJournal, self).write(vals)
for journal in self:
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index e197d28d037..9263f9519f4 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -65,9 +65,10 @@ class AccountMove(models.Model):
if not journal:
company = self.env['res.company'].browse(company_id)
- error_msg = _("No journal could be found in company %s for any of those types: %s") % (
- company.display_name,
- ', '.join(journal_types),
+ error_msg = _(
+ "No journal could be found in company %(company_name)s for any of those types: %(journal_types)s",
+ company_name=company.display_name,
+ journal_types=', '.join(journal_types),
)
raise UserError(error_msg)
@@ -91,7 +92,11 @@ class AccountMove(models.Model):
journal = self.env['account.journal'].browse(self._context['default_journal_id'])
if move_type != 'entry' and journal.type not in journal_types:
- raise UserError(_("Cannot create an invoice of type %s with a journal having %s as type.") % (move_type, journal.type))
+ raise UserError(_(
+ "Cannot create an invoice of type %(move_type)s with a journal having %(journal_type)s as type.",
+ move_type=move_type,
+ journal_type=journal.type,
+ ))
else:
journal = self._search_default_journal(journal_types)
@@ -377,7 +382,7 @@ class AccountMove(models.Model):
if p.invoice_warn != 'block' and p.parent_id and p.parent_id.invoice_warn == 'block':
p = p.parent_id
warning = {
- 'title': _("Warning for %s") % p.name,
+ 'title': _("Warning for %s", p.name),
'message': p.invoice_warn_msg
}
if p.invoice_warn == 'block':
@@ -758,7 +763,7 @@ class AccountMove(models.Model):
return
rounding_line_vals.update({
- 'name': _('%s (rounding)') % biggest_tax_line.name,
+ 'name': _('%s (rounding)', biggest_tax_line.name),
'account_id': biggest_tax_line.account_id.id,
'tax_repartition_line_id': biggest_tax_line.tax_repartition_line_id.id,
'tax_exigible': biggest_tax_line.tax_exigible,
@@ -1582,9 +1587,9 @@ class AccountMove(models.Model):
lock_date = move.company_id._get_user_fiscal_lock_date()
if move.date <= lock_date:
if self.user_has_groups('account.group_account_manager'):
- message = _("You cannot add/modify entries prior to and inclusive of the lock date %s.") % format_date(self.env, lock_date)
+ message = _("You cannot add/modify entries prior to and inclusive of the lock date %s.", format_date(self.env, lock_date))
else:
- message = _("You cannot add/modify entries prior to and inclusive of the lock date %s. Check the company settings or ask someone with the 'Adviser' role") % format_date(self.env, lock_date)
+ message = _("You cannot add/modify entries prior to and inclusive of the lock date %s. Check the company settings or ask someone with the 'Adviser' role", format_date(self.env, lock_date))
raise UserError(message)
return True
@@ -2284,7 +2289,7 @@ class AccountMove(models.Model):
raise UserError(_('You need to add a line before posting.'))
if move.auto_post and move.date > fields.Date.today():
date_msg = move.date.strftime(get_lang(self.env).date_format)
- raise UserError(_("This move is configured to be auto-posted on %s") % date_msg)
+ raise UserError(_("This move is configured to be auto-posted on %s", date_msg))
if not move.partner_id:
if move.is_sale_document():
@@ -3466,9 +3471,9 @@ class AccountMoveLine(models.Model):
control_type_failed = journal.type_control_ids and account.user_type_id not in journal.type_control_ids
control_account_failed = journal.account_control_ids and account not in journal.account_control_ids
if control_journal_failed:
- raise UserError(_('You cannot use this account (%s) in this journal, check the field \'Allowed Journals\' on the related account.') % account.display_name)
+ raise UserError(_('You cannot use this account (%s) in this journal, check the field \'Allowed Journals\' on the related account.', account.display_name))
if control_type_failed or control_account_failed:
- raise UserError(_('You cannot use this account (%s) in this journal, check the section \'Control-Access\' under tab \'Advanced Settings\' on the related journal.') % account.display_name)
+ raise UserError(_('You cannot use this account (%s) in this journal, check the section \'Control-Access\' under tab \'Advanced Settings\' on the related journal.', account.display_name))
@api.constrains('account_id', 'tax_ids', 'tax_line_id', 'reconciled')
def _check_off_balance(self):
diff --git a/addons/account/models/account_partial_reconcile.py b/addons/account/models/account_partial_reconcile.py
index 6e445c20c85..29c0c145944 100644
--- a/addons/account/models/account_partial_reconcile.py
+++ b/addons/account/models/account_partial_reconcile.py
@@ -67,7 +67,7 @@ class AccountPartialReconcile(models.Model):
def _check_required_computed_currencies(self):
bad_partials = self.filtered(lambda partial: not partial.debit_currency_id or not partial.credit_currency_id)
if bad_partials:
- raise ValidationError(_("Missing foreign currencies on partials having ids: %s") % bad_partials.ids)
+ raise ValidationError(_("Missing foreign currencies on partials having ids: %s", bad_partials.ids))
# -------------------------------------------------------------------------
# COMPUTE METHODS
diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py
index e1581932463..ba2e519a914 100644
--- a/addons/account/models/account_payment.py
+++ b/addons/account/models/account_payment.py
@@ -205,9 +205,9 @@ class AccountPayment(models.Model):
if self.is_internal_transfer:
if self.payment_type == 'inbound':
- liquidity_line_name = _('Transfer to %s') % self.journal_id.name
+ liquidity_line_name = _('Transfer to %s', self.journal_id.name)
else: # payment.payment_type == 'outbound':
- liquidity_line_name = _('Transfer from %s') % self.journal_id.name
+ liquidity_line_name = _('Transfer from %s', self.journal_id.name)
else:
liquidity_line_name = self.payment_reference
diff --git a/addons/account/models/account_tax.py b/addons/account/models/account_tax.py
index 0ce074b4622..7e5572aea39 100644
--- a/addons/account/models/account_tax.py
+++ b/addons/account/models/account_tax.py
@@ -184,7 +184,7 @@ class AccountTax(models.Model):
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
- default = dict(default or {}, name=_("%s (Copy)") % self.name)
+ default = dict(default or {}, name=_("%s (Copy)", self.name))
return super(AccountTax, self).copy(default=default)
def name_get(self):
diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py
index 2b880c8b122..649962c411e 100644
--- a/addons/account/models/chart_template.py
+++ b/addons/account/models/chart_template.py
@@ -1040,7 +1040,7 @@ class AccountTaxRepartitionLineTemplate(models.Model):
all_tax_rep_lines = self.mapped('plus_report_line_ids') + self.mapped('minus_report_line_ids')
lines_without_tag = all_tax_rep_lines.filtered(lambda x: not x.tag_name)
if lines_without_tag:
- raise ValidationError(_("The following tax report lines are used in some tax repartition template though they don't generate any tag: %s . This probably means you forgot to set a tag_name on these lines.") % str(lines_without_tag.mapped('name')))
+ raise ValidationError(_("The following tax report lines are used in some tax repartition template though they don't generate any tag: %s . This probably means you forgot to set a tag_name on these lines.", str(lines_without_tag.mapped('name'))))
def get_repartition_line_create_vals(self, company):
rslt = [(5, 0, 0)]
diff --git a/addons/account/models/company.py b/addons/account/models/company.py
index bda2c1301ed..acebbb209bf 100644
--- a/addons/account/models/company.py
+++ b/addons/account/models/company.py
@@ -537,7 +537,7 @@ class ResCompany(models.Model):
hash_corrupted = False
for move in moves:
if move.inalterable_hash != move._compute_hash(previous_hash=previous_hash):
- rslt.update({'msg_cover': _('Corrupted data on journal entry with id %s.') % move.id})
+ rslt.update({'msg_cover': _('Corrupted data on journal entry with id %s.', move.id)})
results_by_journal['results'].append(rslt)
hash_corrupted = True
break
diff --git a/addons/account/models/res_bank.py b/addons/account/models/res_bank.py
index 5b587866eef..226e1c889ad 100644
--- a/addons/account/models/res_bank.py
+++ b/addons/account/models/res_bank.py
@@ -36,7 +36,7 @@ class ResPartnerBank(models.Model):
return self._get_qr_code_url(candidate_method, amount, currency, debtor_partner, free_communication, structured_communication)
elif not silent_errors:
- error_header = _("The following error prevented '%s' QR-code to be generated though it was detected as eligible: ") % candidate_name
+ error_header = _("The following error prevented '%s' QR-code to be generated though it was detected as eligible: ", candidate_name)
raise UserError( error_header + error_message)
return None
diff --git a/addons/account/models/sequence_mixin.py b/addons/account/models/sequence_mixin.py
index f6f4520661d..e75842f8115 100644
--- a/addons/account/models/sequence_mixin.py
+++ b/addons/account/models/sequence_mixin.py
@@ -96,7 +96,7 @@ class SequenceMixin(models.AbstractModel):
"""
self.ensure_one()
if self._sequence_field not in self._fields or not self._fields[self._sequence_field].store:
- raise ValidationError(_('%s is not a stored field') % self._sequence_field)
+ raise ValidationError(_('%s is not a stored field', self._sequence_field))
where_string, param = self._get_last_sequence_domain(relaxed)
if self.id or self.id.origin:
where_string += " AND id != %(id)s "
diff --git a/addons/account/wizard/account_accrual_accounting.py b/addons/account/wizard/account_accrual_accounting.py
index cc6dd3c98ba..b48b5d95a4b 100644
--- a/addons/account/wizard/account_accrual_accounting.py
+++ b/addons/account/wizard/account_accrual_accounting.py
@@ -202,7 +202,7 @@ class AccrualAccountingWizard(models.TransientModel):
record.preview_data = json.dumps({
'groups_vals': preview_vals,
'options': {
- 'discarded_number': (_("%d moves") % preview_discarded) if preview_discarded else False,
+ 'discarded_number': _("%d moves", preview_discarded) if preview_discarded else False,
'columns': preview_columns,
},
})
diff --git a/addons/account/wizard/account_move_reversal.py b/addons/account/wizard/account_move_reversal.py
index e7c51be9aaf..f83fc3a950c 100644
--- a/addons/account/wizard/account_move_reversal.py
+++ b/addons/account/wizard/account_move_reversal.py
@@ -57,7 +57,9 @@ class AccountMoveReversal(models.TransientModel):
def _prepare_default_reversal(self, move):
reverse_date = self.date if self.date_mode == 'custom' else move.date
return {
- 'ref': _('Reversal of: %s, %s') % (move.name, self.reason) if self.reason else _('Reversal of: %s') % (move.name),
+ 'ref': _('Reversal of: %(move_name)s, %(reason)s', move_name=move.name, reason=self.reason)
+ if self.reason
+ else _('Reversal of: %s', move.name),
'date': reverse_date,
'invoice_date': move.is_invoice(include_receipts=True) and (self.date or move.date) or False,
'journal_id': self.journal_id and self.journal_id.id or move.journal_id.id,
diff --git a/addons/account/wizard/account_transfer_wizard.py b/addons/account/wizard/account_transfer_wizard.py
index c6d73973abf..709adc51f74 100644
--- a/addons/account/wizard/account_transfer_wizard.py
+++ b/addons/account/wizard/account_transfer_wizard.py
@@ -81,7 +81,7 @@ class AccountTransferWizard(models.TransientModel):
# Generate counterpart lines' vals
for (counterpart_partner, counterpart_currency), counterpart_vals in counterpart_balances.items():
source_accounts = self.move_line_ids.mapped('account_id')
- counterpart_label = len(source_accounts) == 1 and _("Transfer from %s") % source_accounts.display_name or _("Transfer counterpart")
+ counterpart_label = len(source_accounts) == 1 and _("Transfer from %s", source_accounts.display_name) or _("Transfer counterpart")
if not self.company_id.currency_id.is_zero(counterpart_vals['balance']) or (counterpart_currency and not counterpart_currency.is_zero(counterpart_vals['amount_currency'])):
line_vals.append({
@@ -112,7 +112,7 @@ class AccountTransferWizard(models.TransientModel):
return {
'journal_id': self.journal_id.id,
'date': self.date,
- 'ref': self.destination_account_id.display_name and _("Transfer entry to %s") % self.destination_account_id.display_name or '',
+ 'ref': self.destination_account_id.display_name and _("Transfer entry to %s", self.destination_account_id.display_name) or '',
'line_ids': [(0, 0, line) for line in line_vals],
}
diff --git a/addons/auth_signup/models/res_partner.py b/addons/auth_signup/models/res_partner.py
index 94e8471e00b..fe68ae5380d 100644
--- a/addons/auth_signup/models/res_partner.py
+++ b/addons/auth_signup/models/res_partner.py
@@ -143,11 +143,11 @@ class ResPartner(models.Model):
partner = self.search([('signup_token', '=', token)], limit=1)
if not partner:
if raise_exception:
- raise exceptions.UserError(_("Signup token '%s' is not valid") % token)
+ raise exceptions.UserError(_("Signup token '%s' is not valid", token))
return False
if check_validity and not partner.signup_valid:
if raise_exception:
- raise exceptions.UserError(_("Signup token '%s' is no longer valid") % token)
+ raise exceptions.UserError(_("Signup token '%s' is no longer valid", token))
return False
return partner
diff --git a/addons/auth_signup/models/res_users.py b/addons/auth_signup/models/res_users.py
index c600d969e9d..3aaa43f0f18 100644
--- a/addons/auth_signup/models/res_users.py
+++ b/addons/auth_signup/models/res_users.py
@@ -123,7 +123,7 @@ class ResUsers(models.Model):
invite_partner = user.create_uid.partner_id
if invite_partner:
# notify invite user that new user is connected
- title = _("%s connected") % user.name
+ title = _("%s connected", user.name)
message = _("This is his first connection. Wish him welcome")
self.env['bus.bus'].sendone(
(self._cr.dbname, 'res.partner', invite_partner.id),
@@ -196,7 +196,7 @@ class ResUsers(models.Model):
for user in self:
if not user.email:
- raise UserError(_("Cannot send email: user %s has no email address.") % user.name)
+ raise UserError(_("Cannot send email: user %s has no email address.", user.name))
# TDE FIXME: make this template technical (qweb)
with self.env.cr.savepoint():
force_send = not(self.env.context.get('import_file', False))
diff --git a/addons/base_address_extended/models/res_partner.py b/addons/base_address_extended/models/res_partner.py
index 963da5e9b72..7ddb2acc6c6 100644
--- a/addons/base_address_extended/models/res_partner.py
+++ b/addons/base_address_extended/models/res_partner.py
@@ -35,7 +35,7 @@ class Partner(models.Model):
field_name = re_match.group()[2:-2]
field_pos = re_match.start()
if field_name not in street_fields:
- raise UserError(_("Unrecognized field %s in street format.") % field_name)
+ raise UserError(_("Unrecognized field %s in street format.", field_name))
if not previous_field:
# first iteration: add heading chars in street_format
if partner[field_name]:
@@ -104,7 +104,7 @@ class Partner(models.Model):
# value not found: keep looking for the same field
pass
if field_name not in street_fields:
- raise UserError(_("Unrecognized field %s in street format.") % field_name)
+ raise UserError(_("Unrecognized field %s in street format.", field_name))
previous_pos = re_match.end()
# last field value is what remains in street_raw minus trailing chars in street_format
diff --git a/addons/base_gengo/wizard/base_gengo_translations.py b/addons/base_gengo/wizard/base_gengo_translations.py
index 72d23c5ad2d..7f070c00135 100644
--- a/addons/base_gengo/wizard/base_gengo_translations.py
+++ b/addons/base_gengo/wizard/base_gengo_translations.py
@@ -91,7 +91,7 @@ class BaseGengoTranslations(models.TransientModel):
return (True, gengo)
except Exception as e:
_logger.exception('Gengo connection failed')
- return (False, _("Gengo connection failed with this message:\n``%s``") % e)
+ return (False, _("Gengo connection failed with this message:\n``%s``", e))
def act_update(self):
'''
diff --git a/addons/base_import/models/base_import.py b/addons/base_import/models/base_import.py
index 041d5ef2dd1..d126bb4268e 100644
--- a/addons/base_import/models/base_import.py
+++ b/addons/base_import/models/base_import.py
@@ -297,7 +297,7 @@ class Import(models.TransientModel):
_("Invalid cell value at row %(row)s, column %(col)s: %(cell_value)s") % {
'row': rowx,
'col': colx,
- 'cell_value': xlrd.error_text_from_code.get(cell.value, _("unknown error code %s") % cell.value)
+ 'cell_value': xlrd.error_text_from_code.get(cell.value, _("unknown error code %s", cell.value))
}
)
else:
@@ -856,13 +856,13 @@ class Import(models.TransientModel):
response.raise_for_status()
if response.headers.get('Content-Length') and int(response.headers['Content-Length']) > maxsize:
- raise ValueError(_("File size exceeds configured maximum (%s bytes)") % maxsize)
+ raise ValueError(_("File size exceeds configured maximum (%s bytes)", maxsize))
content = bytearray()
for chunk in response.iter_content(DEFAULT_IMAGE_CHUNK_SIZE):
content += chunk
if len(content) > maxsize:
- raise ValueError(_("File size exceeds configured maximum (%s bytes)") % maxsize)
+ raise ValueError(_("File size exceeds configured maximum (%s bytes)", maxsize))
image = Image.open(io.BytesIO(content))
w, h = image.size
diff --git a/addons/base_import_module/controllers/main.py b/addons/base_import_module/controllers/main.py
index d382d360961..1671798c20c 100644
--- a/addons/base_import_module/controllers/main.py
+++ b/addons/base_import_module/controllers/main.py
@@ -30,7 +30,7 @@ class ImportModule(Controller):
@webservice
def login_upload(self, login, password, db=None, force='', mod_file=None, **kw):
if db and db != request.db:
- raise Exception(_("Could not select database '%s'") % db)
+ raise Exception(_("Could not select database '%s'", db))
uid = request.session.authenticate(request.db, login, password)
self.check_user(uid)
force = True if force == '1' else False
diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py
index 9fff8448ffd..9e2116507a6 100644
--- a/addons/base_import_module/models/ir_module.py
+++ b/addons/base_import_module/models/ir_module.py
@@ -121,7 +121,7 @@ class IrModule(models.Model):
with zipfile.ZipFile(module_file, "r") as z:
for zf in z.filelist:
if zf.file_size > MAX_FILE_SIZE:
- raise UserError(_("File '%s' exceed maximum allowed file size") % zf.filename)
+ raise UserError(_("File '%s' exceed maximum allowed file size", zf.filename))
with tempfile.TemporaryDirectory() as module_dir:
import odoo.modules.module as module
diff --git a/addons/base_sparse_field/models/models.py b/addons/base_sparse_field/models/models.py
index 1991306a631..179f6fbdc36 100644
--- a/addons/base_sparse_field/models/models.py
+++ b/addons/base_sparse_field/models/models.py
@@ -32,9 +32,9 @@ class IrModelFields(models.Model):
if 'serialization_field_id' in vals or 'name' in vals:
for field in self:
if 'serialization_field_id' in vals and field.serialization_field_id.id != vals['serialization_field_id']:
- raise UserError(_('Changing the storing system for field "%s" is not allowed.') % field.name)
+ raise UserError(_('Changing the storing system for field "%s" is not allowed.', field.name))
if field.serialization_field_id and (field.name != vals['name']):
- raise UserError(_('Renaming sparse field "%s" is not allowed') % field.name)
+ raise UserError(_('Renaming sparse field "%s" is not allowed', field.name))
return super(IrModelFields, self).write(vals)
diff --git a/addons/base_vat/models/res_partner.py b/addons/base_vat/models/res_partner.py
index 0b54f0e0286..17f379012bc 100644
--- a/addons/base_vat/models/res_partner.py
+++ b/addons/base_vat/models/res_partner.py
@@ -162,8 +162,18 @@ class ResPartner(models.Model):
else:
company = self.env.company
if company.vat_check_vies:
- return '\n' + _('The VAT number [%s] for partner [%s] either failed the VIES VAT validation check or did not respect the expected format %s.') % (self.vat, self.name, vat_no)
- return '\n' + _('The VAT number [%s] for partner [%s] does not seem to be valid. \nNote: the expected format is %s') % (self.vat, self.name, vat_no)
+ return '\n' + _(
+ 'The VAT number [%(vat)s] for partner [%(name)s] either failed the VIES VAT validation check or did not respect the expected format %(format)s.',
+ vat=self.vat,
+ name=self.name,
+ format=vat_no
+ )
+ return '\n' + _(
+ 'The VAT number [%(vat)s] for partner [%(name)s] does not seem to be valid. \nNote: the expected format is %(format)s',
+ vat=self.vat,
+ name=self.name,
+ format=vat_no
+ )
__check_vat_ch_re1 = re.compile(r'(MWST|TVA|IVA)[0-9]{6}$')
__check_vat_ch_re2 = re.compile(r'E([0-9]{9}|-[0-9]{3}\.[0-9]{3}\.[0-9]{3})(MWST|TVA|IVA)$')
diff --git a/addons/calendar/models/calendar_event.py b/addons/calendar/models/calendar_event.py
index df6347a678c..68740cae04d 100644
--- a/addons/calendar/models/calendar_event.py
+++ b/addons/calendar/models/calendar_event.py
@@ -135,25 +135,27 @@ class Meeting(models.Model):
time_str = to_text(date.strftime(format_time))
if zallday:
- display_time = _("AllDay , %s") % (date_str)
+ display_time = _("AllDay , %(day)s", day=date_str)
elif zduration < 24:
duration = date + timedelta(minutes=round(zduration*60))
duration_time = to_text(duration.strftime(format_time))
- display_time = _(u"%s at (%s To %s) (%s)") % (
- date_str,
- time_str,
- duration_time,
- timezone,
+ display_time = _(
+ u"%(day)s at (%(start)s To %(end)s) (%(timezone)s)",
+ day=date_str,
+ start=time_str,
+ end=duration_time,
+ timezone=timezone,
)
else:
dd_date = to_text(date_deadline.strftime(format_date))
dd_time = to_text(date_deadline.strftime(format_time))
- display_time = _(u"%s at %s To\n %s at %s (%s)") % (
- date_str,
- time_str,
- dd_date,
- dd_time,
- timezone,
+ display_time = _(
+ u"%(date_start)s at %(time_start)s To\n %(date_end)s at %(time_end)s (%(timezone)s)",
+ date_start=date_str,
+ time_start=time_str,
+ date_end=dd_date,
+ time_end=dd_time,
+ timezone=timezone,
)
return display_time
@@ -356,12 +358,20 @@ class Meeting(models.Model):
if meeting.start and meeting.stop and meeting.stop < meeting.start:
raise ValidationError(
_('The ending date and time cannot be earlier than the starting date and time.') + '\n' +
- _("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start, meeting.stop)
+ _("Meeting '%(name)s' starts '%(start_datetime)s' and ends '%(end_datetime)s'",
+ name=meeting.name,
+ start_datetime=meeting.start,
+ end_datetime=meeting.stop
+ )
)
if meeting.start_date and meeting.stop_date and meeting.stop_date < meeting.start_date:
raise ValidationError(
_('The ending date cannot be earlier than the starting date.') + '\n' +
- _("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start_date, meeting.stop_date)
+ _("Meeting '%(name)s' starts '%(start_datetime)s' and ends '%(end_datetime)s'",
+ name=meeting.name,
+ start_datetime=meeting.start,
+ end_datetime=meeting.stop
+ )
)
####################################################
diff --git a/addons/calendar/models/calendar_recurrence.py b/addons/calendar/models/calendar_recurrence.py
index 9ae8c4fc3de..9dae012b6d4 100644
--- a/addons/calendar/models/calendar_recurrence.py
+++ b/addons/calendar/models/calendar_recurrence.py
@@ -124,12 +124,12 @@ class RecurrenceRule(models.Model):
def _compute_name(self):
for recurrence in self:
period = dict(RRULE_TYPE_SELECTION)[recurrence.rrule_type]
- every = _("Every %s %s, ") % (recurrence.interval, period)
+ every = _("Every %(count)s %(period)s, ", count=recurrence.interval, period=period)
if recurrence.end_type == 'count':
- end = _("for %s events") % recurrence.count
+ end = _("for %s events", recurrence.count)
elif recurrence.end_type == 'end_date':
- end = _("until %s") % recurrence.until
+ end = _("until %s", recurrence.until)
else:
end = ''
@@ -140,9 +140,9 @@ class RecurrenceRule(models.Model):
elif recurrence.rrule_type == 'monthly':
if recurrence.month_by == 'day':
weekday_label = dict(BYDAY_SELECTION)[recurrence.byday]
- on = _("on the %(position)s %(weekday)s, ") % {'position': recurrence.byday, 'weekday': weekday_label}
+ on = _("on the %(position)s %(weekday)s, ", position=recurrence.byday, weekday=weekday_label)
else:
- on = _("day %s, ") % recurrence.day
+ on = _("day %s, ", recurrence.day)
else:
on = ''
recurrence.name = every + on + end
diff --git a/addons/calendar_sms/models/calendar.py b/addons/calendar_sms/models/calendar.py
index 6b08ddcbe9d..b47a28b0916 100644
--- a/addons/calendar_sms/models/calendar.py
+++ b/addons/calendar_sms/models/calendar.py
@@ -22,7 +22,7 @@ class CalendarEvent(models.Model):
for event in self:
event._message_sms_with_template(
template_xmlid='calendar_sms.sms_template_data_calendar_reminder',
- template_fallback=_("Event reminder: %s, %s.") % (event.name, event.display_time),
+ template_fallback=_("Event reminder: %(name)s, %(time)s.", name=event.name, time=event.display_time),
partner_ids=self._sms_get_default_partners().ids,
put_in_queue=False
)
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index 2c7b2b541f7..52f669bb9ba 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -894,7 +894,11 @@ class Lead(models.Model):
for message in opportunity.message_ids:
message.write({
'res_id': self.id,
- 'subject': _("From %s : %s") % (opportunity.name, message.subject)
+ 'subject': _(
+ "From %(source_name)s : %(source_subject)s",
+ source_name=opportunity.name,
+ source_subject=message.subject
+ )
})
return True
diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py
index d303623bb6e..10fd1d9cea4 100644
--- a/addons/delivery/models/sale_order.py
+++ b/addons/delivery/models/sale_order.py
@@ -101,7 +101,7 @@ class SaleOrder(models.Model):
}
if carrier.invoice_policy == 'real':
values['price_unit'] = 0
- values['name'] += _(' (Estimated Cost: %s )') % self._format_currency_amount(price_unit)
+ values['name'] += _(' (Estimated Cost: %s )', self._format_currency_amount(price_unit))
else:
values['price_unit'] = price_unit
if carrier.free_over and self.currency_id.is_zero(price_unit) :
diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py
index f7f10919a7c..d4c90d77d55 100644
--- a/addons/delivery/models/stock_picking.py
+++ b/addons/delivery/models/stock_picking.py
@@ -172,7 +172,13 @@ class StockPicking(models.Model):
if res['tracking_number']:
self.carrier_tracking_ref = res['tracking_number']
order_currency = self.sale_id.currency_id or self.company_id.currency_id
- msg = _("Shipment sent to carrier %s for shipping with tracking number %s<br/>Cost: %.2f %s") % (self.carrier_id.name, self.carrier_tracking_ref, self.carrier_price, order_currency.name)
+ msg = _(
+ "Shipment sent to carrier %(carrier_name)s for shipping with tracking number %(ref)s<br/>Cost: %(price).2f %(currency)s",
+ carrier_name=self.carrier_id.name,
+ ref=self.carrier_tracking_ref,
+ price=self.carrier_price,
+ currency=order_currency.name
+ )
self.message_post(body=msg)
self._add_delivery_cost_to_so()
diff --git a/addons/event/models/event_ticket.py b/addons/event/models/event_ticket.py
index 3e96eb78d8c..598179d2070 100644
--- a/addons/event/models/event_ticket.py
+++ b/addons/event/models/event_ticket.py
@@ -51,7 +51,7 @@ class EventTicket(models.Model):
def default_get(self, fields):
res = super(EventTicket, self).default_get(fields)
if 'name' in fields and (not res.get('name') or res['name'] == _('Registration')) and self.env.context.get('default_event_name'):
- res['name'] = _('Registration for %s') % self.env.context['default_event_name']
+ res['name'] = _('Registration for %s', self.env.context['default_event_name'])
return res
# description
diff --git a/addons/fetchmail/models/fetchmail.py b/addons/fetchmail/models/fetchmail.py
index 67dce8c145b..da83677a02c 100644
--- a/addons/fetchmail/models/fetchmail.py
+++ b/addons/fetchmail/models/fetchmail.py
@@ -126,7 +126,7 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
server.write({'state': 'done'})
except Exception as err:
_logger.info("Failed to connect to %s server %s.", server.server_type, server.name, exc_info=True)
- raise UserError(_("Connection test failed: %s") % tools.ustr(err))
+ raise UserError(_("Connection test failed: %s", tools.ustr(err)))
finally:
try:
if connection:
diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py
index c424a8c4b28..93efdef0d9b 100644
--- a/addons/gamification/models/challenge.py
+++ b/addons/gamification/models/challenge.py
@@ -596,7 +596,7 @@ class Challenge(models.Model):
def accept_challenge(self):
user = self.env.user
sudoed = self.sudo()
- sudoed.message_post(body=_("%s has joined the challenge") % user.name)
+ sudoed.message_post(body=_("%s has joined the challenge", user.name))
sudoed.write({'invited_user_ids': [(3, user.id)], 'user_ids': [(4, user.id)]})
return sudoed._generate_goals_from_challenge()
@@ -604,7 +604,7 @@ class Challenge(models.Model):
"""The user discard the suggested challenge"""
user = self.env.user
sudoed = self.sudo()
- sudoed.message_post(body=_("%s has refused the challenge") % user.name)
+ sudoed.message_post(body=_("%s has refused the challenge", user.name))
return sudoed.write({'invited_user_ids': (3, user.id)})
def _check_challenge_reward(self, force=False):
@@ -652,11 +652,15 @@ class Challenge(models.Model):
if challenge_ended:
# open chatter message
- message_body = _("The challenge %s is finished.") % challenge.name
+ message_body = _("The challenge %s is finished.", challenge.name)
if rewarded_users:
user_names = rewarded_users.name_get()
- message_body += _("<br/>Reward (badge %s) for every succeeding user was sent to %s.") % (challenge.reward_id.name, ", ".join(name for (user_id, name) in user_names))
+ message_body += _(
+ "<br/>Reward (badge %(badge_name)s) for every succeeding user was sent to %(users)s.",
+ badge_name=challenge.reward_id.name,
+ users=", ".join(name for (user_id, name) in user_names)
+ )
else:
message_body += _("<br/>Nobody has succeeded to reach every goal, no badge is rewarded for this challenge.")
diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py
index 9a14a1438c3..e26ac0b37ff 100644
--- a/addons/gamification/models/goal.py
+++ b/addons/gamification/models/goal.py
@@ -111,11 +111,17 @@ class GoalDefinition(models.Model):
Model = self.env[definition.model_id.model]
field = Model._fields.get(definition.field_id.name)
if not (field and field.store):
- raise exceptions.UserError(
- _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not stored") % (definition.name, definition.field_id.name))
+ raise exceptions.UserError(_(
+ "The model configuration for the definition %(name)s seems incorrect, please check it.\n\n%(field_name)s not stored",
+ name=definition.name,
+ field_name=definition.field_id.name
+ ))
except KeyError as e:
- raise exceptions.UserError(
- _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not found") % (definition.name, e))
+ raise exceptions.UserError(_(
+ "The model configuration for the definition %(name)s seems incorrect, please check it.\n\n%(error)s not found",
+ name=definition.name,
+ error=e
+ ))
@api.model
def create(self, vals):
@@ -430,7 +436,7 @@ class Goal(models.Model):
if self.computation_mode == 'manually':
# open a wizard window to update the value manually
action = {
- 'name': _("Update %s") % self.definition_id.name,
+ 'name': _("Update %s", self.definition_id.name),
'id': self.id,
'type': 'ir.actions.act_window',
'views': [[False, 'form']],
diff --git a/addons/google_calendar/models/calendar.py b/addons/google_calendar/models/calendar.py
index 57d9f63a440..765473509ba 100644
--- a/addons/google_calendar/models/calendar.py
+++ b/addons/google_calendar/models/calendar.py
@@ -131,15 +131,27 @@ class Meeting(models.Model):
if minutes % (60*24) == 0:
interval = 'days'
duration = minutes / 60 / 24
- name = _("%s - %s Days") % (alarm_type_label, duration)
+ name = _(
+ "%(reminder_type)s - %(duration)s Days",
+ reminder_type=alarm_type_label,
+ duration=duration,
+ )
elif minutes % 60 == 0:
interval = 'hours'
duration = minutes / 60
- name = _("%s - %s Hours") % (alarm_type_label, duration)
+ name = _(
+ "%(reminder_type)s - %(duration)s Hours",
+ reminder_type=alarm_type_label,
+ duration=duration,
+ )
else:
interval = 'minutes'
duration = minutes
- name = _("%s - %s Minutes") % (alarm_type_label, duration)
+ name = _(
+ "%(reminder_type)s - %(duration)s Minutes",
+ reminder_type=alarm_type_label,
+ duration=duration,
+ )
commands += [(0, 0, {'duration': duration, 'interval': interval, 'name': name, 'alarm_type': alarm_type})]
return commands
diff --git a/addons/google_calendar/models/res_users.py b/addons/google_calendar/models/res_users.py
index c2d2dfaf9ac..416cc9f8667 100644
--- a/addons/google_calendar/models/res_users.py
+++ b/addons/google_calendar/models/res_users.py
@@ -74,7 +74,7 @@ class User(models.Model):
with self.pool.cursor() as cr:
self.env.user.with_env(self.env(cr=cr)).write({'google_calendar_rtoken': False})
error_key = error.response.json().get("error", "nc")
- error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]") % error_key
+ error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]", error_key)
raise UserError(error_msg)
def _sync_google_calendar(self, calendar_service: GoogleCalendarService):
diff --git a/addons/hr/models/hr_plan.py b/addons/hr/models/hr_plan.py
index a9361f531ac..47b4ecc9ef5 100644
--- a/addons/hr/models/hr_plan.py
+++ b/addons/hr/models/hr_plan.py
@@ -34,24 +34,24 @@ class HrPlanActivityType(models.Model):
def get_responsible_id(self, employee):
if self.responsible == 'coach':
if not employee.coach_id:
- raise UserError(_('Coach of employee %s is not set.') % employee.name)
+ raise UserError(_('Coach of employee %s is not set.', employee.name))
responsible = employee.coach_id.user_id
if not responsible:
- raise UserError(_('User of coach of employee %s is not set.') % employee.name)
+ raise UserError(_('User of coach of employee %s is not set.', employee.name))
elif self.responsible == 'manager':
if not employee.parent_id:
- raise UserError(_('Manager of employee %s is not set.') % employee.name)
+ raise UserError(_('Manager of employee %s is not set.', employee.name))
responsible = employee.parent_id.user_id
if not responsible:
- raise UserError(_('User of manager of employee %s is not set.') % employee.name)
+ raise UserError(_('User of manager of employee %s is not set.', employee.name))
elif self.responsible == 'employee':
responsible = employee.user_id
if not responsible:
- raise UserError(_('User linked to employee %s is required.') % employee.name)
+ raise UserError(_('User linked to employee %s is required.', employee.name))
elif self.responsible == 'other':
responsible = self.responsible_id
if not responsible:
- raise UserError(_('No specific user given on activity %s.') % self.activity_type_id.name)
+ raise UserError(_('No specific user given on activity %s.', self.activity_type_id.name))
return responsible
diff --git a/addons/hr_contract/models/hr_contract.py b/addons/hr_contract/models/hr_contract.py
index 9e79cd89b32..365f0149288 100644
--- a/addons/hr_contract/models/hr_contract.py
+++ b/addons/hr_contract/models/hr_contract.py
@@ -144,7 +144,7 @@ class Contract(models.Model):
for contract in contracts:
contract.activity_schedule(
'mail.mail_activity_data_todo', contract.date_end,
- _("The contract of %s is about to expire.") % contract.employee_id.name,
+ _("The contract of %s is about to expire.", contract.employee_id.name),
user_id=contract.hr_responsible_id.id or self.env.uid)
contracts.write({'kanban_state': 'blocked'})
diff --git a/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py b/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py
index ff586f68491..37e1f0bf68d 100644
--- a/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py
+++ b/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py
@@ -113,7 +113,14 @@ class HrExpenseSheetRegisterPaymentWizard(models.TransientModel):
payment.action_post()
# Log the payment in the chatter
- body = (_("A payment of %s %s with the reference <a href='/mail/view?%s'>%s</a> related to your expense %s has been made.") % (payment.amount, payment.currency_id.symbol, url_encode({'model': 'account.payment', 'res_id': payment.id}), payment.name, expense_sheet.name))
+ body = _(
+ "A payment of %(amount)s %(currency)s with the reference <a href='/mail/view?%(url)s'>%(payment_name)s</a> related to your expense %(expense_name)s has been made.",
+ amount=payment.amount,
+ currency=payment.currency_id.symbol,
+ url=url_encode({'model': 'account.payment', 'res_id': payment.id}),
+ payment_name=payment.name,
+ expense_name=expense_sheet.name
+ )
expense_sheet.message_post(body=body)
# Reconcile the payment and the expense, i.e. lookup on the payable account move lines
diff --git a/addons/hr_fleet/controllers/main.py b/addons/hr_fleet/controllers/main.py
index 175139e04da..80748991fda 100644
--- a/addons/hr_fleet/controllers/main.py
+++ b/addons/hr_fleet/controllers/main.py
@@ -52,7 +52,12 @@ class HrFleet(Controller):
date_start = car_line_doc.date_start
date_end = car_line_doc.date_end or '...'
- text_to_print = _("%s (driven from: %s to %s)") % (car_name, date_start, date_end)
+ text_to_print = _(
+ "%(car_name)s (driven from: %(date_start)s to %(date_end)s)",
+ car_name=car_name,
+ date_start=date_start,
+ date_end=date_end
+ )
can.drawCentredString(width / 2, height - normal_font_size, text_to_print)
can.save()
header_pdf = PdfFileReader(header, overwriteWarnings=False)
diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py
index 5e88edf967e..9da4c75eb71 100644
--- a/addons/hr_holidays/models/hr_leave.py
+++ b/addons/hr_holidays/models/hr_leave.py
@@ -621,11 +621,11 @@ class HolidaysRequest(models.Model):
if leave.leave_type_request_unit == 'hour':
res.append((
leave.id,
- _("%s on %s: %.2f hours on %s") % (
- target,
- leave.holiday_status_id.name,
- leave.number_of_hours_display,
- fields.Date.to_string(leave.date_from),
+ _("%(person)s on %(leave_type)s: %(duration).2f hours on %(date)s",
+ person=target,
+ leave_type=leave.holiday_status_id.name,
+ duration=leave.number_of_hours_display,
+ date=fields.Date.to_string(leave.date_from),
)
))
else:
@@ -634,11 +634,11 @@ class HolidaysRequest(models.Model):
display_date += ' ⇨ %s' % fields.Date.to_string(leave.date_to)
res.append((
leave.id,
- _("%s on %s: %.2f days (%s)") % (
- target,
- leave.holiday_status_id.name,
- leave.number_of_days,
- display_date,
+ _("%(person)s on %(leave_type)s: %(duration).2f days (%(start)s)",
+ person=target,
+ leave_type=leave.holiday_status_id.name,
+ duration=leave.number_of_days,
+ start=display_date,
)
))
return res
@@ -657,19 +657,26 @@ class HolidaysRequest(models.Model):
dto = leave.date_to
if leave.holiday_status_id.validity_start and leave.holiday_status_id.validity_stop:
if dfrom and dto and (dfrom.date() < vstart or dto.date() > vstop):
- raise ValidationError(
- _('%s are only valid between %s and %s') % (
- leave.holiday_status_id.display_name, leave.holiday_status_id.validity_start, leave.holiday_status_id.validity_stop))
+ raise ValidationError(_(
+ '%(leave_type)s are only valid between %(start)s and %(end)s',
+ leave_type=leave.holiday_status_id.display_name,
+ start=leave.holiday_status_id.validity_start,
+ end=leave.holiday_status_id.validity_stop
+ ))
elif leave.holiday_status_id.validity_start:
if dfrom and (dfrom.date() < vstart):
- raise ValidationError(
- _('%s are only valid starting from %s') % (
- leave.holiday_status_id.display_name, leave.holiday_status_id.validity_start))
+ raise ValidationError(_(
+ '%(leave_type)s are only valid starting from %(date)s',
+ leave_type=leave.holiday_status_id.display_name,
+ date=leave.holiday_status_id.validity_start
+ ))
elif leave.holiday_status_id.validity_stop:
if dto and (dto.date() > vstop):
- raise ValidationError(
- _('%s are only valid until %s') % (
- leave.holiday_status_id.display_name, leave.holiday_status_id.validity_stop))
+ raise ValidationError(_(
+ '%(leave_type)s are only valid until %(date)s',
+ leave_type=leave.holiday_status_id.display_name,
+ date=leave.holiday_status_id.validity_stop
+ ))
def _check_double_validation_rules(self, employees, state):
if self.user_has_groups('hr_holidays.group_hr_holidays_manager'):
@@ -1032,7 +1039,7 @@ class HolidaysRequest(models.Model):
for holiday in self:
if holiday.employee_id.user_id:
holiday.message_post(
- body=_('Your %s planned on %s has been refused') % (holiday.holiday_status_id.display_name, holiday.date_from),
+ body=_('Your %(leave_type)s planned on %(date)s has been refused', leave_type=holiday.holiday_status_id.display_name, date=holiday.date_from),
partner_ids=holiday.employee_id.user_id.partner_id.ids)
self._remove_resource_leave()
@@ -1101,7 +1108,13 @@ class HolidaysRequest(models.Model):
for holiday in self:
start = UTC.localize(holiday.date_from).astimezone(timezone(holiday.employee_id.tz or 'UTC'))
end = UTC.localize(holiday.date_to).astimezone(timezone(holiday.employee_id.tz or 'UTC'))
- note = _('New %s Request created by %s from %s to %s') % (holiday.holiday_status_id.name, holiday.create_uid.name, start, end)
+ note = _(
+ 'New %(leave_type)s Request created by %(user)s from %(start)s to %(end)s',
+ leave_type=holiday.holiday_status_id.name,
+ user=holiday.create_uid.name,
+ start=start,
+ end=end
+ )
if holiday.state == 'draft':
to_clean |= holiday
elif holiday.state == 'confirm':
diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py
index 6fda4311739..5c39867ba50 100644
--- a/addons/hr_holidays/models/hr_leave_allocation.py
+++ b/addons/hr_holidays/models/hr_leave_allocation.py
@@ -389,11 +389,12 @@ class HolidaysAllocation(models.Model):
res.append(
(allocation.id,
- _("Allocation of %s : %.2f %s to %s") %
- (allocation.holiday_status_id.sudo().name,
- allocation.number_of_hours_display if allocation.type_request_unit == 'hour' else allocation.number_of_days,
- 'hours' if allocation.type_request_unit == 'hour' else 'days',
- target))
+ _("Allocation of %(allocation_name)s : %(duration).2f %(duration_type)s to %(person)s",
+ allocation_name=allocation.holiday_status_id.sudo().name,
+ duration=allocation.number_of_hours_display if allocation.type_request_unit == 'hour' else allocation.number_of_days,
+ duration_type='hours' if allocation.type_request_unit == 'hour' else 'days',
+ person=target
+ ))
)
return res
@@ -410,7 +411,11 @@ class HolidaysAllocation(models.Model):
today = fields.Date.today()
if vstop < today:
- raise ValidationError(_('You can allocate %s only before %s.') % (allocation.holiday_status_id.display_name, allocation.holiday_status_id.validity_stop))
+ raise ValidationError(_(
+ 'You can allocate %(allocation_type)s only before %(date)s.',
+ allocation_type=allocation.holiday_status_id.display_name,
+ date=allocation.holiday_status_id.validity_stop
+ ))
@api.model
def create(self, values):
@@ -613,7 +618,12 @@ class HolidaysAllocation(models.Model):
def activity_update(self):
to_clean, to_do = self.env['hr.leave.allocation'], self.env['hr.leave.allocation']
for allocation in self:
- note = _('New Allocation Request created by %s: %s Days of %s') % (allocation.create_uid.name, allocation.number_of_days, allocation.holiday_status_id.name)
+ note = _(
+ 'New Allocation Request created by %(user)s: %(count)s Days of %(allocation_type)s',
+ user=allocation.create_uid.name,
+ count=allocation.number_of_days,
+ allocation_type=allocation.holiday_status_id.name
+ )
if allocation.state == 'draft':
to_clean |= allocation
elif allocation.state == 'confirm':
diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py
index 3623eaebd2c..35357ebd49d 100644
--- a/addons/hr_recruitment/models/hr_recruitment.py
+++ b/addons/hr_recruitment/models/hr_recruitment.py
@@ -466,7 +466,7 @@ class Applicant(models.Model):
if applicant.job_id:
applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1})
applicant.job_id.message_post(
- body=_('New Employee %s Hired') % applicant.partner_name if applicant.partner_name else applicant.name,
+ body=_('New Employee %s Hired', applicant.partner_name if applicant.partner_name else applicant.name),
subtype_xmlid="hr_recruitment.mt_job_applicant_hired")
applicant.message_post_with_view(
'hr_recruitment.applicant_hired_template',
diff --git a/addons/hr_skills/models/hr_skills.py b/addons/hr_skills/models/hr_skills.py
index e562dd58449..759607a8e72 100644
--- a/addons/hr_skills/models/hr_skills.py
+++ b/addons/hr_skills/models/hr_skills.py
@@ -33,13 +33,13 @@ class EmployeeSkill(models.Model):
def _check_skill_type(self):
for record in self:
if record.skill_id not in record.skill_type_id.skill_ids:
- raise ValidationError(_("The skill %s and skill type %s doesn't match") % (record.skill_id.name, record.skill_type_id.name))
+ raise ValidationError(_("The skill %(name)s and skill type %(type)s doesn't match", name=record.skill_id.name, type=record.skill_type_id.name))
@api.constrains('skill_type_id', 'skill_level_id')
def _check_skill_level(self):
for record in self:
if record.skill_level_id not in record.skill_type_id.skill_level_ids:
- raise ValidationError(_("The skill level %s is not valid for skill type: %s ") % (record.skill_level_id.name, record.skill_type_id.name))
+ raise ValidationError(_("The skill level %(level)s is not valid for skill type: %(type)s", level=record.skill_level_id.name, type=record.skill_type_id.name))
class SkillLevel(models.Model):
diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py
index ed0ac3a5bad..c9d294a1a61 100644
--- a/addons/hr_timesheet/models/project.py
+++ b/addons/hr_timesheet/models/project.py
@@ -186,7 +186,12 @@ class Task(models.Model):
for task in self:
if task.allow_timesheets and task.planned_hours > 0:
hours, mins = (str(int(duration)).rjust(2, '0') for duration in divmod(abs(task.remaining_hours) * 60, 60))
- hours_left = _("(%s%s:%s remaining)") % ('-' if task.remaining_hours < 0 else '', hours, mins)
+ hours_left = _(
+ "(%(sign)s%(hours)s:%(minutes)s remaining)",
+ sign='-' if task.remaining_hours < 0 else '',
+ hours=hours,
+ minutes=mins,
+ )
name_mapping[task.id] = name_mapping.get(task.id, '') + " ‒ " + hours_left
return list(name_mapping.items())
return super().name_get()
diff --git a/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py b/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py
index 481a11d1309..37a63f57548 100644
--- a/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py
+++ b/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py
@@ -142,7 +142,7 @@ class SerialDriver(Driver):
self._take_measure()
time.sleep(self._protocol.newMeasureDelay)
except Exception:
- msg = _('Error while reading %s') % self.device_name
+ msg = _('Error while reading %s', self.device_name)
_logger.exception(msg)
self._status = {'status': self.STATUS_ERROR, 'message_title': msg, 'message_body': traceback.format_exc()}
self._push_status()
diff --git a/addons/iap/models/iap.py b/addons/iap/models/iap.py
index 34911b8a42b..3bd79296faa 100644
--- a/addons/iap/models/iap.py
+++ b/addons/iap/models/iap.py
@@ -68,7 +68,7 @@ def jsonrpc(url, method='call', params=None, timeout=15):
return response.get('result')
except (ValueError, requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, requests.exceptions.Timeout, requests.exceptions.HTTPError) as e:
raise exceptions.AccessError(
- _('The url that this service requested returned an error. Please contact the author of the app. The url it tried to contact was %s') % url
+ _('The url that this service requested returned an error. Please contact the author of the app. The url it tried to contact was %s', url)
)
#----------------------------------------------------------
diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py
index a1110b30c4b..783e576e71f 100644
--- a/addons/im_livechat/models/mail_channel.py
+++ b/addons/im_livechat/models/mail_channel.py
@@ -207,7 +207,7 @@ class MailChannel(models.Model):
mail_body = template._render(render_context, engine='ir.qweb', minimal_qcontext=True)
mail_body = self.env['mail.render.mixin']._replace_local_links(mail_body)
mail = self.env['mail.mail'].sudo().create({
- 'subject': _('Conversation with %s') % self.livechat_operator_id.name,
+ 'subject': _('Conversation with %s', self.livechat_operator_id.name),
'email_from': company.catchall_formatted or company.email_formatted,
'author_id': self.env.user.partner_id.id,
'email_to': email,
diff --git a/addons/l10n_ar/models/account_move.py b/addons/l10n_ar/models/account_move.py
index 178f5644f34..afb6ac9ee56 100644
--- a/addons/l10n_ar/models/account_move.py
+++ b/addons/l10n_ar/models/account_move.py
@@ -98,7 +98,7 @@ class AccountMove(models.Model):
for line in inv.mapped('invoice_line_ids').filtered(lambda x: x.display_type not in ('line_section', 'line_note')):
vat_taxes = line.tax_ids.filtered(lambda x: x.tax_group_id.l10n_ar_vat_afip_code)
if len(vat_taxes) != 1:
- raise UserError(_('There must be one and only one VAT tax per line. Check line "%s"') % line.name)
+ raise UserError(_('There must be one and only one VAT tax per line. Check line "%s"', line.name))
elif purchase_aliquots == 'zero' and vat_taxes.tax_group_id.l10n_ar_vat_afip_code != '0':
raise UserError(_('On invoice id "%s" you must use VAT Not Applicable on every line.') % inv.id)
elif purchase_aliquots == 'not_zero' and vat_taxes.tax_group_id.l10n_ar_vat_afip_code == '0':
@@ -129,22 +129,20 @@ class AccountMove(models.Model):
res_code = rec.partner_id.l10n_ar_afip_responsibility_type_id.code
domain = [('company_id', '=', rec.company_id.id), ('l10n_latam_use_documents', '=', True), ('type', '=', 'sale')]
journal = self.env['account.journal']
- partner_type = journal_type = False
+ msg = False
if res_code in ['9', '10'] and rec.journal_id.l10n_ar_afip_pos_system not in expo_journals:
# if partner is foregin and journal is not of expo, we try to change to expo journal
journal = journal.search(domain + [('l10n_ar_afip_pos_system', 'in', expo_journals)], limit=1)
- partner_type, journal_type = (_('foreign partner'), _('exportation'))
+ msg = _('You are trying to create an invoice for foreign partner but you don\'t have an exportation journal')
elif res_code not in ['9', '10'] and rec.journal_id.l10n_ar_afip_pos_system in expo_journals:
# if partner is NOT foregin and journal is for expo, we try to change to local journal
journal = journal.search(domain + [('l10n_ar_afip_pos_system', 'not in', expo_journals)], limit=1)
- partner_type, journal_type = (_('domestic partner'), _('domestic market'))
+ msg = _('You are trying to create an invoice for domestic partner but you don\'t have an domestic market journal')
if journal:
rec.journal_id = journal.id
- elif partner_type and journal_type:
+ elif msg:
# Throw an error to user in order to proper configure the journal for the type of operation
action = self.env.ref('account.action_account_journal_form')
- msg = _('You are trying to create an invoice for %s but you dont have an %s journal') % (
- partner_type, journal_type)
raise RedirectWarning(msg, action.id, _('Go to Journals'))
def post(self):
diff --git a/addons/l10n_ar/models/res_partner.py b/addons/l10n_ar/models/res_partner.py
index 50adb05dc1f..68bb218730b 100644
--- a/addons/l10n_ar/models/res_partner.py
+++ b/addons/l10n_ar/models/res_partner.py
@@ -103,10 +103,10 @@ class ResPartner(models.Model):
try:
module.validate(rec.vat)
except module.InvalidChecksum:
- raise ValidationError(_('The validation digit is not valid for "%s"') % rec.l10n_latam_identification_type_id.name)
+ raise ValidationError(_('The validation digit is not valid for "%s"', rec.l10n_latam_identification_type_id.name))
except module.InvalidLength:
- raise ValidationError(_('Invalid length for "%s"') % rec.l10n_latam_identification_type_id.name)
+ raise ValidationError(_('Invalid length for "%s"', rec.l10n_latam_identification_type_id.name))
except module.InvalidFormat:
- raise ValidationError(_('Only numbers allowed for "%s"') % rec.l10n_latam_identification_type_id.name)
+ raise ValidationError(_('Only numbers allowed for "%s"', rec.l10n_latam_identification_type_id.name))
except Exception as error:
raise ValidationError(repr(error))
diff --git a/addons/l10n_fr_fec/wizard/account_fr_fec.py b/addons/l10n_fr_fec/wizard/account_fr_fec.py
index e09b63e7340..0484c10ce1c 100644
--- a/addons/l10n_fr_fec/wizard/account_fr_fec.py
+++ b/addons/l10n_fr_fec/wizard/account_fr_fec.py
@@ -88,7 +88,7 @@ class AccountFrFec(models.TransientModel):
is_dom_tom = company.country_id.code in dom_tom_group.country_ids.mapped('code')
if not is_dom_tom and not company.vat:
raise Warning(
- _("Missing VAT number for company %s") % company.name)
+ _("Missing VAT number for company %s", company.name))
if not is_dom_tom and company.vat[0:2] != 'FR':
raise Warning(
_("FEC is for French companies only !"))
diff --git a/addons/l10n_fr_pos_cert/models/pos.py b/addons/l10n_fr_pos_cert/models/pos.py
index 4e4b6f2d61e..c8b539a5521 100644
--- a/addons/l10n_fr_pos_cert/models/pos.py
+++ b/addons/l10n_fr_pos_cert/models/pos.py
@@ -28,7 +28,7 @@ class pos_session(models.Model):
date_today = datetime.utcnow()
session_start = Datetime.from_string(self.start_at)
if not date_today - timedelta(hours=24) <= session_start:
- raise UserError(_("This session has been opened another day. To comply with the French law, you should close sessions on a daily basis. Please close session %s and open a new one.") % self.name)
+ raise UserError(_("This session has been opened another day. To comply with the French law, you should close sessions on a daily basis. Please close session %s and open a new one.", self.name))
return True
def open_frontend_cb(self):
diff --git a/addons/l10n_fr_pos_cert/models/res_company.py b/addons/l10n_fr_pos_cert/models/res_company.py
index 5cacda61c1d..c701c6f348e 100644
--- a/addons/l10n_fr_pos_cert/models/res_company.py
+++ b/addons/l10n_fr_pos_cert/models/res_company.py
@@ -64,14 +64,14 @@ class ResCompany(models.Model):
('l10n_fr_secure_sequence_number', '!=', 0)], order="l10n_fr_secure_sequence_number ASC")
if not orders:
- msg_alert = (_('There isn\'t any order flagged for data inalterability yet for the company %s. This mechanism only runs for point of sale orders generated after the installation of the module France - Certification CGI 286 I-3 bis. - POS') % self.env.company.name)
+ msg_alert = (_('There isn\'t any order flagged for data inalterability yet for the company %s. This mechanism only runs for point of sale orders generated after the installation of the module France - Certification CGI 286 I-3 bis. - POS', self.env.company.name))
hash_verified = False
previous_hash = u''
start_order_info = []
for order in orders:
if order.l10n_fr_hash != order._compute_hash(previous_hash=previous_hash):
- msg_alert = (_('Corrupted data on point of sale order with id %s.') % order.id)
+ msg_alert = (_('Corrupted data on point of sale order with id %s.', order.id))
hash_verified = False
break
previous_hash = order.l10n_fr_hash
diff --git a/addons/l10n_id_efaktur/models/account_move.py b/addons/l10n_id_efaktur/models/account_move.py
index 2374be57c1f..e19b6d17367 100644
--- a/addons/l10n_id_efaktur/models/account_move.py
+++ b/addons/l10n_id_efaktur/models/account_move.py
@@ -102,7 +102,7 @@ class AccountMove(models.Model):
"""Reset E-Faktur, so it can be use for other invoice."""
for move in self:
if move.l10n_id_attachment_id:
- raise UserError(_('You have already generated the tax report for this document: %s') % move.name)
+ raise UserError(_('You have already generated the tax report for this document: %s', move.name))
self.env['l10n_id_efaktur.efaktur.range'].push_number(move.company_id.id, move.l10n_id_tax_number[3:])
move.message_post(
body='e-Faktur Reset: %s ' % (move.l10n_id_tax_number),
diff --git a/addons/l10n_it_edi/models/account_edi_format.py b/addons/l10n_it_edi/models/account_edi_format.py
index ab2d7230407..6d52e5cf08e 100644
--- a/addons/l10n_it_edi/models/account_edi_format.py
+++ b/addons/l10n_it_edi/models/account_edi_format.py
@@ -83,13 +83,13 @@ class AccountEdiFormat(models.Model):
else:
company = self.env.company
if elements:
- _logger.info(_('Company not found with codice fiscale: %s. The company\'s user is set by default.') % elements[0].text)
+ _logger.info(_('Company not found with codice fiscale: %s. The company\'s user is set by default.', elements[0].text))
else:
_logger.info(_('Company not found. The company\'s user is set by default.'))
if not self.env.is_superuser():
if self.env.company != company:
- raise UserError(_("You can only import invoice concern your current company: %s") % self.env.company.display_name)
+ raise UserError(_("You can only import invoice concern your current company: %s", self.env.company.display_name))
# Refund type.
# TD01 == invoice
diff --git a/addons/l10n_it_edi/models/account_invoice.py b/addons/l10n_it_edi/models/account_invoice.py
index 62e40420247..3e7c910e7b0 100644
--- a/addons/l10n_it_edi/models/account_invoice.py
+++ b/addons/l10n_it_edi/models/account_invoice.py
@@ -168,7 +168,7 @@ class AccountMove(models.Model):
}
data = b"<?xml version='1.0' encoding='UTF-8'?>" + invoice._export_as_xml()
- description = _('Italian invoice: %s') % invoice.move_type
+ description = _('Italian invoice: %s', invoice.move_type)
invoice.edi_document_ids = self.env['ir.attachment'].create({
'name': report_name,
'res_id': invoice.id,
diff --git a/addons/l10n_latam_invoice_document/models/account_move.py b/addons/l10n_latam_invoice_document/models/account_move.py
index 7472a1f79d5..23705dcae76 100644
--- a/addons/l10n_latam_invoice_document/models/account_move.py
+++ b/addons/l10n_latam_invoice_document/models/account_move.py
@@ -156,7 +156,7 @@ class AccountMove(models.Model):
invoice_type = rec.move_type
if internal_type in ['debit_note', 'invoice'] and invoice_type in ['out_refund', 'in_refund'] and \
rec.l10n_latam_document_type_id.code != '99':
- raise ValidationError(_('You can not use a %s document type with a refund invoice') % internal_type)
+ raise ValidationError(_('You can not use a %s document type with a refund invoice', internal_type))
elif internal_type == 'credit_note' and invoice_type in ['out_invoice', 'in_invoice']:
raise ValidationError(_('You can not use a %s document type with a invoice') % (internal_type))
diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py
index 8f3b1694098..46d14831dd5 100644
--- a/addons/mail/controllers/main.py
+++ b/addons/mail/controllers/main.py
@@ -37,7 +37,7 @@ class MailController(http.Controller):
def _check_token_and_record_or_redirect(cls, model, res_id, token):
comparison = cls._check_token(token)
if not comparison:
- _logger.warning(_('Invalid token in route %s') % request.httprequest.url)
+ _logger.warning(_('Invalid token in route %s', request.httprequest.url))
return comparison, None, cls._redirect_to_messaging()
try:
record = request.env[model].browse(res_id).exists()
diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py
index dd92b4a17b3..81e04898477 100644
--- a/addons/mail/models/mail_activity.py
+++ b/addons/mail/models/mail_activity.py
@@ -433,7 +433,9 @@ class MailActivity(models.Model):
record.message_notify(
partner_ids=activity.user_id.partner_id.ids,
body=body,
- subject=_('%s: %s assigned to you') % (activity.res_name, activity.summary or activity.activity_type_id.name),
+ subject=_('%(activity_name)s: %(summary)s assigned to you',
+ activity_name=activity.res_name,
+ summary=activity.summary or activity.activity_type_id.name),
record_name=activity.res_name,
model_description=model_description,
email_layout_xmlid='mail.mail_notification_light',
diff --git a/addons/mail/models/mail_blacklist.py b/addons/mail/models/mail_blacklist.py
index cbe5cc6693b..059c6e9e629 100644
--- a/addons/mail/models/mail_blacklist.py
+++ b/addons/mail/models/mail_blacklist.py
@@ -28,7 +28,7 @@ class MailBlackList(models.Model):
for value in values:
email = tools.email_normalize(value.get('email'))
if not email:
- raise UserError(_('Invalid email address %r') % value['email'])
+ raise UserError(_('Invalid email address %r', value['email']))
if email in all_emails:
continue
all_emails.append(email)
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index 1d7c35fabc9..23f63f4dad3 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -427,7 +427,7 @@ class Channel(models.Model):
'email_from': company.catchall_formatted or company.email_formatted,
'author_id': self.env.user.partner_id.id,
'body_html': view._render({'channel': self, 'partner': partner}, engine='ir.qweb', minimal_qcontext=True),
- 'subject': _("Guidelines of channel %s") % self.name,
+ 'subject': _("Guidelines of channel %s", self.name),
'recipient_ids': [(4, partner.id)]
}
mail = self.env['mail.mail'].sudo().create(create_values)
@@ -976,7 +976,7 @@ class Channel(models.Model):
def _execute_command_help(self, **kwargs):
partner = self.env.user.partner_id
if self.channel_type == 'channel':
- msg = _("You are in channel <b>#%s</b>.") % self.name
+ msg = _("You are in channel <b>#%s</b>.", self.name)
if self.public == 'private':
msg += _(" This channel is private. People must be invited to join it.")
else:
@@ -1016,6 +1016,6 @@ class Channel(models.Model):
msg = _("You are alone in this channel.")
else:
dots = "..." if len(members) != len(self.channel_partner_ids) - 1 else ""
- msg = _("Users in this channel: %s %s and you.") % (", ".join(members), dots)
+ msg = _("Users in this channel: %(members)s %(dots)s and you.", members=", ".join(members), dots=dots)
self._send_transient_message(partner, msg)
diff --git a/addons/mail/models/mail_render_mixin.py b/addons/mail/models/mail_render_mixin.py
index ddd32659a03..79b66e55f8b 100644
--- a/addons/mail/models/mail_render_mixin.py
+++ b/addons/mail/models/mail_render_mixin.py
@@ -316,7 +316,7 @@ class MailRenderMixin(models.AbstractModel):
render_result = template.render(variables)
except Exception as e:
_logger.info("Failed to render template : %s" % e, exc_info=True)
- raise UserError(_("Failed to render template : %s") % e)
+ raise UserError(_("Failed to render template : %s", e))
if render_result == u"False":
render_result = u""
results[record.id] = render_result
diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py
index f8f90aea5fd..92783104b65 100644
--- a/addons/mail/models/mail_template.py
+++ b/addons/mail/models/mail_template.py
@@ -74,7 +74,7 @@ class MailTemplate(models.Model):
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
default = dict(default or {},
- name=_("%s (copy)") % self.name)
+ name=_("%s (copy)", self.name))
return super(MailTemplate, self).copy(default=default)
def unlink_action(self):
@@ -88,7 +88,7 @@ class MailTemplate(models.Model):
view = self.env.ref('mail.email_compose_message_wizard_form')
for template in self:
- button_name = _('Send Mail (%s)') % template.name
+ button_name = _('Send Mail (%s)', template.name)
action = ActWindow.create({
'name': button_name,
'type': 'ir.actions.act_window',
@@ -200,7 +200,7 @@ class MailTemplate(models.Model):
else:
res = report._render([res_id])
if not res:
- raise UserError(_('Unsupported report type %s found.') % report.report_type)
+ raise UserError(_('Unsupported report type %s found.', report.report_type))
result, format = res
# TODO in trunk, change return format to binary to match message_post expected format
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index ee16931f25e..dcadca5b281 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -544,7 +544,7 @@ class MailThread(models.AbstractModel):
"""
self.ensure_one()
doc_name = self.env['ir.model']._get(self._name).name
- return _('%s created') % doc_name
+ return _('%s created', doc_name)
def _track_subtype(self, init_values):
""" Give the subtypes triggered by the changes on the record according
@@ -671,7 +671,7 @@ class MailThread(models.AbstractModel):
def _routing_warn(self, error_message, message_id, route, raise_exception=True):
""" Tools method used in _routing_check_route: whether to log a warning or raise an error """
- short_message = _("Mailbox unavailable - %s") % error_message
+ short_message = _("Mailbox unavailable - %s", error_message)
full_message = ('Routing mail with Message-Id %s: route %s: %s' %
(message_id, route, error_message))
_logger.info(full_message)
@@ -791,22 +791,27 @@ class MailThread(models.AbstractModel):
self._routing_warn(_('target model unspecified'), message_id, route, raise_exception)
return ()
elif model not in self.env:
- self._routing_warn(_('unknown target model %s') % model, message_id, route, raise_exception)
+ self._routing_warn(_('unknown target model %s', model), message_id, route, raise_exception)
return ()
record_set = self.env[model].browse(thread_id) if thread_id else self.env[model]
# Existing Document: check if exists and model accepts the mailgateway; if not, fallback on create if allowed
if thread_id:
if not record_set.exists():
- self._routing_warn(_('reply to missing document (%s,%s), fall back on document creation') % (model, thread_id), message_id, route, False)
+ self._routing_warn(
+ _('reply to missing document (%(model)s,%(thread)s), fall back on document creation', model=model, thread=thread_id),
+ message_id,
+ route,
+ False
+ )
thread_id = None
elif not hasattr(record_set, 'message_update'):
- self._routing_warn(_('reply to model %s that does not accept document update, fall back on document creation') % model, message_id, route, False)
+ self._routing_warn(_('reply to model %s that does not accept document update, fall back on document creation', model), message_id, route, False)
thread_id = None
# New Document: check model accepts the mailgateway
if not thread_id and model and not hasattr(record_set, 'message_new'):
- self._routing_warn(_('model %s does not accept document creation') % model, message_id, route, raise_exception)
+ self._routing_warn(_('model %s does not accept document creation', model), message_id, route, raise_exception)
return ()
# Update message author. We do it now because we need it for aliases (contact settings)
@@ -834,7 +839,12 @@ class MailThread(models.AbstractModel):
else:
error_code = self.env['mail.alias.mixin']._alias_check_contact_on_record(obj, message, message_dict, alias)
if error_code is not True:
- self._routing_warn(_('alias %s: %s') % (alias.alias_name, error_code or _('unknown error')), message_id, route, False)
+ self._routing_warn(
+ _('alias %(name)s: %(error)s', name=alias.alias_name, error=error_code or _('unknown error')),
+ message_id,
+ route,
+ False
+ )
body = alias._get_alias_bounced_body(message_dict)
self._routing_create_bounce_email(email_from, body, message, references=message_id)
return False
@@ -2595,7 +2605,7 @@ class MailThread(models.AbstractModel):
access_link = self._notify_get_action_link('view')
if model_name:
- view_title = _('View %s') % model_name
+ view_title = _('View %s', model_name)
else:
view_title = _('View')
@@ -2859,7 +2869,7 @@ class MailThread(models.AbstractModel):
assignation_msg = view._render(values, engine='ir.qweb', minimal_qcontext=True)
assignation_msg = self.env['mail.render.mixin']._replace_local_links(assignation_msg)
record.message_notify(
- subject=_('You have been assigned to %s') % record.display_name,
+ subject=_('You have been assigned to %s', record.display_name),
body=assignation_msg,
partner_ids=partner_ids,
record_name=record.display_name,
diff --git a/addons/mail/models/mail_thread_blacklist.py b/addons/mail/models/mail_thread_blacklist.py
index 00f6bb95518..f17302f360e 100644
--- a/addons/mail/models/mail_thread_blacklist.py
+++ b/addons/mail/models/mail_thread_blacklist.py
@@ -93,9 +93,9 @@ class MailBlackListMixin(models.AbstractModel):
def _assert_primary_email(self):
if not hasattr(self, "_primary_email") or not isinstance(self._primary_email, str):
- raise UserError(_('Invalid primary email field on model %s') % self._name)
+ raise UserError(_('Invalid primary email field on model %s', self._name))
if self._primary_email not in self._fields or self._fields[self._primary_email].type != 'char':
- raise UserError(_('Invalid primary email field on model %s') % self._name)
+ raise UserError(_('Invalid primary email field on model %s', self._name))
def _message_receive_bounce(self, email, partner):
""" Override of mail.thread generic method. Purpose is to increment the
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index bbe67a37cdc..3d96ebe25b6 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -64,7 +64,7 @@ class Invite(models.TransientModel):
# send an email if option checked and if a message exists (do not send void emails)
if wizard.send_mail and wizard.message and not wizard.message == '<br>': # when deleting the message, cleditor keeps a <br>
message = self.env['mail.message'].create({
- 'subject': _('Invitation to follow %s: %s') % (model_name, document.display_name),
+ 'subject': _('Invitation to follow %(document_model)s: %(document_name)s', document_model=model_name, document_name=document.display_name),
'body': wizard.message,
'record_name': document.display_name,
'email_from': email_from,
diff --git a/addons/maintenance/models/maintenance.py b/addons/maintenance/models/maintenance.py
index 49d27a2b182..8224cc52d93 100644
--- a/addons/maintenance/models/maintenance.py
+++ b/addons/maintenance/models/maintenance.py
@@ -223,7 +223,7 @@ class MaintenanceEquipment(models.Model):
def _create_new_request(self, date):
self.ensure_one()
self.env['maintenance.request'].create({
- 'name': _('Preventive Maintenance - %s') % self.name,
+ 'name': _('Preventive Maintenance - %s', self.name),
'request_date': date,
'schedule_date': date,
'category_id': self.category_id.id,
diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py
index 31c2acc8dc3..7146c1cc77d 100644
--- a/addons/mass_mailing/models/mailing.py
+++ b/addons/mass_mailing/models/mailing.py
@@ -259,7 +259,7 @@ class MassMailing(models.Model):
def copy(self, default=None):
self.ensure_one()
default = dict(default or {},
- name=_('%s (copy)') % self.name,
+ name=_('%s (copy)', self.name),
contact_list_ids=self.contact_list_ids.ids)
return super(MassMailing, self).copy(default=default)
@@ -469,7 +469,7 @@ class MassMailing(models.Model):
elif 'email' in target._fields:
mail_field = 'email'
else:
- raise UserError(_("Unsupported mass mailing model %s") % self.mailing_model_id.name)
+ raise UserError(_("Unsupported mass mailing model %s", self.mailing_model_id.name))
if self.unique_ab_testing:
query +="""
diff --git a/addons/mass_mailing_sms/models/mailing_mailing.py b/addons/mass_mailing_sms/models/mailing_mailing.py
index 3893f11a091..cd0e6060f6f 100644
--- a/addons/mass_mailing_sms/models/mailing_mailing.py
+++ b/addons/mass_mailing_sms/models/mailing_mailing.py
@@ -171,7 +171,7 @@ class Mailing(models.Model):
if 'phone' in target._fields:
phone_fields.append('phone')
if not phone_fields:
- raise UserError(_("Unsupported %s for mass SMS") % self.mailing_model_id.name)
+ raise UserError(_("Unsupported %s for mass SMS", self.mailing_model_id.name))
query = """
SELECT %(select_query)s
diff --git a/addons/mass_mailing_sms/wizard/mailing_sms_test.py b/addons/mass_mailing_sms/wizard/mailing_sms_test.py
index c9fe95ec8c5..198304dc2c6 100644
--- a/addons/mass_mailing_sms/wizard/mailing_sms_test.py
+++ b/addons/mass_mailing_sms/wizard/mailing_sms_test.py
@@ -23,7 +23,7 @@ class MassSMSTest(models.TransientModel):
sanitized_numbers = [info['sanitized'] for info in sanitize_res.values() if info['sanitized']]
invalid_numbers = [number for number, info in sanitize_res.items() if info['code']]
if invalid_numbers:
- raise exceptions.UserError(_('Following numbers are not correctly encoded: %s, example : "+32 495 85 85 77, +33 545 55 55 55"') % repr(invalid_numbers))
+ raise exceptions.UserError(_('Following numbers are not correctly encoded: %s, example : "+32 495 85 85 77, +33 545 55 55 55"', repr(invalid_numbers)))
self.env['sms.api']._send_sms_batch([{
'res_id': 0,
'number': number,
diff --git a/addons/mass_mailing_sms/wizard/sms_composer.py b/addons/mass_mailing_sms/wizard/sms_composer.py
index b3e50234036..b8d13b7f056 100644
--- a/addons/mass_mailing_sms/wizard/sms_composer.py
+++ b/addons/mass_mailing_sms/wizard/sms_composer.py
@@ -45,7 +45,7 @@ class SMSComposer(models.TransientModel):
trace_values['ignored'] = fields.Datetime.now()
else:
if self.mass_sms_allow_unsubscribe:
- sms_values['body'] = '%s\n%s' % (sms_values['body'] or '', _('STOP SMS : %s') % self._get_unsubscribe_url(record.id, trace_code, sms_values['number']))
+ sms_values['body'] = '%s\n%s' % (sms_values['body'] or '', _('STOP SMS : %s', self._get_unsubscribe_url(record.id, trace_code, sms_values['number'])))
return trace_values
def _get_blacklist_record_ids(self, records, recipients_info):
diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py
index 6f0603c028f..7a154b16d0f 100644
--- a/addons/mrp/models/mrp_bom.py
+++ b/addons/mrp/models/mrp_bom.py
@@ -90,16 +90,18 @@ class MrpBom(models.Model):
for bom in self:
for bom_line in bom.bom_line_ids:
if bom.product_id and bom_line.product_id == bom.product_id:
- raise ValidationError(_("BoM line product %s should not be the same as BoM product.") % bom.display_name)
+ raise ValidationError(_("BoM line product %s should not be the same as BoM product.", bom.display_name))
if bom.product_id and bom_line.bom_product_template_attribute_value_ids:
raise ValidationError(_("BoM cannot concern product %s and have a line with attributes (%s) at the same time.")
% (bom.product_id.display_name, ", ".join([ptav.display_name for ptav in bom_line.bom_product_template_attribute_value_ids])))
for ptav in bom_line.bom_product_template_attribute_value_ids:
if ptav.product_tmpl_id != bom.product_tmpl_id:
- raise ValidationError(
- _("The attribute value %s set on product %s does not match the BoM product %s.") %
- (ptav.display_name, ptav.product_tmpl_id.display_name, bom_line.parent_product_tmpl_id.display_name)
- )
+ raise ValidationError(_(
+ "The attribute value %(attribute)s set on product %(product)s does not match the BoM product %(bom_product)s.",
+ attribute=ptav.display_name,
+ product=ptav.product_tmpl_id.display_name,
+ bom_product=bom_line.parent_product_tmpl_id.display_name
+ ))
@api.onchange('product_uom_id')
def onchange_product_uom_id(self):
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 7a58b069198..491c775f6c3 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -718,7 +718,7 @@ class MrpProduction(models.Model):
not_cancel = self.filtered(lambda m: m.state != 'cancel')
if not_cancel:
productions_name = ', '.join([prod.display_name for prod in not_cancel])
- raise UserError(_('%s cannot be deleted. Try to cancel them before.') % productions_name)
+ raise UserError(_('%s cannot be deleted. Try to cancel them before.', productions_name))
workorders_to_delete = self.workorder_ids.filtered(lambda wo: wo.state != 'done')
if workorders_to_delete:
@@ -794,7 +794,7 @@ class MrpProduction(models.Model):
moves = []
for production in self:
if production.product_id in production.bom_id.byproduct_ids.mapped('product_id'):
- raise UserError(_("You cannot have %s as the finished product and in the Byproducts") % self.product_id.name)
+ raise UserError(_("You cannot have %s as the finished product and in the Byproducts", self.product_id.name))
moves = [production._get_move_finished_values(production.product_id.id, production.product_qty, production.product_uom_id.id)]
for byproduct in production.bom_id.byproduct_ids:
product_uom_factor = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id)
@@ -1554,7 +1554,7 @@ class MrpProduction(models.Model):
def button_unbuild(self):
self.ensure_one()
return {
- 'name': _('Unbuild: %s') % self.product_id.display_name,
+ 'name': _('Unbuild: %s', self.product_id.display_name),
'view_mode': 'form',
'res_model': 'mrp.unbuild',
'view_id': self.env.ref('mrp.mrp_unbuild_form_view_simplified').id,
@@ -1585,7 +1585,7 @@ class MrpProduction(models.Model):
('state', '=', 'done')
])
if sml:
- raise UserError(_('This serial number for product %s has already been produced') % self.product_id.name)
+ raise UserError(_('This serial number for product %s has already been produced', self.product_id.name))
for move in self.move_finished_ids:
if move.has_tracking != 'serial' or move.product_id == self.product_id:
@@ -1596,7 +1596,9 @@ class MrpProduction(models.Model):
('qty_done', '=', 1),
('state', '=', 'done')
]
- message = _('The serial number %s used for byproduct %s has already been produced') % (move_line.lot_id.name, move_line.product_id.name)
+ message = _('The serial number %(number)s used for byproduct %(product_name)s has already been produced',
+ number=move_line.lot_id.name,
+ product_name=move_line.product_id.name)
co_prod_move_lines = self.move_finished_ids.move_line_ids.filtered(lambda ml: ml.product_id != self.product_id)
domain_unbuild = domain + [
('production_id', '=', False),
@@ -1628,7 +1630,9 @@ class MrpProduction(models.Model):
('qty_done', '=', 1),
('state', '=', 'done')
]
- message = _('The serial number %s used for component %s has already been consumed') % (move_line.lot_id.name, move_line.product_id.name)
+ message = _('The serial number %(number)s used for component %(component)s has already been consumed',
+ number=move_line.lot_id.name,
+ component=move_line.product_id.name)
co_prod_move_lines = self.move_raw_ids.move_line_ids
domain_unbuild = domain + [
('production_id', '=', False),
diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py
index 0c1407c7a44..d9e89060c5c 100644
--- a/addons/mrp/models/mrp_workorder.py
+++ b/addons/mrp/models/mrp_workorder.py
@@ -175,9 +175,9 @@ class MrpWorkorder(models.Model):
if wo.state == 'pending' and prev_start and not (prev_start > wo.date_planned_start):
infos.append({
'color': 'text-primary',
- 'msg': _("Waiting the previous work order, planned from %s to %s") % (
- format_datetime(self.env, prev_start, dt_format=False),
- format_datetime(self.env, prev_finished, dt_format=False))
+ 'msg': _("Waiting the previous work order, planned from %(start)s to %(end)s",
+ start=format_datetime(self.env, prev_start, dt_format=False),
+ end=format_datetime(self.env, prev_finished, dt_format=False))
})
if wo.date_planned_finished < fields.Datetime.now():
infos.append({
@@ -187,14 +187,14 @@ class MrpWorkorder(models.Model):
if prev_start and prev_start > wo.date_planned_start:
infos.append({
'color': 'text-danger',
- 'msg': _("Scheduled before the previous work order, planned from %s to %s") % (
- format_datetime(self.env, prev_start, dt_format=False),
- format_datetime(self.env, prev_finished, dt_format=False))
+ 'msg': _("Scheduled before the previous work order, planned from %(start)s to %(end)s",
+ start=format_datetime(self.env, prev_start, dt_format=False),
+ end=format_datetime(self.env, prev_finished, dt_format=False))
})
if conflicted_dict.get(wo.id):
infos.append({
'color': 'text-danger',
- 'msg': _("Planned at the same time than other workorder(s) at %s" % wo.workcenter_id.display_name)
+ 'msg': _("Planned at the same time than other workorder(s) at %s", wo.workcenter_id.display_name)
})
color_icon = infos and infos[-1]['color'] or False
wo.show_json_popover = bool(color_icon)
@@ -751,7 +751,7 @@ class MrpWorkorder(models.Model):
qty_done += line.product_uom_id._compute_quantity(line.qty_done, move.product_uom)
rounding = move.product_uom_id.rounding
if float_compare(qty_done, move.product_uom_qty, precision_rounding=rounding) != 0:
- raise UserError(_('You should consume the quantity of %s defined in the BoM. If you want to consume more or less components, change the consumption setting on the BoM.') % move.product_id.name)
+ raise UserError(_('You should consume the quantity of %s defined in the BoM. If you want to consume more or less components, change the consumption setting on the BoM.', move.product_id.name))
def _check_sn_uniqueness(self):
""" Alert the user if the serial number as already been produced """
@@ -763,4 +763,4 @@ class MrpWorkorder(models.Model):
('state', '=', 'done')
])
if sml:
- raise UserError(_('This serial number for product %s has already been produced') % self.product_id.name)
+ raise UserError(_('This serial number for product %s has already been produced', self.product_id.name))
diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py
index 29657577a4f..cd82ca389f6 100644
--- a/addons/mrp/wizard/change_production_qty.py
+++ b/addons/mrp/wizard/change_production_qty.py
@@ -48,7 +48,11 @@ class ChangeProductionQty(models.TransientModel):
produced = sum(production.move_finished_ids.filtered(lambda m: m.product_id == production.product_id).mapped('quantity_done'))
if wizard.product_qty < produced:
format_qty = '%.{precision}f'.format(precision=precision)
- raise UserError(_("You have already processed %s. Please input a quantity higher than %s ") % (format_qty % produced, format_qty % produced))
+ raise UserError(_(
+ "You have already processed %(quantity)s. Please input a quantity higher than %(minimum)s ",
+ quantity=format_qty % produced,
+ minimum=format_qty % produced
+ ))
old_production_qty = production.product_qty
new_production_qty = wizard.product_qty
done_moves = production.move_finished_ids.filtered(lambda x: x.state == 'done' and x.product_id == production.product_id)
diff --git a/addons/payment_sips/models/payment.py b/addons/payment_sips/models/payment.py
index bc44b5c68b0..49dbd5b4dbd 100644
--- a/addons/payment_sips/models/payment.py
+++ b/addons/payment_sips/models/payment.py
@@ -159,7 +159,7 @@ class TxSips(models.Model):
payment_tx = self.search([('reference', '=', reference)])
if not payment_tx or len(payment_tx) > 1:
- error_msg = _('Sips: received data for reference %s') % reference
+ error_msg = _('Sips: received data for reference %s', reference)
if not payment_tx:
error_msg += _('; no order found')
else:
diff --git a/addons/payment_stripe/models/payment.py b/addons/payment_stripe/models/payment.py
index d13f80bec46..936e8d1c601 100644
--- a/addons/payment_stripe/models/payment.py
+++ b/addons/payment_stripe/models/payment.py
@@ -82,7 +82,7 @@ class PaymentAcquirerStripe(models.Model):
except HTTPError:
_logger.error(resp.text)
stripe_error = resp.json().get('error', {}).get('message', '')
- error_msg = " " + (_("Stripe gave us the following info about the problem: '%s'") % stripe_error)
+ error_msg = " " + (_("Stripe gave us the following info about the problem: '%s'", stripe_error))
raise ValidationError(error_msg)
return resp.json()
@@ -249,11 +249,11 @@ class PaymentTransactionStripe(models.Model):
tx = self.search([('reference', '=', reference)])
if not tx:
- error_msg = (_('Stripe: no order found for reference %s') % reference)
+ error_msg = _('Stripe: no order found for reference %s', reference)
_logger.error(error_msg)
raise ValidationError(error_msg)
elif len(tx) > 1:
- error_msg = (_('Stripe: %s orders found for reference %s') % (len(tx), reference))
+ error_msg = _('Stripe: %(count)s orders found for reference %(reference)s', count=len(tx), reference=reference)
_logger.error(error_msg)
raise ValidationError(error_msg)
return tx[0]
diff --git a/addons/phone_validation/models/mail_thread_phone.py b/addons/phone_validation/models/mail_thread_phone.py
index 9b608c8b601..d560de1911a 100644
--- a/addons/phone_validation/models/mail_thread_phone.py
+++ b/addons/phone_validation/models/mail_thread_phone.py
@@ -106,9 +106,9 @@ class PhoneMixin(models.AbstractModel):
def _assert_phone_field(self):
if not hasattr(self, "_phone_get_number_fields"):
- raise UserError(_('Invalid primary phone field on model %s') % self._name)
+ raise UserError(_('Invalid primary phone field on model %s', self._name))
if not any(fname in self and self._fields[fname].type == 'char' for fname in self._phone_get_number_fields()):
- raise UserError(_('Invalid primary phone field on model %s') % self._name)
+ raise UserError(_('Invalid primary phone field on model %s', self._name))
def _phone_get_number_fields(self):
""" This method returns the fields to use to find the number to use to
diff --git a/addons/phone_validation/tools/phone_validation.py b/addons/phone_validation/tools/phone_validation.py
index 97eb7bac05c..ac96c82a87a 100644
--- a/addons/phone_validation/tools/phone_validation.py
+++ b/addons/phone_validation/tools/phone_validation.py
@@ -17,12 +17,12 @@ try:
try:
phone_nbr = phonenumbers.parse(number, region=country_code, keep_raw_input=True)
except phonenumbers.phonenumberutil.NumberParseException as e:
- raise UserError(_('Unable to parse %s.: %s') % (number, str(e)))
+ raise UserError(_('Unable to parse %(phone)s: %(error)s', phone=number, error=str(e)))
if not phonenumbers.is_possible_number(phone_nbr):
- raise UserError(_('Impossible number %s: probably invalid number of digits.') % number)
+ raise UserError(_('Impossible number %s: probably invalid number of digits.', number))
if not phonenumbers.is_valid_number(phone_nbr):
- raise UserError(_('Invalid number %s: probably incorrect prefix.') % number)
+ raise UserError(_('Invalid number %s: probably incorrect prefix.', number))
return phone_nbr
diff --git a/addons/point_of_sale/models/pos_config.py b/addons/point_of_sale/models/pos_config.py
index 235c97bb806..d63bced8eb9 100644
--- a/addons/point_of_sale/models/pos_config.py
+++ b/addons/point_of_sale/models/pos_config.py
@@ -459,7 +459,7 @@ class PosConfig(models.Model):
def create(self, values):
IrSequence = self.env['ir.sequence'].sudo()
val = {
- 'name': _('POS Order %s') % values['name'],
+ 'name': _('POS Order %s', values['name']),
'padding': 4,
'prefix': "%s/" % values['name'],
'code': "pos.order",
@@ -468,7 +468,7 @@ class PosConfig(models.Model):
# force sequence_id field to new pos.order sequence
values['sequence_id'] = IrSequence.create(val).id
- val.update(name=_('POS order line %s') % values['name'], code='pos.order.line')
+ val.update(name=_('POS order line %s', values['name']), code='pos.order.line')
values['sequence_line_id'] = IrSequence.create(val).id
pos_config = super(PosConfig, self).create(values)
pos_config.sudo()._check_modules_to_install()
diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py
index 085ba223a04..ccb05ff7d42 100644
--- a/addons/point_of_sale/models/pos_order.py
+++ b/addons/point_of_sale/models/pos_order.py
@@ -363,7 +363,7 @@ class PosOrder(models.Model):
total = float_round(self.amount_total, precision_rounding=self.config_id.rounding_method.rounding, rounding_method=self.config_id.rounding_method.rounding_method)
if not float_is_zero(total - self.amount_paid, precision_rounding=self.currency_id.rounding):
- raise UserError(_("Order %s is not fully paid.") % self.name)
+ raise UserError(_("Order %s is not fully paid.", self.name))
self.write({'state': 'paid'})
@@ -479,7 +479,7 @@ class PosOrder(models.Model):
# order. It can be the same session, or if it has been closed the new one that has been opened.
current_session = order.session_id.config_id.current_session_id
if not current_session:
- raise UserError(_('To return product(s), you need to open a session in the POS %s') % order.session_id.config_id.display_name)
+ raise UserError(_('To return product(s), you need to open a session in the POS %s', order.session_id.config_id.display_name))
refund_order = order.copy({
'name': order.name + _(' REFUND'),
'session_id': current_session.id,
@@ -533,7 +533,7 @@ class PosOrder(models.Model):
'mimetype': 'image/jpeg',
})
mail_values = {
- 'subject': _('Receipt %s') % name,
+ 'subject': _('Receipt %s', name),
'body_html': message,
'author_id': self.env.user.partner_id.id,
'email_from': self.env.company.email or self.env.user.email_formatted,
diff --git a/addons/point_of_sale/models/pos_payment.py b/addons/point_of_sale/models/pos_payment.py
index a87762f501a..8dea1f62b92 100644
--- a/addons/point_of_sale/models/pos_payment.py
+++ b/addons/point_of_sale/models/pos_payment.py
@@ -33,7 +33,7 @@ class PosPayment(models.Model):
res = []
for payment in self:
if payment.name:
- res.append((payment.id, _('%s %s') % (payment.name, formatLang(self.env, payment.amount, currency_obj=payment.currency_id))))
+ res.append((payment.id, '%s %s' % (payment.name, formatLang(self.env, payment.amount, currency_obj=payment.currency_id))))
else:
res.append((payment.id, formatLang(self.env, payment.amount, currency_obj=payment.currency_id)))
return res
diff --git a/addons/portal/controllers/mail.py b/addons/portal/controllers/mail.py
index c64859c1ad6..612191b705e 100644
--- a/addons/portal/controllers/mail.py
+++ b/addons/portal/controllers/mail.py
@@ -111,7 +111,7 @@ class PortalChatter(http.Controller):
try:
CustomerPortal._document_check_access(self, 'ir.attachment', attachment_id, access_token)
except (AccessError, MissingError):
- raise UserError(_("The attachment %s does not exist or you do not have the rights to access it.") % attachment_id)
+ raise UserError(_("The attachment %s does not exist or you do not have the rights to access it.", attachment_id))
@http.route(['/mail/chatter_post'], type='http', methods=['POST'], auth='public', website=True)
def portal_chatter_post(self, res_model, res_id, message, redirect=None, attachment_ids='', attachment_tokens='', **kw):
diff --git a/addons/portal/controllers/portal.py b/addons/portal/controllers/portal.py
index 6bec53e7f74..6034a933e77 100644
--- a/addons/portal/controllers/portal.py
+++ b/addons/portal/controllers/portal.py
@@ -273,10 +273,10 @@ class CustomerPortal(Controller):
raise UserError(_("The attachment does not exist or you do not have the rights to access it."))
if attachment_sudo.res_model != 'mail.compose.message' or attachment_sudo.res_id != 0:
- raise UserError(_("The attachment %s cannot be removed because it is not in a pending state.") % attachment_sudo.name)
+ raise UserError(_("The attachment %s cannot be removed because it is not in a pending state.", attachment_sudo.name))
if attachment_sudo.env['mail.message'].search([('attachment_ids', 'in', attachment_sudo.ids)]):
- raise UserError(_("The attachment %s cannot be removed because it is linked to a message.") % attachment_sudo.name)
+ raise UserError(_("The attachment %s cannot be removed because it is linked to a message.", attachment_sudo.name))
return attachment_sudo.unlink()
@@ -364,12 +364,12 @@ class CustomerPortal(Controller):
def _show_report(self, model, report_type, report_ref, download=False):
if report_type not in ('html', 'pdf', 'text'):
- raise UserError(_("Invalid report type: %s") % report_type)
+ raise UserError(_("Invalid report type: %s", report_type))
report_sudo = request.env.ref(report_ref).sudo()
if not isinstance(report_sudo, type(request.env['ir.actions.report'])):
- raise UserError(_("%s is not the reference of a report") % report_ref)
+ raise UserError(_("%s is not the reference of a report", report_ref))
method_name = '_render_qweb_%s' % (report_type)
report = getattr(report_sudo, method_name)([model.id], data={'report_type': report_type})[0]
diff --git a/addons/portal/models/mail_thread.py b/addons/portal/models/mail_thread.py
index 424e3de0c25..0e9b58b9fca 100644
--- a/addons/portal/models/mail_thread.py
+++ b/addons/portal/models/mail_thread.py
@@ -28,7 +28,11 @@ class MailThread(models.AbstractModel):
self.ensure_one()
# check token field exists
if self._mail_post_token_field not in self._fields:
- raise NotImplementedError(_("Model %s does not support token signature, as it does not have %s field.") % (self._name, self._mail_post_token_field))
+ raise NotImplementedError(_(
+ "Model %(model_name)s does not support token signature, as it does not have %(field_name)s field.",
+ model_name=self._name,
+ field_name=self._mail_post_token_field
+ ))
# sign token
secret = self.env["ir.config_parameter"].sudo().get_param("database.secret")
token = (self.env.cr.dbname, self[self._mail_post_token_field], pid)
diff --git a/addons/pos_adyen/models/pos_config.py b/addons/pos_adyen/models/pos_config.py
index b0d9176c628..7578f844ed7 100644
--- a/addons/pos_adyen/models/pos_config.py
+++ b/addons/pos_adyen/models/pos_config.py
@@ -17,7 +17,7 @@ class PosConfig(models.Model):
def _check_adyen_ask_customer_for_tip(self):
for config in self:
if config.adyen_ask_customer_for_tip and (not config.tip_product_id or not config.iface_tipproduct):
- raise ValidationError(_("Please configure a tip product for POS %s to support tipping with Adyen.") % config.name)
+ raise ValidationError(_("Please configure a tip product for POS %s to support tipping with Adyen.", config.name))
@api.onchange('adyen_ask_customer_for_tip')
def _onchange_adyen_ask_customer_for_tip(self):
diff --git a/addons/pos_mercury/models/pos_mercury_transaction.py b/addons/pos_mercury/models/pos_mercury_transaction.py
index 44ca5b89b23..c30d0c64514 100644
--- a/addons/pos_mercury/models/pos_mercury_transaction.py
+++ b/addons/pos_mercury/models/pos_mercury_transaction.py
@@ -19,7 +19,7 @@ class MercuryTransaction(models.Model):
def _get_pos_session(self):
pos_session = self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1)
if not pos_session:
- raise UserError(_("No opened point of sale session for user %s found.") % self.env.user.name)
+ raise UserError(_("No opened point of sale session for user %s found.", self.env.user.name))
pos_session.login()
diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py
index 880766ce545..d1ef0ec714c 100644
--- a/addons/product/models/product_pricelist.py
+++ b/addons/product/models/product_pricelist.py
@@ -519,9 +519,9 @@ class PricelistItem(models.Model):
),
)
elif item.compute_price == 'percentage':
- item.price = _("%s %% discount") % (item.percent_price)
+ item.price = _("%s %% discount", item.percent_price)
else:
- item.price = _("%s %% discount and %s surcharge") % (item.price_discount, item.price_surcharge)
+ item.price = _("%(percentage)s %% discount and %(price)s surcharge", percentage=item.price_discount, price=item.price_surcharge)
@api.onchange('compute_price')
def _onchange_compute_price(self):
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index cb9cd14ee32..8da67700c14 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -436,7 +436,7 @@ class ProductTemplate(models.Model):
if default is None:
default = {}
if 'name' not in default:
- default['name'] = _("%s (copy)") % self.name
+ default['name'] = _("%s (copy)", self.name)
return super(ProductTemplate, self).copy(default=default)
def name_get(self):
diff --git a/addons/project/models/project.py b/addons/project/models/project.py
index 70c5f58f4dc..dee727dfcfb 100644
--- a/addons/project/models/project.py
+++ b/addons/project/models/project.py
@@ -639,7 +639,7 @@ class Task(models.Model):
portal_users = task.allowed_user_ids.filtered('share')
if portal_users:
user_names = ', '.join(portal_users[:10].mapped('name'))
- raise ValidationError(_("The project visibility setting doesn't allow portal users to see the project's tasks. (%s)") % user_names)
+ raise ValidationError(_("The project visibility setting doesn't allow portal users to see the project's tasks. (%s)", user_names))
def _compute_attachment_ids(self):
for task in self:
@@ -752,7 +752,7 @@ class Task(models.Model):
if default is None:
default = {}
if not default.get('name'):
- default['name'] = _("%s (copy)") % self.name
+ default['name'] = _("%s (copy)", self.name)
return super(Task, self).copy(default)
@api.constrains('parent_id')
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index e2d254d56fe..b0d8316f342 100644
--- a/addons/purchase/models/purchase.py
+++ b/addons/purchase/models/purchase.py
@@ -138,7 +138,12 @@ class PurchaseOrder(models.Model):
companies = order.order_line.product_id.company_id
if companies and companies != order.company_id:
bad_products = order.order_line.product_id.filtered(lambda p: p.company_id and p.company_id != order.company_id)
- raise ValidationError((_("Your quotation contains products from company %s whereas your quotation belongs to company %s. \n Please change the company of your quotation or remove the products from other companies (%s).") % (', '.join(companies.mapped('display_name')), order.company_id.display_name, ', '.join(bad_products.mapped('display_name')))))
+ raise ValidationError(_(
+ "Your quotation contains products from company %(product_company)s whereas your quotation belongs to company %(quote_company)s. \n Please change the company of your quotation or remove the products from other companies (%(bad_products)s).",
+ product_company=', '.join(companies.mapped('display_name')),
+ quote_company=order.company_id.display_name,
+ bad_products=', '.join(bad_products.mapped('display_name')),
+ ))
def _compute_access_url(self):
super(PurchaseOrder, self)._compute_access_url()
@@ -284,7 +289,7 @@ class PurchaseOrder(models.Model):
# Block if partner only has warning but parent company is blocked
if partner.purchase_warn != 'block' and partner.parent_id and partner.parent_id.purchase_warn == 'block':
partner = partner.parent_id
- title = _("Warning for %s") % partner.name
+ title = _("Warning for %s", partner.name)
message = partner.purchase_warn_msg
warning = {
'title': title,
@@ -721,9 +726,14 @@ class PurchaseOrder(models.Model):
def _compose_note(self, updated_dates):
"""Helper method for creating log note when user update scheduled date
on portal website."""
- note = _('<p> %s modified receipt dates for the following products:</p>') % self.partner_id.name
+ note = _('<p> %s modified receipt dates for the following products:</p>', self.partner_id.name)
for line, date in updated_dates:
- note += _('<p> &nbsp; - %s from %s to %s </p>') % (line.product_id.display_name, line.date_planned, date)
+ note += _(
+ '<p> &nbsp; - %(product_name)s from %(date_start)s to %(date_end)s </p>',
+ product_name=line.product_id.display_name,
+ date_start=line.date_planned,
+ date_end=date
+ )
return note
@@ -980,7 +990,7 @@ class PurchaseOrderLine(models.Model):
product_info = self.product_id
if product_info.purchase_line_warn != 'no-message':
- title = _("Warning for %s") % product_info.name
+ title = _("Warning for %s", product_info.name)
message = product_info.purchase_line_warn_msg
warning['title'] = title
warning['message'] = message
diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py
index 0ee207103c4..0a4e042a6e4 100644
--- a/addons/purchase_requisition/models/purchase_requisition.py
+++ b/addons/purchase_requisition/models/purchase_requisition.py
@@ -89,7 +89,7 @@ class PurchaseRequisition(models.Model):
('company_id', '=', self.company_id.id),
])
if any(requisitions):
- title = _("Warning for %s") % self.vendor_id.name
+ title = _("Warning for %s", self.vendor_id.name)
message = _("There is already an open blanket order for this supplier. We suggest you to use to complete this open blanket order instead of creating a new one.")
warning = {
'title': title,
@@ -115,7 +115,7 @@ class PurchaseRequisition(models.Model):
def action_in_progress(self):
self.ensure_one()
if not all(obj.line_ids for obj in self):
- raise UserError(_("You cannot confirm agreement '%s' because there is no product line.") % self.name)
+ raise UserError(_("You cannot confirm agreement '%s' because there is no product line.", self.name))
if self.type_id.quantity_copy == 'none' and self.vendor_id:
for requisition_line in self.line_ids:
if requisition_line.price_unit <= 0.0:
diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py
index 67fa411ed57..7d4e80430f3 100644
--- a/addons/purchase_stock/models/purchase.py
+++ b/addons/purchase_stock/models/purchase.py
@@ -218,7 +218,7 @@ class PurchaseOrder(models.Model):
'partner_id': self.partner_id.id
})
if not self.partner_id.property_stock_supplier.id:
- raise UserError(_("You must set a Vendor Location for this partner %s") % self.partner_id.name)
+ raise UserError(_("You must set a Vendor Location for this partner %s", self.partner_id.name))
return {
'picking_type_id': self.picking_type_id.id,
'partner_id': self.partner_id.id,
@@ -258,9 +258,9 @@ class PurchaseOrder(models.Model):
validated_picking = self.picking_ids.filtered(lambda p: p.state == 'done')
if validated_picking:
- note += _("<p>Those dates couldn’t be modified accordingly on the receipt %s which had already been validated.</p>") % validated_picking.name
+ note += _("<p>Those dates couldn’t be modified accordingly on the receipt %s which had already been validated.</p>", validated_picking.name)
else:
- note += _("<p>Those dates have been updated accordingly on the receipt %s.</p>") % self.picking_ids[0].name
+ note += _("<p>Those dates have been updated accordingly on the receipt %s.</p>", self.picking_ids[0].name)
for line, date in updated_dates:
date = datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
line._update_date_planned(date)
diff --git a/addons/repair/models/repair.py b/addons/repair/models/repair.py
index 7d111329763..36c5ff1ca4e 100644
--- a/addons/repair/models/repair.py
+++ b/addons/repair/models/repair.py
@@ -360,7 +360,7 @@ class Repair(models.Model):
account = operation.product_id.product_tmpl_id._get_product_accounts()['income']
if not account:
- raise UserError(_('No account defined for product "%s".') % operation.product_id.name)
+ raise UserError(_('No account defined for product "%s".', operation.product_id.name))
invoice_line_vals = {
'name': name,
@@ -402,7 +402,7 @@ class Repair(models.Model):
account = fee.product_id.product_tmpl_id._get_product_accounts()['income']
if not account:
- raise UserError(_('No account defined for product "%s".') % fee.product_id.name)
+ raise UserError(_('No account defined for product "%s".', fee.product_id.name))
invoice_line_vals = {
'name': name,
diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py
index 7c497a61856..e590bdc0643 100644
--- a/addons/resource/models/resource.py
+++ b/addons/resource/models/resource.py
@@ -160,7 +160,7 @@ class ResourceCalendar(models.Model):
def default_get(self, fields):
res = super(ResourceCalendar, self).default_get(fields)
if not res.get('name') and res.get('company_id'):
- res['name'] = _('Working Hours of %s') % self.env['res.company'].browse(res['company_id']).name
+ res['name'] = _('Working Hours of %s', self.env['res.company'].browse(res['company_id']).name)
if 'attendance_ids' in fields and not res.get('attendance_ids'):
res['attendance_ids'] = [
(0, 0, {'name': _('Monday Morning'), 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
diff --git a/addons/sale/controllers/portal.py b/addons/sale/controllers/portal.py
index 40e854af7c5..868235fde64 100644
--- a/addons/sale/controllers/portal.py
+++ b/addons/sale/controllers/portal.py
@@ -160,7 +160,7 @@ class CustomerPortal(CustomerPortal):
session_obj_date = request.session.get('view_quote_%s' % order_sudo.id)
if session_obj_date != now and request.env.user.share and access_token:
request.session['view_quote_%s' % order_sudo.id] = now
- body = _('Quotation viewed by customer %s') % order_sudo.partner_id.name
+ body = _('Quotation viewed by customer %s', order_sudo.partner_id.name)
_message_post_helper(
"sale.order",
order_sudo.id,
diff --git a/addons/sale/models/account_invoice.py b/addons/sale/models/account_invoice.py
index 5a9667330ea..c02f918e333 100644
--- a/addons/sale/models/account_invoice.py
+++ b/addons/sale/models/account_invoice.py
@@ -96,7 +96,7 @@ class AccountMove(models.Model):
for sale_line in line.sale_line_ids:
todo.add((sale_line.order_id, invoice.name))
for (order, name) in todo:
- order.message_post(body=_("Invoice %s paid") % name)
+ order.message_post(body=_("Invoice %s paid", name))
return res
def _get_invoice_delivery_partner_id(self):
diff --git a/addons/sale/models/payment.py b/addons/sale/models/payment.py
index 30d63d02cec..4904f51e396 100644
--- a/addons/sale/models/payment.py
+++ b/addons/sale/models/payment.py
@@ -83,7 +83,7 @@ class PaymentTransaction(models.Model):
order.amount_total, self.amount,
)
order.message_post(
- subject=_("Amount Mismatch (%s)") % self.acquirer_id.provider,
+ subject=_("Amount Mismatch (%s)", self.acquirer_id.provider),
body=_("The order was not confirmed despite response from the acquirer (%s): order total is %r but acquirer replied with %r.") % (
self.acquirer_id.provider,
order.amount_total,
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index 877bd7602b3..82a62b2bf8a 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -263,7 +263,12 @@ class SaleOrder(models.Model):
companies = order.order_line.product_id.company_id
if companies and companies != order.company_id:
bad_products = order.order_line.product_id.filtered(lambda p: p.company_id and p.company_id != order.company_id)
- raise ValidationError((_("Your quotation contains products from company %s whereas your quotation belongs to company %s. \n Please change the company of your quotation or remove the products from other companies (%s).") % (', '.join(companies.mapped('display_name')), order.company_id.display_name, ', '.join(bad_products.mapped('display_name')))))
+ raise ValidationError(_(
+ "Your quotation contains products from company %(product_company)s whereas your quotation belongs to company %(quote_company)s. \n Please change the company of your quotation or remove the products from other companies (%(bad_products)s).",
+ product_company=', '.join(companies.mapped('display_name')),
+ quote_company=order.company_id.display_name,
+ bad_products=', '.join(bad_products.mapped('display_name')),
+ ))
@api.depends('pricelist_id', 'date_order', 'company_id')
def _compute_currency_rate(self):
@@ -449,7 +454,7 @@ class SaleOrder(models.Model):
lines_to_update.append((1, line.id, {'price_unit': price_unit}))
self.update({'order_line': lines_to_update})
self.show_update_pricelist = False
- self.message_post(body=_("Product prices have been recomputed according to pricelist <b>%s<b> ") % self.pricelist_id.display_name)
+ self.message_post(body=_("Product prices have been recomputed according to pricelist <b>%s<b> ", self.pricelist_id.display_name))
@api.model
def create(self, vals):
@@ -1595,7 +1600,7 @@ class SaleOrderLine(models.Model):
result = {}
warning = {}
if product.sale_line_warn != 'no-message':
- title = _("Warning for %s") % product.name
+ title = _("Warning for %s", product.name)
message = product.sale_line_warn_msg
warning['title'] = title
warning['message'] = message
diff --git a/addons/sale_coupon/models/coupon.py b/addons/sale_coupon/models/coupon.py
index 6fbd5ce451f..bc92f4366a2 100644
--- a/addons/sale_coupon/models/coupon.py
+++ b/addons/sale_coupon/models/coupon.py
@@ -25,7 +25,11 @@ class Coupon(models.Model):
message = {'error': _('This coupon is expired (%s).') % (self.code)}
# Minimum requirement should not be checked if the coupon got generated by a promotion program (the requirement should have only be checked to generate the coupon)
elif self.program_id.program_type == 'coupon_program' and not self.program_id._filter_on_mimimum_amount(order):
- message = {'error': _('A minimum of %s %s should be purchased to get the reward') % (self.program_id.rule_minimum_amount, self.program_id.currency_id.name)}
+ message = {'error': _(
+ 'A minimum of %(amount)s %(currency)s should be purchased to get the reward',
+ amount=self.program_id.rule_minimum_amount,
+ currency=self.program_id.currency_id.name
+ )}
elif not self.program_id.active:
message = {'error': _('The coupon program for %s is in draft or closed state') % (self.code)}
elif self.partner_id and self.partner_id != order.partner_id:
diff --git a/addons/sale_coupon/models/coupon_program.py b/addons/sale_coupon/models/coupon_program.py
index 5bc83d493e0..35fa15cb72e 100644
--- a/addons/sale_coupon/models/coupon_program.py
+++ b/addons/sale_coupon/models/coupon_program.py
@@ -34,7 +34,11 @@ class CouponProgram(models.Model):
if self.maximum_use_number != 0 and self.order_count >= self.maximum_use_number:
message = {'error': _('Promo code %s has been expired.') % (coupon_code)}
elif not self._filter_on_mimimum_amount(order):
- message = {'error': _('A minimum of %s %s should be purchased to get the reward') % (self.rule_minimum_amount, self.currency_id.name)}
+ message = {'error': _(
+ 'A minimum of %(amount)s %(currency)s should be purchased to get the reward',
+ amount=self.rule_minimum_amount,
+ currency=self.currency_id.name
+ )}
elif self.promo_code and self.promo_code == order.promo_code:
message = {'error': _('The promo code is already applied on this order')}
elif not self.promo_code and self in order.no_code_promo_program_ids:
diff --git a/addons/sale_management/models/sale_order.py b/addons/sale_management/models/sale_order.py
index 04a9e87128a..f2ea0512f8b 100644
--- a/addons/sale_management/models/sale_order.py
+++ b/addons/sale_management/models/sale_order.py
@@ -35,7 +35,12 @@ class SaleOrder(models.Model):
companies = order.sale_order_option_ids.product_id.company_id
if companies and companies != order.company_id:
bad_products = order.sale_order_option_ids.product_id.filtered(lambda p: p.company_id and p.company_id != order.company_id)
- raise ValidationError((_("Your quotation contains products from company %s whereas your quotation belongs to company %s. \n Please change the company of your quotation or remove the products from other companies (%s).") % (', '.join(companies.mapped('display_name')), order.company_id.display_name, ', '.join(bad_products.mapped('display_name')))))
+ raise ValidationError(_(
+ "Your quotation contains products from company %(product_company)s whereas your quotation belongs to company %(quote_company)s. \n Please change the company of your quotation or remove the products from other companies (%(bad_products)s).",
+ product_company=', '.join(companies.mapped('display_name')),
+ quote_company=order.company_id.display_name,
+ bad_products=', '.join(bad_products.mapped('display_name')),
+ ))
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
diff --git a/addons/sale_management/models/sale_order_template.py b/addons/sale_management/models/sale_order_template.py
index 5eaed0176f0..0552938bde3 100644
--- a/addons/sale_management/models/sale_order_template.py
+++ b/addons/sale_management/models/sale_order_template.py
@@ -37,7 +37,11 @@ class SaleOrderTemplate(models.Model):
if len(companies) > 1:
raise ValidationError(_("Your template cannot contain products from multiple companies."))
elif companies and companies != template.company_id:
- raise ValidationError((_("Your template contains products from company %s whereas your template belongs to company %s. \n Please change the company of your template or remove the products from other companies.") % (companies.mapped('display_name'), template.company_id.display_name)))
+ raise ValidationError(_(
+ "Your template contains products from company %(product_company)s whereas your template belongs to company %(template_company)s. \n Please change the company of your template or remove the products from other companies.",
+ product_company=', '.join(companies.mapped('display_name')),
+ template_company=template.company_id.display_name,
+ ))
@api.onchange('sale_order_template_line_ids', 'sale_order_template_option_ids')
def _onchange_template_line_ids(self):
diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py
index 41e4e6d5bb4..fde99c982c2 100644
--- a/addons/sale_stock/models/sale_order.py
+++ b/addons/sale_stock/models/sale_order.py
@@ -584,7 +584,13 @@ class SaleOrderLine(models.Model):
return {
'warning': {
'title': _('Warning'),
- 'message': _("This product is packaged by %.2f %s. You should sell %.2f %s.") % (pack.qty, default_uom.name, newqty, self.product_uom.name),
+ 'message': _(
+ "This product is packaged by %(pack_size).2f %(pack_name)s. You should sell %(quantity).2f %(unit)s.",
+ pack_size=pack.qty,
+ pack_name=default_uom.name,
+ quantity=newqty,
+ unit=self.product_uom.name
+ ),
},
}
return {}
diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py
index da7a5926053..b31f89dad69 100644
--- a/addons/sale_timesheet/models/project.py
+++ b/addons/sale_timesheet/models/project.py
@@ -110,7 +110,7 @@ class Project(models.Model):
return self.action_view_timesheet_plan()
return {
'type': 'ir.actions.act_window',
- 'name': _('Timesheets of %s') % self.name,
+ 'name': _('Timesheets of %s', self.name),
'domain': [('project_id', '!=', False)],
'res_model': 'account.analytic.line',
'view_id': False,
diff --git a/addons/sales_team/models/crm_team.py b/addons/sales_team/models/crm_team.py
index ef919653fea..e26a05abe7f 100644
--- a/addons/sales_team/models/crm_team.py
+++ b/addons/sales_team/models/crm_team.py
@@ -133,7 +133,7 @@ class CrmTeam(models.Model):
def _graph_get_model(self):
""" skeleton function defined here because it'll be called by crm and/or sale
"""
- raise UserError(_('Undefined graph model for Sales Team: %s') % self.name)
+ raise UserError(_('Undefined graph model for Sales Team: %s', self.name))
def _graph_get_dates(self, today):
""" return a coherent start and end date for the dashboard graph covering a month period grouped by week.
@@ -151,7 +151,7 @@ class CrmTeam(models.Model):
return 'EXTRACT(WEEK FROM %s)' % self._graph_date_column()
def _graph_y_query(self):
- raise UserError(_('Undefined graph model for Sales Team: %s') % self.name)
+ raise UserError(_('Undefined graph model for Sales Team: %s', self.name))
def _extra_sql_conditions(self):
return ''
diff --git a/addons/sms/models/sms_template.py b/addons/sms/models/sms_template.py
index fb5b8877e87..f3e777f77c4 100644
--- a/addons/sms/models/sms_template.py
+++ b/addons/sms/models/sms_template.py
@@ -32,7 +32,7 @@ class SMSTemplate(models.Model):
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
default = dict(default or {},
- name=_("%s (copy)") % self.name)
+ name=_("%s (copy)", self.name))
return super(SMSTemplate, self).copy(default=default)
def unlink(self):
@@ -44,7 +44,7 @@ class SMSTemplate(models.Model):
view = self.env.ref('sms.sms_composer_view_form')
for template in self:
- button_name = _('Send SMS (%s)') % template.name
+ button_name = _('Send SMS (%s)', template.name)
action = ActWindow.create({
'name': button_name,
'type': 'ir.actions.act_window',
diff --git a/addons/sms/wizard/sms_composer.py b/addons/sms/wizard/sms_composer.py
index 0d3d822ed4b..7467d99a21a 100644
--- a/addons/sms/wizard/sms_composer.py
+++ b/addons/sms/wizard/sms_composer.py
@@ -155,7 +155,7 @@ class SendSMS(models.TransientModel):
sanitized_numbers = [info['sanitized'] for info in sanitize_res.values() if info['sanitized']]
invalid_numbers = [number for number, info in sanitize_res.items() if info['code']]
if invalid_numbers:
- raise UserError(_('Following numbers are not correctly encoded: %s') % repr(invalid_numbers))
+ raise UserError(_('Following numbers are not correctly encoded: %s', repr(invalid_numbers)))
composer.sanitized_numbers = ','.join(sanitized_numbers)
else:
composer.sanitized_numbers = False
@@ -193,7 +193,7 @@ class SendSMS(models.TransientModel):
if self.comment_single_recipient and not self.recipient_single_valid:
raise UserError(_('Invalid recipient number. Please update it.'))
elif not self.comment_single_recipient and self.recipient_invalid_count:
- raise UserError(_('%s invalid recipients') % self.recipient_invalid_count)
+ raise UserError(_('%s invalid recipients', self.recipient_invalid_count))
self._action_send_sms()
return False
diff --git a/addons/snailmail_account/wizard/account_invoice_send.py b/addons/snailmail_account/wizard/account_invoice_send.py
index c4c74f9b9df..d694ca56586 100644
--- a/addons/snailmail_account/wizard/account_invoice_send.py
+++ b/addons/snailmail_account/wizard/account_invoice_send.py
@@ -80,7 +80,7 @@ class AccountInvoiceSend(models.TransientModel):
self.env['bus.bus'].sendone(
(self._cr.dbname, 'res.partner', self.env.user.partner_id.id),
{'type': 'snailmail_invalid_address', 'title': _("Invalid Addresses"),
- 'message': _("%s of the selected invoice(s) had an invalid address and were not sent") % self.invalid_addresses}
+ 'message': _("%s of the selected invoice(s) had an invalid address and were not sent", self.invalid_addresses)}
)
def invalid_addresses_action(self):
diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py
index ea9529e58b3..b7f9ce7e06c 100644
--- a/addons/stock/models/product.py
+++ b/addons/stock/models/product.py
@@ -329,11 +329,11 @@ class Product(models.Model):
# TDE FIXME: should probably clean the search methods
# to prevent sql injections
if field not in ('qty_available', 'virtual_available', 'incoming_qty', 'outgoing_qty', 'free_qty'):
- raise UserError(_('Invalid domain left operand %s') % field)
+ raise UserError(_('Invalid domain left operand %s', field))
if operator not in ('<', '>', '=', '!=', '<=', '>='):
- raise UserError(_('Invalid domain operator %s') % operator)
+ raise UserError(_('Invalid domain operator %s', operator))
if not isinstance(value, (float, int)):
- raise UserError(_('Invalid domain right operand %s') % value)
+ raise UserError(_('Invalid domain right operand %s', value))
# TODO: Still optimization possible when searching virtual quantities
ids = []
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 8155141c7ca..7256e54c5e6 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -499,7 +499,7 @@ class StockMove(models.Model):
return
msg = _("The scheduled date has been automatically updated due to a delay on <a href='#' data-oe-model='%s' data-oe-id='%s'>%s</a>.") % (doc_orig[0]._name, doc_orig[0].id, doc_orig[0].name)
- msg_subject = _("Scheduled date update due to delay on %s") % doc_orig[0].name
+ msg_subject = _("Scheduled date update due to delay on %s", doc_orig[0].name)
# write the message on each document
for doc in documents:
last_message = doc.message_ids[:1]
diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py
index 7e0f88d6b36..0ba3384d755 100644
--- a/addons/stock/models/stock_move_line.py
+++ b/addons/stock/models/stock_move_line.py
@@ -157,7 +157,7 @@ class StockMoveLine(models.Model):
if self.qty_done and self.product_id.tracking == 'serial':
qty_done = self.product_uom_id._compute_quantity(self.qty_done, self.product_id.uom_id)
if float_compare(qty_done, 1.0, precision_rounding=self.product_id.uom_id.rounding) != 0:
- message = _('You can only process 1.0 %s of products with unique serial number.') % self.product_id.uom_id.name
+ message = _('You can only process 1.0 %s of products with unique serial number.', self.product_id.uom_id.name)
res['warning'] = {'title': _('Warning'), 'message': message}
return res
diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py
index 10ce708554b..0be79095598 100644
--- a/addons/stock/models/stock_quant.py
+++ b/addons/stock/models/stock_quant.py
@@ -456,12 +456,12 @@ class StockQuant(models.Model):
# if we want to reserve
available_quantity = self._get_available_quantity(product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=strict)
if float_compare(quantity, available_quantity, precision_rounding=rounding) > 0:
- raise UserError(_('It is not possible to reserve more products of %s than you have in stock.') % product_id.display_name)
+ raise UserError(_('It is not possible to reserve more products of %s than you have in stock.', product_id.display_name))
elif float_compare(quantity, 0, precision_rounding=rounding) < 0:
# if we want to unreserve
available_quantity = sum(quants.mapped('reserved_quantity'))
if float_compare(abs(quantity), available_quantity, precision_rounding=rounding) > 0:
- raise UserError(_('It is not possible to unreserve more products of %s than you have in stock.') % product_id.display_name)
+ raise UserError(_('It is not possible to unreserve more products of %s than you have in stock.', product_id.display_name))
else:
return reserved_quants
diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py
index ff49323f5af..1e7bda0be53 100644
--- a/addons/stock/models/stock_rule.py
+++ b/addons/stock/models/stock_rule.py
@@ -140,7 +140,7 @@ class StockRule(models.Model):
if self.procure_method == 'make_to_order' and self.location_src_id:
suffix = _("<br>A need is created in <b>%s</b> and a rule will be triggered to fulfill it.") % (source)
if self.procure_method == 'mts_else_mto' and self.location_src_id:
- suffix = _("<br>If the products are not available in <b>%s</b>, a rule will be triggered to bring products in this location.") % source
+ suffix = _("<br>If the products are not available in <b>%s</b>, a rule will be triggered to bring products in this location.", source)
message_dict = {
'pull': _('When products are needed in <b>%s</b>, <br/> <b>%s</b> are created from <b>%s</b> to fulfill the need.') % (destination, operation, source) + suffix,
'push': _('When products arrive in <b>%s</b>, <br/> <b>%s</b> are created to send them in <b>%s</b>.') % (source, operation, destination)
diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py
index 96e77ba907a..fcc0713ba28 100644
--- a/addons/stock/models/stock_warehouse.py
+++ b/addons/stock/models/stock_warehouse.py
@@ -740,7 +740,7 @@ class Warehouse(models.Model):
def _get_inter_warehouse_route_values(self, supplier_warehouse):
return {
- 'name': _('%s: Supply Product from %s') % (self.name, supplier_warehouse.name),
+ 'name': _('%(warehouse)s: Supply Product from %(supplier)s', warehouse=self.name, supplier=supplier_warehouse.name),
'warehouse_selectable': True,
'product_selectable': True,
'product_categ_selectable': True,
diff --git a/addons/stock/wizard/stock_picking_return.py b/addons/stock/wizard/stock_picking_return.py
index a66749b81db..7bcda6b4d72 100644
--- a/addons/stock/wizard/stock_picking_return.py
+++ b/addons/stock/wizard/stock_picking_return.py
@@ -118,7 +118,7 @@ class ReturnPicking(models.TransientModel):
'move_lines': [],
'picking_type_id': picking_type_id,
'state': 'draft',
- 'origin': _("Return of %s") % self.picking_id.name,
+ 'origin': _("Return of %s", self.picking_id.name),
'location_id': self.picking_id.location_dest_id.id,
'location_dest_id': self.location_id.id})
new_picking.message_post_with_view('mail.message_origin_link',
diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py
index a87cdcd7510..fa954ec8f50 100644
--- a/addons/stock_account/models/product.py
+++ b/addons/stock_account/models/product.py
@@ -253,13 +253,25 @@ class ProductProduct(models.Model):
'stock_valuation_layer_ids': [(6, None, [stock_valuation_layer.id])],
'move_type': 'entry',
'line_ids': [(0, 0, {
- 'name': _('%s changed cost from %s to %s - %s') % (self.env.user.name, product.standard_price, new_price, product.display_name),
+ 'name': _(
+ '%(user)s changed cost from %(previous)s to %(new_price)s - %(product)s',
+ user=self.env.user.name,
+ previous=product.standard_price,
+ new_price=new_price,
+ product=product.display_name
+ ),
'account_id': debit_account_id,
'debit': abs(value),
'credit': 0,
'product_id': product.id,
}), (0, 0, {
- 'name': _('%s changed cost from %s to %s - %s') % (self.env.user.name, product.standard_price, new_price, product.display_name),
+ 'name': _(
+ '%(user)s changed cost from %(previous)s to %(new_price)s - %(product)s',
+ user=self.env.user.name,
+ previous=product.standard_price,
+ new_price=new_price,
+ product=product.display_name
+ ),
'account_id': credit_account_id,
'debit': 0,
'credit': abs(value),
diff --git a/addons/stock_account/wizard/stock_valuation_layer_revaluation.py b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py
index 49d693b728a..35989e80b67 100644
--- a/addons/stock_account/wizard/stock_valuation_layer_revaluation.py
+++ b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py
@@ -74,12 +74,20 @@ class StockValuationLayerRevaluation(models.TransientModel):
])
# Create a manual stock valuation layer
+ if self.reason:
+ description = _("Manual Stock Valuation: %s.", self.reason)
+ else:
+ description = _("Manual Stock Valuation: No Reason Given.")
+ if product_id.categ_id.property_cost_method == 'average':
+ description += _(
+ " Product cost updated from %(previous)s to %(new_cost)s.",
+ previous=product_id.standard_price,
+ new_cost=product_id.standard_price + self.added_value / self.current_quantity_svl
+ )
revaluation_svl_vals = {
'company_id': self.company_id.id,
'product_id': product_id.id,
- 'description': _("Manual Stock Valuation: %s.%s") % (
- self.reason or _("No Reason Given"),
- product_id.categ_id.property_cost_method == 'average' and (_(" Product cost updated from %s to %s.") % (product_id.standard_price, product_id.standard_price + self.added_value / self.current_quantity_svl)) or ''),
+ 'description': description,
'value': self.added_value,
'quantity': 0,
}
@@ -118,20 +126,28 @@ class StockValuationLayerRevaluation(models.TransientModel):
move_vals = {
'journal_id': self.account_journal_id.id or accounts['stock_journal'].id,
'company_id': self.company_id.id,
- 'ref': _("Revaluation of %s") % product_id.display_name,
+ 'ref': _("Revaluation of %s", product_id.display_name),
'stock_valuation_layer_ids': [(6, None, [revaluation_svl.id])],
'date': self.date or fields.Date.today(),
'move_type': 'entry',
'line_ids': [(0, 0, {
- 'name': _('%s changed stock valuation from %s to %s of %s') % (
- self.env.user.name, self.current_value_svl, self.current_value_svl + self.added_value, product_id.display_name),
+ 'name': _('%(user)s changed stock valuation from %(previous)s to %(new_value)s - %(product)s',
+ user=self.env.user.name,
+ previous=self.current_value_svl,
+ new_value=self.current_value_svl + self.added_value,
+ product=product_id.display_name,
+ ),
'account_id': debit_account_id,
'debit': abs(self.added_value),
'credit': 0,
'product_id': product_id.id,
}), (0, 0, {
- 'name': _('%s changed stock valuation from %s to %s of %s') % (
- self.env.user.name, self.current_value_svl, self.current_value_svl + self.added_value, product_id.display_name),
+ 'name': _('%(user)s changed stock valuation from %(previous)s to %(new_value)s - %(product)s',
+ user=self.env.user.name,
+ previous=self.current_value_svl,
+ new_value=self.current_value_svl + self.added_value,
+ product=product_id.display_name,
+ ),
'account_id': credit_account_id,
'debit': 0,
'credit': abs(self.added_value),
diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py
index 63222bc1385..076ead97c0c 100644
--- a/addons/stock_landed_costs/models/stock_landed_cost.py
+++ b/addons/stock_landed_costs/models/stock_landed_cost.py
@@ -204,7 +204,7 @@ class StockLandedCost(models.Model):
if not lines:
target_model_descriptions = dict(self._fields['target_model']._description_selection(self.env))
- raise UserError(_("You cannot apply landed costs on the chosen %s(s). Landed costs can only be applied for products with automated inventory valuation and FIFO or average costing method.") % target_model_descriptions[self.target_model])
+ raise UserError(_("You cannot apply landed costs on the chosen %s(s). Landed costs can only be applied for products with automated inventory valuation and FIFO or average costing method.", target_model_descriptions[self.target_model]))
return lines
def compute_landed_cost(self):
@@ -285,7 +285,7 @@ class StockLandedCost(models.Model):
for cost in self:
if not cost._get_targeted_move_ids():
target_model_descriptions = dict(self._fields['target_model']._description_selection(self.env))
- raise UserError(_('Please define %s on which those additional costs should apply.') % target_model_descriptions[cost.target_model])
+ raise UserError(_('Please define %s on which those additional costs should apply.', target_model_descriptions[cost.target_model]))
def _check_sum(self):
""" Check if each cost line its valuation lines sum to the correct amount
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index c69ee0d66ce..383308061de 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -773,11 +773,11 @@ class ExportXlsxWriter:
# fails note that you can't export
cell_value = pycompat.to_text(cell_value)
except UnicodeDecodeError:
- raise UserError(_("Binary fields can not be exported to Excel unless their content is base64-encoded. That does not seem to be the case for %s.") % self.field_names[column])
+ raise UserError(_("Binary fields can not be exported to Excel unless their content is base64-encoded. That does not seem to be the case for %s.", self.field_names)[column])
if isinstance(cell_value, str):
if len(cell_value) > self.worksheet.xls_strmax:
- cell_value = _("The content of this cell is too long for an XLSX file (more than %s characters). Please use the CSV format for this export.") % self.worksheet.xls_strmax
+ cell_value = _("The content of this cell is too long for an XLSX file (more than %s characters). Please use the CSV format for this export.", self.worksheet.xls_strmax)
else:
cell_value = cell_value.replace("\r", " ")
elif isinstance(cell_value, datetime.datetime):
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index afe67a8a9ef..3e810dfa729 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -284,7 +284,7 @@ class Website(models.Model):
copy_menu(submenu, new_menu)
for website in self:
new_top_menu = top_menu.copy({
- 'name': _('Top Menu for Website %s') % website.id,
+ 'name': _('Top Menu for Website %s', website.id),
'website_id': website.id,
})
for submenu in top_menu.child_id:
@@ -408,7 +408,7 @@ class Website(models.Model):
for page in pages:
dependencies.setdefault(page_key, [])
dependencies[page_key].append({
- 'text': _('Page <b>%s</b> contains a link to this page') % page.url,
+ 'text': _('Page <b>%s</b> contains a link to this page', page.url),
'item': page.name,
'link': page.url,
})
@@ -436,7 +436,7 @@ class Website(models.Model):
menu_key = _('Menus')
for menu in menus:
dependencies.setdefault(menu_key, []).append({
- 'text': _('This page is in the menu <b>%s</b>') % menu.name,
+ 'text': _('This page is in the menu <b>%s</b>', menu.name),
'link': '/web#id=%s&view_type=form&model=website.menu' % menu.id,
'item': menu.name,
})
@@ -472,7 +472,7 @@ class Website(models.Model):
for p in pages:
dependencies.setdefault(page_key, [])
dependencies[page_key].append({
- 'text': _('Page <b>%s</b> is calling this file') % p.url,
+ 'text': _('Page <b>%s</b> is calling this file', p.url),
'item': p.name,
'link': p.url,
})
diff --git a/addons/website/models/website_visitor.py b/addons/website/models/website_visitor.py
index 3af252bda6e..7ff7702df94 100644
--- a/addons/website/models/website_visitor.py
+++ b/addons/website/models/website_visitor.py
@@ -67,7 +67,7 @@ class WebsiteVisitor(models.Model):
def name_get(self):
return [(
record.id,
- (record.name or _('Website Visitor #%s') % record.id)
+ (record.name or _('Website Visitor #%s', record.id))
) for record in self]
@api.depends('partner_id.email_normalized', 'partner_id.mobile', 'partner_id.phone')
diff --git a/addons/website_blog/models/website.py b/addons/website_blog/models/website.py
index a647326c340..fb153e3d756 100644
--- a/addons/website_blog/models/website.py
+++ b/addons/website_blog/models/website.py
@@ -26,7 +26,7 @@ class Website(models.Model):
dep[page_key] = []
for p in posts:
dep[page_key].append({
- 'text': _('Blog Post <b>%s</b> seems to have a link to this page !') % p.name,
+ 'text': _('Blog Post <b>%s</b> seems to have a link to this page !', p.name),
'item': p.name,
'link': p.website_url,
})
@@ -51,7 +51,7 @@ class Website(models.Model):
dep[page_key] = []
for p in posts:
dep[page_key].append({
- 'text': _('Blog Post <b>%s</b> seems to be calling this file !') % p.name,
+ 'text': _('Blog Post <b>%s</b> seems to be calling this file !', p.name),
'item': p.name,
'link': p.website_url,
})
diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py
index c99d2c0b1d0..42c07b289c7 100644
--- a/addons/website_blog/models/website_blog.py
+++ b/addons/website_blog/models/website_blog.py
@@ -215,7 +215,7 @@ class BlogPost(models.Model):
@api.returns('self', lambda value: value.id)
def copy_data(self, default=None):
self.ensure_one()
- name = _("%s (copy)") % self.name
+ name = _("%s (copy)", self.name)
default = dict(default or {}, name=name)
return super(BlogPost, self).copy_data(default)
diff --git a/addons/website_crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/website_crm_partner_assign/wizard/crm_forward_to_partner.py
index 9f6a466ef92..9267f6300e3 100644
--- a/addons/website_crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/website_crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -69,7 +69,7 @@ class CrmLeadForwardToPartner(models.TransientModel):
if no_email:
raise UserError(_('Set an email address for the partner(s): %s') % ", ".join(no_email))
if self.forward_type == 'single' and not self.partner_id.email:
- raise UserError(_('Set an email address for the partner %s') % self.partner_id.name)
+ raise UserError(_('Set an email address for the partner %s', self.partner_id.name))
partners_leads = {}
for lead in self.assignation_lines:
diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py
index f8cf3c6ea02..abe6d4c39da 100644
--- a/addons/website_forum/models/forum.py
+++ b/addons/website_forum/models/forum.py
@@ -464,7 +464,7 @@ class Post(models.Model):
filter_regexp = r'(<img.*?>)|(<a[^>]*?href[^>]*?>)|(<[a-z|A-Z]+[^>]*style\s*=\s*[\'"][^\'"]*\s*background[^:]*:[^url;]*url)'
content_match = re.search(filter_regexp, content, re.I)
if content_match:
- raise AccessError(_('%d karma required to post an image or link.') % forum.karma_editor)
+ raise AccessError(_('%d karma required to post an image or link.', forum.karma_editor))
return content
def _default_website_meta(self):
@@ -492,9 +492,9 @@ class Post(models.Model):
raise UserError(_('Posting answer on a [Deleted] or [Closed] question is not possible.'))
# karma-based access
if not post.parent_id and not post.can_ask:
- raise AccessError(_('%d karma required to create a new question.') % post.forum_id.karma_ask)
+ raise AccessError(_('%d karma required to create a new question.', post.forum_id.karma_ask))
elif post.parent_id and not post.can_answer:
- raise AccessError(_('%d karma required to answer a question.') % post.forum_id.karma_answer)
+ raise AccessError(_('%d karma required to answer a question.', post.forum_id.karma_answer))
if not post.parent_id and not post.can_post:
post.sudo().state = 'pending'
@@ -511,7 +511,7 @@ class Post(models.Model):
# Make sure only author or moderator can edit/delete messages
for post in self.browse(res_ids):
if not post.can_edit:
- raise AccessError(_('%d karma required to edit a post.') % post.karma_edit)
+ raise AccessError(_('%d karma required to edit a post.', post.karma_edit))
return super(Post, self).get_mail_message_access(res_ids, operation, model_name=model_name)
def write(self, vals):
@@ -527,18 +527,18 @@ class Post(models.Model):
if 'state' in vals:
if vals['state'] in ['active', 'close']:
if not post.can_close:
- raise AccessError(_('%d karma required to close or reopen a post.') % post.karma_close)
+ raise AccessError(_('%d karma required to close or reopen a post.', post.karma_close))
trusted_keys += ['state', 'closed_uid', 'closed_date', 'closed_reason_id']
elif vals['state'] == 'flagged':
if not post.can_flag:
- raise AccessError(_('%d karma required to flag a post.') % post.forum_id.karma_flag)
+ raise AccessError(_('%d karma required to flag a post.', post.forum_id.karma_flag))
trusted_keys += ['state', 'flag_user_id']
if 'active' in vals:
if not post.can_unlink:
- raise AccessError(_('%d karma required to delete or reactivate a post.') % post.karma_unlink)
+ raise AccessError(_('%d karma required to delete or reactivate a post.', post.karma_unlink))
if 'is_correct' in vals:
if not post.can_accept:
- raise AccessError(_('%d karma required to accept or refuse an answer.') % post.karma_accept)
+ raise AccessError(_('%d karma required to accept or refuse an answer.', post.karma_accept))
# update karma except for self-acceptance
mult = 1 if vals['is_correct'] else -1
if vals['is_correct'] != post.is_correct and post.create_uid.id != self._uid:
@@ -546,9 +546,9 @@ class Post(models.Model):
self.env.user.sudo().add_karma(post.forum_id.karma_gen_answer_accept * mult)
if tag_ids:
if set(post.tag_ids.ids) != tag_ids and self.env.user.karma < post.forum_id.karma_edit_retag:
- raise AccessError(_('%d karma required to retag.') % post.forum_id.karma_edit_retag)
+ raise AccessError(_('%d karma required to retag.', post.forum_id.karma_edit_retag))
if any(key not in trusted_keys for key in vals) and not post.can_edit:
- raise AccessError(_('%d karma required to edit a post.') % post.karma_edit)
+ raise AccessError(_('%d karma required to edit a post.', post.karma_edit))
res = super(Post, self).write(vals)
@@ -575,7 +575,7 @@ class Post(models.Model):
if post.state == 'active' and post.parent_id:
post.parent_id.message_post_with_view(
'website_forum.forum_post_template_new_answer',
- subject=_('Re: %s') % post.parent_id.name,
+ subject=_('Re: %s', post.parent_id.name),
partner_ids=[(4, p.id) for p in tag_partners],
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('website_forum.mt_answer_new'))
elif post.state == 'active' and not post.parent_id:
@@ -647,7 +647,7 @@ class Post(models.Model):
def validate(self):
for post in self:
if not post.can_moderate:
- raise AccessError(_('%d karma required to validate a post.') % post.forum_id.karma_moderate)
+ raise AccessError(_('%d karma required to validate a post.', post.forum_id.karma_moderate))
# if state == pending, no karma previously added for the new question
if post.state == 'pending':
post.create_uid.sudo().add_karma(post.forum_id.karma_gen_question_new)
@@ -662,7 +662,7 @@ class Post(models.Model):
def refuse(self):
for post in self:
if not post.can_moderate:
- raise AccessError(_('%d karma required to refuse a post.') % post.forum_id.karma_moderate)
+ raise AccessError(_('%d karma required to refuse a post.', post.forum_id.karma_moderate))
post.moderator_id = self.env.user
return True
@@ -670,7 +670,7 @@ class Post(models.Model):
res = []
for post in self:
if not post.can_flag:
- raise AccessError(_('%d karma required to flag a post.') % post.forum_id.karma_flag)
+ raise AccessError(_('%d karma required to flag a post.', post.forum_id.karma_flag))
if post.state == 'flagged':
res.append({'error': 'post_already_flagged'})
elif post.state == 'active':
@@ -691,7 +691,7 @@ class Post(models.Model):
def mark_as_offensive(self, reason_id):
for post in self:
if not post.can_moderate:
- raise AccessError(_('%d karma required to mark a post as offensive.') % post.forum_id.karma_moderate)
+ raise AccessError(_('%d karma required to mark a post as offensive.', post.forum_id.karma_moderate))
# remove some karma
_logger.info('Downvoting user <%s> for posting spam/offensive contents', post.create_uid)
post.create_uid.sudo().add_karma(post.forum_id.karma_gen_answer_flagged)
@@ -721,7 +721,7 @@ class Post(models.Model):
def unlink(self):
for post in self:
if not post.can_unlink:
- raise AccessError(_('%d karma required to unlink a post.') % post.karma_unlink)
+ raise AccessError(_('%d karma required to unlink a post.', post.karma_unlink))
# if unlinking an answer with accepted answer: remove provided karma
for post in self:
if post.is_correct:
@@ -766,7 +766,7 @@ class Post(models.Model):
# karma-based action check: use the post field that computed own/all value
if not self.can_comment_convert:
- raise AccessError(_('%d karma required to convert an answer to a comment.') % self.karma_comment_convert)
+ raise AccessError(_('%d karma required to convert an answer to a comment.', self.karma_comment_convert))
# post the message
question = self.parent_id
@@ -806,9 +806,9 @@ class Post(models.Model):
can_convert = self.env.user.karma >= karma_convert
if not can_convert:
if is_author and karma_own < karma_all:
- raise AccessError(_('%d karma required to convert your comment to an answer.') % karma_own)
+ raise AccessError(_('%d karma required to convert your comment to an answer.', karma_own))
else:
- raise AccessError(_('%d karma required to convert a comment to an answer.') % karma_all)
+ raise AccessError(_('%d karma required to convert a comment to an answer.', karma_all))
# check the message's author has not already an answer
question = post.parent_id if post.parent_id else post
@@ -846,7 +846,7 @@ class Post(models.Model):
)
can_unlink = user.karma >= karma_unlink
if not can_unlink:
- raise AccessError(_('%d karma required to unlink a comment.') % karma_unlink)
+ raise AccessError(_('%d karma required to unlink a comment.', karma_unlink))
result.append(comment.unlink())
return result
@@ -893,7 +893,7 @@ class Post(models.Model):
self.ensure_one()
if not self.can_comment:
- raise AccessError(_('%d karma required to comment.') % self.karma_comment)
+ raise AccessError(_('%d karma required to comment.', self.karma_comment))
if not kwargs.get('record_name') and self.parent_id:
kwargs['record_name'] = self.parent_id.name
return super(Post, self).message_post(message_type=message_type, **kwargs)
@@ -1005,9 +1005,9 @@ class Vote(models.Model):
def _check_karma_rights(self, upvote=None):
# karma check
if upvote and not self.post_id.can_upvote:
- raise AccessError(_('%d karma required to upvote.') % self.post_id.forum_id.karma_upvote)
+ raise AccessError(_('%d karma required to upvote.', self.post_id.forum_id.karma_upvote))
elif not upvote and not self.post_id.can_downvote:
- raise AccessError(_('%d karma required to downvote.') % self.post_id.forum_id.karma_downvote)
+ raise AccessError(_('%d karma required to downvote.', self.post_id.forum_id.karma_downvote))
def _vote_update_karma(self, old_vote, new_vote):
if self.post_id.parent_id:
@@ -1042,5 +1042,5 @@ class Tags(models.Model):
def create(self, vals):
forum = self.env['forum.forum'].browse(vals.get('forum_id'))
if self.env.user.karma < forum.karma_tag_create:
- raise AccessError(_('%d karma required to create a new Tag.') % forum.karma_tag_create)
+ raise AccessError(_('%d karma required to create a new Tag.', forum.karma_tag_create))
return super(Tags, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(vals)
diff --git a/addons/website_livechat/models/mail_channel.py b/addons/website_livechat/models/mail_channel.py
index 804571bde42..86ab7aeb2c3 100644
--- a/addons/website_livechat/models/mail_channel.py
+++ b/addons/website_livechat/models/mail_channel.py
@@ -58,7 +58,7 @@ class MailChannel(models.Model):
message = _("""%s has started a conversation with %s.
The chat request has been canceled.""") % (name, operator or _('an operator'))
else:
- message = _('%s has left the conversation.') % name
+ message = _('%s has left the conversation.', name)
return message
diff --git a/addons/website_sale/models/product_image.py b/addons/website_sale/models/product_image.py
index 5fe484a6a5c..eea9afb6967 100644
--- a/addons/website_sale/models/product_image.py
+++ b/addons/website_sale/models/product_image.py
@@ -40,7 +40,7 @@ class ProductImage(models.Model):
def _check_valid_video_url(self):
for image in self:
if image.video_url and not image.embed_code:
- raise ValidationError(_("Provided video URL for '%s' is not valid. Please enter a valid video URL.") % image.name)
+ raise ValidationError(_("Provided video URL for '%s' is not valid. Please enter a valid video URL.", image.name))
@api.model_create_multi
def create(self, vals_list):
diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py
index 73e52810c61..c71a6201f9f 100644
--- a/addons/website_sale/models/sale_order.py
+++ b/addons/website_sale/models/sale_order.py
@@ -361,9 +361,9 @@ class SaleOrderLine(models.Model):
def get_sale_order_line_multiline_description_sale(self, product):
description = super(SaleOrderLine, self).get_sale_order_line_multiline_description_sale(product)
if self.linked_line_id:
- description += "\n" + _("Option for: %s") % self.linked_line_id.product_id.display_name
+ description += "\n" + _("Option for: %s", self.linked_line_id.product_id.display_name)
if self.option_line_ids:
- description += "\n" + '\n'.join([_("Option: %s") % option_line.product_id.display_name for option_line in self.option_line_ids])
+ description += "\n" + '\n'.join([_("Option: %s", option_line.product_id.display_name) for option_line in self.option_line_ids])
return description
@api.depends('product_id.display_name')
diff --git a/addons/website_sale_stock/controllers/main.py b/addons/website_sale_stock/controllers/main.py
index 43f70fa4e9f..da26a11173c 100644
--- a/addons/website_sale_stock/controllers/main.py
+++ b/addons/website_sale_stock/controllers/main.py
@@ -20,7 +20,11 @@ class WebsiteSaleStock(WebsiteSale):
cart_qty = sum(order.order_line.filtered(lambda p: p.product_id.id == line.product_id.id).mapped('product_uom_qty'))
avl_qty = line.product_id.with_context(warehouse=order.warehouse_id.id).virtual_available
if cart_qty > avl_qty:
- values.append(_('You ask for %s products but only %s is available') % (cart_qty, avl_qty if avl_qty > 0 else 0))
+ values.append(_(
+ 'You ask for %(quantity)s products but only %(available_qty)s is available',
+ quantity=cart_qty,
+ available_qty=avl_qty if avl_qty > 0 else 0
+ ))
if values:
raise ValidationError('. '.join(values) + '.')
return super(WebsiteSaleStock, self).payment_transaction(**kwargs)
diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index 1e896d3f754..68648b7ff9d 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -993,7 +993,7 @@ class WebsiteSlides(WebsiteProfile):
return preview
existing_slide = Slide.search([('channel_id', '=', int(data['channel_id'])), ('document_id', '=', document_id)], limit=1)
if existing_slide:
- preview['error'] = _('This video already exists in this channel on the following slide: %s') % existing_slide.name
+ preview['error'] = _('This video already exists in this channel on the following slide: %s', existing_slide.name)
return preview
values = Slide._parse_document_url(data['url'], only_preview_fields=True)
if values.get('error'):
@@ -1051,7 +1051,7 @@ class WebsiteSlides(WebsiteProfile):
return {'error': e.args[0]}
except Exception as e:
_logger.error(e)
- return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s') % e}
+ return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s', e)}
# ensure correct ordering by re sequencing slides in front-end (backend should be ok thanks to list view)
channel._resequence_slides(slide, force_category=category)
diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py
index 36ba1c351f7..401878ee94b 100644
--- a/addons/website_slides/models/slide_channel.py
+++ b/addons/website_slides/models/slide_channel.py
@@ -446,7 +446,7 @@ class Channel(models.Model):
action = self.env.ref('website_slides.slide_channel_partner_action').read()[0]
action['domain'] = [('channel_id', 'in', self.ids)]
if len(self) == 1:
- action['display_name'] = _('Attendees of %s') % self.name
+ action['display_name'] = _('Attendees of %s', self.name)
action['context'] = {'active_test': False, 'default_channel_id': self.id}
if state:
action['domain'] += [('completed', '=', state == 'completed')]
diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py
index 96dc76c8c63..2ebe650043a 100644
--- a/addons/website_slides/models/slide_question.py
+++ b/addons/website_slides/models/slide_question.py
@@ -24,9 +24,9 @@ class SlideQuestion(models.Model):
def _check_answers_integrity(self):
for question in self:
if len(question.answer_ids.filtered(lambda answer: answer.is_correct)) != 1:
- raise ValidationError(_('Question "%s" must have 1 correct answer') % question.question)
+ raise ValidationError(_('Question "%s" must have 1 correct answer', question.question))
if len(question.answer_ids) < 2:
- raise ValidationError(_('Question "%s" must have 1 correct answer and at least 1 invalid answer') % question.question)
+ raise ValidationError(_('Question "%s" must have 1 correct answer and at least 1 invalid answer', question.question))
@api.depends('slide_id')
def _compute_statistics(self):
diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py
index 6e600f90b44..45bf3a722be 100644
--- a/addons/website_slides/models/slide_slide.py
+++ b/addons/website_slides/models/slide_slide.py
@@ -795,7 +795,7 @@ class Slide(models.Model):
if error == 'keyInvalid':
return _('Your Google API key is invalid, please update it into your settings.\nSettings > Website > Features > API Key')
- return _('Could not fetch data from url. Document or access right not available:\n%s') % error
+ return _('Could not fetch data from url. Document or access right not available:\n%s', error)
@api.model
def _parse_google_document(self, document_id, only_preview_fields):