From 0cf352bbe5b8586702153b743b191a3cc371f061 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 15 Jun 2020 18:38:14 +0200 Subject: [PATCH 001/116] Add module account_invoice_overdue_reminder --- account_invoice_overdue_reminder/__init__.py | 2 + .../__manifest__.py | 32 + .../data/mail_template.xml | 82 +++ .../data/overdue_reminder_result.xml | 47 ++ .../migrations/12.0.2.0.0/post-migration.py | 52 ++ .../migrations/12.0.2.0.0/pre-migration.py | 11 + .../models/__init__.py | 7 + .../models/account_invoice.py | 60 ++ .../account_invoice_overdue_reminder.py | 61 ++ .../models/company.py | 38 ++ .../models/config_settings.py | 20 + .../models/overdue_reminder_action.py | 66 +++ .../models/overdue_reminder_result.py | 20 + .../models/partner.py | 13 + .../readme/CONFIGURATION.rst | 9 + .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 31 + .../readme/USAGE.rst | 12 + .../security/ir.model.access.csv | 7 + .../security/rule.xml | 18 + .../views/account_invoice.xml | 50 ++ .../account_invoice_overdue_reminder.xml | 109 ++++ .../views/config_settings.xml | 46 ++ .../views/overdue_reminder_action.xml | 101 ++++ .../views/overdue_reminder_result.xml | 62 ++ .../views/partner.xml | 25 + .../views/report.xml | 19 + .../views/report_overdue_reminder.xml | 94 +++ .../wizard/__init__.py | 1 + .../wizard/overdue_reminder_wizard.py | 558 ++++++++++++++++++ .../wizard/overdue_reminder_wizard_view.xml | 241 ++++++++ 31 files changed, 1895 insertions(+) create mode 100644 account_invoice_overdue_reminder/__init__.py create mode 100644 account_invoice_overdue_reminder/__manifest__.py create mode 100644 account_invoice_overdue_reminder/data/mail_template.xml create mode 100644 account_invoice_overdue_reminder/data/overdue_reminder_result.xml create mode 100644 account_invoice_overdue_reminder/migrations/12.0.2.0.0/post-migration.py create mode 100644 account_invoice_overdue_reminder/migrations/12.0.2.0.0/pre-migration.py create mode 100644 account_invoice_overdue_reminder/models/__init__.py create mode 100644 account_invoice_overdue_reminder/models/account_invoice.py create mode 100644 account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py create mode 100644 account_invoice_overdue_reminder/models/company.py create mode 100644 account_invoice_overdue_reminder/models/config_settings.py create mode 100644 account_invoice_overdue_reminder/models/overdue_reminder_action.py create mode 100644 account_invoice_overdue_reminder/models/overdue_reminder_result.py create mode 100644 account_invoice_overdue_reminder/models/partner.py create mode 100644 account_invoice_overdue_reminder/readme/CONFIGURATION.rst create mode 100644 account_invoice_overdue_reminder/readme/CONTRIBUTORS.rst create mode 100644 account_invoice_overdue_reminder/readme/DESCRIPTION.rst create mode 100644 account_invoice_overdue_reminder/readme/USAGE.rst create mode 100644 account_invoice_overdue_reminder/security/ir.model.access.csv create mode 100644 account_invoice_overdue_reminder/security/rule.xml create mode 100644 account_invoice_overdue_reminder/views/account_invoice.xml create mode 100644 account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml create mode 100644 account_invoice_overdue_reminder/views/config_settings.xml create mode 100644 account_invoice_overdue_reminder/views/overdue_reminder_action.xml create mode 100644 account_invoice_overdue_reminder/views/overdue_reminder_result.xml create mode 100644 account_invoice_overdue_reminder/views/partner.xml create mode 100644 account_invoice_overdue_reminder/views/report.xml create mode 100644 account_invoice_overdue_reminder/views/report_overdue_reminder.xml create mode 100644 account_invoice_overdue_reminder/wizard/__init__.py create mode 100644 account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py create mode 100644 account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml diff --git a/account_invoice_overdue_reminder/__init__.py b/account_invoice_overdue_reminder/__init__.py new file mode 100644 index 000000000..9b4296142 --- /dev/null +++ b/account_invoice_overdue_reminder/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/account_invoice_overdue_reminder/__manifest__.py b/account_invoice_overdue_reminder/__manifest__.py new file mode 100644 index 000000000..09cda1fd9 --- /dev/null +++ b/account_invoice_overdue_reminder/__manifest__.py @@ -0,0 +1,32 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Overdue Invoice Reminder', + 'version': '12.0.2.0.0', + 'category': 'Accounting', + 'license': 'AGPL-3', + 'summary': 'Simple mail/letter/phone overdue customer invoice reminder ', + 'author': 'Akretion,Odoo Community Association (OCA)', + 'maintainers': ['alexis-via'], + 'website': 'https://github.com/OCA/credit-control', + 'depends': ['account'], + 'data': [ + 'security/ir.model.access.csv', + 'security/rule.xml', + 'wizard/overdue_reminder_wizard_view.xml', + 'views/partner.xml', + 'views/report.xml', + 'views/report_overdue_reminder.xml', + 'views/account_invoice.xml', + 'views/account_invoice_overdue_reminder.xml', + 'views/overdue_reminder_result.xml', + 'views/overdue_reminder_action.xml', + 'views/config_settings.xml', + 'data/overdue_reminder_result.xml', + 'data/mail_template.xml', + ], + 'installable': True, + 'application': True, +} diff --git a/account_invoice_overdue_reminder/data/mail_template.xml b/account_invoice_overdue_reminder/data/mail_template.xml new file mode 100644 index 000000000..7f79eadd5 --- /dev/null +++ b/account_invoice_overdue_reminder/data/mail_template.xml @@ -0,0 +1,82 @@ + + + + + + + + Overdue Invoice Reminder + + + ${object.partner_id.lang} + + ${object.user_id.email or object.company_id.email} + ${object.partner_id.email} + ${object.company_id.name} - Overdue invoice reminder n°${object.counter} + +

Dear customer,

+ +

According to our books, the following invoices are overdue:

+ + + + + + + + + + + + + +% for inv in object.invoice_ids: + + + + + + + + + + + +% endfor +% for (currency, total_residual) in object.total_residual(): + + + + + + + + + + +% endfor +
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.Total UntaxedTotalResidualPast Reminders
${inv.number}${format_date(inv.date_invoice)}${inv.payment_term_id.name or ''}${format_date(inv.date_due)}${inv.name or ''}${format_amount(inv.amount_untaxed_invoice_signed, inv.currency_id)}${format_amount(inv.amount_total_signed, inv.currency_id)}${format_amount(inv.residual_signed, inv.currency_id)}${inv.overdue_reminder_counter}
Total Residual in ${currency.name}:${format_amount(total_residual, currency)}
+ +

If you made a payment for these invoices a few days ago, please ignore this email.

+ +% if object.company_id.overdue_reminder_attach_invoice: +

You will find enclosed the overdue invoices.

+% endif + +% if object.counter > 2: +

Despite several reminders, we are disappointed to see that these overdue invoices are still unpaid. In order to avoid legal proceedings, we urge you to paid these overdue invoices in the next days.

+% endif + +

Regards,

+ + +]]>
+
+ + +
diff --git a/account_invoice_overdue_reminder/data/overdue_reminder_result.xml b/account_invoice_overdue_reminder/data/overdue_reminder_result.xml new file mode 100644 index 000000000..dbd1c8f20 --- /dev/null +++ b/account_invoice_overdue_reminder/data/overdue_reminder_result.xml @@ -0,0 +1,47 @@ + + + + + + + + Message left on voicemail + 10 + + + + Unreachable + 20 + + + + Invoice not received + 30 + + + + Invoice waiting approval + 40 + + + + Invoice dispute + 50 + + + + Invoice in payment pipe + 60 + + + + Payment sent + 70 + + + + diff --git a/account_invoice_overdue_reminder/migrations/12.0.2.0.0/post-migration.py b/account_invoice_overdue_reminder/migrations/12.0.2.0.0/post-migration.py new file mode 100644 index 000000000..8b491d96a --- /dev/null +++ b/account_invoice_overdue_reminder/migrations/12.0.2.0.0/post-migration.py @@ -0,0 +1,52 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, SUPERUSER_ID + + +def migrate(cr, version): + if not version: + return + + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + orao = env['overdue.reminder.action'] + aioro = env['account.invoice.overdue.reminder'] + + # The system is designed so that you can't + # send 2 reminders for the same customer the + # same day + # So, in order to create overdue.reminder.action, we + # read account.invoice.overdue.reminder and we group by + # date/company/partner + cr.execute( + """ + SELECT id, partner_id as commercial_partner_id, date, user_id, + reminder_type, result_id, result_notes, mail_id, company_id + FROM account_invoice_overdue_reminder + """) + tmp = {} # (key = date, company, commercial_partner_id) + # value = vals with list of ids + for old in cr.dictfetchall(): + key = (old['date'], old['company_id'], old['commercial_partner_id']) + if key in tmp: + tmp[key]['reminder_ids'].append(old['id']) + else: + tmp[key] = { + 'reminder_ids': [old['id']], + 'date': old['date'], + 'commercial_partner_id': old['commercial_partner_id'], + 'partner_id': old['commercial_partner_id'], + 'user_id': old['user_id'], + 'reminder_type': old['reminder_type'], + 'result_id': old['result_id'], + 'result_notes': old['result_notes'], + 'mail_id': old['mail_id'], + 'company_id': old['company_id'], + } + for vals in tmp.values(): + reminder_ids = vals.pop('reminder_ids') + action = orao.create(vals) + reminders = aioro.browse(reminder_ids) + reminders.write({'action_id': action.id}) diff --git a/account_invoice_overdue_reminder/migrations/12.0.2.0.0/pre-migration.py b/account_invoice_overdue_reminder/migrations/12.0.2.0.0/pre-migration.py new file mode 100644 index 000000000..6b278bc9f --- /dev/null +++ b/account_invoice_overdue_reminder/migrations/12.0.2.0.0/pre-migration.py @@ -0,0 +1,11 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +def migrate(cr, version): + if not version: + return + + cr.execute( + 'DELETE from overdue_reminder_action') diff --git a/account_invoice_overdue_reminder/models/__init__.py b/account_invoice_overdue_reminder/models/__init__.py new file mode 100644 index 000000000..8799acc16 --- /dev/null +++ b/account_invoice_overdue_reminder/models/__init__.py @@ -0,0 +1,7 @@ +from . import company +from . import config_settings +from . import partner +from . import account_invoice +from . import overdue_reminder_result +from . import overdue_reminder_action +from . import account_invoice_overdue_reminder diff --git a/account_invoice_overdue_reminder/models/account_invoice.py b/account_invoice_overdue_reminder/models/account_invoice.py new file mode 100644 index 000000000..4237791fe --- /dev/null +++ b/account_invoice_overdue_reminder/models/account_invoice.py @@ -0,0 +1,60 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + no_overdue_reminder = fields.Boolean( + string='Disable Overdue Reminder', + track_visibility='onchange') + overdue_reminder_ids = fields.One2many( + 'account.invoice.overdue.reminder', + 'invoice_id', + string='Overdue Reminder Action History') + overdue_reminder_last_date = fields.Date( + compute='_compute_overdue_reminder', + string='Last Overdue Reminder Date', store=True) + overdue_reminder_counter = fields.Integer( + string='Overdue Reminder Count', store=True, + compute='_compute_overdue_reminder', + help="This counter is not increased in case of phone reminder.") + overdue = fields.Boolean(compute='_compute_overdue') + + _sql_constraints = [( + 'counter_positive', + 'CHECK(overdue_reminder_counter >= 0)', + 'Overdue Invoice Counter must always be positive')] + + @api.depends('type', 'state', 'date_due') + def _compute_overdue(self): + today = fields.Date.context_today(self) + for inv in self: + overdue = False + if ( + inv.type == 'out_invoice' and + inv.state == 'open' and + inv.date_due < today): + overdue = True + inv.overdue = overdue + + @api.depends( + 'overdue_reminder_ids.action_id.date', + 'overdue_reminder_ids.counter', + 'overdue_reminder_ids.action_id.reminder_type') + def _compute_overdue_reminder(self): + aioro = self.env['account.invoice.overdue.reminder'] + for inv in self: + reminder = aioro.search( + [('invoice_id', '=', inv.id)], order='action_date desc', limit=1) + date = reminder and reminder.action_date or False + counter_reminder = aioro.search([ + ('invoice_id', '=', inv.id), + ('action_reminder_type', 'in', ('mail', 'post'))], + order='action_date desc, id desc', limit=1) + counter = counter_reminder and counter_reminder.counter or False + inv.overdue_reminder_last_date = date + inv.overdue_reminder_counter = counter diff --git a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py new file mode 100644 index 000000000..45178b8c0 --- /dev/null +++ b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py @@ -0,0 +1,61 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class AccountInvoiceOverdueReminder(models.Model): + _name = 'account.invoice.overdue.reminder' + _description = 'Overdue Invoice Reminder Action History' + _order = 'id desc' + + # For the link to invoice: why a M2O and not a M2M ? + # Because of the "counter" field: a single reminder action for a customer, + # the "counter" may not be the same for each invoice + invoice_id = fields.Many2one( + 'account.invoice', string='Invoice', ondelete='cascade', readonly=True) + action_id = fields.Many2one( + 'overdue.reminder.action', string='Overdue Reminder Action', + ondelete='cascade') + action_commercial_partner_id = fields.Many2one( + related='action_id.commercial_partner_id', store=True) + action_partner_id = fields.Many2one( + related='action_id.partner_id', store=True) + action_date = fields.Date(related='action_id.date', store=True) + action_user_id = fields.Many2one(related='action_id.user_id') + action_reminder_type = fields.Selection( + related='action_id.reminder_type', store=True) + action_result_id = fields.Many2one( + related='action_id.result_id', readonly=False) + action_result_notes = fields.Text( + related='action_id.result_notes', readonly=False) + action_mail_id = fields.Many2one( + related='action_id.mail_id') + action_mail_state = fields.Selection( + related='action_id.mail_id.state', string='E-mail Status') + counter = fields.Integer(readonly=True) + company_id = fields.Many2one( + related='invoice_id.company_id', store=True) + + _sql_constraints = [( + 'counter_positive', + 'CHECK(counter >= 0)', + 'Counter must always be positive')] + + @api.constrains('invoice_id') + def invoice_id_check(self): + for action in self: + if action.invoice_id and action.invoice_id.type != 'out_invoice': + raise ValidationError(_( + "An overdue reminder can only be attached " + "to a customer invoice")) + + @api.depends('invoice_id', 'counter') + def name_get(self): + res = [] + for rec in self: + name = _('%s Reminder %d') % (rec.invoice_id.number, rec.counter) + res.append((rec.id, name)) + return res diff --git a/account_invoice_overdue_reminder/models/company.py b/account_invoice_overdue_reminder/models/company.py new file mode 100644 index 000000000..65904039c --- /dev/null +++ b/account_invoice_overdue_reminder/models/company.py @@ -0,0 +1,38 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ + + +class ResCompany(models.Model): + _inherit = 'res.company' + + overdue_reminder_attach_invoice = fields.Boolean( + string='Attach Invoices to Overdue Reminder E-mails', default=True) + overdue_reminder_start_days = fields.Integer( + string='Default Overdue Reminder Trigger Delay (days)') + overdue_reminder_min_interval_days = fields.Integer( + string='Default Overdue Reminder Minimum Interval (days)', default=5) + overdue_reminder_interface = fields.Selection( + '_overdue_reminder_interface_selection', + string='Default Overdue Reminder Wizard Interface', + default='onebyone') + + @api.model + def _overdue_reminder_interface_selection(self): + return [ + ('onebyone', _('One by One')), + ('mass', _('Mass')), + ] + + _sql_constraints = [ + ( + 'overdue_reminder_start_days_positive', + 'CHECK(overdue_reminder_start_days >= 0)', + 'Overdue Reminder Trigger Delay must always be positive'), + ( + 'overdue_reminder_min_interval_days_positive', + 'CHECK(overdue_reminder_min_interval_days > 0)', + 'Overdue Reminder Trigger Delay must always be strictly positive'), + ] diff --git a/account_invoice_overdue_reminder/models/config_settings.py b/account_invoice_overdue_reminder/models/config_settings.py new file mode 100644 index 000000000..2e2e34541 --- /dev/null +++ b/account_invoice_overdue_reminder/models/config_settings.py @@ -0,0 +1,20 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + overdue_reminder_attach_invoice = fields.Boolean( + related='company_id.overdue_reminder_attach_invoice', readonly=False) + overdue_reminder_start_days = fields.Integer( + related='company_id.overdue_reminder_start_days', readonly=False) + overdue_reminder_min_interval_days = fields.Integer( + related='company_id.overdue_reminder_min_interval_days', + readonly=False) + overdue_reminder_interface = fields.Selection( + related='company_id.overdue_reminder_interface', + readonly=False) diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_action.py b/account_invoice_overdue_reminder/models/overdue_reminder_action.py new file mode 100644 index 000000000..bcb1eb6cf --- /dev/null +++ b/account_invoice_overdue_reminder/models/overdue_reminder_action.py @@ -0,0 +1,66 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ + + +class OverdueReminderAction(models.Model): + _name = 'overdue.reminder.action' + _description = 'Overdue Reminder Action History' + _order = 'date desc, id desc' + + commercial_partner_id = fields.Many2one( + 'res.partner', readonly=True, string='Customer', index=True, + domain=[('parent_id', '=', False)]) + partner_id = fields.Many2one( + 'res.partner', readonly=True, string='Contact') + date = fields.Date( + default=fields.Date.context_today, required=True, index=True, + readonly=True) + user_id = fields.Many2one( + 'res.users', string='Performed by', required=True, readonly=True, + ondelete='restrict', default=lambda self: self.env.user) + reminder_type = fields.Selection( + '_reminder_type_selection', default='mail', string='Type', + required=True, readonly=True) + result_id = fields.Many2one( + 'overdue.reminder.result', ondelete='restrict', + string='Info/Result') + result_notes = fields.Text(string='Info/Result Notes') + mail_id = fields.Many2one( + 'mail.mail', string='Reminder E-mail', readonly=True) + mail_state = fields.Selection( + related='mail_id.state', string='E-mail Status') + company_id = fields.Many2one( + 'res.company', string='Company', readonly=True) + reminder_count = fields.Integer( + compute='_compute_invoice_count', store=True, string='Number of invoices') + reminder_ids = fields.One2many( + 'account.invoice.overdue.reminder', 'action_id', readonly=True) + + @api.model + def _reminder_type_selection(self): + return [ + ('mail', _('E-mail')), + ('phone', _('Phone')), + ('post', _('Letter')), + ] + + @api.depends('reminder_ids') + def _compute_invoice_count(self): + rg_res = self.env['account.invoice.overdue.reminder'].read_group( + [('action_id', 'in', self.ids), ('invoice_id', '!=', False)], + ['action_id'], ['action_id']) + mapped_data = dict([(x['action_id'][0], x['action_id_count']) for x in rg_res]) + for rec in self: + rec.reminder_count = mapped_data.get(rec.id, 0) + + @api.depends('commercial_partner_id', 'date') + def name_get(self): + res = [] + for action in self: + name = _('%s, Reminder %s') % ( + action.commercial_partner_id.display_name, action.date) + res.append((action.id, name)) + return res diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_result.py b/account_invoice_overdue_reminder/models/overdue_reminder_result.py new file mode 100644 index 000000000..4bbf342ce --- /dev/null +++ b/account_invoice_overdue_reminder/models/overdue_reminder_result.py @@ -0,0 +1,20 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class OverdueReminderResult(models.Model): + _name = 'overdue.reminder.result' + _description = 'Overdue Invoice Reminder Result/Info' + _order = 'sequence, id desc' + + name = fields.Char(required=True, translate=True) + active = fields.Boolean(default=True) + sequence = fields.Integer() + + _sql_constraints = [( + 'name_unique', + 'unique(name)', + 'This overdue reminder result already exists')] diff --git a/account_invoice_overdue_reminder/models/partner.py b/account_invoice_overdue_reminder/models/partner.py new file mode 100644 index 000000000..3f8afa07f --- /dev/null +++ b/account_invoice_overdue_reminder/models/partner.py @@ -0,0 +1,13 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + # Property of commercial partner, applies for the whole entity + no_overdue_reminder = fields.Boolean( + string='Disable Overdue Invoice Reminder', company_dependent=True) diff --git a/account_invoice_overdue_reminder/readme/CONFIGURATION.rst b/account_invoice_overdue_reminder/readme/CONFIGURATION.rst new file mode 100644 index 000000000..8ddc48931 --- /dev/null +++ b/account_invoice_overdue_reminder/readme/CONFIGURATION.rst @@ -0,0 +1,9 @@ +You should increase the **osv_memory_age_limit** (default value = 1, which means 1 hour) in the Odoo server config file: for example, you can set it to 12 (12 hours). The value must be superior to the duration of the invoicing reminder wizard from the start screen to the end. + +Go to the menu *Invoicing > Configuration > Settings* then go to the section *Overdue Invoice Reminder*: you will be able to configure if you want to attach the overdue invoice to the reminder emails and set default values for some parameters. + +Then, go to the menu *Settings > Technical > E-mail > Templates* and search for the mail template *Overdue Invoice Reminder*. You can edit the subject and the body of this email template. If you are in a multi-lang setup, don't forget to also update the translations. + +Go to the menu *Invoicing > Configuration > Management > Invoice Reminder Results* and customize the list of entries. + +If `py3o `_ is your favorite reporting engine for Odoo (with the module *report_py3o* of the project `OCA/reporting-engine `_), you can use the sample py3o report for the overdue reminder letter available in the module *account_invoice_overdue_reminder_py3o* of Akretion's `py3o report templates `_ project. diff --git a/account_invoice_overdue_reminder/readme/CONTRIBUTORS.rst b/account_invoice_overdue_reminder/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..ff65d68ce --- /dev/null +++ b/account_invoice_overdue_reminder/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Alexis de Lattre diff --git a/account_invoice_overdue_reminder/readme/DESCRIPTION.rst b/account_invoice_overdue_reminder/readme/DESCRIPTION.rst new file mode 100644 index 000000000..5aa9e9652 --- /dev/null +++ b/account_invoice_overdue_reminder/readme/DESCRIPTION.rst @@ -0,0 +1,31 @@ +This Odoo module is designed to send overdue invoice reminders to customers. It handles reminders by e-mail, letter and phone. + +This module is an alternative to the OCA module *account_credit_control*. Why another module for invoice reminders ? Because the module *account_credit_control* is quite complex (we experienced that some users find it too complex and eventually stop using it) and its interface is designed to send massive volume of reminders. + +This module has been designed from the start with the following priorities: + +* **keep control**: you must keep tight control on the overdue invoice reminders that you send. Overdue invoice reminders are part of the communication with your customers, and this is very important to keep a good relation with your customers. +* **usability**: the module is easy to configure and easy to use. +* **no accounting skills needed**: the module can be used by users without accounting skills. It can even be used by salesman! +* **multi-currency**: if you invoice your customer in another currency that your company currency, the invoice reminders only mention the currency of the invoices. And if you invoice a customer with different currencies, the reminder is clear and easy-to-understand by your customer, with a total residual per currency. +* **multi-channel**: supports overdue invoice reminders by e-mail (default), phone and letter. +* **simplicity**: for the developers, the code is small and easy to understand. + +The specifications written before starting the development of this module are written in this `document `_ (in French). + +The module has one important limitation: it sends a reminder for an invoice when it has past it's *Due Date* (which is in fact the *Final Due Date*): if the invoice has a payment term with several lines, it won't send a reminder before the last term is overdue. + +An overdue reminder for a customer always include all the overdue invoices of that customer. + +The module supports a clever per-invoice reminder counter mechanism: + +* the reminder counter is a property of an invoice, +* the reminder counter of each overdue invoice is incremented when sending a reminder by email or by post. It is not incremented for reminders by phone. +* in an email or a letter, the subject will be *Overdue invoice reminder n°N* where N is the maximum value of the counter of the overdue invoices plus one. + +There are two user interfaces to send reminders: + +* the **one-by-one** interface, which displays one screen for each customer that has overdue invoices, one after the other. You should use this interface when you have a reasonable volume of reminders to send (less than 100 overdue reminders for example). It gives you a tight control on the reminders and the possibility to easily and rapidly customize the reminder e-mails. +* the **mass** interface, which displays a list view of all customers that have overdue invoices, and you can process several reminders at the same time (via the *Actions* menu). + +This video tutorial in English will show you how to configure and use the module: `Youtube link `_. diff --git a/account_invoice_overdue_reminder/readme/USAGE.rst b/account_invoice_overdue_reminder/readme/USAGE.rst new file mode 100644 index 000000000..6709a03ca --- /dev/null +++ b/account_invoice_overdue_reminder/readme/USAGE.rst @@ -0,0 +1,12 @@ +Of course, before sending invoice reminders, you must import your bank statements and process them, so that you are up-to-date on customer payments. + +Then, go to the menu *Invoicing > Accounting > Actions > Overdue Invoice Remind*: you will get the start screen where you can: + +* filter the customers that you want to remind (filter by customer or by salesman), +* check that your bank journals are up-to-date, +* choose between the *one-by-one* and *mass* interfaces, +* customize some parameters. + +Then follow the process until the end. + +You can also start the invoice reminder wizard via the button *Overdue Reminder* on an overdue invoice. diff --git a/account_invoice_overdue_reminder/security/ir.model.access.csv b/account_invoice_overdue_reminder/security/ir.model.access.csv new file mode 100644 index 000000000..06b103e78 --- /dev/null +++ b/account_invoice_overdue_reminder/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_overdue_reminder_result_read,Read access on overdue.reminder.result,model_overdue_reminder_result,account.group_account_invoice,1,0,0,0 +access_overdue_reminder_result_full,Full access on overdue.reminder.result,model_overdue_reminder_result,account.group_account_manager,1,1,1,1 +access_overdue_reminder_action_user,Read/create/write on reminder actions,model_overdue_reminder_action,account.group_account_invoice,1,1,1,0 +access_overdue_reminder_action_manager,Full access on reminder actions,model_overdue_reminder_action,account.group_account_manager,1,1,1,1 +access_account_invoice_overdue_reminder_user,Read/create/write on reminder counters,model_account_invoice_overdue_reminder,account.group_account_invoice,1,1,1,0 +access_account_invoice_overdue_reminder_manager,Full access on reminder counters,model_account_invoice_overdue_reminder,account.group_account_manager,1,1,1,1 diff --git a/account_invoice_overdue_reminder/security/rule.xml b/account_invoice_overdue_reminder/security/rule.xml new file mode 100644 index 000000000..ddb45be5d --- /dev/null +++ b/account_invoice_overdue_reminder/security/rule.xml @@ -0,0 +1,18 @@ + + + + + + + + Overdue Invoice Reminder multi-company + + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + + + + diff --git a/account_invoice_overdue_reminder/views/account_invoice.xml b/account_invoice_overdue_reminder/views/account_invoice.xml new file mode 100644 index 000000000..9b0ad26bb --- /dev/null +++ b/account_invoice_overdue_reminder/views/account_invoice.xml @@ -0,0 +1,50 @@ + + + + + + + + overdue.reminder.customer.invoice.form + account.invoice + + + + + + + + + + + + + + + + + + + + + overdue.reminder.customer.invoice.search + account.invoice + + + + + + + + + + diff --git a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml new file mode 100644 index 000000000..f4d10d48b --- /dev/null +++ b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml @@ -0,0 +1,109 @@ + + + + + + + + account.invoice.overdue.reminder.form + account.invoice.overdue.reminder + +
+ + + + + + + + + + + + + + + +
+
+
+ + + account.invoice.overdue.reminder.norelated.form + account.invoice.overdue.reminder + 100 + +
+ + + + + +
+
+
+ + + account.invoice.overdue.reminder.tree + account.invoice.overdue.reminder + + + + + + + + + + + + + + + + account.invoice.overdue.reminder.norelated.tree + account.invoice.overdue.reminder + 100 + + + + + + + + + + account.invoice.overdue.reminder.search + account.invoice.overdue.reminder + + + + + + + + + + + + + + + + + + + + + Invoice Reminder Counters + account.invoice.overdue.reminder + tree,form + {'overdue_reminder_main_view': True} + + + +
diff --git a/account_invoice_overdue_reminder/views/config_settings.xml b/account_invoice_overdue_reminder/views/config_settings.xml new file mode 100644 index 000000000..2d1cfc876 --- /dev/null +++ b/account_invoice_overdue_reminder/views/config_settings.xml @@ -0,0 +1,46 @@ + + + + + + + + overdue.reminder.res.config.settings.form + res.config.settings + + + +

Overdue Invoice Reminder

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + diff --git a/account_invoice_overdue_reminder/views/overdue_reminder_action.xml b/account_invoice_overdue_reminder/views/overdue_reminder_action.xml new file mode 100644 index 000000000..4b7c96084 --- /dev/null +++ b/account_invoice_overdue_reminder/views/overdue_reminder_action.xml @@ -0,0 +1,101 @@ + + + + + + + + overdue.reminder.action.form + overdue.reminder.action + +
+ + + + + + + + + + + + + + + + +
+
+
+ + + overdue.reminder.action.tree + overdue.reminder.action + + + + + + + + + + + + + overdue.reminder.action.search + overdue.reminder.action + + + + + + + + + + + + + + + + + + + overdue.reminder.action.pivot + overdue.reminder.action + + + + + + + + + + overdue.reminder.action.graph + overdue.reminder.action + + + + + + + + + Invoice Reminder Actions + overdue.reminder.action + pivot,graph,tree,form + {'pivot_measures': ['__count', 'reminder_count']} + + + + +
diff --git a/account_invoice_overdue_reminder/views/overdue_reminder_result.xml b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml new file mode 100644 index 000000000..ea431537e --- /dev/null +++ b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml @@ -0,0 +1,62 @@ + + + + + + + + overdue.reminder.result.form + overdue.reminder.result + +
+ +
+ +
+ + + +
+
+
+
+ + + overdue.reminder.result.tree + overdue.reminder.result + + + + + + + + + + overdue.reminder.result.search + overdue.reminder.result + + + + + + + + + + Invoice Reminder Results + overdue.reminder.result + tree,form + + + + +
diff --git a/account_invoice_overdue_reminder/views/partner.xml b/account_invoice_overdue_reminder/views/partner.xml new file mode 100644 index 000000000..b7643bb4a --- /dev/null +++ b/account_invoice_overdue_reminder/views/partner.xml @@ -0,0 +1,25 @@ + + + + + + + + overdue.reminder.res.partner.form + res.partner + + + + + + + + + + + + diff --git a/account_invoice_overdue_reminder/views/report.xml b/account_invoice_overdue_reminder/views/report.xml new file mode 100644 index 000000000..aac57854a --- /dev/null +++ b/account_invoice_overdue_reminder/views/report.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/account_invoice_overdue_reminder/views/report_overdue_reminder.xml b/account_invoice_overdue_reminder/views/report_overdue_reminder.xml new file mode 100644 index 000000000..acac84946 --- /dev/null +++ b/account_invoice_overdue_reminder/views/report_overdue_reminder.xml @@ -0,0 +1,94 @@ + + + + + + diff --git a/account_invoice_overdue_reminder/wizard/__init__.py b/account_invoice_overdue_reminder/wizard/__init__.py new file mode 100644 index 000000000..62b5c3a6f --- /dev/null +++ b/account_invoice_overdue_reminder/wizard/__init__.py @@ -0,0 +1 @@ +from . import overdue_reminder_wizard diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py new file mode 100644 index 000000000..42b76047d --- /dev/null +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py @@ -0,0 +1,558 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, tools, _ +from odoo.exceptions import UserError +from dateutil.relativedelta import relativedelta +import base64 +import logging +logger = logging.getLogger(__name__) + +MOD = 'account_invoice_overdue_reminder' + + +class OverdueReminderStart(models.TransientModel): + _name = 'overdue.reminder.start' + _description = 'Wizard to reminder overdue customer invoice' + + partner_ids = fields.Many2many( + 'res.partner', string='Customers', + domain=[('customer', '=', True), ('parent_id', '=', False)]) + user_ids = fields.Many2many( + 'res.users', string='Salesman') + payment_ids = fields.Many2many( + 'overdue.reminder.start.payment', 'wizard_id', readonly=True) + start_days = fields.Integer( + string='Trigger Delay', + help="Odoo will propose to send an overdue reminder to a customer " + "if it has at least one invoice which is overdue for more than " + "N days (N = trigger delay).") + min_interval_days = fields.Integer( + string='Minimum Delay Since Last Reminder', + help="Odoo will not propose to send a reminder to a customer " + "that already got a reminder for some of the same overdue invoices " + "less than N days ago (N = Minimum Delay Since Last Reminder).") + up_to_date = fields.Boolean( + string='I consider that payments are up-to-date') + company_id = fields.Many2one( + 'res.company', readonly=True, required=True, + default=lambda self: self.env['res.company']._company_default_get()) + interface = fields.Selection( + '_interface_selection', + string='Wizard Interface', + default='onebyone', required=True) + + @api.model + def _interface_selection(self): + return self.env['res.company']._overdue_reminder_interface_selection() + + @api.model + def default_get(self, fields_list): + res = super().default_get(fields_list) + amo = self.env['account.move'] + company = self.env.user.company_id + journals = self.env['account.journal'].search([ + ('company_id', '=', company.id), + ('type', 'in', ('bank', 'cash'))]) + payments = [] + for journal in journals: + last = amo.search( + [('journal_id', '=', journal.id)], + order='date desc, id desc', limit=1) + vals = { + 'journal_id': journal.id, + 'last_entry_date': last and last.date or False, + 'last_entry_create_date': last and last.create_date or False, + 'last_entry_create_uid': last and last.create_uid.id or False, + } + payments.append((0, 0, vals)) + res.update({ + 'payment_ids': payments, + 'start_days': company.overdue_reminder_start_days, + 'min_interval_days': company.overdue_reminder_min_interval_days, + }) + return res + + def _prepare_base_domain(self): + base_domain = [ + ('company_id', '=', self.company_id.id), + ('type', '=', 'out_invoice'), + ('state', '=', 'open'), + ('no_overdue_reminder', '=', False), + ] + return base_domain + + def _prepare_remind_trigger_domain(self, base_domain): + today = fields.Date.context_today(self) + limit_date = today + if self.start_days: + limit_date -= relativedelta(days=self.start_days) + domain = base_domain + [('date_due', '<', limit_date)] + if self.partner_ids: + domain.append(('commercial_partner_id', 'in', self.partner_ids.ids)) + if self.user_ids: + domain.append(('user_id', 'in', self.user_ids.ids)) + return domain + + def run(self): + self.ensure_one() + if not self.up_to_date: + raise UserError(_( + "In order to start overdue reminders, you must make sure that " + "customer payments are up-to-date.")) + if self.start_days < 0: + raise UserError(_( + "The trigger delay cannot be negative.")) + if self.min_interval_days < 1: + raise UserError(_( + "The minimum delay since last reminder must be strictly positive.")) + aio = self.env['account.invoice'] + ajo = self.env['account.journal'] + rpo = self.env['res.partner'] + orso = self.env['overdue.reminder.step'] + user_id = self.env.user.id + existing_actions = orso.search([('user_id', '=', user_id)]) + existing_actions.unlink() + payment_journals = ajo.search([ + ('company_id', '=', self.company_id.id), + ('type', 'in', ('bank', 'cash')), + ]) + sale_journals = ajo.search([ + ('company_id', '=', self.company_id.id), + ('type', '=', 'sale'), + ]) + today = fields.Date.context_today(self) + min_interval_date = today - relativedelta(days=self.min_interval_days) + # It is important to understand this: there are 2 search on invoice : + # 1. a first search to know if a partner must be reminded or not + # 2. a second search to get the invoices to remind for that partner + # There are some slight differences between these 2 searches; + # for example: search 1 compares due_date to (today + start_days) + # whereas search 2 compares due_date to today + base_domain = self._prepare_base_domain() + domain = self._prepare_remind_trigger_domain(base_domain) + rg_res = aio.read_group( + domain, + ['commercial_partner_id', 'residual_company_signed'], + ['commercial_partner_id']) + # Sort by residual amount desc + rg_res_sorted = sorted( + rg_res, + key=lambda to_sort: to_sort['residual_company_signed'], + reverse=True) + action_ids = [] + for rg_re in rg_res_sorted: + commercial_partner_id = rg_re['commercial_partner_id'][0] + commercial_partner = rpo.browse(commercial_partner_id) + vals = self._prepare_reminder_step( + commercial_partner, base_domain, min_interval_date, + payment_journals, sale_journals) + if vals: + action = orso.create(vals) + action_ids.append(action.id) + if not action_ids: + raise UserError(_( + "There are no overdue reminders.")) + if self.interface == 'onebyone': + xid = MOD + '.overdue_reminder_step_onebyone_action' + action = self.env.ref(xid).read()[0] + action['res_id'] = action_ids[0] + elif self.interface == 'mass': + action = orso.goto_list_view() + return action + + def _prepare_reminder_step( + self, commercial_partner, base_domain, min_interval_date, + payment_journals, sale_journals): + amlo = self.env['account.move.line'] + if commercial_partner.no_overdue_reminder: + logger.info( + 'Skipping customer %s that has no_overdue_reminder=True', + commercial_partner.display_name) + return False + invs = self.env['account.invoice'].search( + base_domain + [ + ('commercial_partner_id', '=', commercial_partner.id), + ('date_due', '<', fields.Date.context_today(self))]) + assert invs + # Check min interval + if any([ + inv.overdue_reminder_last_date > min_interval_date + for inv in invs + if inv.overdue_reminder_last_date]): + logger.info( + 'Skipping customer %s that has at least one invoice ' + 'with last reminder after %s', + commercial_partner.display_name, + fields.Date.to_string(min_interval_date)) + return False + max_counter = max([inv.overdue_reminder_counter for inv in invs]) + unrec_domain = [ + ('account_id', '=', commercial_partner.property_account_receivable_id.id), + ('partner_id', '=', commercial_partner.id), + ('full_reconcile_id', '=', False), + ('matched_debit_ids', '=', False), + ('matched_credit_ids', '=', False), + ] + unrec_payments = amlo.search( + unrec_domain + [ + ('journal_id', 'in', payment_journals.ids), + ]) + unrec_refunds = amlo.search( + unrec_domain + [ + ('journal_id', 'in', sale_journals.ids), + ('credit', '>', 0), + ]) + warn_unrec = unrec_payments + unrec_refunds + vals = { + 'partner_id': invs[0].partner_id.id, + 'commercial_partner_id': commercial_partner.id, + 'user_id': self.env.user.id, + 'invoice_ids': [(6, 0, invs.ids)], + 'company_id': self.company_id.id, + 'warn_unreconciled_move_line_ids': [(6, 0, warn_unrec.ids)], + 'counter': max_counter + 1, + 'interface': self.interface, + } + return vals + + +class OverdueReminderStartPayment(models.TransientModel): + _name = 'overdue.reminder.start.payment' + _description = 'Status of payments' + + wizard_id = fields.Many2one( + 'overdue.reminder.start', ondelete='cascade') + journal_id = fields.Many2one( + 'account.journal', string='Journal', readonly=True) + last_entry_date = fields.Date( + string='Last Entry', readonly=True) + last_entry_create_date = fields.Datetime( + string='Last Entry Created on', readonly=True) + last_entry_create_uid = fields.Many2one( + 'res.users', string='Last Entry Created by', readonly=True) + + +class OverdueReminderStep(models.TransientModel): + _name = 'overdue.reminder.step' + _description = 'Overdue reminder wizard step' + + partner_id = fields.Many2one( + 'res.partner', required=True, string='Invoicing Contact') + partner_email = fields.Char(related='partner_id.email', readonly=True) + partner_phone = fields.Char(related='partner_id.phone', readonly=True) + partner_mobile = fields.Char(related='partner_id.mobile', readonly=True) + commercial_partner_id = fields.Many2one( + 'res.partner', string='Customer', readonly=True, required=True) + user_id = fields.Many2one('res.users', required=True, readonly=True) + counter = fields.Integer(string="New Remind Counter", readonly=True) + date = fields.Date(default=fields.Date.context_today, readonly=True) + reminder_type = fields.Selection( + '_reminder_type_selection', default='mail', + string='Reminder Type', required=True) + mail_subject = fields.Char(string='Subject') + mail_body = fields.Html() + result_id = fields.Many2one( + 'overdue.reminder.result', string='Call Result/Info') + result_notes = fields.Text(string='Call Notes') + create_activity = fields.Boolean() + activity_type_id = fields.Many2one( + 'mail.activity.type', string='Activity') + activity_summary = fields.Char(string='Summary') + activity_deadline = fields.Date('Deadline') + activity_note = fields.Html(string='Note') + activity_user_id = fields.Many2one( + 'res.users', string='Assigned to', default=lambda self: self.env.user) + letter_printed = fields.Boolean(readonly=True) + invoice_ids = fields.Many2many( + 'account.invoice', string='Overdue Invoices', readonly=True) + company_id = fields.Many2one( + 'res.company', readonly=True, required=True, + default=lambda self: self.env['res.company']._company_default_get()) + warn_unreconciled_move_line_ids = fields.Many2many( + 'account.move.line', string='Unreconciled Payments/Refunds', + readonly=True) + unreconciled_move_line_normal = fields.Boolean( + string='Check if unreconciled payments/refunds above have a good ' + 'reason not to be reconciled with an open invoice') + interface = fields.Char(readonly=True) + state = fields.Selection([ + ('draft', 'Draft'), + ('skipped', 'Skipped'), + ('done', 'Done'), + ], default='draft', readonly=True) + + @api.model + def _reminder_type_selection(self): + return self.env['overdue.reminder.action']._reminder_type_selection() + + @api.model + def create(self, vals): + action = super().create(vals) + commercial_partner = self.env['res.partner'].browse( + vals['commercial_partner_id']) + xmlid = MOD + '.overdue_invoice_reminder_mail_template' + mail_tpl = self.env.ref(xmlid) + mail_tpl_lang = mail_tpl.with_context(lang=commercial_partner.lang or 'en_US') + mail_subject = mail_tpl_lang._render_template( + mail_tpl_lang.subject, self._name, action.id) + mail_body = mail_tpl_lang._render_template( + mail_tpl_lang.body_html, self._name, action.id) + if mail_tpl.user_signature: + signature = self.env.user.signature + if signature: + mail_body = tools.append_content_to_html( + mail_body, signature, plaintext=False) + mail_body = tools.html_sanitize(mail_body) + action.write({ + 'mail_subject': mail_subject, + 'mail_body': mail_body, + }) + return action + + @api.onchange('reminder_type') + def reminder_type_change(self): + if self.reminder_type and self.reminder_type != 'phone': + self.result_id = False + self.result_notes = False + self.create_activity = False + + def next(self): + self.ensure_one() + left = self.search([ + ('state', '=', 'draft'), + ('user_id', '=', self.user_id.id), + ('company_id', '=', self.company_id.id)], limit=1) + if left: + action = self.env.ref( + MOD + '.overdue_reminder_step_onebyone_action').read()[0] + action['res_id'] = left.id + else: + action = self.env.ref( + MOD + '.overdue_reminder_end_action').read()[0] + return action + + def goto_list_view(self): + action = self.env.ref( + MOD + '.overdue_reminder_step_mass_action').read()[0] + return action + + def skip(self): + self.write({'state': 'skipped'}) + if len(self) == 1: + if self.interface == 'onebyone': + action = self.next() + else: + action = self.goto_list_view() + return action + + def _prepare_mail_activity(self): + self.ensure_one() + partner_model_id = self.env.ref('base.model_res_partner').id + if not self.activity_user_id: + raise UserError(_( + "For the reminder of customer '%s', you must assign someone " + "for the activity.") % self.commercial_partner_id.display_name) + if not self.activity_deadline: + raise UserError(_( + "For the reminder of customer '%s', the deadline is missing " + "for the activity.") % self.commercial_partner_id.display_name) + vals = { + 'activity_type_id': self.activity_type_id.id or False, + 'summary': self.activity_summary, + 'date_deadline': self.activity_deadline, + 'user_id': self.activity_user_id.id, + 'note': self.activity_note, + 'res_id': self.commercial_partner_id.id, + 'res_model_id': partner_model_id, + } + return vals + + def check_warnings(self): + self.ensure_one() + for rec in self: + if rec.company_id != self.env.user.company_id: + raise UserError(_( + "User company is different from action company. " + "This should never happen.")) + if ( + rec.warn_unreconciled_move_line_ids and + not rec.unreconciled_move_line_normal): + raise UserError(_( + "Customer '%s' has unreconciled payments/refunds. " + "You should reconcile these payments/refunds and start the " + "overdue remind process again " + "(or check the option to confirm that these unreconciled " + "payments/refunds have a good reason not to be " + "reconciled with an open invoice).") + % rec.commercial_partner_id.display_name) + + def validate(self): + orao = self.env['overdue.reminder.action'] + mao = self.env['mail.activity'] + self.check_warnings() + for rec in self: + vals = {} + if rec.reminder_type == 'mail': + vals = rec.validate_mail() + elif rec.reminder_type == 'phone': + vals = rec.validate_phone() + elif rec.reminder_type == 'post': + vals = rec.validate_post() + rec._prepare_overdue_reminder_action(vals) + orao.create(vals) + if rec.create_activity: + mao.create(self._prepare_mail_activity()) + self.write({'state': 'done'}) + if len(self) == 1: + if self.interface == 'onebyone': + action = self.next() + else: + action = self.goto_list_view() + return action + + def validate_mail(self): + self.ensure_one() + iao = self.env['ir.attachment'] + if not self.mail_subject: + raise UserError(_('Mail subject is empty.')) + if not self.mail_body: + raise UserError(_('Mail body is empty.')) + xmlid = MOD + '.overdue_invoice_reminder_mail_template' + mvals = self.env.ref(xmlid).generate_email(self.id) + mvals.update({ + 'subject': self.mail_subject, + 'body_html': self.mail_body, + }) + mvals.pop('attachment_ids', None) + mvals.pop('attachments', None) + mail = self.env['mail.mail'].create(mvals) + inv_report = self.env['ir.actions.report']._get_report_from_name( + 'account.report_invoice_with_payments') + if self.company_id.overdue_reminder_attach_invoice: + attachment_ids = [] + for inv in self.invoice_ids: + if inv_report.report_type in ('qweb-html', 'qweb-pdf'): + report_bin, report_format = inv_report.render_qweb_pdf([inv.id]) + else: + res = inv_report.render([inv.id]) + if not res: + raise UserError(_( + "Report format '%s' is not supported.") + % inv_report.report_type) + report_bin, report_format = res + # WARN : update when backporting + filename = '%s.%s' % (inv._get_report_base_filename(), report_format) + attach = iao.create({ + 'name': filename, + 'datas_fname': filename, + 'datas': base64.b64encode(report_bin), + 'res_model': 'mail.message', + 'res_id': mail.mail_message_id.id, + }) + attachment_ids.append(attach.id) + mail.write({'attachment_ids': [(6, 0, attachment_ids)]}) + vals = {'mail_id': mail.id} + return vals + + def validate_phone(self): + self.ensure_one() + assert self.reminder_type == 'phone' + vals = { + 'result_id': self.result_id.id or False, + 'result_notes': self.result_notes, + } + return vals + + def validate_post(self): + self.ensure_one() + assert self.reminder_type == 'post' + if not self.letter_printed: + raise UserError(_( + "Remind letter hasn't been printed!")) + return {} + + def _prepare_overdue_reminder_action(self, vals): + vals.update({ + 'user_id': self.user_id.id, + 'reminder_type': self.reminder_type, + 'reminder_ids': [], + 'company_id': self.company_id.id, + 'commercial_partner_id': self.commercial_partner_id.id, + 'partner_id': self.partner_id.id, + }) + for inv in self.invoice_ids: + rvals = {'invoice_id': inv.id} + if self.reminder_type != 'phone': + rvals['counter'] = inv.overdue_reminder_counter + 1 + vals['reminder_ids'].append((0, 0, rvals)) + + def print_letter(self): + self.check_warnings() + self.write({'letter_printed': True}) + action = action = self.env.ref( + MOD + '.overdue_reminder_step_report').with_context( + {'discard_logo_check': True}).report_action(self) + return action + + def print_invoices(self): + # in v12, it seems printing several invoices at the same time + # doesn't work + action = self.env.ref('account.account_invoices')\ + .with_context( + {'discard_logo_check': True}).report_action(self.invoice_ids.ids) + return action + + def total_residual(self): + self.ensure_one() + res = {} + for inv in self.invoice_ids: + if inv.currency_id in res: + res[inv.currency_id] += inv.residual_signed + else: + res[inv.currency_id] = inv.residual_signed + return res.items() + + def _get_report_base_filename(self): + self.ensure_one() + fname = 'overdue_letter-%s' % self.commercial_partner_id.name.replace(' ', '_') + return fname + + +class OverdueReminderEnd(models.TransientModel): + _name = 'overdue.reminder.end' + _description = 'Congratulation end screen for overdue reminder wizard' + + +class OverdueRemindMassUpdate(models.TransientModel): + _name = 'overdue.reminder.mass.update' + _description = 'Update several actions at the same time' + + update_action = fields.Selection([ + ('validate', 'Validate'), + ('reminder_type', 'Change Reminder Type'), + ('skip', 'Skip')], + required=True, readonly=True) + reminder_type = fields.Selection( + '_reminder_type_selection', + string='New Reminder Type') + + @api.model + def _reminder_type_selection(self): + return self.env['overdue.reminder.action']._reminder_type_selection() + + def run(self): + self.ensure_one() + assert self._context.get('active_model') == 'overdue.reminder.step' + actions = self.env['overdue.reminder.step'].browse( + self._context.get('active_ids')) + if self.update_action == 'validate': + actions.validate() + elif self.update_action == 'skip': + actions.skip() + elif self.update_action == 'reminder_type': + if not self.reminder_type: + raise UserError(_("You must select the new reminder type.")) + actions.write({'reminder_type': self.reminder_type}) + return diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml new file mode 100644 index 000000000..a3c2aefc9 --- /dev/null +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml @@ -0,0 +1,241 @@ + + + + + + + + overdue.reminder.start.form + overdue.reminder.start + +
+ + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+ + + Overdue Invoice Remind + overdue.reminder.start + form + new + + + + + + overdue.reminder.step.form + overdue.reminder.step + +
+ + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- + From 9b0bd5a7fb1bbeaf98c9033cf9256bdfa876f7fb Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 12 Nov 2020 23:55:58 +0100 Subject: [PATCH 006/116] overdue_reminder: Order overdue invoices starting from oldest (NOTE: update your mail templates) Add ability to add contacts as Cc of the reminder email (added to the Cc of the mail template) Add partner_policy with 3 options to give some choice about which contact should be selected to send reminders Access reminders from partner via Action menu --- .../data/mail_template.xml | 2 +- .../account_invoice_overdue_reminder.py | 2 + .../models/company.py | 11 ++++++ .../models/config_settings.py | 5 ++- .../models/overdue_reminder_action.py | 3 +- .../account_invoice_overdue_reminder.xml | 3 +- .../views/config_settings.xml | 4 ++ .../views/overdue_reminder_action.xml | 3 +- .../views/partner.xml | 7 ++++ .../views/report_overdue_reminder.xml | 2 +- .../wizard/overdue_reminder_wizard.py | 38 ++++++++++++++++++- .../wizard/overdue_reminder_wizard_view.xml | 4 +- 12 files changed, 75 insertions(+), 9 deletions(-) diff --git a/account_invoice_overdue_reminder/data/mail_template.xml b/account_invoice_overdue_reminder/data/mail_template.xml index 7f79eadd5..70a2bad17 100644 --- a/account_invoice_overdue_reminder/data/mail_template.xml +++ b/account_invoice_overdue_reminder/data/mail_template.xml @@ -35,7 +35,7 @@ Residual Past Reminders -% for inv in object.invoice_ids: +% for inv in object.invoice_ids.sorted(key='date_invoice'): ${inv.number} ${format_date(inv.date_invoice)} diff --git a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py index 45178b8c0..d94e92a91 100644 --- a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py +++ b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py @@ -33,6 +33,8 @@ class AccountInvoiceOverdueReminder(models.Model): related='action_id.result_notes', readonly=False) action_mail_id = fields.Many2one( related='action_id.mail_id') + action_mail_cc = fields.Char( + related='action_id.mail_id.email_cc', readonly=True, string='Cc') action_mail_state = fields.Selection( related='action_id.mail_id.state', string='E-mail Status') counter = fields.Integer(readonly=True) diff --git a/account_invoice_overdue_reminder/models/company.py b/account_invoice_overdue_reminder/models/company.py index 65904039c..80b96bd2b 100644 --- a/account_invoice_overdue_reminder/models/company.py +++ b/account_invoice_overdue_reminder/models/company.py @@ -18,6 +18,9 @@ class ResCompany(models.Model): '_overdue_reminder_interface_selection', string='Default Overdue Reminder Wizard Interface', default='onebyone') + overdue_reminder_partner_policy = fields.Selection( + '_overdue_reminder_partner_policy_selection', + default='last_reminder', string='Contact to Remind') @api.model def _overdue_reminder_interface_selection(self): @@ -26,6 +29,14 @@ def _overdue_reminder_interface_selection(self): ('mass', _('Mass')), ] + @api.model + def _overdue_reminder_partner_policy_selection(self): + return [ + ('last_reminder', 'Last Reminder'), + ('last_invoice', 'Last Invoice'), + ('invoice_contact', 'Invoice Contact'), + ] + _sql_constraints = [ ( 'overdue_reminder_start_days_positive', diff --git a/account_invoice_overdue_reminder/models/config_settings.py b/account_invoice_overdue_reminder/models/config_settings.py index 2e2e34541..5c1946286 100644 --- a/account_invoice_overdue_reminder/models/config_settings.py +++ b/account_invoice_overdue_reminder/models/config_settings.py @@ -16,5 +16,6 @@ class ResConfigSettings(models.TransientModel): related='company_id.overdue_reminder_min_interval_days', readonly=False) overdue_reminder_interface = fields.Selection( - related='company_id.overdue_reminder_interface', - readonly=False) + related='company_id.overdue_reminder_interface', readonly=False) + overdue_reminder_partner_policy = fields.Selection( + related='company_id.overdue_reminder_partner_policy', readonly=False) diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_action.py b/account_invoice_overdue_reminder/models/overdue_reminder_action.py index bcb1eb6cf..2ab659902 100644 --- a/account_invoice_overdue_reminder/models/overdue_reminder_action.py +++ b/account_invoice_overdue_reminder/models/overdue_reminder_action.py @@ -17,7 +17,7 @@ class OverdueReminderAction(models.Model): 'res.partner', readonly=True, string='Contact') date = fields.Date( default=fields.Date.context_today, required=True, index=True, - readonly=True) + readonly=False) user_id = fields.Many2one( 'res.users', string='Performed by', required=True, readonly=True, ondelete='restrict', default=lambda self: self.env.user) @@ -32,6 +32,7 @@ class OverdueReminderAction(models.Model): 'mail.mail', string='Reminder E-mail', readonly=True) mail_state = fields.Selection( related='mail_id.state', string='E-mail Status') + mail_cc = fields.Char(related='mail_id.email_cc', readonly=True) company_id = fields.Many2one( 'res.company', string='Company', readonly=True) reminder_count = fields.Integer( diff --git a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml index f4d10d48b..40dea6662 100644 --- a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml +++ b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml @@ -16,12 +16,13 @@ - + + diff --git a/account_invoice_overdue_reminder/views/config_settings.xml b/account_invoice_overdue_reminder/views/config_settings.xml index 2d1cfc876..5f986859f 100644 --- a/account_invoice_overdue_reminder/views/config_settings.xml +++ b/account_invoice_overdue_reminder/views/config_settings.xml @@ -23,6 +23,10 @@
- + + Overdue Reminder Actions + {'search_default_commercial_partner_id': [active_id]} + overdue.reminder.action + + form +
diff --git a/account_invoice_overdue_reminder/wizard/__init__.py b/account_invoice_overdue_reminder/wizard/__init__.py index 62b5c3a6f..c4ac6ccc8 100644 --- a/account_invoice_overdue_reminder/wizard/__init__.py +++ b/account_invoice_overdue_reminder/wizard/__init__.py @@ -1 +1,2 @@ +from . import res_config_settings from . import overdue_reminder_wizard diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py index 0872c1b89..f59161854 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py @@ -1,10 +1,11 @@ -# Copyright 2020 Akretion France (http://www.akretion.com/) +# Copyright 2020-2021 Akretion France (http://www.akretion.com/) # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import api, fields, models, tools, _ from odoo.exceptions import UserError from dateutil.relativedelta import relativedelta +from collections import defaultdict import base64 import logging logger = logging.getLogger(__name__) @@ -18,7 +19,7 @@ class OverdueReminderStart(models.TransientModel): partner_ids = fields.Many2many( 'res.partner', string='Customers', - domain=[('customer', '=', True), ('parent_id', '=', False)]) + domain=[('customer_rank', '>', 0), ('parent_id', '=', False)]) user_ids = fields.Many2many( 'res.users', string='Salesman') payment_ids = fields.Many2many( @@ -37,7 +38,7 @@ class OverdueReminderStart(models.TransientModel): string='I consider that payments are up-to-date') company_id = fields.Many2one( 'res.company', readonly=True, required=True, - default=lambda self: self.env['res.company']._company_default_get()) + default=lambda self: self.env.company) interface = fields.Selection( '_interface_selection', string='Wizard Interface', @@ -59,7 +60,7 @@ def _partner_policy_selection(self): def default_get(self, fields_list): res = super().default_get(fields_list) amo = self.env['account.move'] - company = self.env.user.company_id + company = self.env.company journals = self.env['account.journal'].search([ ('company_id', '=', company.id), ('type', 'in', ('bank', 'cash'))]) @@ -86,8 +87,9 @@ def default_get(self, fields_list): def _prepare_base_domain(self): base_domain = [ ('company_id', '=', self.company_id.id), - ('type', '=', 'out_invoice'), - ('state', '=', 'open'), + ('move_type', '=', 'out_invoice'), + ('state', '=', 'posted'), + ('payment_state', 'not in', ('paid', 'reversed', 'in_payment')), ('no_overdue_reminder', '=', False), ] return base_domain @@ -97,7 +99,7 @@ def _prepare_remind_trigger_domain(self, base_domain): limit_date = today if self.start_days: limit_date -= relativedelta(days=self.start_days) - domain = base_domain + [('date_due', '<', limit_date)] + domain = base_domain + [('invoice_date_due', '<', limit_date)] if self.partner_ids: domain.append(('commercial_partner_id', 'in', self.partner_ids.ids)) if self.user_ids: @@ -116,7 +118,7 @@ def run(self): if self.min_interval_days < 1: raise UserError(_( "The minimum delay since last reminder must be strictly positive.")) - aio = self.env['account.invoice'] + amo = self.env['account.move'] ajo = self.env['account.journal'] rpo = self.env['res.partner'] orso = self.env['overdue.reminder.step'] @@ -141,14 +143,14 @@ def run(self): # whereas search 2 compares due_date to today base_domain = self._prepare_base_domain() domain = self._prepare_remind_trigger_domain(base_domain) - rg_res = aio.read_group( + rg_res = amo.read_group( domain, - ['commercial_partner_id', 'residual_company_signed'], + ['commercial_partner_id', 'amount_residual_signed'], ['commercial_partner_id']) # Sort by residual amount desc rg_res_sorted = sorted( rg_res, - key=lambda to_sort: to_sort['residual_company_signed'], + key=lambda to_sort: to_sort['amount_residual_signed'], reverse=True) action_ids = [] for rg_re in rg_res_sorted: @@ -165,7 +167,7 @@ def run(self): "There are no overdue reminders.")) if self.interface == 'onebyone': xid = MOD + '.overdue_reminder_step_onebyone_action' - action = self.env.ref(xid).read()[0] + action = self.env.ref(xid).sudo().read()[0] action['res_id'] = action_ids[0] elif self.interface == 'mass': action = orso.goto_list_view() @@ -180,10 +182,10 @@ def _prepare_reminder_step( 'Skipping customer %s that has no_overdue_reminder=True', commercial_partner.display_name) return False - invs = self.env['account.invoice'].search( + invs = self.env['account.move'].search( base_domain + [ ('commercial_partner_id', '=', commercial_partner.id), - ('date_due', '<', fields.Date.context_today(self))]) + ('invoice_date_due', '<', fields.Date.context_today(self))]) assert invs # Check min interval if any([ @@ -225,12 +227,12 @@ def _prepare_reminder_step( partner_id = commercial_partner.address_get( ['invoice'])['invoice'] elif self.partner_policy == 'last_invoice': - last_inv = self.env['account.invoice'].search([ + last_inv = self.env['account.move'].search([ ('company_id', '=', self.company_id.id), - ('type', 'in', ('out_invoice', 'out_refund')), + ('move_type', 'in', ('out_invoice', 'out_refund')), ('commercial_partner_id', '=', commercial_partner.id), - ('state', 'in', ('open', 'in_payment', 'paid')), - ], order='date_invoice desc', limit=1) + ('state', '=', 'posted'), + ], order='invoice_date desc', limit=1) partner_id = last_inv.partner_id.id elif self.partner_policy == 'invoice_contact': partner_id = commercial_partner.address_get( @@ -298,10 +300,10 @@ class OverdueReminderStep(models.TransientModel): 'res.users', string='Assigned to', default=lambda self: self.env.user) letter_printed = fields.Boolean(readonly=True) invoice_ids = fields.Many2many( - 'account.invoice', string='Overdue Invoices', readonly=True) + 'account.move', string='Overdue Invoices', readonly=True) company_id = fields.Many2one( 'res.company', readonly=True, required=True, - default=lambda self: self.env['res.company']._company_default_get()) + default=lambda self: self.env.company) warn_unreconciled_move_line_ids = fields.Many2many( 'account.move.line', string='Unreconciled Payments/Refunds', readonly=True) @@ -321,27 +323,22 @@ def _reminder_type_selection(self): @api.model def create(self, vals): - action = super().create(vals) + step = super().create(vals) commercial_partner = self.env['res.partner'].browse( vals['commercial_partner_id']) xmlid = MOD + '.overdue_invoice_reminder_mail_template' mail_tpl = self.env.ref(xmlid) mail_tpl_lang = mail_tpl.with_context(lang=commercial_partner.lang or 'en_US') mail_subject = mail_tpl_lang._render_template( - mail_tpl_lang.subject, self._name, action.id) + mail_tpl_lang.subject, self._name, [step.id])[step.id] mail_body = mail_tpl_lang._render_template( - mail_tpl_lang.body_html, self._name, action.id) - if mail_tpl.user_signature: - signature = self.env.user.signature - if signature: - mail_body = tools.append_content_to_html( - mail_body, signature, plaintext=False) + mail_tpl_lang.body_html, self._name, [step.id])[step.id] mail_body = tools.html_sanitize(mail_body) - action.write({ + step.write({ 'mail_subject': mail_subject, 'mail_body': mail_body, }) - return action + return step @api.onchange('reminder_type') def reminder_type_change(self): @@ -358,16 +355,16 @@ def next(self): ('company_id', '=', self.company_id.id)], limit=1) if left: action = self.env.ref( - MOD + '.overdue_reminder_step_onebyone_action').read()[0] + MOD + '.overdue_reminder_step_onebyone_action').sudo().read()[0] action['res_id'] = left.id else: action = self.env.ref( - MOD + '.overdue_reminder_end_action').read()[0] + MOD + '.overdue_reminder_end_action').sudo().read()[0] return action def goto_list_view(self): action = self.env.ref( - MOD + '.overdue_reminder_step_mass_action').read()[0] + MOD + '.overdue_reminder_step_mass_action').sudo().read()[0] return action def skip(self): @@ -404,7 +401,7 @@ def _prepare_mail_activity(self): def check_warnings(self): self.ensure_one() for rec in self: - if rec.company_id != self.env.user.company_id: + if rec.company_id != self.env.company: raise UserError(_( "User company is different from action company. " "This should never happen.")) @@ -455,7 +452,8 @@ def validate_mail(self): if not self.mail_body: raise UserError(_('Mail body is empty.')) xmlid = MOD + '.overdue_invoice_reminder_mail_template' - mvals = self.env.ref(xmlid).generate_email(self.id) + mvals = self.env.ref(xmlid).generate_email( + self.id, ['email_from', 'email_to', 'partner_to', 'reply_to']) cc_list = [p.email for p in self.mail_cc_partner_ids if p.email] if mvals.get('email_cc'): cc_list.append(mvals['email_cc']) @@ -475,7 +473,7 @@ def validate_mail(self): attachment_ids = [] for inv in self.invoice_ids: if inv_report.report_type in ('qweb-html', 'qweb-pdf'): - report_bin, report_format = inv_report.render_qweb_pdf([inv.id]) + report_bin, report_format = inv_report._render_qweb_pdf([inv.id]) else: res = inv_report.render([inv.id]) if not res: @@ -483,11 +481,9 @@ def validate_mail(self): "Report format '%s' is not supported.") % inv_report.report_type) report_bin, report_format = res - # WARN : update when backporting filename = '%s.%s' % (inv._get_report_base_filename(), report_format) attach = iao.create({ 'name': filename, - 'datas_fname': filename, 'datas': base64.b64encode(report_bin), 'res_model': 'mail.message', 'res_id': mail.mail_message_id.id, @@ -547,12 +543,9 @@ def print_invoices(self): def total_residual(self): self.ensure_one() - res = {} + res = defaultdict(float) for inv in self.invoice_ids: - if inv.currency_id in res: - res[inv.currency_id] += inv.residual_signed - else: - res[inv.currency_id] = inv.residual_signed + res[inv.currency_id] += inv.amount_residual * (inv.move_type == 'out_refund' and -1 or 1) return res.items() def _get_report_base_filename(self): diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml index 292e5f41f..ca077259c 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml @@ -1,13 +1,12 @@ - overdue.reminder.start.form overdue.reminder.start @@ -58,7 +57,7 @@ new - + overdue.reminder.step.form @@ -83,23 +82,25 @@ - - + + - - - - - + + + + + - + + - + + @@ -166,7 +167,6 @@ [('state', '=', 'draft'), ('user_id', '=', uid)] - overdue.reminder.end.form overdue.reminder.end @@ -208,36 +208,34 @@ - - - - - + + Change Reminder Type + overdue.reminder.mass.update + form + {'default_update_action': 'reminder_type'} + + list + new + + + Validate + overdue.reminder.mass.update + form + {'default_update_action': 'validate'} + + list + new + + + Skip + overdue.reminder.mass.update + form + {'default_update_action': 'skip'} + + list + new + diff --git a/account_invoice_overdue_reminder/models/config_settings.py b/account_invoice_overdue_reminder/wizard/res_config_settings.py similarity index 93% rename from account_invoice_overdue_reminder/models/config_settings.py rename to account_invoice_overdue_reminder/wizard/res_config_settings.py index 5c1946286..4f71cb136 100644 --- a/account_invoice_overdue_reminder/models/config_settings.py +++ b/account_invoice_overdue_reminder/wizard/res_config_settings.py @@ -1,4 +1,4 @@ -# Copyright 2020 Akretion France (http://www.akretion.com/) +# Copyright 2020-2021 Akretion France (http://www.akretion.com/) # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/account_invoice_overdue_reminder/views/config_settings.xml b/account_invoice_overdue_reminder/wizard/res_config_settings_view.xml similarity index 65% rename from account_invoice_overdue_reminder/views/config_settings.xml rename to account_invoice_overdue_reminder/wizard/res_config_settings_view.xml index 5f986859f..a9ea73deb 100644 --- a/account_invoice_overdue_reminder/views/config_settings.xml +++ b/account_invoice_overdue_reminder/wizard/res_config_settings_view.xml @@ -1,6 +1,6 @@ @@ -13,31 +13,37 @@ res.config.settings - +

Overdue Invoice Reminder

-
-
+
+
+ +
-
+
+
+
+
+
+
-
-
-
-
From ceade90b564f6e9e48d128dbf9ca17caa6df96d7 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 11 Feb 2021 19:04:15 +0100 Subject: [PATCH 012/116] account_invoice_overdue_reminder: black, isort and other reformatting --- .../__manifest__.py | 50 +- .../data/mail_template.xml | 18 +- .../data/overdue_reminder_result.xml | 3 +- .../account_invoice_overdue_reminder.py | 70 +- .../models/account_move.py | 75 +- .../models/overdue_reminder_action.py | 91 ++- .../models/overdue_reminder_result.py | 13 +- .../models/res_company.py | 56 +- .../models/res_partner.py | 5 +- .../readme/CONFIGURATION.rst | 2 +- .../security/ir.model.access.csv | 1 - .../security/ir_rule.xml | 9 +- .../account_invoice_overdue_reminder.xml | 136 +++- .../views/account_move.xml | 43 +- .../views/overdue_reminder_action.xml | 110 ++- .../views/overdue_reminder_result.xml | 33 +- .../views/report.xml | 11 +- .../views/report_overdue_reminder.xml | 70 +- .../views/res_partner.xml | 15 +- .../wizard/overdue_reminder_wizard.py | 766 ++++++++++-------- .../wizard/overdue_reminder_wizard_view.xml | 238 ++++-- .../wizard/res_config_settings.py | 18 +- .../wizard/res_config_settings_view.xml | 66 +- 23 files changed, 1159 insertions(+), 740 deletions(-) diff --git a/account_invoice_overdue_reminder/__manifest__.py b/account_invoice_overdue_reminder/__manifest__.py index ab1c08a22..0abe4aa44 100644 --- a/account_invoice_overdue_reminder/__manifest__.py +++ b/account_invoice_overdue_reminder/__manifest__.py @@ -3,30 +3,30 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'Overdue Invoice Reminder', - 'version': '14.0.1.0.0', - 'category': 'Accounting', - 'license': 'AGPL-3', - 'summary': 'Simple mail/letter/phone overdue customer invoice reminder ', - 'author': 'Akretion,Odoo Community Association (OCA)', - 'maintainers': ['alexis-via'], - 'website': 'https://github.com/OCA/credit-control', - 'depends': ['account'], - 'data': [ - 'security/ir.model.access.csv', - 'security/ir_rule.xml', - 'wizard/overdue_reminder_wizard_view.xml', - 'views/res_partner.xml', - 'views/report.xml', - 'views/report_overdue_reminder.xml', - 'views/account_move.xml', - 'views/account_invoice_overdue_reminder.xml', - 'views/overdue_reminder_result.xml', - 'views/overdue_reminder_action.xml', - 'wizard/res_config_settings_view.xml', - 'data/overdue_reminder_result.xml', - 'data/mail_template.xml', + "name": "Overdue Invoice Reminder", + "version": "14.0.1.0.0", + "category": "Accounting", + "license": "AGPL-3", + "summary": "Simple mail/letter/phone overdue customer invoice reminder ", + "author": "Akretion,Odoo Community Association (OCA)", + "maintainers": ["alexis-via"], + "website": "https://github.com/OCA/credit-control", + "depends": ["account"], + "data": [ + "security/ir.model.access.csv", + "security/ir_rule.xml", + "wizard/overdue_reminder_wizard_view.xml", + "views/res_partner.xml", + "views/report.xml", + "views/report_overdue_reminder.xml", + "views/account_move.xml", + "views/account_invoice_overdue_reminder.xml", + "views/overdue_reminder_result.xml", + "views/overdue_reminder_action.xml", + "wizard/res_config_settings_view.xml", + "data/overdue_reminder_result.xml", + "data/mail_template.xml", ], - 'installable': True, - 'application': True, + "installable": True, + "application": True, } diff --git a/account_invoice_overdue_reminder/data/mail_template.xml b/account_invoice_overdue_reminder/data/mail_template.xml index fb6c5906b..d0b893a2b 100644 --- a/account_invoice_overdue_reminder/data/mail_template.xml +++ b/account_invoice_overdue_reminder/data/mail_template.xml @@ -1,22 +1,28 @@ - + - Overdue Invoice Reminder - - + + ${object.partner_id.lang} ${object.user_id.email or object.company_id.email} ${object.partner_id.email} - ${object.company_id.name} - Overdue invoice reminder n°${object.counter} - ${object.company_id.name} - Overdue invoice reminder n°${object.counter} +

Dear customer,

diff --git a/account_invoice_overdue_reminder/data/overdue_reminder_result.xml b/account_invoice_overdue_reminder/data/overdue_reminder_result.xml index 548b6388f..5e4d5c5f1 100644 --- a/account_invoice_overdue_reminder/data/overdue_reminder_result.xml +++ b/account_invoice_overdue_reminder/data/overdue_reminder_result.xml @@ -1,10 +1,9 @@ - + - diff --git a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py index ef0b14a27..98bdf925e 100644 --- a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py +++ b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py @@ -2,62 +2,64 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError class AccountInvoiceOverdueReminder(models.Model): - _name = 'account.invoice.overdue.reminder' - _description = 'Overdue Invoice Reminder Action History' - _order = 'id desc' + _name = "account.invoice.overdue.reminder" + _description = "Overdue Invoice Reminder Action History" + _order = "id desc" # For the link to invoice: why a M2O and not a M2M ? # Because of the "counter" field: a single reminder action for a customer, # the "counter" may not be the same for each invoice invoice_id = fields.Many2one( - 'account.move', string='Invoice', ondelete='cascade', readonly=True) + "account.move", string="Invoice", ondelete="cascade", readonly=True + ) action_id = fields.Many2one( - 'overdue.reminder.action', string='Overdue Reminder Action', - ondelete='cascade') + "overdue.reminder.action", string="Overdue Reminder Action", ondelete="cascade" + ) action_commercial_partner_id = fields.Many2one( - related='action_id.commercial_partner_id', store=True) - action_partner_id = fields.Many2one( - related='action_id.partner_id', store=True) - action_date = fields.Date(related='action_id.date', store=True) - action_user_id = fields.Many2one(related='action_id.user_id') + related="action_id.commercial_partner_id", store=True + ) + action_partner_id = fields.Many2one(related="action_id.partner_id", store=True) + action_date = fields.Date(related="action_id.date", store=True) + action_user_id = fields.Many2one(related="action_id.user_id") action_reminder_type = fields.Selection( - related='action_id.reminder_type', store=True) - action_result_id = fields.Many2one( - related='action_id.result_id', readonly=False) - action_result_notes = fields.Text( - related='action_id.result_notes', readonly=False) - action_mail_id = fields.Many2one( - related='action_id.mail_id') + related="action_id.reminder_type", store=True + ) + action_result_id = fields.Many2one(related="action_id.result_id", readonly=False) + action_result_notes = fields.Text(related="action_id.result_notes", readonly=False) + action_mail_id = fields.Many2one(related="action_id.mail_id") action_mail_cc = fields.Char( - related='action_id.mail_id.email_cc', readonly=True, string='Cc') + related="action_id.mail_id.email_cc", readonly=True, string="Cc" + ) action_mail_state = fields.Selection( - related='action_id.mail_id.state', string='E-mail Status') + related="action_id.mail_id.state", string="E-mail Status" + ) counter = fields.Integer(readonly=True) - company_id = fields.Many2one( - related='invoice_id.company_id', store=True) + company_id = fields.Many2one(related="invoice_id.company_id", store=True) - _sql_constraints = [( - 'counter_positive', - 'CHECK(counter >= 0)', - 'Counter must always be positive')] + _sql_constraints = [ + ("counter_positive", "CHECK(counter >= 0)", "Counter must always be positive") + ] - @api.constrains('invoice_id') + @api.constrains("invoice_id") def invoice_id_check(self): for action in self: - if action.invoice_id and action.invoice_id.move_type != 'out_invoice': - raise ValidationError(_( - "An overdue reminder can only be attached " - "to a customer invoice")) + if action.invoice_id and action.invoice_id.move_type != "out_invoice": + raise ValidationError( + _( + "An overdue reminder can only be attached " + "to a customer invoice" + ) + ) - @api.depends('invoice_id', 'counter') + @api.depends("invoice_id", "counter") def name_get(self): res = [] for rec in self: - name = _('%s Reminder %d') % (rec.invoice_id.name, rec.counter) + name = _("%s Reminder %d") % (rec.invoice_id.name, rec.counter) res.append((rec.id, name)) return res diff --git a/account_invoice_overdue_reminder/models/account_move.py b/account_invoice_overdue_reminder/models/account_move.py index 9776ba5d1..3c1716786 100644 --- a/account_invoice_overdue_reminder/models/account_move.py +++ b/account_invoice_overdue_reminder/models/account_move.py @@ -6,56 +6,71 @@ class AccountMove(models.Model): - _inherit = 'account.move' + _inherit = "account.move" no_overdue_reminder = fields.Boolean( - string='Disable Overdue Reminder', - tracking=True) + string="Disable Overdue Reminder", tracking=True + ) overdue_reminder_ids = fields.One2many( - 'account.invoice.overdue.reminder', - 'invoice_id', - string='Overdue Reminder Action History') + "account.invoice.overdue.reminder", + "invoice_id", + string="Overdue Reminder Action History", + ) overdue_reminder_last_date = fields.Date( - compute='_compute_overdue_reminder', - string='Last Overdue Reminder Date', store=True) + compute="_compute_overdue_reminder", + string="Last Overdue Reminder Date", + store=True, + ) overdue_reminder_counter = fields.Integer( - string='Overdue Reminder Count', store=True, - compute='_compute_overdue_reminder', - help="This counter is not increased in case of phone reminder.") - overdue = fields.Boolean(compute='_compute_overdue') + string="Overdue Reminder Count", + store=True, + compute="_compute_overdue_reminder", + help="This counter is not increased in case of phone reminder.", + ) + overdue = fields.Boolean(compute="_compute_overdue") - _sql_constraints = [( - 'counter_positive', - 'CHECK(overdue_reminder_counter >= 0)', - 'Overdue Invoice Counter must always be positive')] + _sql_constraints = [ + ( + "counter_positive", + "CHECK(overdue_reminder_counter >= 0)", + "Overdue Invoice Counter must always be positive", + ) + ] - @api.depends('move_type', 'state', 'payment_state', 'invoice_date_due') + @api.depends("move_type", "state", "payment_state", "invoice_date_due") def _compute_overdue(self): today = fields.Date.context_today(self) for move in self: overdue = False if ( - move.move_type == 'out_invoice' and - move.state == 'posted' and - move.payment_state not in ('paid', 'reversed', 'in_payment') and - move.invoice_date_due < today): + move.move_type == "out_invoice" + and move.state == "posted" + and move.payment_state not in ("paid", "reversed", "in_payment") + and move.invoice_date_due < today + ): overdue = True move.overdue = overdue @api.depends( - 'overdue_reminder_ids.action_id.date', - 'overdue_reminder_ids.counter', - 'overdue_reminder_ids.action_id.reminder_type') + "overdue_reminder_ids.action_id.date", + "overdue_reminder_ids.counter", + "overdue_reminder_ids.action_id.reminder_type", + ) def _compute_overdue_reminder(self): - aioro = self.env['account.invoice.overdue.reminder'] + aioro = self.env["account.invoice.overdue.reminder"] for move in self: reminder = aioro.search( - [('invoice_id', '=', move.id)], order='action_date desc', limit=1) + [("invoice_id", "=", move.id)], order="action_date desc", limit=1 + ) date = reminder and reminder.action_date or False - counter_reminder = aioro.search([ - ('invoice_id', '=', move.id), - ('action_reminder_type', 'in', ('mail', 'post'))], - order='action_date desc, id desc', limit=1) + counter_reminder = aioro.search( + [ + ("invoice_id", "=", move.id), + ("action_reminder_type", "in", ("mail", "post")), + ], + order="action_date desc, id desc", + limit=1, + ) counter = counter_reminder and counter_reminder.counter or False move.overdue_reminder_last_date = date move.overdue_reminder_counter = counter diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_action.py b/account_invoice_overdue_reminder/models/overdue_reminder_action.py index 401146d7e..a5c15e5e4 100644 --- a/account_invoice_overdue_reminder/models/overdue_reminder_action.py +++ b/account_invoice_overdue_reminder/models/overdue_reminder_action.py @@ -2,66 +2,81 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models class OverdueReminderAction(models.Model): - _name = 'overdue.reminder.action' - _description = 'Overdue Reminder Action History' - _order = 'date desc, id desc' + _name = "overdue.reminder.action" + _description = "Overdue Reminder Action History" + _order = "date desc, id desc" commercial_partner_id = fields.Many2one( - 'res.partner', readonly=True, string='Customer', index=True, - domain=[('parent_id', '=', False)]) - partner_id = fields.Many2one( - 'res.partner', readonly=True, string='Contact') + "res.partner", + readonly=True, + string="Customer", + index=True, + domain=[("parent_id", "=", False)], + ) + partner_id = fields.Many2one("res.partner", readonly=True, string="Contact") date = fields.Date( - default=fields.Date.context_today, required=True, index=True, - readonly=False) + default=fields.Date.context_today, required=True, index=True, readonly=False + ) user_id = fields.Many2one( - 'res.users', string='Performed by', required=True, readonly=True, - ondelete='restrict', default=lambda self: self.env.user) + "res.users", + string="Performed by", + required=True, + readonly=True, + ondelete="restrict", + default=lambda self: self.env.user, + ) reminder_type = fields.Selection( - '_reminder_type_selection', default='mail', string='Type', - required=True, readonly=True) + "_reminder_type_selection", + default="mail", + string="Type", + required=True, + readonly=True, + ) result_id = fields.Many2one( - 'overdue.reminder.result', ondelete='restrict', - string='Info/Result') - result_notes = fields.Text(string='Info/Result Notes') - mail_id = fields.Many2one( - 'mail.mail', string='Reminder E-mail', readonly=True) - mail_state = fields.Selection( - related='mail_id.state', string='E-mail Status') - mail_cc = fields.Char(related='mail_id.email_cc', readonly=True) - company_id = fields.Many2one( - 'res.company', string='Company', readonly=True) + "overdue.reminder.result", ondelete="restrict", string="Info/Result" + ) + result_notes = fields.Text(string="Info/Result Notes") + mail_id = fields.Many2one("mail.mail", string="Reminder E-mail", readonly=True) + mail_state = fields.Selection(related="mail_id.state", string="E-mail Status") + mail_cc = fields.Char(related="mail_id.email_cc", readonly=True) + company_id = fields.Many2one("res.company", string="Company", readonly=True) reminder_count = fields.Integer( - compute='_compute_invoice_count', store=True, string='Number of invoices') + compute="_compute_invoice_count", store=True, string="Number of invoices" + ) reminder_ids = fields.One2many( - 'account.invoice.overdue.reminder', 'action_id', readonly=True) + "account.invoice.overdue.reminder", "action_id", readonly=True + ) @api.model def _reminder_type_selection(self): return [ - ('mail', _('E-mail')), - ('phone', _('Phone')), - ('post', _('Letter')), - ] + ("mail", _("E-mail")), + ("phone", _("Phone")), + ("post", _("Letter")), + ] - @api.depends('reminder_ids') + @api.depends("reminder_ids") def _compute_invoice_count(self): - rg_res = self.env['account.invoice.overdue.reminder'].read_group( - [('action_id', 'in', self.ids), ('invoice_id', '!=', False)], - ['action_id'], ['action_id']) - mapped_data = dict([(x['action_id'][0], x['action_id_count']) for x in rg_res]) + rg_res = self.env["account.invoice.overdue.reminder"].read_group( + [("action_id", "in", self.ids), ("invoice_id", "!=", False)], + ["action_id"], + ["action_id"], + ) + mapped_data = {x["action_id"][0]: x["action_id_count"] for x in rg_res} for rec in self: rec.reminder_count = mapped_data.get(rec.id, 0) - @api.depends('commercial_partner_id', 'date') + @api.depends("commercial_partner_id", "date") def name_get(self): res = [] for action in self: - name = _('%s, Reminder %s') % ( - action.commercial_partner_id.display_name, action.date) + name = _("%s, Reminder %s") % ( + action.commercial_partner_id.display_name, + action.date, + ) res.append((action.id, name)) return res diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_result.py b/account_invoice_overdue_reminder/models/overdue_reminder_result.py index d6c705353..d246250e3 100644 --- a/account_invoice_overdue_reminder/models/overdue_reminder_result.py +++ b/account_invoice_overdue_reminder/models/overdue_reminder_result.py @@ -6,15 +6,14 @@ class OverdueReminderResult(models.Model): - _name = 'overdue.reminder.result' - _description = 'Overdue Invoice Reminder Result/Info' - _order = 'sequence, id desc' + _name = "overdue.reminder.result" + _description = "Overdue Invoice Reminder Result/Info" + _order = "sequence, id desc" name = fields.Char(required=True, translate=True) active = fields.Boolean(default=True) sequence = fields.Integer() - _sql_constraints = [( - 'name_unique', - 'unique(name)', - 'This overdue reminder result already exists')] + _sql_constraints = [ + ("name_unique", "unique(name)", "This overdue reminder result already exists") + ] diff --git a/account_invoice_overdue_reminder/models/res_company.py b/account_invoice_overdue_reminder/models/res_company.py index fcd0a684a..73c715810 100644 --- a/account_invoice_overdue_reminder/models/res_company.py +++ b/account_invoice_overdue_reminder/models/res_company.py @@ -2,48 +2,56 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models class ResCompany(models.Model): - _inherit = 'res.company' + _inherit = "res.company" overdue_reminder_attach_invoice = fields.Boolean( - string='Attach Invoices to Overdue Reminder E-mails', default=True) + string="Attach Invoices to Overdue Reminder E-mails", default=True + ) overdue_reminder_start_days = fields.Integer( - string='Default Overdue Reminder Trigger Delay (days)') + string="Default Overdue Reminder Trigger Delay (days)" + ) overdue_reminder_min_interval_days = fields.Integer( - string='Default Overdue Reminder Minimum Interval (days)', default=5) + string="Default Overdue Reminder Minimum Interval (days)", default=5 + ) overdue_reminder_interface = fields.Selection( - '_overdue_reminder_interface_selection', - string='Default Overdue Reminder Wizard Interface', - default='onebyone') + "_overdue_reminder_interface_selection", + string="Default Overdue Reminder Wizard Interface", + default="onebyone", + ) overdue_reminder_partner_policy = fields.Selection( - '_overdue_reminder_partner_policy_selection', - default='last_reminder', string='Contact to Remind') + "_overdue_reminder_partner_policy_selection", + default="last_reminder", + string="Contact to Remind", + ) @api.model def _overdue_reminder_interface_selection(self): return [ - ('onebyone', _('One by One')), - ('mass', _('Mass')), - ] + ("onebyone", _("One by One")), + ("mass", _("Mass")), + ] @api.model def _overdue_reminder_partner_policy_selection(self): return [ - ('last_reminder', _('Last Reminder')), - ('last_invoice', _('Last Invoice')), - ('invoice_contact', _('Invoice Contact')), - ] + ("last_reminder", _("Last Reminder")), + ("last_invoice", _("Last Invoice")), + ("invoice_contact", _("Invoice Contact")), + ] _sql_constraints = [ ( - 'overdue_reminder_start_days_positive', - 'CHECK(overdue_reminder_start_days >= 0)', - 'Overdue Reminder Trigger Delay must always be positive'), + "overdue_reminder_start_days_positive", + "CHECK(overdue_reminder_start_days >= 0)", + "Overdue Reminder Trigger Delay must always be positive", + ), ( - 'overdue_reminder_min_interval_days_positive', - 'CHECK(overdue_reminder_min_interval_days > 0)', - 'Overdue Reminder Trigger Delay must always be strictly positive'), - ] + "overdue_reminder_min_interval_days_positive", + "CHECK(overdue_reminder_min_interval_days > 0)", + "Overdue Reminder Trigger Delay must always be strictly positive", + ), + ] diff --git a/account_invoice_overdue_reminder/models/res_partner.py b/account_invoice_overdue_reminder/models/res_partner.py index 90cba9cf7..1b6a6d717 100644 --- a/account_invoice_overdue_reminder/models/res_partner.py +++ b/account_invoice_overdue_reminder/models/res_partner.py @@ -6,8 +6,9 @@ class ResPartner(models.Model): - _inherit = 'res.partner' + _inherit = "res.partner" # Property of commercial partner, applies for the whole entity no_overdue_reminder = fields.Boolean( - string='Disable Overdue Invoice Reminder', company_dependent=True) + string="Disable Overdue Invoice Reminder", company_dependent=True + ) diff --git a/account_invoice_overdue_reminder/readme/CONFIGURATION.rst b/account_invoice_overdue_reminder/readme/CONFIGURATION.rst index 8ddc48931..45b71ca32 100644 --- a/account_invoice_overdue_reminder/readme/CONFIGURATION.rst +++ b/account_invoice_overdue_reminder/readme/CONFIGURATION.rst @@ -1,4 +1,4 @@ -You should increase the **osv_memory_age_limit** (default value = 1, which means 1 hour) in the Odoo server config file: for example, you can set it to 12 (12 hours). The value must be superior to the duration of the invoicing reminder wizard from the start screen to the end. +You should increase the **transient_age_limit** (default value = 1, which means 1 hour) in the Odoo server config file: for example, you can set it to 12 (12 hours). The value must be superior to the duration of the invoicing reminder wizard from the start screen to the end. Go to the menu *Invoicing > Configuration > Settings* then go to the section *Overdue Invoice Reminder*: you will be able to configure if you want to attach the overdue invoice to the reminder emails and set default values for some parameters. diff --git a/account_invoice_overdue_reminder/security/ir.model.access.csv b/account_invoice_overdue_reminder/security/ir.model.access.csv index 9c2540cc8..91a3322f3 100644 --- a/account_invoice_overdue_reminder/security/ir.model.access.csv +++ b/account_invoice_overdue_reminder/security/ir.model.access.csv @@ -10,4 +10,3 @@ access_overdue_reminder_start_payment,Full access on overdue.reminder.start.paym access_overdue_reminder_step,Full access on overdue.reminder.step (wizard),model_overdue_reminder_step,account.group_account_invoice,1,1,1,1 access_overdue_reminder_end,Full access on overdue.reminder.end (wizard),model_overdue_reminder_end,account.group_account_invoice,1,1,1,1 access_overdue_reminder_mass_update,Full access on overdue.reminder.mass.update (wizard),model_overdue_reminder_mass_update,account.group_account_invoice,1,1,1,1 - diff --git a/account_invoice_overdue_reminder/security/ir_rule.xml b/account_invoice_overdue_reminder/security/ir_rule.xml index 607756400..45c3a62d7 100644 --- a/account_invoice_overdue_reminder/security/ir_rule.xml +++ b/account_invoice_overdue_reminder/security/ir_rule.xml @@ -1,17 +1,18 @@ - + - Overdue Invoice Reminder multi-company - - ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] diff --git a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml index 8987b1d99..b434e6d11 100644 --- a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml +++ b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml @@ -1,10 +1,9 @@ - + - @@ -14,20 +13,38 @@
- - - - - - - - - - + + + + + + + + + + - - + +
@@ -40,9 +57,12 @@
- - - + + +
@@ -53,14 +73,26 @@ account.invoice.overdue.reminder - - - - - - - - + + + + + + + +
@@ -71,8 +103,8 @@ 100 - - + + @@ -82,18 +114,46 @@ account.invoice.overdue.reminder - - - - - - - + + + + + + + - - - - + + + + diff --git a/account_invoice_overdue_reminder/views/account_move.xml b/account_invoice_overdue_reminder/views/account_move.xml index a0202b1e2..bebac21d0 100644 --- a/account_invoice_overdue_reminder/views/account_move.xml +++ b/account_invoice_overdue_reminder/views/account_move.xml @@ -1,34 +1,41 @@ - + - overdue.reminder.customer.invoice.form account.move - + - + - - - - + + + + - + @@ -37,10 +44,10 @@ account.move - + - + @@ -48,11 +55,15 @@ overdue.reminder.customer.invoice.search account.move - + - - + + diff --git a/account_invoice_overdue_reminder/views/overdue_reminder_action.xml b/account_invoice_overdue_reminder/views/overdue_reminder_action.xml index cb8bdfaa5..a1d80ab33 100644 --- a/account_invoice_overdue_reminder/views/overdue_reminder_action.xml +++ b/account_invoice_overdue_reminder/views/overdue_reminder_action.xml @@ -1,10 +1,9 @@ - + - @@ -14,22 +13,34 @@
- - - - - - - - + + + + + + + + - - + + - +
@@ -40,11 +51,17 @@ overdue.reminder.action - - - - - + + + + +
@@ -54,16 +71,40 @@ overdue.reminder.action - - - - - - + + + + + + - - - + + + @@ -74,8 +115,8 @@ overdue.reminder.action - - + + @@ -85,7 +126,7 @@ overdue.reminder.action - + @@ -97,6 +138,11 @@ {'pivot_measures': ['__count', 'reminder_count']} - +
diff --git a/account_invoice_overdue_reminder/views/overdue_reminder_result.xml b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml index 90ebde524..e6a2f0c50 100644 --- a/account_invoice_overdue_reminder/views/overdue_reminder_result.xml +++ b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml @@ -1,10 +1,9 @@ - + - @@ -14,10 +13,15 @@
- + - - + +
@@ -29,8 +33,8 @@ overdue.reminder.result - - + + @@ -40,8 +44,12 @@ overdue.reminder.result - - + + @@ -52,6 +60,11 @@ tree,form - +
diff --git a/account_invoice_overdue_reminder/views/report.xml b/account_invoice_overdue_reminder/views/report.xml index af5ed4bd4..df63c5ea1 100644 --- a/account_invoice_overdue_reminder/views/report.xml +++ b/account_invoice_overdue_reminder/views/report.xml @@ -1,18 +1,21 @@ - + - Overdue Letter overdue.reminder.step qweb-pdf - account_invoice_overdue_reminder.report_overdue_reminder - account_invoice_overdue_reminder.report_overdue_reminder + account_invoice_overdue_reminder.report_overdue_reminder + account_invoice_overdue_reminder.report_overdue_reminder (object._get_report_base_filename()) diff --git a/account_invoice_overdue_reminder/views/report_overdue_reminder.xml b/account_invoice_overdue_reminder/views/report_overdue_reminder.xml index 77154e072..2bd040f2a 100644 --- a/account_invoice_overdue_reminder/views/report_overdue_reminder.xml +++ b/account_invoice_overdue_reminder/views/report_overdue_reminder.xml @@ -1,15 +1,20 @@ - + - + diff --git a/account_invoice_overdue_reminder/views/res_partner.xml b/account_invoice_overdue_reminder/views/res_partner.xml index 058cec640..54edc71a6 100644 --- a/account_invoice_overdue_reminder/views/res_partner.xml +++ b/account_invoice_overdue_reminder/views/res_partner.xml @@ -5,33 +5,31 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> - - - - overdue.reminder.res.partner.form - res.partner - - - - + overdue.reminder.res.partner.form + res.partner + + + + - - + + + - - - - - - Overdue Reminder Actions - {'search_default_commercial_partner_id': [active_id]} - overdue.reminder.action - - form - - + + + + Overdue Reminder Actions + {'search_default_commercial_partner_id': [active_id]} + overdue.reminder.action + + form + diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py index 21c2c63c5..00da1174e 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py @@ -540,7 +540,7 @@ def _get_attachment_ids(self, mail): report_bin, report_format = iaro._render( "account.report_invoice_with_payments", [inv.id] ) - filename = "{}.{}".format(inv._get_report_base_filename(), report_format) + filename = f"{inv._get_report_base_filename()}.{report_format}" attach = iao.create( { "name": filename, diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml index 02be1408f..788949a12 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml @@ -5,310 +5,329 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> - - - overdue.reminder.start.form - overdue.reminder.start - -
- - - - - - - -
\n" " " msgstr "" -"
\n" -"

Spettabile cliente,

\n" -"

secondo i nostri registri, la seguente fattura è " -"scaduta:

\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Numero fatturaData fatturaTermini di pagamentoScadenzaRif. ordineTipoTotale nettoTotaleResiduoPromemoria antecedenti
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" Totale\n" -" residuo in\n" -" :\n" -" \n" -" \n" -"
\n" -"\n" -"

Se avete effettuato un pagamento per questa fattura " -"alcuni giorni fa, ignorate questa e-mail.

\n" -"\n" -" \n" -"

Troverà in allegato la fattura scaduta.

\n" -"
\n" -"\n" -" \n" -"

Nonostante diversi promemoria, siamo dispiaciuti nel " -"vedere che queste fatture scadute sono ancora\n" -" insolute.\n" -" Per evitare procedimenti legali, La sollecitiamo a " -"saldare queste fatture scadute nei prossimi\n" -" giorni.\n" -"

\n" -"
\n" -"\n" -"

Cordialmente,

\n" -"\n" -" \n" -"

\n" -" \n" -"

\n" -"
\n" -"\n" -"
\n" -" " + +#. module: account_invoice_overdue_reminder +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings +msgid " days" +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder by phone. Result/Info: %(result)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "" +"Overdue reminder sent by mail: %(mail_subject)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder sent by post." +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -332,7 +221,6 @@ msgstr "Importo dovuto" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format msgid "" "An overdue reminder can only be attached to a customer invoice or credit note" msgstr "" @@ -523,14 +411,14 @@ msgstr "Gentile Cliente," #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days -msgid "Default Overdue Reminder Minimum Interval (days)" -msgstr "Intervallo minimo predefinito per sollecito (giorni)" +msgid "Default Overdue Reminder Minimum Interval" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days -msgid "Default Overdue Reminder Trigger Delay (days)" -msgstr "Ritardo predefinito per attivazione del sollecito (giorni)" +msgid "Default Overdue Reminder Trigger Delay" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -539,19 +427,16 @@ msgid "Default Overdue Reminder Wizard Interface" msgstr "Interfaccia procedura guidata per sollecito predefinito" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Minimum Interval" -msgstr "Intervallo minimo predefinito per sollecito" - -#. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Trigger Delay" -msgstr "Ritardo predefinito attivazione promemoria" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days +msgid "Default overdue reminder minimum interval in days" +msgstr "" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Wizard Interface" -msgstr "Interfaccia predefinita procedura guidata" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days +msgid "Default overdue reminder trigger delay in days" +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -573,7 +458,6 @@ msgstr "Disabilitare solleciti fatture scadute" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__no_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__no_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__no_overdue_reminder msgid "Disable Overdue Reminder" msgstr "Disabilitare sollecito" @@ -608,7 +492,7 @@ msgstr "Scadenza" #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "E-mail" msgstr "E-mail" @@ -621,7 +505,6 @@ msgstr "Stato e-mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "E-mail missing on partner '%s'." msgstr "E-mail mancante sul partner '%s'." @@ -638,7 +521,6 @@ msgstr "Filtri" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', the deadline is missing for the activity." msgstr "Per il sollecito del cliente '%s', manca la scadenza per l'attività." @@ -646,7 +528,6 @@ msgstr "Per il sollecito del cliente '%s', manca la scadenza per l'attività." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', you must assign someone for the activity." msgstr "" @@ -655,7 +536,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Good job!" msgstr "Ottimo lavoro!" @@ -707,7 +587,6 @@ msgstr "Fattura" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Invoice Contact" msgstr "Contatto fattura" @@ -797,25 +676,12 @@ msgstr "Ultima registrazione creata il" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Last Invoice" msgstr "Ultima fattura" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_invoice_overdue_reminder____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_mass_update____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start_payment____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_last_date #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_last_date -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_last_date msgid "Last Overdue Reminder Date" msgstr "Data ultimo sollecito" @@ -823,7 +689,6 @@ msgstr "Data ultimo sollecito" #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_form -#, python-format msgid "Last Reminder" msgstr "Ultimo promemoria" @@ -852,7 +717,6 @@ msgstr "Ultimo aggiornamento il" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "Letter" msgstr "Lettera" @@ -869,21 +733,18 @@ msgstr "Corpo e-mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail body is empty." msgstr "Corpo e-mail vuoto." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail subject is empty." msgstr "Oggetto e-mail vuoto." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Mass" msgstr "Massivo" @@ -909,6 +770,7 @@ msgstr "Nome" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__counter +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "New Remind Counter" msgstr "Contatore nuovi promemoria" @@ -956,7 +818,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "One by One" msgstr "Uno per uno" @@ -978,7 +839,6 @@ msgstr "Rif. ordine" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue msgid "Overdue" msgstr "Scaduta" @@ -1028,13 +888,11 @@ msgstr "Lettera scadenza" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_remind_sent #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_remind_sent -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_remind_sent msgid "Overdue Remind Sent" msgstr "Promemoria scadenza inviato" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_move_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_partner_property_form msgid "Overdue Reminder" msgstr "Promemoria scadenza" @@ -1047,7 +905,6 @@ msgstr "Azione promemoria scadenza" #: model:ir.model,name:account_invoice_overdue_reminder.model_overdue_reminder_action #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_ids #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_ids -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_ids msgid "Overdue Reminder Action History" msgstr "Storico azione promemoria scadenza" @@ -1059,7 +916,6 @@ msgstr "Azioni promemoria scadenza" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_invoice_filter msgid "Overdue Reminder Count" msgstr "Conteggio promemoria scadenza" @@ -1117,13 +973,14 @@ msgstr "Eseguito da" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_phone #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Phone" msgstr "Telefono" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Post" msgstr "Invia" @@ -1140,7 +997,6 @@ msgstr "Stampa fatture scadute" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Remind letter hasn't been printed!" msgstr "La lettera promemoria non è stata stampata!" @@ -1242,35 +1098,30 @@ msgstr "Imponibile" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The minimum delay since last reminder must be strictly positive." msgstr "Il ritardo minimo dall'ultimo promemoria deve essere positivo." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The trigger delay cannot be negative." msgstr "Il ritardo di azione non può essere negativo." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no invoices to remind for customer '%s'." msgstr "Non ci sono fatture da sollecitare al cliente '%s'." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no overdue reminders." msgstr "Non ci sono promemoria di scadenza." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter msgid "This counter is not increased in case of phone reminder." msgstr "" "Questo contatore non viene incrementato nel caso di promemoria telefonico." @@ -1311,6 +1162,7 @@ msgstr "Ritardo di attivazione" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action__reminder_type #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Type" msgstr "Tipo" @@ -1342,7 +1194,6 @@ msgstr "Utente" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "User company is different from action company. This should never happen." msgstr "" @@ -1380,14 +1231,12 @@ msgstr "Procedura guidata per ricordare le fatture scadute dei clienti" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You must select the new reminder type." msgstr "Bisogna selezionare il nuovo tipo di promemoria." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You processed all your overdue invoice reminders." msgstr "Sono stati elaborati tutti i promemoria di fatture scadute." @@ -1398,13 +1247,319 @@ msgstr "Distinti saluti," #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_start_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid "days" msgstr "giorni" +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "overdue_letter-%s" +msgstr "" + #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "" "{{object.company_id.name}} - Sollecito fatture scadute n°{{object.counter}}" + +#, python-format +#~ msgid "%(invoice_name)s Reminder %(counter)d" +#~ msgstr "%(invoice_name)s Promemoria %(counter)d" + +#~ msgid "" +#~ "
\n" +#~ "

Dear customer,

\n" +#~ "

According to our books, the following invoices are " +#~ "overdue:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast Reminders
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " Total\n" +#~ " Residual in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

If you made a payment for these invoices a few days " +#~ "ago, please ignore this email.

\n" +#~ "\n" +#~ " \n" +#~ "

You will find enclosed the overdue invoices.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Despite several reminders, we are disappointed to " +#~ "see that these overdue invoices are still\n" +#~ " unpaid.\n" +#~ " In order to avoid legal proceedings, we urge you " +#~ "to paid these overdue invoices in the next\n" +#~ " days.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Regards,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "
\n" +#~ " " +#~ msgstr "" +#~ "
\n" +#~ "

Spettabile cliente,

\n" +#~ "

secondo i nostri registri, la seguente fattura è " +#~ "scaduta:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Numero fatturaData fatturaTermini di pagamentoScadenzaRif. ordineTipoTotale nettoTotaleResiduoPromemoria antecedenti
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " Totale\n" +#~ " residuo in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

Se avete effettuato un pagamento per questa fattura " +#~ "alcuni giorni fa, ignorate questa e-mail.

\n" +#~ "\n" +#~ " \n" +#~ "

Troverà in allegato la fattura scaduta.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Nonostante diversi promemoria, siamo dispiaciuti " +#~ "nel vedere che queste fatture scadute sono ancora\n" +#~ " insolute.\n" +#~ " Per evitare procedimenti legali, La sollecitiamo " +#~ "a saldare queste fatture scadute nei prossimi\n" +#~ " giorni.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Cordialmente,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "
\n" +#~ " " + +#~ msgid "Default Overdue Reminder Minimum Interval (days)" +#~ msgstr "Intervallo minimo predefinito per sollecito (giorni)" + +#~ msgid "Default Overdue Reminder Trigger Delay (days)" +#~ msgstr "Ritardo predefinito per attivazione del sollecito (giorni)" + +#~ msgid "Default Reminder Minimum Interval" +#~ msgstr "Intervallo minimo predefinito per sollecito" + +#~ msgid "Default Reminder Trigger Delay" +#~ msgstr "Ritardo predefinito attivazione promemoria" + +#~ msgid "Default Wizard Interface" +#~ msgstr "Interfaccia predefinita procedura guidata" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/account_invoice_overdue_reminder/i18n/nl.po b/account_invoice_overdue_reminder/i18n/nl.po index b9defa9b4..db45f134b 100644 --- a/account_invoice_overdue_reminder/i18n/nl.po +++ b/account_invoice_overdue_reminder/i18n/nl.po @@ -19,14 +19,12 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format -msgid "%(invoice_name)s Reminder %(counter)d" -msgstr "%(invoice_name)s Herinnering %(counter)d" +msgid "%(invoice_name)s Reminder n°%(counter)d" +msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "%(partner_name)s, Reminder %(date)s" msgstr "%(partner_name)s, Herinnering %(date)s" @@ -75,71 +73,73 @@ msgid "" "LightGray % endif \">\n" " \n" -" \n" +" \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" +"or ''\"/>\n" " \n" " \n" -" \n" +" \n" " \n" " \n" -" \n" +" \n" " \n" " \n" +"black;\">\n" +" \n" +" \n" " \n" " \n" +"* (inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" " \n" +"(inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" " \n" +"* (inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" -" \n" +" \n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " Total\n" " Residual in\n" -" :\n" +" :\n" " \n" " \n" " \n" +"total_residual[0])\"/>\n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -147,8 +147,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -166,14 +166,38 @@ msgid "" "\n" " \n" "

\n" -" \n" +" \n" "

\n" "
\n" -"\n" "
\n" " " msgstr "" +#. module: account_invoice_overdue_reminder +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings +msgid " days" +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder by phone. Result/Info: %(result)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "" +"Overdue reminder sent by mail: %(mail_subject)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder sent by post." +msgstr "" + #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document msgid "According to our books, the following invoices are overdue:" @@ -197,7 +221,6 @@ msgstr "Te betalen bedrag" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format msgid "" "An overdue reminder can only be attached to a customer invoice or credit note" msgstr "" @@ -379,14 +402,14 @@ msgstr "Beste klant," #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days -msgid "Default Overdue Reminder Minimum Interval (days)" -msgstr "Standaard minimuminterval voor achterstallige herinneringen (dagen)" +msgid "Default Overdue Reminder Minimum Interval" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days -msgid "Default Overdue Reminder Trigger Delay (days)" -msgstr "Standaard achterstallige herinnering Triggervertraging (dagen)" +msgid "Default Overdue Reminder Trigger Delay" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -395,19 +418,16 @@ msgid "Default Overdue Reminder Wizard Interface" msgstr "Standaardinterface voor de wizard voor achterstallige herinneringen" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Minimum Interval" -msgstr "Standaard herinneringsminimuminterval" - -#. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Trigger Delay" -msgstr "Standaardherinneringsvertraging" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days +msgid "Default overdue reminder minimum interval in days" +msgstr "" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Wizard Interface" -msgstr "Standaard wizardinterface" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days +msgid "Default overdue reminder trigger delay in days" +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -430,7 +450,6 @@ msgstr "Schakel de herinnering voor achterstallige facturen uit" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__no_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__no_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__no_overdue_reminder msgid "Disable Overdue Reminder" msgstr "Herinnering voor achterstallige betalingen uitschakelen" @@ -465,7 +484,7 @@ msgstr "Vervaldatum" #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "E-mail" msgstr "" @@ -478,7 +497,6 @@ msgstr "E-mailstatus" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "E-mail missing on partner '%s'." msgstr "Missende e-mail op relatie '%s'." @@ -495,7 +513,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', the deadline is missing for the activity." msgstr "" @@ -504,7 +521,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', you must assign someone for the activity." msgstr "" @@ -514,7 +530,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Good job!" msgstr "Goed gedaan!" @@ -564,7 +579,6 @@ msgstr "Factuur" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Invoice Contact" msgstr "Factuurrelatie" @@ -654,25 +668,12 @@ msgstr "Laatste boeking aangemaakt op" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Last Invoice" msgstr "Laatste factuur" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_invoice_overdue_reminder____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_mass_update____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start_payment____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step____last_update -msgid "Last Modified on" -msgstr "Laatst bewerkt op" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_last_date #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_last_date -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_last_date msgid "Last Overdue Reminder Date" msgstr "Laatste betaalherinneringsdatum" @@ -680,7 +681,6 @@ msgstr "Laatste betaalherinneringsdatum" #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_form -#, python-format msgid "Last Reminder" msgstr "Laatste herinnering" @@ -709,7 +709,6 @@ msgstr "Laatst bewerkt op" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "Letter" msgstr "Brief" @@ -726,21 +725,18 @@ msgstr "Mailinhoud" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail body is empty." msgstr "Mailinhoud is leeg." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail subject is empty." msgstr "Mailonderwerp is leeg." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Mass" msgstr "Massa" @@ -766,6 +762,7 @@ msgstr "Naam" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__counter +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "New Remind Counter" msgstr "Volgende aantal herinneringen" @@ -815,7 +812,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "One by One" msgstr "Eén voor één" @@ -837,7 +833,6 @@ msgstr "Orderref." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue msgid "Overdue" msgstr "Achterstallig" @@ -887,13 +882,11 @@ msgstr "Achterstallige brief" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_remind_sent #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_remind_sent -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_remind_sent msgid "Overdue Remind Sent" msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_move_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_partner_property_form msgid "Overdue Reminder" msgstr "Betalingsherinnering" @@ -906,7 +899,6 @@ msgstr "Actie betalingsherinnering" #: model:ir.model,name:account_invoice_overdue_reminder.model_overdue_reminder_action #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_ids #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_ids -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_ids msgid "Overdue Reminder Action History" msgstr "Actiehistorie betalingsherinnering" @@ -918,7 +910,6 @@ msgstr "Acties betalingsherinnering" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_invoice_filter msgid "Overdue Reminder Count" msgstr "Aantal betalingsherinneringen" @@ -975,13 +966,14 @@ msgstr "Uitgevoerd door" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_phone #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Phone" msgstr "Telefoon" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Post" msgstr "" @@ -998,7 +990,6 @@ msgstr "Print achterstallige facturen" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Remind letter hasn't been printed!" msgstr "Herinneringsbrief is niet uitgeprint!" @@ -1100,7 +1091,6 @@ msgstr "Exclusief BTW" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The minimum delay since last reminder must be strictly positive." msgstr "" "De minimale vertraging sinds de laatste herinnering moet strikt positief " @@ -1109,28 +1099,24 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The trigger delay cannot be negative." msgstr "De triggervertraging kan niet negatief zijn." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no invoices to remind for customer '%s'." msgstr "Er zijn geen facturen om aan te herinneren voor klant '%s'." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no overdue reminders." msgstr "Er zijn geen betalingsherinneringen." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter msgid "This counter is not increased in case of phone reminder." msgstr "Deze teller loopt niet op bij telefonische herinneringen." @@ -1170,6 +1156,7 @@ msgstr "Triggervertraging" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action__reminder_type #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Type" msgstr "" @@ -1201,7 +1188,6 @@ msgstr "Gebruiker" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "User company is different from action company. This should never happen." msgstr "" @@ -1239,14 +1225,12 @@ msgstr "Wizard voor betalingsherinnering klantfactuur" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You must select the new reminder type." msgstr "Je moet een nieuw herinneringstype kiezen." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You processed all your overdue invoice reminders." msgstr "Alle betalingsherinneringen zijn verwerkt." @@ -1257,16 +1241,43 @@ msgstr "Met vriendelijke groet," #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_start_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid "days" msgstr "dagen" +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "overdue_letter-%s" +msgstr "" + #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" +#, python-format +#~ msgid "%(invoice_name)s Reminder %(counter)d" +#~ msgstr "%(invoice_name)s Herinnering %(counter)d" + +#~ msgid "Default Overdue Reminder Minimum Interval (days)" +#~ msgstr "Standaard minimuminterval voor achterstallige herinneringen (dagen)" + +#~ msgid "Default Overdue Reminder Trigger Delay (days)" +#~ msgstr "Standaard achterstallige herinnering Triggervertraging (dagen)" + +#~ msgid "Default Reminder Minimum Interval" +#~ msgstr "Standaard herinneringsminimuminterval" + +#~ msgid "Default Reminder Trigger Delay" +#~ msgstr "Standaardherinneringsvertraging" + +#~ msgid "Default Wizard Interface" +#~ msgstr "Standaard wizardinterface" + +#~ msgid "Last Modified on" +#~ msgstr "Laatst bewerkt op" + #~ msgid "" #~ "
\n" #~ "

Dear customer,

\n" @@ -1338,13 +1349,13 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1360,8 +1371,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1467,13 +1478,13 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1489,8 +1500,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" diff --git a/account_invoice_overdue_reminder/i18n/pt.po b/account_invoice_overdue_reminder/i18n/pt.po index 28bb3fed2..774c0bc8d 100644 --- a/account_invoice_overdue_reminder/i18n/pt.po +++ b/account_invoice_overdue_reminder/i18n/pt.po @@ -19,14 +19,12 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format -msgid "%(invoice_name)s Reminder %(counter)d" -msgstr "Lembrete %(counter)d - %(invoice_name)s" +msgid "%(invoice_name)s Reminder n°%(counter)d" +msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "%(partner_name)s, Reminder %(date)s" msgstr "%(partner_name)s, Lembrete %(date)s" @@ -75,71 +73,73 @@ msgid "" "LightGray % endif \">\n" " \n" -" \n" +" \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" +"or ''\"/>\n" " \n" " \n" -" \n" +" \n" " \n" " \n" -" \n" +" \n" " \n" " \n" +"black;\">\n" +" \n" +" \n" " \n" " \n" +"* (inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" " \n" +"(inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" " \n" +"* (inv.move_type == 'out_refund' and -1 or 1), inv.currency_id)\"/>\n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" -" \n" +" \n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " Total\n" " Residual in\n" -" :\n" +" :\n" " \n" " \n" " \n" +"total_residual[0])\"/>\n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -147,8 +147,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -166,14 +166,38 @@ msgid "" "\n" " \n" "

\n" -" \n" +" \n" "

\n" "
\n" -"\n" "
\n" " " msgstr "" +#. module: account_invoice_overdue_reminder +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings +msgid " days" +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder by phone. Result/Info: %(result)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "" +"Overdue reminder sent by mail: %(mail_subject)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder sent by post." +msgstr "" + #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document msgid "According to our books, the following invoices are overdue:" @@ -197,7 +221,6 @@ msgstr "Valor em Dívida" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format msgid "" "An overdue reminder can only be attached to a customer invoice or credit note" msgstr "" @@ -379,14 +402,14 @@ msgstr "Caro Cliente," #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days -msgid "Default Overdue Reminder Minimum Interval (days)" -msgstr "Intervalo Mínimo Pré definido para o Aviso de Cobrança (dias)" +msgid "Default Overdue Reminder Minimum Interval" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days -msgid "Default Overdue Reminder Trigger Delay (days)" -msgstr "Atraso Máximo Pré definido para o Aviso de Cobrança (dias)" +msgid "Default Overdue Reminder Trigger Delay" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -395,19 +418,16 @@ msgid "Default Overdue Reminder Wizard Interface" msgstr "Interface do assistente de Aviso de cobrança pré definido" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Minimum Interval" -msgstr "Intervalo Mínimo Pré definido para o Aviso de Cobrança" - -#. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Trigger Delay" -msgstr "Atraso Máximo Pré definido para o Aviso de Cobrança" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days +msgid "Default overdue reminder minimum interval in days" +msgstr "" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Wizard Interface" -msgstr "Interface do assistente pré definido" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days +msgid "Default overdue reminder trigger delay in days" +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -429,7 +449,6 @@ msgstr "Desligar o Aviso de Cobrança de faturas" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__no_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__no_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__no_overdue_reminder msgid "Disable Overdue Reminder" msgstr "Desligar o Aviso de Cobrança" @@ -464,7 +483,7 @@ msgstr "Data de vencimento" #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "E-mail" msgstr "E-mail" @@ -477,7 +496,6 @@ msgstr "Estado do E-mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "E-mail missing on partner '%s'." msgstr "E-mail em falta no parceiro '%s'." @@ -494,7 +512,6 @@ msgstr "Filtros" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', the deadline is missing for the activity." msgstr "" @@ -504,7 +521,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', you must assign someone for the activity." msgstr "" @@ -513,7 +529,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Good job!" msgstr "Bom trabalho!" @@ -563,7 +578,6 @@ msgstr "Fatura" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Invoice Contact" msgstr "Contacto da Fatura" @@ -653,25 +667,12 @@ msgstr "Ultimo Lançamento criado em" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Last Invoice" msgstr "Ultima Fatura" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_invoice_overdue_reminder____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_mass_update____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start_payment____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step____last_update -msgid "Last Modified on" -msgstr "Última Modificação em" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_last_date #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_last_date -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_last_date msgid "Last Overdue Reminder Date" msgstr "Última Data de Vencimento no Aviso de cobrança" @@ -679,7 +680,6 @@ msgstr "Última Data de Vencimento no Aviso de cobrança" #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_form -#, python-format msgid "Last Reminder" msgstr "Último Aviso de cobrança" @@ -708,7 +708,6 @@ msgstr "Última Atualização em" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "Letter" msgstr "Carta" @@ -725,21 +724,18 @@ msgstr "Corpo do mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail body is empty." msgstr "O corpo do mail está vazio." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail subject is empty." msgstr "O assunto do mail está vazio." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Mass" msgstr "Massa" @@ -765,6 +761,7 @@ msgstr "Nome" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__counter +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "New Remind Counter" msgstr "Novo Contador de Avisos de cobrança" @@ -812,7 +809,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "One by One" msgstr "Um por Um" @@ -834,7 +830,6 @@ msgstr "Ref. da Ordem." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue msgid "Overdue" msgstr "Vencido" @@ -884,13 +879,11 @@ msgstr "Carta Aviso de Cobrança" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_remind_sent #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_remind_sent -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_remind_sent msgid "Overdue Remind Sent" msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_move_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_partner_property_form msgid "Overdue Reminder" msgstr "Aviso de Cobrança" @@ -903,7 +896,6 @@ msgstr "Ação de Aviso de Cobrança" #: model:ir.model,name:account_invoice_overdue_reminder.model_overdue_reminder_action #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_ids #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_ids -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_ids msgid "Overdue Reminder Action History" msgstr "História das Ações de Aviso de Cobrança" @@ -915,7 +907,6 @@ msgstr "Ações de Avisos de Cobrança" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_invoice_filter msgid "Overdue Reminder Count" msgstr "Contagem de Avisos de Cobrança" @@ -974,13 +965,14 @@ msgstr "Realizado por" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_phone #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Phone" msgstr "Telefone" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Post" msgstr "Publicar" @@ -997,7 +989,6 @@ msgstr "Imprimir Faturas Vencidas" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Remind letter hasn't been printed!" msgstr "A carta de aviso não foi impressa!" @@ -1099,7 +1090,6 @@ msgstr "Impostos Excluídas" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The minimum delay since last reminder must be strictly positive." msgstr "" "O mínimo atraso desde o último aviso de cobrança deve ser sempre positivo." @@ -1107,7 +1097,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The trigger delay cannot be negative." msgstr "" "Atraso máximo pré definido para o Aviso de Cobrança não pode ser negativo." @@ -1115,21 +1104,18 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no invoices to remind for customer '%s'." msgstr "Não há faturas para lembrar ao cliente '%s'." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no overdue reminders." msgstr "Não existem avisos de faturas vencidas." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter msgid "This counter is not increased in case of phone reminder." msgstr "Este contador não é aumentado em caso de lembrete telefónico." @@ -1169,6 +1155,7 @@ msgstr "Atraso Máximo" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action__reminder_type #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Type" msgstr "Tipo" @@ -1200,7 +1187,6 @@ msgstr "Utilizador" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "User company is different from action company. This should never happen." msgstr "" @@ -1238,14 +1224,12 @@ msgstr "Assistente de aviso de cobrança de faturas de cliente" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You must select the new reminder type." msgstr "Deve selecionar o novo tipo de aviso de cobrança." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You processed all your overdue invoice reminders." msgstr "Processou todos os avisos de cobrança." @@ -1256,10 +1240,15 @@ msgstr "Cumprimentos," #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_start_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid "days" msgstr "dias" +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "overdue_letter-%s" +msgstr "" + #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template msgid "" @@ -1268,6 +1257,28 @@ msgstr "" "{{object.company_id.name}} - Lembrete de vencimento de faturas nº {{object." "counter}}" +#, python-format +#~ msgid "%(invoice_name)s Reminder %(counter)d" +#~ msgstr "Lembrete %(counter)d - %(invoice_name)s" + +#~ msgid "Default Overdue Reminder Minimum Interval (days)" +#~ msgstr "Intervalo Mínimo Pré definido para o Aviso de Cobrança (dias)" + +#~ msgid "Default Overdue Reminder Trigger Delay (days)" +#~ msgstr "Atraso Máximo Pré definido para o Aviso de Cobrança (dias)" + +#~ msgid "Default Reminder Minimum Interval" +#~ msgstr "Intervalo Mínimo Pré definido para o Aviso de Cobrança" + +#~ msgid "Default Reminder Trigger Delay" +#~ msgstr "Atraso Máximo Pré definido para o Aviso de Cobrança" + +#~ msgid "Default Wizard Interface" +#~ msgstr "Interface do assistente pré definido" + +#~ msgid "Last Modified on" +#~ msgstr "Última Modificação em" + #~ msgid "" #~ "
\n" #~ "

Dear customer,

\n" @@ -1339,13 +1350,13 @@ msgstr "" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1361,8 +1372,8 @@ msgstr "" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1468,13 +1479,13 @@ msgstr "" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1490,8 +1501,8 @@ msgstr "" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" diff --git a/account_invoice_overdue_reminder/i18n/pt_BR.po b/account_invoice_overdue_reminder/i18n/pt_BR.po index b70b4dba8..bf2aaa28e 100644 --- a/account_invoice_overdue_reminder/i18n/pt_BR.po +++ b/account_invoice_overdue_reminder/i18n/pt_BR.po @@ -19,14 +19,12 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format -msgid "%(invoice_name)s Reminder %(counter)d" -msgstr "%(invoice_name)s Lembrete %(counter)d" +msgid "%(invoice_name)s Reminder n°%(counter)d" +msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "%(partner_name)s, Reminder %(date)s" msgstr "%(partner_name)s, Lembrete %(date)s" @@ -40,84 +38,126 @@ msgstr "(object._get_report_base_filename())" msgid "" "
\n" "

Dear customer,

\n" -"

According to our books, the following invoices are overdue:

\n" +"

According to our books, the following invoices are " +"overdue:

\n" "\n" -" \n" +"
\n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" -" \n" -" \n" -" \n" +" \n" +" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" " \n" " \n" -" \n" +" \n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" " \n" "
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast RemindersInvoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast Reminders
\n" -" \n" +" \n" +"
\n" +" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" " \n" -" \n" +" \n" +" \n" "
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " Total\n" " Residual in\n" -" :\n" +" :\n" " \n" -" \n" +" \n" +" \n" " \n" "
\n" "\n" -"

If you made a payment for these invoices a few days ago, please ignore this email.

\n" +"

If you made a payment for these invoices a few days ago, " +"please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" " \n" -"

Despite several reminders, we are disappointed to see that these overdue invoices are still\n" +"

Despite several reminders, we are disappointed to see " +"that these overdue invoices are still\n" " unpaid.\n" -" In order to avoid legal proceedings, we urge you to paid these overdue invoices in the next\n" +" In order to avoid legal proceedings, we urge you to " +"paid these overdue invoices in the next\n" " days.\n" "

\n" "
\n" @@ -126,136 +166,37 @@ msgid "" "\n" " \n" "

\n" -" \n" +" \n" "

\n" "
\n" -"\n" "
\n" " " msgstr "" -"```html\n" -"
\n" -"

Caro cliente,

\n" -"

De acordo com nossos registros, as seguintes faturas estão " -"vencidas:

\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Número da " -"FaturaData da " -"FaturaCondições " -"de PagamentoData de " -"VencimentoRef. do " -"PedidoTipoTotal Sem " -"ImpostosTotalSaldo " -"DevedorLembretes " -"Enviados
\n" -" \n" -" \n" -" \n" -" \n" -" " -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" Total\n" -" Devedor em\n" -" :\n" -" \n" -" \n" -"
\n" -"\n" -"

Se você realizou o pagamento dessas faturas há alguns dias, por " -"favor, ignore este e-mail.

\n" -"\n" -" \n" -"

Você encontrará anexadas as faturas vencidas.

\n" -"
\n" -"\n" -" \n" -"

Apesar de vários lembretes, lamentamos ver que essas faturas " -"vencidas ainda não foram pagas.\n" -" Para evitar medidas legais, solicitamos que você pague essas " -"faturas nos próximos dias.\n" -"

\n" -"
\n" -"\n" -"

Atenciosamente,

\n" -"\n" -" \n" -"

\n" -" \n" -"

\n" -"
\n" -"\n" -"
\n" -"```\n" -" " + +#. module: account_invoice_overdue_reminder +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings +msgid " days" +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder by phone. Result/Info: %(result)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "" +"Overdue reminder sent by mail: %(mail_subject)s." +msgstr "" + +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "Overdue reminder sent by post." +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -280,10 +221,8 @@ msgstr "Valor devido" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 -#, python-format msgid "" -"An overdue reminder can only be attached to a customer invoice or credit " -"note" +"An overdue reminder can only be attached to a customer invoice or credit note" msgstr "" "Um lembrete de atraso somente pode ser anexado a uma fatura ou nota de " "crédito de cliente" @@ -437,8 +376,8 @@ msgstr "" "O cliente possui pagamentos/reembolsos não conciliados. Você deve \n" " conciliar esses pagamentos/reembolsos e reiniciar o " "processo \n" -" de lembrete de atraso, ou verificar manualmente se esses " -"\n" +" de lembrete de atraso, ou verificar manualmente se " +"esses \n" " pagamentos/reembolsos não conciliados têm uma razão " "válida para \n" " não estarem conciliados com uma fatura em aberto." @@ -473,14 +412,14 @@ msgstr "Prezado Cliente," #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days -msgid "Default Overdue Reminder Minimum Interval (days)" -msgstr "Intervalo Mínimo Padrão de Lembrete de Atraso (dias)" +msgid "Default Overdue Reminder Minimum Interval" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days -msgid "Default Overdue Reminder Trigger Delay (days)" -msgstr "Intervalo Padrão de Disparo do Lembrete de Vencimento (dias)" +msgid "Default Overdue Reminder Trigger Delay" +msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -489,19 +428,16 @@ msgid "Default Overdue Reminder Wizard Interface" msgstr "Interface Padrão do Assistente de Lembrete de Atraso" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Minimum Interval" -msgstr "Intervalo Padrão Mínimo de Lembrete" - -#. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Reminder Trigger Delay" -msgstr "Intervalo Padrão de Disparo do Lembrete" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days +msgid "Default overdue reminder minimum interval in days" +msgstr "" #. module: account_invoice_overdue_reminder -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings -msgid "Default Wizard Interface" -msgstr "Interface Padrão do Assistente" +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days +#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days +msgid "Default overdue reminder trigger delay in days" +msgstr "" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -523,7 +459,6 @@ msgstr "Desativar Lembrete de Fatura Vencida" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__no_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__no_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__no_overdue_reminder msgid "Disable Overdue Reminder" msgstr "Desativar Lembrete de Vencimento" @@ -558,7 +493,7 @@ msgstr "Data de Vencimento" #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "E-mail" msgstr "E-mail" @@ -571,7 +506,6 @@ msgstr "Status do E-mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "E-mail missing on partner '%s'." msgstr "E-mail ausente do parceiro '%s'." @@ -588,15 +522,14 @@ msgstr "Filtros" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', the deadline is missing for the activity." -msgstr "Para o lembrete do cliente '%s', o prazo está ausente para a atividade." +msgstr "" +"Para o lembrete do cliente '%s', o prazo está ausente para a atividade." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "For the reminder of customer '%s', you must assign someone for the activity." msgstr "" @@ -605,7 +538,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Good job!" msgstr "Bom trabalho!" @@ -657,7 +589,6 @@ msgstr "Fatura" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Invoice Contact" msgstr "Contato da Fatura" @@ -747,25 +678,12 @@ msgstr "Último Lançamento Criado em" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Last Invoice" msgstr "Última Fatura" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_invoice_overdue_reminder____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_mass_update____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_start_payment____last_update -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step____last_update -msgid "Last Modified on" -msgstr "Última Modificação em" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_last_date #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_last_date -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_last_date msgid "Last Overdue Reminder Date" msgstr "Data do Último Lembrete de Atraso" @@ -773,7 +691,6 @@ msgstr "Data do Último Lembrete de Atraso" #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_form -#, python-format msgid "Last Reminder" msgstr "Último Lembrete" @@ -802,7 +719,6 @@ msgstr "Última Atualização em" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/overdue_reminder_action.py:0 -#, python-format msgid "Letter" msgstr "Carta" @@ -819,21 +735,18 @@ msgstr "Corpo do E-mail" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail body is empty." msgstr "O corpo do e-mail está vazio." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Mail subject is empty." msgstr "O assunto do e-mail está vazio." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "Mass" msgstr "Massa" @@ -859,6 +772,7 @@ msgstr "Nome" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__counter +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "New Remind Counter" msgstr "Novo Contador de Lembretes" @@ -907,7 +821,6 @@ msgstr "" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/res_company.py:0 -#, python-format msgid "One by One" msgstr "Um por Um" @@ -929,7 +842,6 @@ msgstr "Referência do Pedido" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue msgid "Overdue" msgstr "Vencido" @@ -979,13 +891,11 @@ msgstr "Carta de Cobrança de Fatura Vencida" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_remind_sent #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_remind_sent -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_remind_sent msgid "Overdue Remind Sent" msgstr "Lembrete de Fatura Vencida Enviado" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_move_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_partner_property_form msgid "Overdue Reminder" msgstr "Lembrete de Vencimento" @@ -998,7 +908,6 @@ msgstr "Ação do Lembrete de Vencimento" #: model:ir.model,name:account_invoice_overdue_reminder.model_overdue_reminder_action #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_ids #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_ids -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_ids msgid "Overdue Reminder Action History" msgstr "Histórico de Ações do Lembrete de Vencimento" @@ -1010,7 +919,6 @@ msgstr "Ação do Lembrete de Vencimento" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_invoice_filter msgid "Overdue Reminder Count" msgstr "Contagem de Lembretes de Vencimento" @@ -1070,13 +978,14 @@ msgstr "Realizado por" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_phone #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search -#, python-format +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Phone" msgstr "Telefone" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Post" msgstr "Correio" @@ -1093,7 +1002,6 @@ msgstr "Imprimir Faturas Vencidas" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "Remind letter hasn't been printed!" msgstr "A Carta de Lembrete Não Foi Impressa!" @@ -1195,35 +1103,31 @@ msgstr "Imposto Excluído" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The minimum delay since last reminder must be strictly positive." -msgstr "O atraso mínimo desde o último lembrete deve ser estritamente positivo." +msgstr "" +"O atraso mínimo desde o último lembrete deve ser estritamente positivo." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "The trigger delay cannot be negative." msgstr "O atraso para acionamento não pode ser negativo." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no invoices to remind for customer '%s'." msgstr "Não há faturas para lembrar para o cliente '%s'." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "There are no overdue reminders." msgstr "Não há lembretes de vencimento." #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_bank_statement_line__overdue_reminder_counter #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_move__overdue_reminder_counter -#: model:ir.model.fields,help:account_invoice_overdue_reminder.field_account_payment__overdue_reminder_counter msgid "This counter is not increased in case of phone reminder." msgstr "Este contador não é incrementado em caso de lembrete por telefone." @@ -1263,6 +1167,7 @@ msgstr "Atraso para Acionamento" #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_action__reminder_type #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.account_invoice_overdue_reminder_search #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_action_search +#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_step_search msgid "Type" msgstr "Tipo" @@ -1294,7 +1199,6 @@ msgstr "Usuário" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "" "User company is different from action company. This should never happen." msgstr "" @@ -1332,14 +1236,12 @@ msgstr "Assistente para lembrete de fatura vencida de cliente" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You must select the new reminder type." msgstr "Você deve selecionar o novo tipo de lembrete." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 -#, python-format msgid "You processed all your overdue invoice reminders." msgstr "Você processou todos os seus lembretes de faturas vencidas." @@ -1350,13 +1252,307 @@ msgstr "Atenciosamente," #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.overdue_reminder_start_form -#: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid "days" msgstr "dias" +#. module: account_invoice_overdue_reminder +#. odoo-python +#: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 +msgid "overdue_letter-%s" +msgstr "" + #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "" "{{object.company_id.name}} - Lembrete de fatura vencida nº{{object.counter}}" + +#, python-format +#~ msgid "%(invoice_name)s Reminder %(counter)d" +#~ msgstr "%(invoice_name)s Lembrete %(counter)d" + +#~ msgid "" +#~ "
\n" +#~ "

Dear customer,

\n" +#~ "

According to our books, the following invoices are " +#~ "overdue:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast Reminders
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " Total\n" +#~ " Residual in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

If you made a payment for these invoices a few days " +#~ "ago, please ignore this email.

\n" +#~ "\n" +#~ " \n" +#~ "

You will find enclosed the overdue invoices.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Despite several reminders, we are disappointed to " +#~ "see that these overdue invoices are still\n" +#~ " unpaid.\n" +#~ " In order to avoid legal proceedings, we urge you " +#~ "to paid these overdue invoices in the next\n" +#~ " days.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Regards,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "
\n" +#~ " " +#~ msgstr "" +#~ "```html\n" +#~ "
\n" +#~ "

Caro cliente,

\n" +#~ "

De acordo com nossos registros, as seguintes faturas estão " +#~ "vencidas:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Número " +#~ "da FaturaData da " +#~ "FaturaCondições de PagamentoData de " +#~ "VencimentoRef. do " +#~ "PedidoTipo\n" +#~ " Total " +#~ "Sem ImpostosTotal\n" +#~ " Saldo " +#~ "DevedorLembretes Enviados
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " Total\n" +#~ " Devedor em\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

Se você realizou o pagamento dessas faturas há alguns dias, por " +#~ "favor, ignore este e-mail.

\n" +#~ "\n" +#~ " \n" +#~ "

Você encontrará anexadas as faturas vencidas.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Apesar de vários lembretes, lamentamos ver que essas faturas " +#~ "vencidas ainda não foram pagas.\n" +#~ " Para evitar medidas legais, solicitamos que você pague essas " +#~ "faturas nos próximos dias.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Atenciosamente,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "
\n" +#~ "```\n" +#~ " " + +#~ msgid "Default Overdue Reminder Minimum Interval (days)" +#~ msgstr "Intervalo Mínimo Padrão de Lembrete de Atraso (dias)" + +#~ msgid "Default Overdue Reminder Trigger Delay (days)" +#~ msgstr "Intervalo Padrão de Disparo do Lembrete de Vencimento (dias)" + +#~ msgid "Default Reminder Minimum Interval" +#~ msgstr "Intervalo Padrão Mínimo de Lembrete" + +#~ msgid "Default Reminder Trigger Delay" +#~ msgstr "Intervalo Padrão de Disparo do Lembrete" + +#~ msgid "Default Wizard Interface" +#~ msgstr "Interface Padrão do Assistente" + +#~ msgid "Last Modified on" +#~ msgstr "Última Modificação em" From e3ae58ec333e08e6539910b956c723810a4995cd Mon Sep 17 00:00:00 2001 From: mymage Date: Mon, 8 Sep 2025 07:56:20 +0000 Subject: [PATCH 107/116] Translated using Weblate (Italian) Currently translated at 100.0% (185 of 185 strings) Translation: credit-control-18.0/credit-control-18.0-account_invoice_overdue_reminder Translate-URL: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder/it/ --- account_invoice_overdue_reminder/i18n/it.po | 158 ++++++++++++++++++-- 1 file changed, 148 insertions(+), 10 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/it.po b/account_invoice_overdue_reminder/i18n/it.po index 6f8dd8c25..e77c0dcdc 100644 --- a/account_invoice_overdue_reminder/i18n/it.po +++ b/account_invoice_overdue_reminder/i18n/it.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-05-29 22:25+0000\n" -"Last-Translator: Sergio Zanchetta \n" +"PO-Revision-Date: 2025-09-08 10:43+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" @@ -20,7 +20,7 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 msgid "%(invoice_name)s Reminder n°%(counter)d" -msgstr "" +msgstr "%(invoice_name)s Promemoria n°%(counter)d" #. module: account_invoice_overdue_reminder #. odoo-python @@ -172,17 +172,153 @@ msgid "" "
\n" " " msgstr "" +"
\n" +"

Spettabile cliente,

\n" +"

secondo i nostri registri, la seguente fattura è " +"scaduta:

\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Numero fatturaData fatturaTermini di pagamentoScadenzaRif. ordineTipoTotale nettoTotaleResiduoPromemoria antecedenti
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" Totale\n" +" residuo in\n" +" :\n" +" \n" +" \n" +"
\n" +"\n" +"

Se avete effettuato un pagamento per questa fattura " +"alcuni giorni fa, ignorate questa e-mail.

\n" +"\n" +" \n" +"

Troverà in allegato la fattura scaduta.

\n" +"
\n" +"\n" +" \n" +"

Nonostante diversi promemoria, siamo dispiaciuti nel " +"vedere che queste fatture scadute sono ancora\n" +" insolute.\n" +" Per evitare procedimenti legali, La sollecitiamo a " +"saldare queste fatture scadute nei prossimi\n" +" giorni.\n" +"

\n" +"
\n" +"\n" +"

Cordialmente,

\n" +"\n" +" \n" +"

\n" +" \n" +"

\n" +"
\n" +"\n" +"
\n" +" " #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid " days" -msgstr "" +msgstr " giorni" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "Overdue reminder by phone. Result/Info: %(result)s." msgstr "" +"Promemoria scadenza da telefono. Risultato/Info: %(result)s." #. module: account_invoice_overdue_reminder #. odoo-python @@ -191,12 +327,14 @@ msgid "" "Overdue reminder sent by mail: %(mail_subject)s." msgstr "" +"Promemoria scadenza inviato per e-mail: %(mail_subject)s." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "Overdue reminder sent by post." -msgstr "" +msgstr "Promemoria scadenza inviata per posta." #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -412,13 +550,13 @@ msgstr "Gentile Cliente," #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days msgid "Default Overdue Reminder Minimum Interval" -msgstr "" +msgstr "Intervallo minimo promemoria scadenza predefinito" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days msgid "Default Overdue Reminder Trigger Delay" -msgstr "" +msgstr "Ritardo attivazione promemoria scadenza predefinito" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -430,13 +568,13 @@ msgstr "Interfaccia procedura guidata per sollecito predefinito" #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days msgid "Default overdue reminder minimum interval in days" -msgstr "" +msgstr "Intervallo minimo predefinito per sollecito in giorni" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days msgid "Default overdue reminder trigger delay in days" -msgstr "" +msgstr "Ritardo attivazione promemoria scadenza predefinito in giorni" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -1254,7 +1392,7 @@ msgstr "giorni" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "overdue_letter-%s" -msgstr "" +msgstr "overdue_letter-%s" #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template From 0e617c1cc56983a783d8c6ff5fab9de11153a21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi?= Date: Tue, 14 Oct 2025 14:05:41 +0000 Subject: [PATCH 108/116] Translated using Weblate (French) Currently translated at 100.0% (185 of 185 strings) Translation: credit-control-18.0/credit-control-18.0-account_invoice_overdue_reminder Translate-URL: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder/fr/ --- account_invoice_overdue_reminder/i18n/fr.po | 157 ++++++++++++++++++-- 1 file changed, 145 insertions(+), 12 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/fr.po b/account_invoice_overdue_reminder/i18n/fr.po index 97beb25d6..82e7fc86e 100644 --- a/account_invoice_overdue_reminder/i18n/fr.po +++ b/account_invoice_overdue_reminder/i18n/fr.po @@ -6,21 +6,21 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-03-02 14:36+0000\n" -"Last-Translator: Alexis de Lattre \n" +"PO-Revision-Date: 2025-10-14 14:15+0000\n" +"Last-Translator: Rémi \n" "Language-Team: none\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py:0 msgid "%(invoice_name)s Reminder n°%(counter)d" -msgstr "" +msgstr "%(invoice_name)s Relance n°%(counter)d" #. module: account_invoice_overdue_reminder #. odoo-python @@ -172,17 +172,148 @@ msgid "" "
\n" " " msgstr "" +"
\n" +"

Cher client,

\n" +"

D'après nos comptes, les factures suivantes n'ont pas été " +"réglées :

\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Numéro de FactureDate de FactureConditions de paiementDate d'échéanceRéf. de CommandeTypeTotal HTTotal TTCRestantRelances précédentes
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Total\n" +" Restant en\n" +"  :\n" +" \n" +" \n" +" \n" +"
\n" +"\n" +"

Si vous avez effectué le paiement dans les derniers " +"jours, merci de ne pas tenir compte de ce message.

\n" +"\n" +" \n" +"

Vous trouverez attachées les factures en objet.

\n" +"
\n" +"\n" +" \n" +"

Malgré plusieurs relances, nous constatons que ces " +"factures ne sont toujours pas payées.\n" +" Merci de régulariser au plus vite.\n" +"

\n" +"
\n" +"\n" +"

Cordialement,

\n" +"\n" +" \n" +"

\n" +" \n" +"

\n" +"
\n" +"
\n" +" " #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings msgid " days" -msgstr "" +msgstr " jours" #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "Overdue reminder by phone. Result/Info: %(result)s." -msgstr "" +msgstr "Relance par téléphone. Résultat/Info : %(result)s." #. module: account_invoice_overdue_reminder #. odoo-python @@ -191,12 +322,14 @@ msgid "" "Overdue reminder sent by mail: %(mail_subject)s." msgstr "" +"Relance envoyée par e-mail : %(mail_subject)s." #. module: account_invoice_overdue_reminder #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "Overdue reminder sent by post." -msgstr "" +msgstr "Relance envoyée par la poste." #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -414,13 +547,13 @@ msgstr "Cher client," #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days msgid "Default Overdue Reminder Minimum Interval" -msgstr "" +msgstr "Intervalle minimal par défaut pour l'envoi des relances" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days msgid "Default Overdue Reminder Trigger Delay" -msgstr "" +msgstr "Délai par défaut avant d'envoyer des relances" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_res_company__overdue_reminder_interface @@ -432,13 +565,13 @@ msgstr "Interface de relance par défaut" #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_min_interval_days #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_min_interval_days msgid "Default overdue reminder minimum interval in days" -msgstr "" +msgstr "Intervalle minimal par défaut entre chaque relance en jours" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_company__overdue_reminder_start_days #: model:ir.model.fields,help:account_invoice_overdue_reminder.field_res_config_settings__overdue_reminder_start_days msgid "Default overdue reminder trigger delay in days" -msgstr "" +msgstr "Délai par défaut en jours avant d'envoyer des relances" #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.report_overdue_reminder_document @@ -1261,7 +1394,7 @@ msgstr "jours" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "overdue_letter-%s" -msgstr "" +msgstr "overdue_letter-%s" #. module: account_invoice_overdue_reminder #: model:mail.template,subject:account_invoice_overdue_reminder.overdue_invoice_reminder_mail_template From 4d4c31a208e003139e6fc83a1980f04464ab3310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi?= Date: Tue, 14 Oct 2025 14:22:08 +0000 Subject: [PATCH 109/116] Translated using Weblate (French) Currently translated at 100.0% (185 of 185 strings) Translation: credit-control-18.0/credit-control-18.0-account_invoice_overdue_reminder Translate-URL: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder/fr/ --- account_invoice_overdue_reminder/i18n/fr.po | 86 ++++++++++----------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/fr.po b/account_invoice_overdue_reminder/i18n/fr.po index 82e7fc86e..f1a85244c 100644 --- a/account_invoice_overdue_reminder/i18n/fr.po +++ b/account_invoice_overdue_reminder/i18n/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-10-14 14:15+0000\n" +"PO-Revision-Date: 2025-10-14 14:40+0000\n" "Last-Translator: Rémi \n" "Language-Team: none\n" "Language: fr\n" @@ -172,84 +172,84 @@ msgid "" " \n" " " msgstr "" -"
\n" +"
\n" "

Cher client,

\n" "

D'après nos comptes, les factures suivantes n'ont pas été " -"réglées :

\n" +"réglées :

\n" "\n" -" \n" +"
\n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" -" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" @@ -263,14 +263,14 @@ msgstr "" " \n" -" \n" @@ -287,7 +287,7 @@ msgstr "" "

Vous trouverez attachées les factures en objet.

\n" " \n" "\n" -" \n" +" \n" "

Malgré plusieurs relances, nous constatons que ces " "factures ne sont toujours pas payées.\n" " Merci de régulariser au plus vite.\n" From a02820a0c521d26ae413564aafda477a61317a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Mon, 27 Oct 2025 16:48:40 +0100 Subject: [PATCH 110/116] [OU-ADD] account_invoice_overdue_reminder: Migration scripts --- .../migrations/18.0.1.0.0/post-migration.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py diff --git a/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py b/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py new file mode 100644 index 000000000..2c6d78ec1 --- /dev/null +++ b/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py @@ -0,0 +1,8 @@ +# Copyright 2025 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from openupgradelib import openupgrade, openupgrade_180 + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade_180.convert_company_dependent(env, "res.partner", "no_overdue_reminder") From 6f8b431bc7f6e0590f74a351540c18d10ee51822 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 23 Jan 2026 12:04:18 +0100 Subject: [PATCH 111/116] [FIX] account_invoice_overdue_reminder: use format_date() in mail.template --- account_invoice_overdue_reminder/data/mail_template.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_invoice_overdue_reminder/data/mail_template.xml b/account_invoice_overdue_reminder/data/mail_template.xml index bba9eef17..ca06da14a 100644 --- a/account_invoice_overdue_reminder/data/mail_template.xml +++ b/account_invoice_overdue_reminder/data/mail_template.xml @@ -67,13 +67,13 @@

\n" " \n" " \n" " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1387,8 +1389,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1442,8 +1444,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1526,8 +1528,8 @@ msgstr "" #~ "

Wenn Sie diese Rechnungen bereits bezahlt haben, " #~ "ignorieren Sie diese E-Mail bitte.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Anbei finden Sie die überfälligen Rechnungen.

\n" #~ "
\n" #~ "\n" diff --git a/account_invoice_overdue_reminder/i18n/es.po b/account_invoice_overdue_reminder/i18n/es.po index 00c577318..b65bb3107 100644 --- a/account_invoice_overdue_reminder/i18n/es.po +++ b/account_invoice_overdue_reminder/i18n/es.po @@ -65,8 +65,8 @@ msgid "" "
\n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1388,8 +1390,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1443,8 +1445,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1527,8 +1529,8 @@ msgstr "" #~ "

Si realizó el pago de estas facturas hace unos días, " #~ "ignore este correo electrónico.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Adjunto encontrará las facturas vencidas.

\n" #~ "
\n" #~ "\n" @@ -1602,8 +1604,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1678,8 +1680,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1731,8 +1733,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1520,8 +1670,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1575,8 +1725,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1656,8 +1806,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "

Si vous avez payé ces factures il y a quelques jours, " #~ "nous vous prions d'ignorer cet e-mail.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Vous trouverez ci-joint les factures impayées.\n" #~ " \n" @@ -1781,12 +1931,12 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "

\n" #~ " \n" -#~ " \n" -#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ "% endfor\n" #~ "% for (currency, total_residual) in object.total_residual():\n" @@ -1810,8 +1960,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ " \n" #~ " \n" #~ " \n" +#~ "font-weight: bold; text-align: right;\">Total Residual in $" +#~ "{currency.name}:\n" #~ " \n" #~ " \n" -#~ " \n" -#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" #~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ "% endfor\n" #~ "% for (currency, total_residual) in object.total_residual():\n" @@ -1905,8 +2055,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ " \n" #~ " \n" #~ " \n" +#~ "font-weight: bold; text-align: right;\">Total reste à payer en $" +#~ "{currency.name}:\n" #~ " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1519,8 +1666,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1574,8 +1721,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1658,8 +1805,8 @@ msgstr "" #~ "

Se avete effettuato un pagamento per questa fattura " #~ "alcuni giorni fa, ignorate questa e-mail.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Troverà in allegato la fattura scaduta.

\n" #~ "
\n" #~ "\n" diff --git a/account_invoice_overdue_reminder/i18n/nl.po b/account_invoice_overdue_reminder/i18n/nl.po index db45f134b..41f69adee 100644 --- a/account_invoice_overdue_reminder/i18n/nl.po +++ b/account_invoice_overdue_reminder/i18n/nl.po @@ -65,8 +65,8 @@ msgid "" "
\n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1382,8 +1384,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1435,8 +1437,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1511,8 +1513,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ "

Als betaling reeds is uitgevoerd, negeer dan deze " #~ "email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

De achterstallige facturen zijn bijgevoegd aan " #~ "deze email.

\n" #~ "
\n" diff --git a/account_invoice_overdue_reminder/i18n/pt.po b/account_invoice_overdue_reminder/i18n/pt.po index 774c0bc8d..d8ce8512d 100644 --- a/account_invoice_overdue_reminder/i18n/pt.po +++ b/account_invoice_overdue_reminder/i18n/pt.po @@ -65,8 +65,8 @@ msgid "" "
\n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1383,8 +1385,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1436,8 +1438,8 @@ msgstr "" #~ "
\n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1512,8 +1514,8 @@ msgstr "" #~ "

Se efetuou o pagamento recentemente, pf ignore este e-" #~ "mail.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Poderá verificar as faturas vencidas em anexo.\n" #~ " \n" diff --git a/account_invoice_overdue_reminder/i18n/pt_BR.po b/account_invoice_overdue_reminder/i18n/pt_BR.po index bf2aaa28e..205374887 100644 --- a/account_invoice_overdue_reminder/i18n/pt_BR.po +++ b/account_invoice_overdue_reminder/i18n/pt_BR.po @@ -65,8 +65,8 @@ msgid "" "

\n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" #~ " \n" @@ -1386,8 +1388,8 @@ msgstr "" #~ "

If you made a payment for these invoices a few days " #~ "ago, please ignore this email.

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

You will find enclosed the overdue invoices.

\n" #~ "
\n" #~ "\n" @@ -1469,18 +1471,18 @@ msgstr "" #~ "['selection'])[inv.move_type]\">
\n" #~ " \n" #~ " \n" #~ " \n" #~ "
Numéro de FactureDate de FactureConditions de paiementDate d'échéanceRéf. de CommandeTypeTotal HTTotal TTCRestantRelances précédentesNuméro de FactureDate de FactureConditions de paiementDate d'échéanceRéf. de CommandeTypeTotal HTTotal TTCRestantRelances précédentes
\n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black; text-align: right;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black; text-align: right;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black; text-align: right;\">\n" " \n" " \n" +"\"padding: 5px; border: 1px solid black;\">\n" " \n" "
\n" " \n" " \n" -" \n" +" \n" " Total\n" " Restant en\n" -"  :\n" +" :\n" " \n" +" \n" " \n" " - + - + From c5c88f6193ca99ec3a84fee9f282e1d4aff626ec Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 11 Mar 2026 22:33:48 +0000 Subject: [PATCH 112/116] [UPD] Update account_invoice_overdue_reminder.pot --- .../i18n/account_invoice_overdue_reminder.pot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot b/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot index a4da9808e..79a6e8e1b 100644 --- a/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot +++ b/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot @@ -56,13 +56,13 @@ msgid "" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" From 9dc67a99896848110689672d5f4cb2bdeaac20ae Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 11 Mar 2026 22:37:58 +0000 Subject: [PATCH 113/116] [BOT] post-merge updates --- account_invoice_overdue_reminder/README.rst | 2 +- account_invoice_overdue_reminder/__manifest__.py | 2 +- account_invoice_overdue_reminder/static/description/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/account_invoice_overdue_reminder/README.rst b/account_invoice_overdue_reminder/README.rst index 6b13c2432..e1fefb2fb 100644 --- a/account_invoice_overdue_reminder/README.rst +++ b/account_invoice_overdue_reminder/README.rst @@ -11,7 +11,7 @@ Overdue Invoice Reminder !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3ae47b6dcc00b3cc6b53b13a5ce8299babfc7c7f72e970130d13042f6d74feb3 + !! source digest: sha256:b6e15d13e201281878ea28fa9f232d5f3f225fa9ae11d390c5b305190976f713 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_invoice_overdue_reminder/__manifest__.py b/account_invoice_overdue_reminder/__manifest__.py index 777138e43..e1ccc2458 100644 --- a/account_invoice_overdue_reminder/__manifest__.py +++ b/account_invoice_overdue_reminder/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Overdue Invoice Reminder", - "version": "18.0.1.2.0", + "version": "18.0.1.3.0", "category": "Accounting", "license": "AGPL-3", "summary": "Simple mail/letter/phone overdue customer invoice reminder ", diff --git a/account_invoice_overdue_reminder/static/description/index.html b/account_invoice_overdue_reminder/static/description/index.html index fa1b287c6..4b46e9300 100644 --- a/account_invoice_overdue_reminder/static/description/index.html +++ b/account_invoice_overdue_reminder/static/description/index.html @@ -372,7 +372,7 @@

Overdue Invoice Reminder

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:3ae47b6dcc00b3cc6b53b13a5ce8299babfc7c7f72e970130d13042f6d74feb3 +!! source digest: sha256:b6e15d13e201281878ea28fa9f232d5f3f225fa9ae11d390c5b305190976f713 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/credit-control Translate me on Weblate Try me on Runboat

This Odoo module is designed to send overdue invoice reminders to From 8ae8cf62354c0569c8e35f9a98007edf2cc7c0a1 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 11 Mar 2026 22:38:07 +0000 Subject: [PATCH 114/116] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: credit-control-18.0/credit-control-18.0-account_invoice_overdue_reminder Translate-URL: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder/ --- account_invoice_overdue_reminder/i18n/ca.po | 24 +- account_invoice_overdue_reminder/i18n/de.po | 84 +-- account_invoice_overdue_reminder/i18n/es.po | 132 ++--- account_invoice_overdue_reminder/i18n/fr.po | 530 +++++++++++------- account_invoice_overdue_reminder/i18n/it.po | 495 ++++++++++------ account_invoice_overdue_reminder/i18n/nl.po | 80 +-- account_invoice_overdue_reminder/i18n/pt.po | 84 +-- .../i18n/pt_BR.po | 64 ++- 8 files changed, 901 insertions(+), 592 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/ca.po b/account_invoice_overdue_reminder/i18n/ca.po index 7fc903a35..fa23005e5 100644 --- a/account_invoice_overdue_reminder/i18n/ca.po +++ b/account_invoice_overdue_reminder/i18n/ca.po @@ -63,8 +63,8 @@ msgid "" "

Past Reminders
\n" -" \n" +" \n" " \n" @@ -84,7 +85,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -92,9 +94,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -145,8 +147,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -186,8 +188,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder diff --git a/account_invoice_overdue_reminder/i18n/de.po b/account_invoice_overdue_reminder/i18n/de.po index 2b7d87b26..cfbe537a3 100644 --- a/account_invoice_overdue_reminder/i18n/de.po +++ b/account_invoice_overdue_reminder/i18n/de.po @@ -65,8 +65,8 @@ msgid "" "
Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -188,8 +190,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder @@ -1266,8 +1268,8 @@ msgstr "" msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "" -"{{object.company_id.name}} - Erinnerung überfällige Rechnung Nr.{{object." -"counter}}" +"{{object.company_id.name}} - Erinnerung überfällige Rechnung Nr." +"{{object.counter}}" #, python-format #~ msgid "%(invoice_name)s Reminder %(counter)d" @@ -1303,8 +1305,8 @@ msgstr "" #~ "
Past Reminders
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1336,9 +1338,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1347,14 +1349,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Letzte Erinnerungen
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1475,9 +1477,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1486,14 +1488,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -188,8 +190,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder @@ -1304,8 +1306,8 @@ msgstr "" #~ "
Past Reminders
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1337,9 +1339,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1348,14 +1350,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Recordatorios pasados
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1476,9 +1478,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1487,14 +1489,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Past Reminders
\n" @@ -1615,8 +1617,8 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1628,9 +1630,9 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1639,14 +1641,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Recordatorios anteriores
\n" @@ -1744,8 +1746,8 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1757,9 +1759,9 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1768,9 +1770,9 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1806,8 +1808,8 @@ msgstr "" #~ "

Si ha pagado estas facturas en los anteriores días, " #~ "por favor ignore este mensaje

\n" #~ "\n" -#~ " \n" +#~ " \n" #~ "

Podrá encontrar adjuntas las facturas por pagar.\n" #~ " \n" diff --git a/account_invoice_overdue_reminder/i18n/fr.po b/account_invoice_overdue_reminder/i18n/fr.po index f1a85244c..35fabe5c5 100644 --- a/account_invoice_overdue_reminder/i18n/fr.po +++ b/account_invoice_overdue_reminder/i18n/fr.po @@ -65,8 +65,8 @@ msgid "" "

Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -172,137 +174,6 @@ msgid "" " \n" " " msgstr "" -"
\n" -"

Cher client,

\n" -"

D'après nos comptes, les factures suivantes n'ont pas été " -"réglées :

\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Numéro de FactureDate de FactureConditions de paiementDate d'échéanceRéf. de CommandeTypeTotal HTTotal TTCRestantRelances précédentes
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" Total\n" -" Restant en\n" -" :\n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"

Si vous avez effectué le paiement dans les derniers " -"jours, merci de ne pas tenir compte de ce message.

\n" -"\n" -" \n" -"

Vous trouverez attachées les factures en objet.

\n" -"
\n" -"\n" -" \n" -"

Malgré plusieurs relances, nous constatons que ces " -"factures ne sont toujours pas payées.\n" -" Merci de régulariser au plus vite.\n" -"

\n" -"
\n" -"\n" -"

Cordialement,

\n" -"\n" -" \n" -"

\n" -" \n" -"

\n" -"
\n" -"
\n" -" " #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings @@ -319,8 +190,8 @@ msgstr "Relance par téléphone. Résultat/Info : %(result)s." #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" "Relance envoyée par e-mail : %(mail_subject)s." @@ -1402,6 +1273,285 @@ msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" +#~ msgid "" +#~ "
\n" +#~ "

Dear customer,

\n" +#~ "

According to our books, the following invoices are " +#~ "overdue:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast Reminders
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " Total\n" +#~ " Residual in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

If you made a payment for these invoices a few days " +#~ "ago, please ignore this email.

\n" +#~ "\n" +#~ " \n" +#~ "

You will find enclosed the overdue invoices.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Despite several reminders, we are disappointed to " +#~ "see that these overdue invoices are still\n" +#~ " unpaid.\n" +#~ " In order to avoid legal proceedings, we urge you " +#~ "to paid these overdue invoices in the next\n" +#~ " days.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Regards,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "
\n" +#~ " " +#~ msgstr "" +#~ "
\n" +#~ "

Cher client,

\n" +#~ "

D'après nos comptes, les factures suivantes n'ont pas " +#~ "été réglées :

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Numéro de FactureDate de FactureConditions de paiementDate d'échéanceRéf. de CommandeTypeTotal HTTotal TTCRestantRelances précédentes
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " Total\n" +#~ " Restant en\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

Si vous avez effectué le paiement dans les derniers " +#~ "jours, merci de ne pas tenir compte de ce message.

\n" +#~ "\n" +#~ " \n" +#~ "

Vous trouverez attachées les factures en objet.\n" +#~ " \n" +#~ "\n" +#~ " \n" +#~ "

Malgré plusieurs relances, nous constatons que ces " +#~ "factures ne sont toujours pas payées.\n" +#~ " Merci de régulariser au plus vite.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Cordialement,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "
\n" +#~ " " + #, python-format #~ msgid "%(invoice_name)s Reminder %(counter)d" #~ msgstr "%(invoice_name)s relance n°%(counter)d" @@ -1436,8 +1586,8 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "
Past Reminders
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1469,9 +1619,9 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1480,14 +1630,14 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Relances envoyées
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1608,9 +1758,9 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1619,14 +1769,14 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
${inv.name}\n" -#~ " ${format_date(inv.invoice_date)}${inv." -#~ "invoice_payment_term_id.name or ''}${format_date(inv.invoice_date_due)}$" +#~ "{format_date(inv.invoice_date)}$" +#~ "{inv.invoice_payment_term_id.name or ''}$" +#~ "{format_date(inv.invoice_date_due)}${inv.ref or " #~ "''}${format_amount(inv.amount_residual * (inv.move_type == " #~ "'out_refund' and -1 or 1), inv.currency_id)}${inv." -#~ "overdue_reminder_counter}$" +#~ "{inv.overdue_reminder_counter}
Total Residual in ${currency." -#~ "name}:${format_amount(total_residual, currency)}\n" @@ -1876,12 +2026,12 @@ msgstr "{{object.company_id.name}} - Relance client n°{{object.counter}}" #~ "
${inv.name}\n" -#~ " ${format_date(inv.invoice_date)}${inv." -#~ "invoice_payment_term_id.name or ''}${format_date(inv.invoice_date_due)}$" +#~ "{format_date(inv.invoice_date)}$" +#~ "{inv.invoice_payment_term_id.name or ''}$" +#~ "{format_date(inv.invoice_date_due)}${inv.ref or " #~ "''}${format_amount(inv.amount_residual * (inv.move_type == " #~ "'out_refund' and -1 or 1), inv.currency_id)}${inv." -#~ "overdue_reminder_counter}$" +#~ "{inv.overdue_reminder_counter}
Total reste à payer en ${currency." -#~ "name}:${format_amount(total_residual, currency)}\n" diff --git a/account_invoice_overdue_reminder/i18n/it.po b/account_invoice_overdue_reminder/i18n/it.po index e77c0dcdc..2c239766a 100644 --- a/account_invoice_overdue_reminder/i18n/it.po +++ b/account_invoice_overdue_reminder/i18n/it.po @@ -65,8 +65,8 @@ msgid "" " Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -172,141 +174,6 @@ msgid "" " \n" " " msgstr "" -"
\n" -"

Spettabile cliente,

\n" -"

secondo i nostri registri, la seguente fattura è " -"scaduta:

\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Numero fatturaData fatturaTermini di pagamentoScadenzaRif. ordineTipoTotale nettoTotaleResiduoPromemoria antecedenti
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" Totale\n" -" residuo in\n" -" :\n" -" \n" -" \n" -"
\n" -"\n" -"

Se avete effettuato un pagamento per questa fattura " -"alcuni giorni fa, ignorate questa e-mail.

\n" -"\n" -" \n" -"

Troverà in allegato la fattura scaduta.

\n" -"
\n" -"\n" -" \n" -"

Nonostante diversi promemoria, siamo dispiaciuti nel " -"vedere che queste fatture scadute sono ancora\n" -" insolute.\n" -" Per evitare procedimenti legali, La sollecitiamo a " -"saldare queste fatture scadute nei prossimi\n" -" giorni.\n" -"

\n" -"
\n" -"\n" -"

Cordialmente,

\n" -"\n" -" \n" -"

\n" -" \n" -"

\n" -"
\n" -"\n" -"
\n" -" " #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings @@ -324,8 +191,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" "Promemoria scadenza inviato per e-mail: %(mail_subject)s." @@ -1401,6 +1268,286 @@ msgid "" msgstr "" "{{object.company_id.name}} - Sollecito fatture scadute n°{{object.counter}}" +#~ msgid "" +#~ "
\n" +#~ "

Dear customer,

\n" +#~ "

According to our books, the following invoices are " +#~ "overdue:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Invoice NumberInvoice DatePayment TermsDue DateOrder Ref.TypeTotal UntaxedTotalResidualPast Reminders
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " Total\n" +#~ " Residual in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

If you made a payment for these invoices a few days " +#~ "ago, please ignore this email.

\n" +#~ "\n" +#~ " \n" +#~ "

You will find enclosed the overdue invoices.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Despite several reminders, we are disappointed to " +#~ "see that these overdue invoices are still\n" +#~ " unpaid.\n" +#~ " In order to avoid legal proceedings, we urge you " +#~ "to paid these overdue invoices in the next\n" +#~ " days.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Regards,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "
\n" +#~ " " +#~ msgstr "" +#~ "
\n" +#~ "

Spettabile cliente,

\n" +#~ "

secondo i nostri registri, la seguente fattura è " +#~ "scaduta:

\n" +#~ "\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
Numero fatturaData fatturaTermini di pagamentoScadenzaRif. ordineTipoTotale nettoTotaleResiduoPromemoria antecedenti
\n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ " Totale\n" +#~ " residuo in\n" +#~ " :\n" +#~ " \n" +#~ " \n" +#~ "
\n" +#~ "\n" +#~ "

Se avete effettuato un pagamento per questa fattura " +#~ "alcuni giorni fa, ignorate questa e-mail.

\n" +#~ "\n" +#~ " \n" +#~ "

Troverà in allegato la fattura scaduta.

\n" +#~ "
\n" +#~ "\n" +#~ " \n" +#~ "

Nonostante diversi promemoria, siamo dispiaciuti " +#~ "nel vedere che queste fatture scadute sono ancora\n" +#~ " insolute.\n" +#~ " Per evitare procedimenti legali, La sollecitiamo " +#~ "a saldare queste fatture scadute nei prossimi\n" +#~ " giorni.\n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "

Cordialmente,

\n" +#~ "\n" +#~ " \n" +#~ "

\n" +#~ " \n" +#~ "

\n" +#~ "
\n" +#~ "\n" +#~ "
\n" +#~ " " + #, python-format #~ msgid "%(invoice_name)s Reminder %(counter)d" #~ msgstr "%(invoice_name)s Promemoria %(counter)d" @@ -1435,8 +1582,8 @@ msgstr "" #~ "
Past Reminders
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1468,9 +1615,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1479,14 +1626,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Promemoria antecedenti
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1607,9 +1754,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1618,14 +1765,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -188,8 +190,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder @@ -1306,8 +1308,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ "
Past Reminders
\n" @@ -1319,8 +1321,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1332,9 +1334,9 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1343,14 +1345,14 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Aantal herinneringen
\n" @@ -1448,8 +1450,8 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1461,9 +1463,9 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1472,14 +1474,14 @@ msgstr "{{object.company_id.name}} - Betalingsherinnering n°{{object.counter}}" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -188,8 +190,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder @@ -1254,8 +1256,8 @@ msgstr "" msgid "" "{{object.company_id.name}} - Overdue invoice reminder n°{{object.counter}}" msgstr "" -"{{object.company_id.name}} - Lembrete de vencimento de faturas nº {{object." -"counter}}" +"{{object.company_id.name}} - Lembrete de vencimento de faturas nº " +"{{object.counter}}" #, python-format #~ msgid "%(invoice_name)s Reminder %(counter)d" @@ -1307,8 +1309,8 @@ msgstr "" #~ "
Past Reminders
\n" @@ -1320,8 +1322,8 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1333,9 +1335,9 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1344,14 +1346,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Lembretes Anteriores
\n" @@ -1449,8 +1451,8 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1462,9 +1464,9 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1473,14 +1475,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
Past Reminders
\n" -" \n" +" \n" " \n" @@ -86,7 +87,8 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -94,9 +96,9 @@ msgid "" " \n" -" \n" +" \n" " \n" @@ -147,8 +149,8 @@ msgid "" "

If you made a payment for these invoices a few days ago, " "please ignore this email.

\n" "\n" -" \n" +" \n" "

You will find enclosed the overdue invoices.

\n" "
\n" "\n" @@ -188,8 +190,8 @@ msgstr "" #. odoo-python #: code:addons/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py:0 msgid "" -"Overdue reminder sent by mail: %(mail_subject)s." +"Overdue reminder sent by mail: %(mail_subject)s." msgstr "" #. module: account_invoice_overdue_reminder @@ -1302,8 +1304,8 @@ msgstr "" #~ "
Past Reminders
\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1335,9 +1337,9 @@ msgstr "" #~ "['move_type']['selection'])[inv.move_type]\">\n" -#~ " \n" +#~ " \n" #~ " \n" @@ -1346,14 +1348,14 @@ msgstr "" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ "
\n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" -#~ " \n" +#~ " \n" #~ " \n" #~ " \n" From 3a19bc48d6cd6b85e6253d8e56b55efcd5504a0a Mon Sep 17 00:00:00 2001 From: mymage Date: Mon, 16 Mar 2026 08:20:54 +0000 Subject: [PATCH 115/116] Translated using Weblate (Italian) Currently translated at 100.0% (185 of 185 strings) Translation: credit-control-18.0/credit-control-18.0-account_invoice_overdue_reminder Translate-URL: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder/it/ --- account_invoice_overdue_reminder/i18n/it.po | 140 +++++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/account_invoice_overdue_reminder/i18n/it.po b/account_invoice_overdue_reminder/i18n/it.po index 2c239766a..2574aaf11 100644 --- a/account_invoice_overdue_reminder/i18n/it.po +++ b/account_invoice_overdue_reminder/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-09-08 10:43+0000\n" +"PO-Revision-Date: 2026-03-16 10:45+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.4\n" +"X-Generator: Weblate 5.15.2\n" #. module: account_invoice_overdue_reminder #. odoo-python @@ -174,6 +174,142 @@ msgid "" " \n" " " msgstr "" +"
\n" +"

Spettabile cliente,

\n" +"

secondo i nostri registri, la seguente fattura è " +"scaduta:

\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
" +"Numero fattura" +"Data fattura" +"Termini di pagamento" +"Scadenza" +"Rif. ordine" +"Tipo" +"Totale netto" +"Totale" +"Residuo" +"Promemoria antecedenti
\n" +" \n" +" \n" +" " +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Totale\n" +" residuo in\n" +" :\n" +" \n" +" \n" +" \n" +"
\n" +"\n" +"

Se avete effettuato un pagamento per questa fattura " +"alcuni giorni fa, ignorate questa e-mail.

\n" +"\n" +" \n" +"

Troverà in allegato la fattura scaduta.

\n" +"
\n" +"\n" +" \n" +"

Nonostante diversi promemoria, siamo dispiaciuti nel " +"vedere che queste fatture scadute sono ancora\n" +" insolute.\n" +" Per evitare procedimenti legali, La sollecitiamo a " +"saldare queste fatture scadute nei prossimi\n" +" giorni.\n" +"

\n" +"
\n" +"\n" +"

Cordialmente,

\n" +"\n" +" \n" +"

\n" +" \n" +"

\n" +"
\n" +"
\n" +" " #. module: account_invoice_overdue_reminder #: model_terms:ir.ui.view,arch_db:account_invoice_overdue_reminder.view_account_config_settings From 3810bcf03e5e139870c1bd594340f5d88068b403 Mon Sep 17 00:00:00 2001 From: stferraro Date: Tue, 28 Apr 2026 14:05:21 -0400 Subject: [PATCH 116/116] [MIG] account_invoice_overdue_reminder: Migration to 19.0 --- account_invoice_overdue_reminder/README.rst | 10 +- .../__manifest__.py | 2 +- .../i18n/account_invoice_overdue_reminder.pot | 4 - account_invoice_overdue_reminder/i18n/ca.po | 5 - account_invoice_overdue_reminder/i18n/de.po | 4 - account_invoice_overdue_reminder/i18n/es.po | 5 - account_invoice_overdue_reminder/i18n/fr.po | 5 - account_invoice_overdue_reminder/i18n/it.po | 4 - account_invoice_overdue_reminder/i18n/nl.po | 5 - account_invoice_overdue_reminder/i18n/pt.po | 4 - .../i18n/pt_BR.po | 4 - .../migrations/18.0.1.0.0/post-migration.py | 8 - .../account_invoice_overdue_reminder.py | 33 ++- .../models/account_move.py | 11 +- .../models/overdue_reminder_action.py | 24 +- .../models/overdue_reminder_result.py | 7 +- .../models/res_company.py | 32 ++- .../static/description/index.html | 6 +- .../tests/__init__.py | 8 + .../test_account_invoice_overdue_reminder.py | 112 +++++++++ .../tests/test_account_move.py | 125 ++++++++++ .../tests/test_overdue_reminder_action.py | 64 +++++ .../test_overdue_reminder_mass_update.py | 77 ++++++ .../tests/test_overdue_reminder_start.py | 145 ++++++++++++ .../tests/test_overdue_reminder_step.py | 223 ++++++++++++++++++ .../account_invoice_overdue_reminder.xml | 26 +- .../views/overdue_reminder_result.xml | 2 +- .../wizard/overdue_reminder_wizard.py | 92 ++++---- .../wizard/overdue_reminder_wizard_view.xml | 3 +- 29 files changed, 882 insertions(+), 168 deletions(-) delete mode 100644 account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py create mode 100644 account_invoice_overdue_reminder/tests/__init__.py create mode 100644 account_invoice_overdue_reminder/tests/test_account_invoice_overdue_reminder.py create mode 100644 account_invoice_overdue_reminder/tests/test_account_move.py create mode 100644 account_invoice_overdue_reminder/tests/test_overdue_reminder_action.py create mode 100644 account_invoice_overdue_reminder/tests/test_overdue_reminder_mass_update.py create mode 100644 account_invoice_overdue_reminder/tests/test_overdue_reminder_start.py create mode 100644 account_invoice_overdue_reminder/tests/test_overdue_reminder_step.py diff --git a/account_invoice_overdue_reminder/README.rst b/account_invoice_overdue_reminder/README.rst index e1fefb2fb..9cd2c6c85 100644 --- a/account_invoice_overdue_reminder/README.rst +++ b/account_invoice_overdue_reminder/README.rst @@ -21,13 +21,13 @@ Overdue Invoice Reminder :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcredit--control-lightgray.png?logo=github - :target: https://github.com/OCA/credit-control/tree/18.0/account_invoice_overdue_reminder + :target: https://github.com/OCA/credit-control/tree/19.0/account_invoice_overdue_reminder :alt: OCA/credit-control .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/credit-control-18-0/credit-control-18-0-account_invoice_overdue_reminder + :target: https://translation.odoo-community.org/projects/credit-control-19-0/credit-control-19-0-account_invoice_overdue_reminder :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/credit-control&target_branch=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/credit-control&target_branch=19.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -148,7 +148,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -186,6 +186,6 @@ Current `maintainer `__: |maintainer-alexis-via| -This module is part of the `OCA/credit-control `_ project on GitHub. +This module is part of the `OCA/credit-control `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_invoice_overdue_reminder/__manifest__.py b/account_invoice_overdue_reminder/__manifest__.py index e1ccc2458..6055e687f 100644 --- a/account_invoice_overdue_reminder/__manifest__.py +++ b/account_invoice_overdue_reminder/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Overdue Invoice Reminder", - "version": "18.0.1.3.0", + "version": "19.0.1.0.0", "category": "Accounting", "license": "AGPL-3", "summary": "Simple mail/letter/phone overdue customer invoice reminder ", diff --git a/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot b/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot index 79a6e8e1b..cd0bc38d6 100644 --- a/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot +++ b/account_invoice_overdue_reminder/i18n/account_invoice_overdue_reminder.pot @@ -701,10 +701,6 @@ msgstr "" msgid "Minimum Delay Since Last Reminder" msgstr "" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name diff --git a/account_invoice_overdue_reminder/i18n/ca.po b/account_invoice_overdue_reminder/i18n/ca.po index fa23005e5..a4d55861a 100644 --- a/account_invoice_overdue_reminder/i18n/ca.po +++ b/account_invoice_overdue_reminder/i18n/ca.po @@ -743,11 +743,6 @@ msgstr "" msgid "Minimum Delay Since Last Reminder" msgstr "" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name msgid "Name" diff --git a/account_invoice_overdue_reminder/i18n/de.po b/account_invoice_overdue_reminder/i18n/de.po index cfbe537a3..27f946a17 100644 --- a/account_invoice_overdue_reminder/i18n/de.po +++ b/account_invoice_overdue_reminder/i18n/de.po @@ -763,10 +763,6 @@ msgstr "Nachricht auf der Voicemail hinterlassen" msgid "Minimum Delay Since Last Reminder" msgstr "Mindestverzögerung seit der letzten Erinnerung" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Mobil" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name diff --git a/account_invoice_overdue_reminder/i18n/es.po b/account_invoice_overdue_reminder/i18n/es.po index b65bb3107..0f41e4452 100644 --- a/account_invoice_overdue_reminder/i18n/es.po +++ b/account_invoice_overdue_reminder/i18n/es.po @@ -765,11 +765,6 @@ msgstr "Mensaje dejado en el correo de voz" msgid "Minimum Delay Since Last Reminder" msgstr "Retraso Mínimo Desde el Último Recordatorio" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Teléfono móvil" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name msgid "Name" diff --git a/account_invoice_overdue_reminder/i18n/fr.po b/account_invoice_overdue_reminder/i18n/fr.po index 35fabe5c5..460e6192d 100644 --- a/account_invoice_overdue_reminder/i18n/fr.po +++ b/account_invoice_overdue_reminder/i18n/fr.po @@ -767,11 +767,6 @@ msgstr "Message laissé sur répondeur" msgid "Minimum Delay Since Last Reminder" msgstr "Délai minimum depuis la dernière relance" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Portable" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name msgid "Name" diff --git a/account_invoice_overdue_reminder/i18n/it.po b/account_invoice_overdue_reminder/i18n/it.po index 2574aaf11..17789bb79 100644 --- a/account_invoice_overdue_reminder/i18n/it.po +++ b/account_invoice_overdue_reminder/i18n/it.po @@ -899,10 +899,6 @@ msgstr "Messaggio lasciato nella segreteria telefonica" msgid "Minimum Delay Since Last Reminder" msgstr "Ritardo minimo dall'ultimo promemoria" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Cellulare" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name diff --git a/account_invoice_overdue_reminder/i18n/nl.po b/account_invoice_overdue_reminder/i18n/nl.po index 41f69adee..9276f4306 100644 --- a/account_invoice_overdue_reminder/i18n/nl.po +++ b/account_invoice_overdue_reminder/i18n/nl.po @@ -752,11 +752,6 @@ msgstr "Bericht achtergelaten op voicemail" msgid "Minimum Delay Since Last Reminder" msgstr "Minimumvertraging sinds laatste herinnering" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Mobiel" - #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name msgid "Name" diff --git a/account_invoice_overdue_reminder/i18n/pt.po b/account_invoice_overdue_reminder/i18n/pt.po index d8ce8512d..4f90b89eb 100644 --- a/account_invoice_overdue_reminder/i18n/pt.po +++ b/account_invoice_overdue_reminder/i18n/pt.po @@ -751,10 +751,6 @@ msgstr "Mensagem deixada no gravador" msgid "Minimum Delay Since Last Reminder" msgstr "Mínimo atraso desde o último Aviso de cobrança" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Móvel" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name diff --git a/account_invoice_overdue_reminder/i18n/pt_BR.po b/account_invoice_overdue_reminder/i18n/pt_BR.po index 205374887..3deb42387 100644 --- a/account_invoice_overdue_reminder/i18n/pt_BR.po +++ b/account_invoice_overdue_reminder/i18n/pt_BR.po @@ -762,10 +762,6 @@ msgstr "Mensagem deixada na caixa postal" msgid "Minimum Delay Since Last Reminder" msgstr "Atraso Mínimo Desde o Último Lembrete" -#. module: account_invoice_overdue_reminder -#: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_step__partner_mobile -msgid "Mobile" -msgstr "Celular" #. module: account_invoice_overdue_reminder #: model:ir.model.fields,field_description:account_invoice_overdue_reminder.field_overdue_reminder_result__name diff --git a/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py b/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py deleted file mode 100644 index 2c6d78ec1..000000000 --- a/account_invoice_overdue_reminder/migrations/18.0.1.0.0/post-migration.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2025 Tecnativa - Víctor Martínez -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from openupgradelib import openupgrade, openupgrade_180 - - -@openupgrade.migrate() -def migrate(env, version): - openupgrade_180.convert_company_dependent(env, "res.partner", "no_overdue_reminder") diff --git a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py index 70863cff4..7f2d800a6 100644 --- a/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py +++ b/account_invoice_overdue_reminder/models/account_invoice_overdue_reminder.py @@ -2,7 +2,7 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.exceptions import ValidationError @@ -14,9 +14,7 @@ class AccountInvoiceOverdueReminder(models.Model): # For the link to invoice: why a M2O and not a M2M ? # Because of the "counter" field: a single reminder action for a customer, # the "counter" may not be the same for each invoice - invoice_id = fields.Many2one( - "account.move", string="Invoice", ondelete="cascade", readonly=True - ) + invoice_id = fields.Many2one("account.move", string="Invoice", ondelete="cascade") action_id = fields.Many2one( "overdue.reminder.action", string="Overdue Reminder Action", ondelete="cascade" ) @@ -32,28 +30,24 @@ class AccountInvoiceOverdueReminder(models.Model): action_result_id = fields.Many2one(related="action_id.result_id", readonly=False) action_result_notes = fields.Html(related="action_id.result_notes", readonly=False) action_mail_id = fields.Many2one(related="action_id.mail_id") - action_mail_cc = fields.Char( - related="action_id.mail_id.email_cc", readonly=True, string="Cc" - ) + action_mail_cc = fields.Char(related="action_id.mail_id.email_cc", string="Cc") action_mail_state = fields.Selection( related="action_id.mail_id.state", string="E-mail Status" ) - counter = fields.Integer(readonly=True) + counter = fields.Integer() company_id = fields.Many2one(related="invoice_id.company_id", store=True) - _sql_constraints = [ - ("counter_positive", "CHECK(counter >= 0)", "Counter must always be positive") - ] + _counter_positive = models.Constraint( + "CHECK(counter >= 0)", + "Counter must always be positive", + ) @api.constrains("invoice_id") def invoice_id_check(self): for action in self: - if action.invoice_id and action.invoice_id.move_type not in [ - "out_invoice", - "out_refund", - ]: + if action.invoice_id and not action.invoice_id.is_sale_document(): raise ValidationError( - _( + self.env._( "An overdue reminder can only be attached " "to a customer invoice or credit note" ) @@ -62,7 +56,8 @@ def invoice_id_check(self): @api.depends("invoice_id", "counter") def _compute_display_name(self): for rec in self: - name = _("%(invoice_name)s Reminder n°%(counter)d") % ( - {"invoice_name": rec.invoice_id.name, "counter": rec.counter} + rec.display_name = self.env._( + "%(invoice_name)s Reminder n°%(counter)d", + invoice_name=rec.invoice_id.name, + counter=rec.counter, ) - rec.display_name = name diff --git a/account_invoice_overdue_reminder/models/account_move.py b/account_invoice_overdue_reminder/models/account_move.py index 1fa1dce20..817d10cf4 100644 --- a/account_invoice_overdue_reminder/models/account_move.py +++ b/account_invoice_overdue_reminder/models/account_move.py @@ -34,13 +34,10 @@ class AccountMove(models.Model): ) overdue = fields.Boolean(compute="_compute_overdue") - _sql_constraints = [ - ( - "counter_positive", - "CHECK(overdue_reminder_counter >= 0)", - "Overdue Invoice Counter must always be positive", - ) - ] + _counter_positive = models.Constraint( + "CHECK(overdue_reminder_counter >= 0)", + "Overdue Invoice Counter must always be positive", + ) @api.depends("move_type", "state", "payment_state", "invoice_date_due") def _compute_overdue(self): diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_action.py b/account_invoice_overdue_reminder/models/overdue_reminder_action.py index 3e10d83de..1d0dcb41a 100644 --- a/account_invoice_overdue_reminder/models/overdue_reminder_action.py +++ b/account_invoice_overdue_reminder/models/overdue_reminder_action.py @@ -2,7 +2,7 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.tools.misc import format_date @@ -55,29 +55,27 @@ class OverdueReminderAction(models.Model): @api.model def _reminder_type_selection(self): return [ - ("mail", _("E-mail")), - ("phone", _("Phone")), - ("post", _("Letter")), + ("mail", "E-mail"), + ("phone", "Phone"), + ("post", "Letter"), ] @api.depends("reminder_ids") def _compute_invoice_count(self): - rg_res = self.env["account.invoice.overdue.reminder"].read_group( + rg_res = self.env["account.invoice.overdue.reminder"]._read_group( [("action_id", "in", self.ids), ("invoice_id", "!=", False)], ["action_id"], - ["action_id"], + ["__count"], ) - mapped_data = {x["action_id"][0]: x["action_id_count"] for x in rg_res} + mapped_data = {action.id: count for action, count in rg_res if action} for rec in self: rec.reminder_count = mapped_data.get(rec.id, 0) @api.depends("commercial_partner_id", "date") def _compute_display_name(self): for action in self: - name = _("%(partner_name)s, Reminder %(date)s") % ( - { - "partner_name": action.commercial_partner_id.display_name, - "date": format_date(self.env, action.date), - } + action.display_name = self.env._( + "%(partner_name)s, Reminder %(date)s", + partner_name=action.commercial_partner_id.display_name, + date=format_date(self.env, action.date), ) - action.display_name = name diff --git a/account_invoice_overdue_reminder/models/overdue_reminder_result.py b/account_invoice_overdue_reminder/models/overdue_reminder_result.py index d246250e3..29c4e6ba9 100644 --- a/account_invoice_overdue_reminder/models/overdue_reminder_result.py +++ b/account_invoice_overdue_reminder/models/overdue_reminder_result.py @@ -14,6 +14,7 @@ class OverdueReminderResult(models.Model): active = fields.Boolean(default=True) sequence = fields.Integer() - _sql_constraints = [ - ("name_unique", "unique(name)", "This overdue reminder result already exists") - ] + _name_unique = models.Constraint( + "unique(name)", + "This overdue reminder result already exists", + ) diff --git a/account_invoice_overdue_reminder/models/res_company.py b/account_invoice_overdue_reminder/models/res_company.py index 090bd0475..ec651ae4e 100644 --- a/account_invoice_overdue_reminder/models/res_company.py +++ b/account_invoice_overdue_reminder/models/res_company.py @@ -2,7 +2,7 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models +from odoo import api, fields, models class ResCompany(models.Model): @@ -34,27 +34,23 @@ class ResCompany(models.Model): @api.model def _overdue_reminder_interface_selection(self): return [ - ("onebyone", _("One by One")), - ("mass", _("Mass")), + ("onebyone", "One by One"), + ("mass", "Mass"), ] @api.model def _overdue_reminder_partner_policy_selection(self): return [ - ("last_reminder", _("Last Reminder")), - ("last_invoice", _("Last Invoice")), - ("invoice_contact", _("Invoice Contact")), + ("last_reminder", "Last Reminder"), + ("last_invoice", "Last Invoice"), + ("invoice_contact", "Invoice Contact"), ] - _sql_constraints = [ - ( - "overdue_reminder_start_days_positive", - "CHECK(overdue_reminder_start_days >= 0)", - "Overdue Reminder Trigger Delay must always be positive", - ), - ( - "overdue_reminder_min_interval_days_positive", - "CHECK(overdue_reminder_min_interval_days > 0)", - "Overdue Reminder Minimum Interval must always be strictly positive", - ), - ] + _overdue_reminder_start_days_positive = models.Constraint( + "CHECK(overdue_reminder_start_days >= 0)", + "Overdue Reminder Trigger Delay must always be positive", + ) + _overdue_reminder_min_interval_days_positive = models.Constraint( + "CHECK(overdue_reminder_min_interval_days > 0)", + "Overdue Reminder Minimum Interval must always be strictly positive", + ) diff --git a/account_invoice_overdue_reminder/static/description/index.html b/account_invoice_overdue_reminder/static/description/index.html index 4b46e9300..64a4eb8b7 100644 --- a/account_invoice_overdue_reminder/static/description/index.html +++ b/account_invoice_overdue_reminder/static/description/index.html @@ -374,7 +374,7 @@

Overdue Invoice Reminder

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:b6e15d13e201281878ea28fa9f232d5f3f225fa9ae11d390c5b305190976f713 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/credit-control Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/credit-control Translate me on Weblate Try me on Runboat

This Odoo module is designed to send overdue invoice reminders to customers. It handles reminders by e-mail, letter and phone.

This module is an alternative to the OCA module @@ -493,7 +493,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -521,7 +521,7 @@

Maintainers

promote its widespread use.

Current maintainer:

alexis-via

-

This module is part of the OCA/credit-control project on GitHub.

+

This module is part of the OCA/credit-control project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/account_invoice_overdue_reminder/tests/__init__.py b/account_invoice_overdue_reminder/tests/__init__.py new file mode 100644 index 000000000..8ff4fd361 --- /dev/null +++ b/account_invoice_overdue_reminder/tests/__init__.py @@ -0,0 +1,8 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from . import test_account_invoice_overdue_reminder +from . import test_account_move +from . import test_overdue_reminder_action +from . import test_overdue_reminder_start +from . import test_overdue_reminder_step +from . import test_overdue_reminder_mass_update diff --git a/account_invoice_overdue_reminder/tests/test_account_invoice_overdue_reminder.py b/account_invoice_overdue_reminder/tests/test_account_invoice_overdue_reminder.py new file mode 100644 index 000000000..cc4506dc2 --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_account_invoice_overdue_reminder.py @@ -0,0 +1,112 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command +from odoo.exceptions import ValidationError +from odoo.tests.common import TransactionCase + + +class TestAccountInvoiceOverdueReminder(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create({"name": "Test Customer"}) + cls.invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "invoice_line_ids": [ + Command.create( + { + "name": "Test line", + "quantity": 1, + "price_unit": 100, + }, + ) + ], + } + ) + cls.invalid_invoice = cls.env["account.move"].create( + { + "move_type": "in_invoice", + "partner_id": cls.partner.id, + "invoice_line_ids": [ + Command.create( + { + "name": "Vendor line", + "quantity": 1, + "price_unit": 100, + }, + ) + ], + } + ) + cls.reminder_action = cls.env["overdue.reminder.action"].create( + { + "commercial_partner_id": cls.partner.id, + "partner_id": cls.partner.id, + "date": "2024-01-01", + "user_id": cls.env.ref("base.user_admin").id, + "reminder_type": "mail", + } + ) + + def test_accept_out_invoice(self): + rec = self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.invoice.id, + "action_id": self.reminder_action.id, + "counter": 1, + } + ) + self.assertTrue(rec.exists()) + self.assertEqual(rec.counter, 1) + + def test_display_name_compute(self): + rec = self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.invoice.id, + "action_id": self.reminder_action.id, + "counter": 3, + } + ) + expected = f"{self.invoice.name} Reminder n°3" + self.assertEqual(rec.display_name, expected) + + def test_reject_in_invoice(self): + with self.assertRaisesRegex( + ValidationError, + "An overdue reminder can only be attached to a customer " + "invoice or credit note", + ): + self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.invalid_invoice.id, + "action_id": self.reminder_action.id, + "counter": 1, + } + ) + + def test_accept_credit_note(self): + credit_note = self.env["account.move"].create( + { + "move_type": "out_refund", + "partner_id": self.partner.id, + "invoice_line_ids": [ + Command.create( + { + "name": "Test refund line", + "quantity": 1, + "price_unit": 100, + }, + ) + ], + } + ) + rec = self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": credit_note.id, + "action_id": self.reminder_action.id, + "counter": 1, + } + ) + self.assertTrue(rec.exists()) diff --git a/account_invoice_overdue_reminder/tests/test_account_move.py b/account_invoice_overdue_reminder/tests/test_account_move.py new file mode 100644 index 000000000..363615896 --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_account_move.py @@ -0,0 +1,125 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command, fields +from odoo.tests.common import TransactionCase + + +class TestAccountMove(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create({"name": "Test Customer"}) + cls.company = cls.env.company + cls.overdue_invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "invoice_date_due": fields.Date.subtract(fields.Date.today(), days=5), + "invoice_line_ids": [ + Command.create( + { + "name": "Test line overdue", + "quantity": 1, + "price_unit": 100, + }, + ) + ], + "company_id": cls.company.id, + } + ) + cls.overdue_invoice.action_post() + cls.overdue_invoice.payment_state = "not_paid" + cls.not_due_invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "invoice_date_due": fields.Date.add(fields.Date.today(), days=5), + "invoice_line_ids": [ + Command.create( + { + "name": "Test line not due", + "quantity": 1, + "price_unit": 100, + }, + ) + ], + "company_id": cls.company.id, + } + ) + cls.not_due_invoice.action_post() + cls.not_due_invoice.payment_state = "not_paid" + + cls.reminder_action = cls.env["overdue.reminder.action"].create( + { + "commercial_partner_id": cls.partner.id, + "partner_id": cls.partner.id, + "date": fields.Date.today(), + "user_id": cls.env.ref("base.user_admin").id, + "reminder_type": "mail", + } + ) + + def test_overdue_computation(self): + self.assertTrue(self.overdue_invoice.overdue, "Invoice should be overdue") + self.assertFalse(self.not_due_invoice.overdue, "Invoice should not be overdue") + + def test_overdue_reminder_counter_initial(self): + self.assertEqual(self.overdue_invoice.overdue_reminder_counter, 0) + self.assertFalse(self.overdue_invoice.overdue_reminder_last_date) + + def test_overdue_remind_sent_logic(self): + company = self.env.company + company.overdue_reminder_min_interval_days = 3 + self.assertFalse(self.overdue_invoice.overdue_remind_sent) + self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.overdue_invoice.id, + "action_id": self.reminder_action.id, + "counter": 1, + "action_date": fields.Date.subtract(fields.Date.today(), days=1), + } + ) + self.overdue_invoice._compute_overdue_reminder_sent() + self.assertTrue(self.overdue_invoice.overdue_remind_sent) + + def test_compute_overdue_reminder_multiple(self): + self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.overdue_invoice.id, + "action_id": self.reminder_action.id, + "counter": 1, + "action_date": fields.Date.subtract(fields.Date.today(), days=5), + } + ) + self.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": self.overdue_invoice.id, + "action_id": self.reminder_action.id, + "counter": 3, + "action_date": fields.Date.subtract(fields.Date.today(), days=1), + } + ) + self.overdue_invoice._compute_overdue_reminder() + reminder = self.env["account.invoice.overdue.reminder"].search( + [("invoice_id", "=", self.overdue_invoice.id)], + order="action_date desc, id desc", + limit=1, + ) + self.assertEqual( + self.overdue_invoice.overdue_reminder_last_date, reminder.action_date + ) + self.assertEqual( + self.overdue_invoice.overdue_reminder_counter, reminder.counter + ) + + def test_no_overdue_reminder_flag(self): + self.overdue_invoice.no_overdue_reminder = True + self.assertTrue( + self.overdue_invoice.no_overdue_reminder, + "Invoice should have no_overdue_reminder=True", + ) + self.overdue_invoice._compute_overdue() + self.assertTrue( + self.overdue_invoice.overdue, + "Overdue may still be True, we are only testing the flag here", + ) diff --git a/account_invoice_overdue_reminder/tests/test_overdue_reminder_action.py b/account_invoice_overdue_reminder/tests/test_overdue_reminder_action.py new file mode 100644 index 000000000..f8356865b --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_overdue_reminder_action.py @@ -0,0 +1,64 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command, fields +from odoo.tests.common import TransactionCase +from odoo.tools.misc import format_date + + +class TestOverdueReminderAction(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create({"name": "Test Partner"}) + cls.product = cls.env["product.product"].create({"name": "Test Product"}) + uom_unit = cls.env.ref("uom.product_uom_unit") + cls.invoice_model = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "invoice_date": "2025-12-31", + "line_ids": [ + Command.create( + { + "name": "Test line", + "partner_id": cls.partner.id, + "quantity": 1.0, + "price_unit": 100.0, + "product_id": cls.product.id, + "product_uom_id": uom_unit.id, + }, + ) + ], + } + ) + cls.reminder_action = cls.env["overdue.reminder.action"].create( + { + "reminder_type": "mail", + "partner_id": cls.partner.id, + "commercial_partner_id": cls.partner.id, + } + ) + cls.reminder_model = cls.env["account.invoice.overdue.reminder"].create( + { + "invoice_id": cls.invoice_model.id, + "action_id": cls.reminder_action.id, + "counter": 0, + } + ) + + def test_default_values(self): + self.assertEqual(self.reminder_action.user_id, self.env.user) + self.assertEqual(self.reminder_action.reminder_type, "mail") + self.assertEqual( + self.reminder_action.date, fields.Date.context_today(self.reminder_action) + ) + + def test_compute_invoice_count(self): + self.reminder_action._compute_invoice_count() + self.assertEqual(self.reminder_action.reminder_count, 1) + + def test_compute_display_name(self): + self.reminder_action._compute_display_name() + self.assertIn("Test Partner", self.reminder_action.display_name) + expected_date = format_date(self.env, self.reminder_action.date) + self.assertIn(expected_date, self.reminder_action.display_name) diff --git a/account_invoice_overdue_reminder/tests/test_overdue_reminder_mass_update.py b/account_invoice_overdue_reminder/tests/test_overdue_reminder_mass_update.py new file mode 100644 index 000000000..b7138fe5c --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_overdue_reminder_mass_update.py @@ -0,0 +1,77 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command, fields +from odoo.exceptions import UserError + +from odoo.addons.base.tests.common import BaseCommon + + +class TestOverdueRemindMassUpdate(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create( + { + "name": "Test Partner", + "email": "test@example.com", + } + ) + cls.user_admin = cls.env.ref("base.user_admin") + cls.invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "invoice_date": fields.Date.today(), + "invoice_date_due": fields.Date.today(), + } + ) + cls.step = cls.env["overdue.reminder.step"].create( + { + "partner_id": cls.partner.id, + "commercial_partner_id": cls.partner.id, + "user_id": cls.user_admin.id, + "invoice_ids": [Command.set(cls.invoice.ids)], + "reminder_type": "mail", + } + ) + + def _create_wizard(self, update_action, reminder_type=None): + return self.env["overdue.reminder.mass.update"].create( + { + "update_action": update_action, + "reminder_type": reminder_type, + } + ) + + def test_run_validate(self): + wizard_rec = self._create_wizard("validate") + wizard_rec.with_context( + active_model="overdue.reminder.step", active_ids=[self.step.id] + ).run() + self.assertEqual(self.step.state, "done") + + def test_run_skip(self): + wizard_rec = self._create_wizard("skip") + wizard_rec.with_context( + active_model="overdue.reminder.step", active_ids=[self.step.id] + ).run() + self.assertEqual(self.step.state, "skipped") + + def test_run_reminder_type_change(self): + wizard = self.env["overdue.reminder.mass.update"].create( + { + "update_action": "reminder_type", + "reminder_type": "phone", + } + ) + wizard.with_context( + active_model="overdue.reminder.step", active_ids=[self.step.id] + ).run() + self.assertEqual(self.step.reminder_type, "phone") + + def test_run_reminder_type_missing(self): + wizard = self._create_wizard("reminder_type") + with self.assertRaises(UserError): + wizard.with_context( + active_model="overdue.reminder.step", active_ids=[self.step.id] + ).run() diff --git a/account_invoice_overdue_reminder/tests/test_overdue_reminder_start.py b/account_invoice_overdue_reminder/tests/test_overdue_reminder_start.py new file mode 100644 index 000000000..95de54d2d --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_overdue_reminder_start.py @@ -0,0 +1,145 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command, fields +from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase + + +class TestOverdueReminderStart(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.company = cls.env.company + cls.partner = cls.env["res.partner"].create( + { + "name": "Test Customer", + "customer_rank": 1, + } + ) + cls.user = cls.env.user + cls.invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "commercial_partner_id": cls.partner.id, + "invoice_date": fields.Date.subtract(fields.Date.today(), days=30), + "invoice_date_due": fields.Date.subtract(fields.Date.today(), days=15), + "invoice_line_ids": [ + Command.create( + { + "name": "Test Line", + "quantity": 1, + "price_unit": 100, + } + ), + ], + } + ) + cls.invoice.action_post() + cls.wizard = cls.env["overdue.reminder.start"].create( + { + "start_days": 5, + "min_interval_days": 5, + "company_id": cls.company.id, + "partner_policy": "invoice_contact", + "interface": "onebyone", + } + ) + + def test_default_get(self): + values = self.wizard.default_get( + ["start_days", "min_interval_days", "partner_policy", "payment_ids"] + ) + self.assertIn("start_days", values) + self.assertIn("payment_ids", values) + + def test_prepare_base_domain(self): + domain = self.wizard._prepare_base_domain() + self.assertIn(("company_id", "=", self.company.id), domain) + self.assertIn(("state", "=", "posted"), domain) + + def test_run_interface_onebyone_and_mass(self): + """ + Test the run method for both 'onebyone' and 'mass' interfaces, + ensuring both the 'if vals:' and interface branches are covered. + """ + self.invoice.write( + { + "invoice_date_due": fields.Date.subtract(fields.Date.today(), days=10), + "payment_state": "not_paid", + "amount_residual": self.invoice.amount_total, + } + ) + self.wizard.start_days = 0 + self.wizard.min_interval_days = 1 + self.wizard.partner_ids = self.partner + + self.wizard.interface = "onebyone" + action_one = self.wizard.run() + self.assertIn("res_id", action_one) + self.assertIsInstance(action_one["res_id"], int) + steps = self.env["overdue.reminder.step"].search( + [ + ("commercial_partner_id", "=", self.partner.id), + ] + ) + self.assertGreater(len(steps), 0) + self.wizard.interface = "mass" + action_mass = self.wizard.run() + self.assertEqual(action_mass["type"], "ir.actions.act_window") + self.assertEqual(action_mass["res_model"], "overdue.reminder.step") + + def test_prepare_remind_trigger_domain(self): + base = self.wizard._prepare_base_domain() + domain = self.wizard._prepare_remind_trigger_domain(base) + self.assertTrue(any(d[0] == "invoice_date_due" for d in domain)) + + def test_run_negative_start_days(self): + self.wizard.start_days = -1 + with self.assertRaises(UserError): + self.wizard.run() + + def test_run_invalid_min_interval(self): + self.wizard.start_days = 1 + self.wizard.min_interval_days = 0 + with self.assertRaises(UserError): + self.wizard.run() + + def test_run_no_overdue_reminders(self): + self.wizard.start_days = 0 + no_invoice_partner = self.env["res.partner"].create( + { + "name": "No Invoice Partner", + "customer_rank": 1, + } + ) + self.wizard.partner_ids = no_invoice_partner + with self.assertRaises(UserError): + self.wizard.run() + + steps = self.env["overdue.reminder.step"].search( + [ + ("commercial_partner_id", "=", no_invoice_partner.id), + ] + ) + self.assertEqual(len(steps), 0) + + def test_run_creates_reminder_step(self): + self.invoice.write( + { + "invoice_date_due": fields.Date.subtract(fields.Date.today(), days=10), + "payment_state": "not_paid", + "amount_residual": self.invoice.amount_total, + } + ) + self.wizard.start_days = 5 + self.wizard.min_interval_days = 1 + self.wizard.partner_ids = self.partner + action = self.wizard.run() + self.assertTrue(action) + steps = self.env["overdue.reminder.step"].search( + [ + ("commercial_partner_id", "=", self.partner.id), + ] + ) + self.assertGreater(len(steps), 0) diff --git a/account_invoice_overdue_reminder/tests/test_overdue_reminder_step.py b/account_invoice_overdue_reminder/tests/test_overdue_reminder_step.py new file mode 100644 index 000000000..2a0697bd3 --- /dev/null +++ b/account_invoice_overdue_reminder/tests/test_overdue_reminder_step.py @@ -0,0 +1,223 @@ +# Copyright 2026 NICO SOLUTIONS - ENGINEERING & IT, Nils Coenen +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from unittest.mock import Mock, patch + +from odoo import Command, fields +from odoo.exceptions import UserError + +from odoo.addons.account_invoice_overdue_reminder.wizard import ( + overdue_reminder_wizard as wizard, +) +from odoo.addons.base.tests.common import BaseCommon + + +class TestOverdueReminderStep(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.company = cls.env.company + cls.partner = cls.env["res.partner"].create( + { + "name": "Test Customer", + "email": "test@example.com", + } + ) + cls.user = cls.env.user + cls.invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": cls.partner.id, + "commercial_partner_id": cls.partner.id, + "invoice_date": fields.Date.today(), + "invoice_date_due": fields.Date.today(), + "invoice_line_ids": [ + Command.create( + { + "name": "Test Line", + "quantity": 1, + "price_unit": 100, + } + ) + ], + } + ) + cls.invoice.action_post() + cls.step = cls.env["overdue.reminder.step"].create( + { + "partner_id": cls.partner.id, + "commercial_partner_id": cls.partner.id, + "user_id": cls.user.id, + "invoice_ids": [Command.set(cls.invoice.ids)], + "reminder_type": "mail", + "company_id": cls.company.id, + } + ) + + def test_compute_counter_and_mail(self): + self.step._compute_counter_and_mail() + self.assertGreaterEqual(self.step.counter, 1) + self.assertTrue(self.step.mail_subject) + self.assertTrue(self.step.mail_body) + + def test_reminder_type_change(self): + self.step.reminder_type_change() + self.assertFalse(self.step.result_id) + self.assertFalse(self.step.result_notes) + self.assertFalse(self.step.create_activity) + self.step.reminder_type = "phone" + self.step.reminder_type_change() + self.assertEqual(self.step.reminder_type, "phone") + + def test_skip(self): + self.step.skip() + self.assertEqual(self.step.state, "skipped") + + def test_total_residual(self): + totals = dict(self.step.total_residual()) + self.assertIn(self.invoice.currency_id, totals) + self.assertEqual(totals[self.invoice.currency_id], self.invoice.amount_residual) + + def test_validate_mail_and_generate_mail_vals(self): + """ + This test verifies that mail values can be generated correctly from + an overdue reminder step. External dependencies like template rendering + are mocked to isolate the test from actual QWeb templates or email sending. + """ + self.step.mail_subject = "Test Subject" + self.step.mail_body = "

Test Body

" + self.assertTrue(self.step.validate_mail()) + with patch.object( + type(self.step), + "_get_overdue_invoice_reminder_template", + return_value="module.template_xmlid", + ): + with patch.object(self.env, "ref") as mock_ref: + mock_template = mock_ref.return_value + mock_template._generate_template.return_value = { + self.step.id: {"email_from": "from@test.com"} + } + vals = self.step.generate_mail_vals() + self.assertIn("mail_id", vals) + + def test_validate_phone(self): + self.step.reminder_type = "phone" + vals = self.step.validate_phone() + self.assertIn("result_id", vals) + self.assertIn("result_notes", vals) + + def test_validate_post_raises(self): + self.step.reminder_type = "post" + self.step.letter_printed = False + with self.assertRaises(UserError): + self.step.validate_post() + + def test_prepare_mail_activity_raises(self): + self.step.activity_user_id = False + with self.assertRaises(UserError): + self.step._prepare_mail_activity() + self.step.activity_user_id = self.user + self.step.activity_deadline = False + with self.assertRaises(UserError): + self.step._prepare_mail_activity() + + def test_check_warnings_raises(self): + self.step.company_id = self.env["res.company"].create({"name": "Other"}) + with self.assertRaises(UserError): + self.step.check_warnings() + self.step.company_id = self.company + + def test_validate_no_invoices(self): + self.step.invoice_ids = [(5, 0, 0)] + with self.assertRaises(UserError): + self.step.validate() + + def test_get_report_base_filename(self): + fname = self.step._get_report_base_filename() + self.assertIn("overdue_letter", fname) + + def test_prepare_overdue_reminder_action(self): + """ + This test validates that _prepare_overdue_reminder_action sets the + expected values and triggers a message_post. + We mock MailThread.message_post to avoid actually sending an email, + and to allow verifying that the method was called. + """ + vals = {"reminder_ids": [], "mail_id": 1} + with patch( + "odoo.addons.mail.models.mail_thread.MailThread.message_post" + ) as mock_post: + self.step._prepare_overdue_reminder_action(vals) + self.assertIn("user_id", vals) + self.assertEqual(vals["user_id"], self.step.user_id.id) + self.assertTrue(mock_post.called) + + def test_print_letter_and_print_invoices(self): + """ + This test verifies that printing invoices and overdue reminder letters + triggers the expected report actions. + - check_warnings is mocked to skip any validation logic. + - report_action is mocked for both invoices and letters to avoid + actually generating reports and to allow verifying the call and return value. + """ + with patch.object( + wizard.OverdueReminderStep, "check_warnings", return_value=None + ): + report_account_invoices = self.env.ref("account.account_invoices") + with patch.object( + type(report_account_invoices), + "report_action", + return_value="report_action_called", + ): + res = self.step.print_invoices() + self.assertEqual(res, "report_action_called") + + report_letter = self.env.ref( + "account_invoice_overdue_reminder.overdue_reminder_step_report" + ) + with patch.object( + type(report_letter), + "report_action", + return_value="letter_report_action", + ): + res_letter = self.step.print_letter() + self.assertEqual(res_letter, "letter_report_action") + + def test_validate_successful_mail_and_validate_method(self): + """ + This test validates the full mail reminder flow while mocking + external dependencies such as template rendering, email sending + and UI navigation actions. + """ + self.step.mail_subject = "Subject" + self.step.mail_body = "

Body

" + mock_template = Mock() + mock_template._generate_template.return_value = { + self.step.id: {"email_from": "from@test.com"} + } + with ( + patch.object( + type(self.step), + "_get_overdue_invoice_reminder_template", + return_value="module.template_xmlid", + ), + patch.object(self.env, "ref", return_value=mock_template), + patch("odoo.addons.mail.models.mail_mail.MailMail.send", return_value=True), + patch.object(type(self.step), "_get_attachment_ids", return_value=[]), + patch.object( + type(self.step), + "goto_list_view", + return_value={"type": "ir.actions.act_window"}, + ), + ): + action = self.step.validate() + self.assertEqual(self.step.state, "done") + self.assertEqual(action["type"], "ir.actions.act_window") + actions = self.env["overdue.reminder.action"].search( + [("partner_id", "=", self.partner.id)], limit=1 + ) + self.assertTrue(actions.mail_id) + self.assertEqual( + self.env["mail.mail"].search_count([("subject", "=", "Subject")]), 1 + ) + self.assertEqual(actions.mail_id.subject, "Subject") + self.assertIn("Body", actions.mail_id.body_html) diff --git a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml index cf390cee9..a3c97b368 100644 --- a/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml +++ b/account_invoice_overdue_reminder/views/account_invoice_overdue_reminder.xml @@ -11,7 +11,11 @@ - + @@ -52,9 +57,13 @@ - + - + @@ -65,7 +74,11 @@ account.invoice.overdue.reminder - + 100 - - + + diff --git a/account_invoice_overdue_reminder/views/overdue_reminder_result.xml b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml index a606957ab..6d7beee18 100644 --- a/account_invoice_overdue_reminder/views/overdue_reminder_result.xml +++ b/account_invoice_overdue_reminder/views/overdue_reminder_result.xml @@ -61,6 +61,6 @@ id="overdue_reminder_result_menu" action="overdue_reminder_result_action" sequence="100" - parent="account.account_management_menu" + parent="account.menu_finance" /> diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py index 51d26b024..49897dc61 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard.py @@ -9,7 +9,7 @@ from dateutil.relativedelta import relativedelta from markupsafe import Markup -from odoo import Command, _, api, fields, models, tools +from odoo import Command, api, fields, models, tools from odoo.exceptions import UserError logger = logging.getLogger(__name__) @@ -119,14 +119,15 @@ def _prepare_remind_trigger_domain(self, base_domain): def run(self): self.ensure_one() if self.start_days < 0: - raise UserError(_("The trigger delay cannot be negative.")) + raise UserError(self.env._("The trigger delay cannot be negative.")) if self.min_interval_days < 1: raise UserError( - _("The minimum delay since last reminder must be strictly positive.") + self.env._( + "The minimum delay since last reminder must be strictly positive." + ) ) amo = self.env["account.move"] ajo = self.env["account.journal"] - rpo = self.env["res.partner"] orso = self.env["overdue.reminder.step"] user_id = self.env.user.id existing_actions = orso.search([("user_id", "=", user_id)]) @@ -153,19 +154,18 @@ def run(self): # whereas search 2 compares due_date to today base_domain = self._prepare_base_domain() domain = self._prepare_remind_trigger_domain(base_domain) - rg_res = amo.read_group( + rg_res = amo._read_group( domain, - ["commercial_partner_id", "amount_residual_signed"], ["commercial_partner_id"], + ["amount_residual_signed:sum"], ) # Sort by residual amount desc - rg_res_sorted = sorted( - rg_res, key=lambda to_sort: to_sort["amount_residual_signed"], reverse=True - ) + rg_res_sorted = sorted(rg_res, key=lambda to_sort: to_sort[1], reverse=True) action_ids = [] for rg_re in rg_res_sorted: - commercial_partner_id = rg_re["commercial_partner_id"][0] - commercial_partner = rpo.browse(commercial_partner_id) + commercial_partner = rg_re[0] + if not commercial_partner: + continue vals = self._prepare_reminder_step( commercial_partner, base_domain, @@ -177,7 +177,7 @@ def run(self): action = orso.create(vals) action_ids.append(action.id) if not action_ids: - raise UserError(_("There are no overdue reminders.")) + raise UserError(self.env._("There are no overdue reminders.")) if self.interface == "onebyone": xid = MOD + ".overdue_reminder_step_onebyone_action" action = self.env["ir.actions.actions"]._for_xml_id(xid) @@ -309,7 +309,6 @@ class OverdueReminderStep(models.TransientModel): ) partner_email = fields.Char(related="partner_id.email", readonly=True) partner_phone = fields.Char(related="partner_id.phone", readonly=True) - partner_mobile = fields.Char(related="partner_id.mobile", readonly=True) commercial_partner_id = fields.Many2one( "res.partner", string="Customer", readonly=True, required=True ) @@ -437,8 +436,10 @@ def next_step(self): "tag": "display_notification", "params": { "type": "success", - "title": _("Good job!"), - "message": _("You processed all your overdue invoice reminders."), + "title": self.env._("Good job!"), + "message": self.env._( + "You processed all your overdue invoice reminders." + ), "next": {"type": "ir.actions.act_window_close"}, }, } @@ -451,7 +452,7 @@ def goto_list_view(self): return action def skip(self): - self.write({"state": "skipped"}) + self.state = "skipped" if len(self) == 1: if self.interface == "onebyone": action = self.next_step() @@ -464,19 +465,19 @@ def _prepare_mail_activity(self): partner_model_id = self.env.ref("base.model_res_partner").id if not self.activity_user_id: raise UserError( - _( - "For the reminder of customer '%s', you must assign someone " - "for the activity." + self.env._( + "For the reminder of customer '%(customer)s', " + "you must assign someone for the activity.", + customer=self.commercial_partner_id.display_name, ) - % self.commercial_partner_id.display_name ) if not self.activity_deadline: raise UserError( - _( - "For the reminder of customer '%s', the deadline is missing " - "for the activity." + self.env._( + "For the reminder of customer '%(customer)s'," + "the deadline is missing for the activity.", + customer=self.commercial_partner_id.display_name, ) - % self.commercial_partner_id.display_name ) vals = { "activity_type_id": self.activity_type_id.id or False, @@ -493,7 +494,7 @@ def check_warnings(self): for rec in self: if rec.company_id != self.env.company: raise UserError( - _( + self.env._( "User company is different from action company. " "This should never happen." ) @@ -506,8 +507,10 @@ def validate(self): for rec in self: if not rec.invoice_ids: raise UserError( - _("There are no invoices to remind for customer '%s'.") - % rec.commercial_partner_id.display_name + self.env._( + "There are no invoices to remind for customer '%(customer)s'.", + customer=rec.commercial_partner_id.display_name, + ) ) vals = {} if rec.reminder_type == "mail" and rec.validate_mail(): @@ -520,7 +523,7 @@ def validate(self): orao.create(vals) if rec.create_activity: mao.create(self._prepare_mail_activity()) - self.write({"state": "done"}) + self.state = "done" if len(self) == 1: if self.interface == "onebyone": action = self.next_step() @@ -555,12 +558,15 @@ def validate_mail(self): self.ensure_one() if not self.partner_id.email: raise UserError( - _("E-mail missing on partner '%s'.") % self.partner_id.display_name + self.env._( + "E-mail missing on partner '%(partner)s'.", + partner=self.partner_id.display_name, + ) ) if not self.mail_subject: - raise UserError(_("Mail subject is empty.")) + raise UserError(self.env._("Mail subject is empty.")) if not self.mail_body: - raise UserError(_("Mail body is empty.")) + raise UserError(self.env._("Mail body is empty.")) return True def generate_mail_vals(self): @@ -587,7 +593,7 @@ def generate_mail_vals(self): mail = self.env["mail.mail"].sudo().create(mvals) if self.company_id.overdue_reminder_attach_invoice: attachment_ids = self._get_attachment_ids(mail) - mail.write({"attachment_ids": [Command.set(attachment_ids)]}) + mail.attachment_ids = [Command.set(attachment_ids)] vals = {"mail_id": mail.id} return vals @@ -604,7 +610,7 @@ def validate_post(self): self.ensure_one() assert self.reminder_type == "post" if not self.letter_printed: - raise UserError(_("Remind letter hasn't been printed!")) + raise UserError(self.env._("Remind letter hasn't been printed!")) return {} def _prepare_overdue_reminder_action(self, vals): @@ -626,7 +632,7 @@ def _prepare_overdue_reminder_action(self, vals): if self.reminder_type == "mail": inv.message_post( body=Markup( - _( + self.env._( "Overdue reminder sent by mail: " "%(mail_subject)s.", @@ -638,7 +644,7 @@ def _prepare_overdue_reminder_action(self, vals): elif self.reminder_type == "phone": inv.message_post( body=Markup( - _( + self.env._( "Overdue reminder by phone. " "Result/Info: %(result)s.", result=self.result_id.name, @@ -647,12 +653,14 @@ def _prepare_overdue_reminder_action(self, vals): ) elif self.reminder_type == "post": inv.message_post( - body=Markup(_("Overdue reminder sent by post.")) + body=Markup( + self.env._("Overdue reminder sent by post.") + ) ) def print_letter(self): self.check_warnings() - self.write({"letter_printed": True}) + self.letter_printed = True action = action = ( self.env.ref(MOD + ".overdue_reminder_step_report") .with_context(discard_logo_check=True) @@ -682,7 +690,7 @@ def total_residual(self): def _get_report_base_filename(self): self.ensure_one() partner_name = self.commercial_partner_id.name.replace(" ", "_") - fname = _("overdue_letter-%s") % partner_name + fname = self.env._("overdue_letter-%(partner)s", partner=partner_name) return fname @@ -709,9 +717,9 @@ def _reminder_type_selection(self): def run(self): self.ensure_one() - assert self._context.get("active_model") == "overdue.reminder.step" + assert self.env.context.get("active_model") == "overdue.reminder.step" actions = self.env["overdue.reminder.step"].browse( - self._context.get("active_ids") + self.env.context.get("active_ids") ) if self.update_action == "validate": actions.validate() @@ -719,6 +727,6 @@ def run(self): actions.skip() elif self.update_action == "reminder_type": if not self.reminder_type: - raise UserError(_("You must select the new reminder type.")) - actions.write({"reminder_type": self.reminder_type}) + raise UserError(self.env._("You must select the new reminder type.")) + actions.reminder_type = self.reminder_type return diff --git a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml index b22b3171b..755328b8f 100644 --- a/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml +++ b/account_invoice_overdue_reminder/wizard/overdue_reminder_wizard_view.xml @@ -124,8 +124,7 @@ - - + s