From 0ac84bfd2ef98060805cd89cc4a120391eaa83b1 Mon Sep 17 00:00:00 2001 From: Saran440 Date: Fri, 26 May 2023 09:06:56 +0700 Subject: [PATCH 01/15] [15.0][ADD] hr_expense_advance_overdue_reminder --- .../README.rst | 126 +++++ .../__init__.py | 4 + .../__manifest__.py | 26 + .../data/mail_template.xml | 84 ++++ .../data/sequence_data.xml | 9 + .../models/__init__.py | 6 + .../models/base_reminder_mixin.py | 35 ++ .../models/hr_advance_overdue_reminder.py | 243 +++++++++ .../models/hr_expense_sheet.py | 103 ++++ .../models/reminder_definition.py | 28 ++ .../readme/CONFIGURE.rst | 6 + .../readme/CONTRIBUTORS.rst | 4 + .../readme/DESCRIPTION.rst | 9 + .../readme/USAGE.rst | 20 + .../security/ir.model.access.csv | 8 + .../static/description/index.html | 469 ++++++++++++++++++ .../tests/__init__.py | 3 + ...est_hr_expense_advance_overdue_reminder.py | 210 ++++++++ .../views/hr_advance_overdue_view.xml | 196 ++++++++ .../views/hr_expense_views.xml | 107 ++++ .../views/reminder_definition_view.xml | 99 ++++ .../wizard/__init__.py | 4 + .../hr_advance_overdue_reminder_wizard.py | 129 +++++ .../hr_advance_overdue_reminder_wizard.xml | 70 +++ .../wizard/mail_compose_message.py | 15 + 25 files changed, 2013 insertions(+) create mode 100644 hr_expense_advance_overdue_reminder/README.rst create mode 100644 hr_expense_advance_overdue_reminder/__init__.py create mode 100644 hr_expense_advance_overdue_reminder/__manifest__.py create mode 100644 hr_expense_advance_overdue_reminder/data/mail_template.xml create mode 100644 hr_expense_advance_overdue_reminder/data/sequence_data.xml create mode 100644 hr_expense_advance_overdue_reminder/models/__init__.py create mode 100644 hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py create mode 100644 hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py create mode 100644 hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py create mode 100644 hr_expense_advance_overdue_reminder/models/reminder_definition.py create mode 100644 hr_expense_advance_overdue_reminder/readme/CONFIGURE.rst create mode 100644 hr_expense_advance_overdue_reminder/readme/CONTRIBUTORS.rst create mode 100644 hr_expense_advance_overdue_reminder/readme/DESCRIPTION.rst create mode 100644 hr_expense_advance_overdue_reminder/readme/USAGE.rst create mode 100644 hr_expense_advance_overdue_reminder/security/ir.model.access.csv create mode 100644 hr_expense_advance_overdue_reminder/static/description/index.html create mode 100644 hr_expense_advance_overdue_reminder/tests/__init__.py create mode 100644 hr_expense_advance_overdue_reminder/tests/test_hr_expense_advance_overdue_reminder.py create mode 100644 hr_expense_advance_overdue_reminder/views/hr_advance_overdue_view.xml create mode 100644 hr_expense_advance_overdue_reminder/views/hr_expense_views.xml create mode 100644 hr_expense_advance_overdue_reminder/views/reminder_definition_view.xml create mode 100644 hr_expense_advance_overdue_reminder/wizard/__init__.py create mode 100644 hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py create mode 100644 hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.xml create mode 100644 hr_expense_advance_overdue_reminder/wizard/mail_compose_message.py diff --git a/hr_expense_advance_overdue_reminder/README.rst b/hr_expense_advance_overdue_reminder/README.rst new file mode 100644 index 000000000..95f18e6da --- /dev/null +++ b/hr_expense_advance_overdue_reminder/README.rst @@ -0,0 +1,126 @@ +================================= +Employee Advance Overdue Reminder +================================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr--expense-lightgray.png?logo=github + :target: https://github.com/OCA/hr-expense/tree/15.0/hr_expense_advance_overdue_reminder + :alt: OCA/hr-expense +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-expense-15-0/hr-expense-15-0-hr_expense_advance_overdue_reminder + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/289/15.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allow company to send overdue advance reminders to the employee. +it sends a reminder for an expense advance when it has past it's *Due Date* +An overdue reminder for a employee always include all the overdue advance an amount of that employee. + +The module supports a clever expense reimbursement reminder counter mechanism: + +* the reminder counter is a property of an expense advance, +* the reminder counter of each overdue expense advance is incremented every time when you sending a reminder by email / letter. +* in an email template, you can configure at *Settings > Technical > Email > Email Templates > Name 'Advance: Overdue Reminder'* + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure this module, you need to: + +#. Go to *Expenses > Configuration > Reminder Definition*. +#. Set reminder definition. +#. Specify the time period for the set due date clearing advance. This field is Terms Due Date has default 30 days and it will compute due date by today + Terms Due Date, when you Post Journal Entries on expense sheet. +#. Specify other fields (if any) + +Usage +===== + +**This module has the following steps to use:** + +#. Create an advance document and submit it to manager for approval. +#. Once approved, post the journal entries. +#. If the due date is not manually selected, it will be auto-generated from the reminder settings. +#. Register Payment. + +**To check for overdue and uncleared advances:** + +#. Go to Expenses > Expense Reports > Reports to Overdue. +#. Select an advance that needs a reminder. +#. Click on Action > Overdue Reminder. +#. Verify the information and click the "Start" button to create an overdue reminder. +#. It will generate a reminder only for the selected document. + +**To send a reminder to an employee:** + +#. Go to Expenses > Employee Overdue > Overdue Reminder +#. Select the document for which you need to send a reminder to the employee. +#. Verify the information and Send or print the reminder to the employee. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Ecosoft + +Contributors +~~~~~~~~~~~~ + +* `Ecosoft `__: + + * Saran Lim. + * Pimolnat Suntian + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-Saran440| image:: https://github.com/Saran440.png?size=40px + :target: https://github.com/Saran440 + :alt: Saran440 + +Current `maintainer `__: + +|maintainer-Saran440| + +This module is part of the `OCA/hr-expense `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_expense_advance_overdue_reminder/__init__.py b/hr_expense_advance_overdue_reminder/__init__.py new file mode 100644 index 000000000..4d7a49b5e --- /dev/null +++ b/hr_expense_advance_overdue_reminder/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models +from . import wizard diff --git a/hr_expense_advance_overdue_reminder/__manifest__.py b/hr_expense_advance_overdue_reminder/__manifest__.py new file mode 100644 index 000000000..e0462113c --- /dev/null +++ b/hr_expense_advance_overdue_reminder/__manifest__.py @@ -0,0 +1,26 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Employee Advance Overdue Reminder", + "version": "15.0.1.0.0", + "category": "Human Resources", + "author": "Ecosoft, Odoo Community Association (OCA)", + "license": "AGPL-3", + "summary": "Simple mail overdue employee advance reminder", + "website": "https://github.com/OCA/hr-expense", + "depends": [ + "hr_expense_advance_clearing_sequence", + ], + "data": [ + "security/ir.model.access.csv", + "data/mail_template.xml", + "data/sequence_data.xml", + "views/reminder_definition_view.xml", + "views/hr_expense_views.xml", + "views/hr_advance_overdue_view.xml", + "wizard/hr_advance_overdue_reminder_wizard.xml", + ], + "installable": True, + "maintainers": ["Saran440"], +} diff --git a/hr_expense_advance_overdue_reminder/data/mail_template.xml b/hr_expense_advance_overdue_reminder/data/mail_template.xml new file mode 100644 index 000000000..daa1457c4 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/data/mail_template.xml @@ -0,0 +1,84 @@ + + + + Advance: Overdue Reminder + + {{ (object.create_uid.email or object.company_id.email) }} + {{ object.employee_id.address_home_id.id }} + {{ object.company_id.name }} - Overdue advance reminder {{ object.name or 'n/a' }} + +
+

+ Dear , +

+ According to our books, the following expense advance are overdue: + + + + + + + + + + + + + + + + + + + + + + + + + +
Expense NumberExpense NameDateDue DateTotal AmountResidualPast Reminders
+ +
+ + + +
+

+ If you made a clearing for these advance a few days ago, please ignore this email. +

+ Regards,
+ +

+
+
+ {{ object.employee_id.lang }} + +
+
diff --git a/hr_expense_advance_overdue_reminder/data/sequence_data.xml b/hr_expense_advance_overdue_reminder/data/sequence_data.xml new file mode 100644 index 000000000..36b941b77 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/data/sequence_data.xml @@ -0,0 +1,9 @@ + + + + Advance Overdue Reminder Sequence + advance.overdue.reminder.sequence + + EXOR + + diff --git a/hr_expense_advance_overdue_reminder/models/__init__.py b/hr_expense_advance_overdue_reminder/models/__init__.py new file mode 100644 index 000000000..74dbd5ab6 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/models/__init__.py @@ -0,0 +1,6 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import base_reminder_mixin +from . import reminder_definition +from . import hr_expense_sheet +from . import hr_advance_overdue_reminder diff --git a/hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py b/hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py new file mode 100644 index 000000000..1ef6b59ab --- /dev/null +++ b/hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py @@ -0,0 +1,35 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class BaseReminderMixIn(models.AbstractModel): + _name = "base.reminder.mixin" + _description = "Mixin used in base model that reminder" + + reminder_type = fields.Selection( + selection="_reminder_type_selection", + default="mail", + string="Reminder", + required=True, + ) + mail_template_id = fields.Many2one( + comodel_name="mail.template", + default=lambda self: self.env.ref( + "hr_expense_advance_overdue_reminder.email_template_overdue_reminder" + ), + ) + letter_report = fields.Many2one(comodel_name="ir.actions.report") + create_activity = fields.Boolean( + help="If set, system will be notified reminder next time.", + ) + activity_type_id = fields.Many2one( + comodel_name="mail.activity.type", string="Activity" + ) + activity_summary = fields.Char(string="Summary") + activity_note = fields.Html(string="Note") + + @api.model + def _reminder_type_selection(self): + return [("mail", _("E-mail")), ("letter", _("Letter"))] diff --git a/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py b/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py new file mode 100644 index 000000000..6fec70af6 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py @@ -0,0 +1,243 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from dateutil.relativedelta import relativedelta + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class HrAdvanceOverdueReminder(models.Model): + _name = "hr.advance.overdue.reminder" + _inherit = ["mail.thread", "base.reminder.mixin"] + _description = "Hr Advance Overdue Reminder" + _order = "name desc" + + expense_sheet_ids = fields.Many2many( + comodel_name="hr.expense.sheet", + relation="expense_sheet_overdue_reminder_rel", + column1="overdue_reminder_id", + column2="expense_sheet_id", + string="Overdue Expense Advance Sheet", + readonly=True, + states={"draft": [("readonly", False)]}, + ) + name = fields.Char(required=True, default="/", readonly=True, copy=False) + employee_id = fields.Many2one( + comodel_name="hr.employee", + required=True, + tracking=True, + readonly=True, + states={"draft": [("readonly", False)]}, + ) + employee_email = fields.Char( + related="employee_id.private_email", + string="Email", + ) + user_id = fields.Many2one(comodel_name="res.users", readonly=True) + date = fields.Date(default=fields.Date.context_today, readonly=True) + reminder_definition_id = fields.Many2one( + comodel_name="reminder.definition", + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, + ) + reminder_type = fields.Selection( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + reminder_next_time = fields.Date( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + mail_template_id = fields.Many2one( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + letter_report = fields.Many2one( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + create_activity = fields.Boolean( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + activity_type_id = fields.Many2one( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + activity_summary = fields.Char( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + activity_scheduled_date = fields.Date( + string="Scheduled Date", + readonly=True, + states={"draft": [("readonly", False)]}, + ) + activity_note = fields.Html( + readonly=True, + states={"draft": [("readonly", False)]}, + ) + activity_user_id = fields.Many2one( + comodel_name="res.users", + string="Assigned to", + compute="_compute_activity_user", + store=True, + states={"draft": [("readonly", False)]}, + tracking=True, + ) + company_id = fields.Many2one( + comodel_name="res.company", + readonly=True, + required=True, + default=lambda self: self.env.company, + ) + state = fields.Selection( + [("draft", "Draft"), ("done", "Done"), ("cancel", "Cancelled")], + default="draft", + readonly=True, + tracking=True, + ) + + @api.depends("create_activity", "employee_id") + def _compute_activity_user(self): + for rec in self: + rec.activity_user_id = False + if rec.create_activity: + rec.activity_user_id = rec.employee_id.user_id.id + + @api.model + def _reminder_type_selection(self): + return [("mail", _("E-mail")), ("letter", _("Letter"))] + + @api.onchange("reminder_definition_id") + def onchange_reminder_definition(self): + reminder = self.reminder_definition_id + if reminder: + today = fields.Date.context_today(self) + self.write( + { + "reminder_type": reminder.reminder_type, + "reminder_next_time": today + + relativedelta(days=reminder.reminder_number), + "mail_template_id": reminder.mail_template_id.id, + "letter_report": reminder.letter_report.id, + "create_activity": reminder.create_activity, + "activity_type_id": reminder.activity_type_id.id, + "activity_summary": reminder.activity_summary, + "activity_note": reminder.activity_note, + } + ) + + def print_letter(self): + self.ensure_one() + if self.letter_report.model != self._name: + raise UserError(_("Letter report is not use in '{}'").format(self._name)) + action = self.letter_report.with_context(discard_logo_check=True).report_action( + self + ) + return action + + def unlink(self): + """Not allow delete document when sent already.""" + if any(rec.state != "draft" for rec in self): + raise UserError( + _("You are attempting to delete a record that has already been sent.") + ) + return super().unlink() + + def _get_report_base_filename(self): + self.ensure_one() + fname = "overdue_letter-%s" % self.employee_id.name.replace(" ", "_") + return fname + + def _prepare_mail_activity(self): + self.ensure_one() + expense_sheet_model_id = self.env.ref("hr_expense.model_hr_expense_sheet").id + vals = [ + { + "activity_type_id": self.activity_type_id.id or False, + "summary": self.activity_summary, + "date_deadline": self.activity_scheduled_date, + "user_id": self.activity_user_id.id, + "note": self.activity_note, + "res_id": sheet.id, + "res_model_id": expense_sheet_model_id, + } + for sheet in self.expense_sheet_ids + ] + return vals + + def _get_mail_template(self): + return "hr_expense_advance_overdue_reminder.email_template_overdue_reminder" + + def validate_mail(self): + self.ensure_one() + if self.employee_id.sudo().address_home_id.type == "private": + raise UserError(_("You can not sent email with address private contact.")) + template = self.env.ref(self._get_mail_template(), raise_if_not_found=False) + compose_form = self.env.ref("mail.email_compose_message_wizard_form", False) + ctx = dict( + default_model="hr.advance.overdue.reminder", + default_res_id=self.id, + default_use_template=bool(template), + default_template_id=template.id, + default_composition_mode="comment", + custom_layout="mail.mail_notification_light", + force_email=True, + active_ids=self.ids, + ) + return { + "name": _("Compose Email"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "mail.compose.message", + "views": [(compose_form.id, "form")], + "view_id": compose_form.id, + "target": "new", + "context": ctx, + } + + @api.model + def create(self, vals): + if vals.get("number", "/") == "/": + number = ( + self.env["ir.sequence"].next_by_code( + "advance.overdue.reminder.sequence" + ) + or "/" + ) + vals["name"] = number + return super().create(vals) + + def _update_overdue_advance(self): + self.ensure_one() + self.expense_sheet_ids.write( + { + "overdue_reminder_last_date": self.date, + "reminder_next_time": self.reminder_next_time, + } + ) + self.state = "done" + self._create_activity() + return False + + def _create_activity(self): + self.ensure_one() + MailActivity = self.env["mail.activity"] + mail_activity = False + if self.create_activity: + mail_activity = MailActivity.create(self._prepare_mail_activity()) + return mail_activity + + def action_validate(self): + self.ensure_one() + if self.reminder_type == "mail": + return self.validate_mail() + action = self.print_letter() + self._update_overdue_advance() + return action + + def action_cancel(self): + return self.write({"state": "cancel"}) diff --git a/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py b/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py new file mode 100644 index 000000000..97213adab --- /dev/null +++ b/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py @@ -0,0 +1,103 @@ +# Copyright 2020 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from dateutil.relativedelta import relativedelta + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class HrExpenseSheet(models.Model): + _inherit = "hr.expense.sheet" + + overdue_reminder_ids = fields.Many2many( + comodel_name="hr.advance.overdue.reminder", + relation="expense_sheet_overdue_reminder_rel", + column1="expense_sheet_id", + column2="overdue_reminder_id", + string="Overdue Reminder Action History", + ) + overdue_reminder_last_date = fields.Date( + string="Last Reminder Date", + ) + reminder_next_time = fields.Date( + string="Next Reminder Date", + ) + overdue_reminder_counter = fields.Integer( + string="Reminder Count", + compute="_compute_overdue_reminder", + help="This counter is increased when reminder.", + ) + is_overdue = fields.Boolean( + compute="_compute_overdue", + ) + clearing_date_due = fields.Date( + string="Clearing Due Date", + readonly=True, + states={"draft": [("readonly", False)]}, + tracking=True, + ) + + @api.onchange("clearing_date_due") + def _onchange_clearing_date_due(self): + today = fields.Date.context_today(self) + if self.clearing_date_due and self.clearing_date_due < today: + raise UserError(_("You can not select clearing due date less than today.")) + + @api.depends("state", "clearing_date_due") + def _compute_overdue(self): + date = self._context.get("manual_date", fields.Date.context_today(self)) + for sheet in self: + sheet.is_overdue = False + # Check if the sheet is an advance, has a clearing date due, and is not yet cleared + if ( + sheet.advance + and sheet.clearing_date_due + and sheet.clearing_date_due < date + and sheet.clearing_residual > 0.0 + and (not sheet.reminder_next_time or sheet.reminder_next_time < date) + ): + sheet.is_overdue = True + + @api.depends("overdue_reminder_ids") + def _compute_overdue_reminder(self): + for sheet in self: + reminder = sheet.overdue_reminder_ids.filtered(lambda l: l.state == "done") + sheet.overdue_reminder_counter = len(reminder) + + def action_sheet_move_create(self): + res = super().action_sheet_move_create() + reminder = self.env["reminder.definition"].search([], limit=1) + for sheet in self.filtered("advance"): + if not sheet.clearing_date_due: + if not reminder: + raise UserError( + _( + "Please configured reminder definition before " + "Post Journal Entries" + ) + ) + move_date = res[sheet.id].date + sheet.clearing_date_due = move_date + relativedelta( + days=reminder.clearing_terms_days or 0.0 + ) + return res + + def action_overdue_reminder(self): + if any(not sheet.is_overdue for sheet in self): + raise UserError(_("You cannot remind this report.")) + employee_ids = self.mapped("employee_id.id") + reminder = self.env["reminder.definition"].search([], limit=1) + return { + "name": _("New Advance Overdue"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "hr.advance.overdue.reminder.wizard", + "target": "new", + "context": { + "active_model": self._context.get("active_model", False), + "active_ids": self._context.get("active_ids", False), + "default_employee_ids": employee_ids, + "default_reminder_definition_id": reminder.id, + }, + } diff --git a/hr_expense_advance_overdue_reminder/models/reminder_definition.py b/hr_expense_advance_overdue_reminder/models/reminder_definition.py new file mode 100644 index 000000000..b0dda69e0 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/models/reminder_definition.py @@ -0,0 +1,28 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ReminderDefinition(models.Model): + _name = "reminder.definition" + _inherit = "base.reminder.mixin" + _description = "Reminder Definition" + + name = fields.Char( + string="Description", + required=True, + ) + clearing_terms_days = fields.Integer( + string="Clearing Terms", + default=30, + help="In case this field is configured, " + "the system will help calculate Clearing Date Due according to the term.", + ) + reminder_number = fields.Integer(string="Reminder Every", default=5) + active = fields.Boolean(default=True) + company_id = fields.Many2one( + comodel_name="res.company", + string="Company", + default=lambda self: self.env.company, + ) diff --git a/hr_expense_advance_overdue_reminder/readme/CONFIGURE.rst b/hr_expense_advance_overdue_reminder/readme/CONFIGURE.rst new file mode 100644 index 000000000..3d4f23ecc --- /dev/null +++ b/hr_expense_advance_overdue_reminder/readme/CONFIGURE.rst @@ -0,0 +1,6 @@ +To configure this module, you need to: + +#. Go to *Expenses > Configuration > Reminder Definition*. +#. Set reminder definition. +#. Specify the time period for the set due date clearing advance. This field is Terms Due Date has default 30 days and it will compute due date by today + Terms Due Date, when you Post Journal Entries on expense sheet. +#. Specify other fields (if any) diff --git a/hr_expense_advance_overdue_reminder/readme/CONTRIBUTORS.rst b/hr_expense_advance_overdue_reminder/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..9aea16765 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* `Ecosoft `__: + + * Saran Lim. + * Pimolnat Suntian diff --git a/hr_expense_advance_overdue_reminder/readme/DESCRIPTION.rst b/hr_expense_advance_overdue_reminder/readme/DESCRIPTION.rst new file mode 100644 index 000000000..c6da7c323 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/readme/DESCRIPTION.rst @@ -0,0 +1,9 @@ +This module allow company to send overdue advance reminders to the employee. +it sends a reminder for an expense advance when it has past it's *Due Date* +An overdue reminder for a employee always include all the overdue advance an amount of that employee. + +The module supports a clever expense reimbursement reminder counter mechanism: + +* the reminder counter is a property of an expense advance, +* the reminder counter of each overdue expense advance is incremented every time when you sending a reminder by email / letter. +* in an email template, you can configure at *Settings > Technical > Email > Email Templates > Name 'Advance: Overdue Reminder'* diff --git a/hr_expense_advance_overdue_reminder/readme/USAGE.rst b/hr_expense_advance_overdue_reminder/readme/USAGE.rst new file mode 100644 index 000000000..f7479e4bb --- /dev/null +++ b/hr_expense_advance_overdue_reminder/readme/USAGE.rst @@ -0,0 +1,20 @@ +**This module has the following steps to use:** + +#. Create an advance document and submit it to manager for approval. +#. Once approved, post the journal entries. +#. If the due date is not manually selected, it will be auto-generated from the reminder settings. +#. Register Payment. + +**To check for overdue and uncleared advances:** + +#. Go to Expenses > Expense Reports > Reports to Overdue. +#. Select an advance that needs a reminder. +#. Click on Action > Overdue Reminder. +#. Verify the information and click the "Start" button to create an overdue reminder. +#. It will generate a reminder only for the selected document. + +**To send a reminder to an employee:** + +#. Go to Expenses > Employee Overdue > Overdue Reminder +#. Select the document for which you need to send a reminder to the employee. +#. Verify the information and Send or print the reminder to the employee. diff --git a/hr_expense_advance_overdue_reminder/security/ir.model.access.csv b/hr_expense_advance_overdue_reminder/security/ir.model.access.csv new file mode 100644 index 000000000..8168a67fc --- /dev/null +++ b/hr_expense_advance_overdue_reminder/security/ir.model.access.csv @@ -0,0 +1,8 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_reminder_definition_all,access_reminder_definition_all,model_reminder_definition,,1,0,0,0 +access_reminder_definition_settings,access_reminder_definition_settings,model_reminder_definition,base.group_system,1,1,1,1 +access_hr_advance_overdue_reminder_wizard,access_hr_advance_overdue_reminder_wizard,model_hr_advance_overdue_reminder_wizard,hr.group_hr_manager,1,1,1,1 +access_hr_advance_overdue_reminder_wizard_accountant,access_hr_advance_overdue_reminder_wizard_accountant,model_hr_advance_overdue_reminder_wizard,account.group_account_user,1,1,1,1 +access_hr_advance_overdue_reminder_manager,access_hr_advance_overdue_reminder_manager,model_hr_advance_overdue_reminder,hr.group_hr_manager,1,1,1,1 +access_hr_advance_overdue_reminder_accountant,access_hr_advance_overdue_reminder_accountant,model_hr_advance_overdue_reminder,account.group_account_user,1,1,1,1 +access_hr_advance_overdue_reminder_user,access_hr_advance_overdue_reminder_user,model_hr_advance_overdue_reminder,,1,0,0,0 diff --git a/hr_expense_advance_overdue_reminder/static/description/index.html b/hr_expense_advance_overdue_reminder/static/description/index.html new file mode 100644 index 000000000..e27ae2281 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/static/description/index.html @@ -0,0 +1,469 @@ + + + + + + +Employee Advance Overdue Reminder + + + +
+

Employee Advance Overdue Reminder

+ + +

Beta License: AGPL-3 OCA/hr-expense Translate me on Weblate Try me on Runbot

+

This module allow company to send overdue advance reminders to the employee. +it sends a reminder for an expense advance when it has past it’s Due Date +An overdue reminder for a employee always include all the overdue advance an amount of that employee.

+

The module supports a clever expense reimbursement reminder counter mechanism:

+
    +
  • the reminder counter is a property of an expense advance,
  • +
  • the reminder counter of each overdue expense advance is incremented every time when you sending a reminder by email / letter.
  • +
  • in an email template, you can configure at Settings > Technical > Email > Email Templates > Name ‘Advance: Overdue Reminder’
  • +
+

Table of contents

+ +
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Expenses > Configuration > Reminder Definition.
  2. +
  3. Set reminder definition.
  4. +
  5. Specify the time period for the set due date clearing advance. This field is Terms Due Date has default 30 days and it will compute due date by today + Terms Due Date, when you Post Journal Entries on expense sheet.
  6. +
  7. Specify other fields (if any)
  8. +
+
+
+

Usage

+

This module has the following steps to use:

+
    +
  1. Create an advance document and submit it to manager for approval.
  2. +
  3. Once approved, post the journal entries.
  4. +
  5. If the due date is not manually selected, it will be auto-generated from the reminder settings.
  6. +
  7. Register Payment.
  8. +
+

To check for overdue and uncleared advances:

+
    +
  1. Go to Expenses > Expense Reports > Reports to Overdue.
  2. +
  3. Select an advance that needs a reminder.
  4. +
  5. Click on Action > Overdue Reminder.
  6. +
  7. Verify the information and click the “Start” button to create an overdue reminder.
  8. +
  9. It will generate a reminder only for the selected document.
  10. +
+

To send a reminder to an employee:

+
    +
  1. Go to Expenses > Employee Overdue > Overdue Reminder
  2. +
  3. Select the document for which you need to send a reminder to the employee.
  4. +
  5. Verify the information and Send or print the reminder to the employee.
  6. +
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Ecosoft
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

Saran440

+

This module is part of the OCA/hr-expense project on GitHub.

+

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

+
+
+
+ + diff --git a/hr_expense_advance_overdue_reminder/tests/__init__.py b/hr_expense_advance_overdue_reminder/tests/__init__.py new file mode 100644 index 000000000..342ae91ea --- /dev/null +++ b/hr_expense_advance_overdue_reminder/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_hr_expense_advance_overdue_reminder diff --git a/hr_expense_advance_overdue_reminder/tests/test_hr_expense_advance_overdue_reminder.py b/hr_expense_advance_overdue_reminder/tests/test_hr_expense_advance_overdue_reminder.py new file mode 100644 index 000000000..e02641633 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/tests/test_hr_expense_advance_overdue_reminder.py @@ -0,0 +1,210 @@ +# Copyright 2023 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from freezegun import freeze_time + +from odoo import fields +from odoo.exceptions import UserError +from odoo.tests.common import Form, TransactionCase + + +class TestHrExpenseAdvanceOverdueReminder(TransactionCase): + @classmethod + @freeze_time("2001-01-01") + def setUpClass(cls): + super().setUpClass() + cls.reminder_config = cls.env["reminder.definition"] + cls.overdue_wizard = cls.env["hr.advance.overdue.reminder.wizard"] + cls.mail_compose = cls.env["mail.compose.message"] + cls.journal_bank = cls.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) + cls.letter_report = cls.env["ir.actions.report"].search([], limit=1) + employee_home = cls.env["res.partner"].create({"name": "Employee Home Address"}) + cls.employee = cls.env["hr.employee"].create( + {"name": "Employee A", "address_home_id": employee_home.id} + ) + # Advance product + advance_account = cls.env["account.account"].create( + { + "code": "154000", + "name": "Employee Advance", + "user_type_id": cls.env.ref( + "account.data_account_type_current_assets" + ).id, + "reconcile": True, + } + ) + cls.emp_advance = cls.env.ref("hr_expense_advance_clearing.product_emp_advance") + cls.emp_advance.property_account_expense_id = advance_account + # Create advance expense 1,000 + cls.advance = cls._create_expense_sheet( + cls, "Advance 1,000", cls.employee, cls.emp_advance, 1000.0, advance=True + ) + + def _create_expense( + self, + description, + employee, + product, + amount, + advance=False, + payment_mode="own_account", + account=False, + ): + with Form( + self.env["hr.expense"].with_context(default_advance=advance) + ) as expense: + expense.name = description + expense.employee_id = employee + expense.unit_amount = amount + expense.payment_mode = payment_mode + expense = expense.save() + expense.tax_ids = False # Test no vat + return expense + + def _create_expense_sheet( + self, description, employee, product, amount, advance=False + ): + expense = self._create_expense( + self, description, employee, product, amount, advance + ) + # Add expense to expense sheet + expense_sheet = self.env["hr.expense.sheet"].create( + { + "name": description, + "advance": advance, + "employee_id": expense.employee_id.id, + "expense_line_ids": [(6, 0, [expense.id])], + } + ) + return expense_sheet + + def _register_payment(self, move_id, amount, ctx=False, hr_return_advance=False): + ctx = ctx or { + "active_ids": [move_id.id], + "active_id": move_id.id, + "active_model": "account.move", + } + ctx["hr_return_advance"] = hr_return_advance + PaymentWizard = self.env["account.payment.register"] + with Form(PaymentWizard.with_context(**ctx)) as f: + f.journal_id = self.journal_bank + f.payment_date = fields.Date.today() + f.amount = amount + payment_wizard = f.save() + payment_wizard.action_create_payments() + + @freeze_time("2001-01-01") + def test_01_reminder_advance(self): + # Overdue date configured due date < today 1 day + self.assertFalse(self.advance.clearing_date_due) + self.assertEqual(self.advance.state, "draft") + # Change clearing due date less than today, it should error + with self.assertRaises(UserError): + with Form(self.advance) as av: + av.clearing_date_due = "2000-01-01" + self.advance.clearing_date_due = False + self.advance.action_submit_sheet() + self.advance.approve_expense_sheets() + # Clearing Due Date is not selected, it will default from reminder config + with self.assertRaises(UserError): + self.advance.action_sheet_move_create() + reminder = self.reminder_config.create({"name": "Overdue Reminder"}) + self.assertEqual(reminder.clearing_terms_days, 30) + self.advance.action_sheet_move_create() + self.assertEqual( + self.advance.clearing_date_due.strftime("%Y-%m-%d"), "2001-01-31" + ) + self.assertFalse(self.advance.is_overdue) + self.assertEqual(self.advance.clearing_residual, 1000.0) + self._register_payment(self.advance.account_move_id, 1000.0) + self.assertEqual(self.advance.state, "done") + # Check Overdue Advance + with self.assertRaises(UserError): + self.advance.action_overdue_reminder() + self.advance.clearing_date_due = "2000-12-31" + self.assertTrue(self.advance.is_overdue) + result = self.advance.action_overdue_reminder() + # Open wizard overdue reminder + self.assertEqual(result["res_model"], "hr.advance.overdue.reminder.wizard") + with Form( + self.overdue_wizard.with_context( + active_ids=self.advance.ids, + default_employee_ids=self.advance.employee_id.ids, + default_reminder_definition_id=reminder.id, + ) + ) as wiz: + wiz.reminder_number = 5 + wizard_reminder = wiz.save() + self.assertTrue(wizard_reminder.employee_ids) + action = wizard_reminder.with_context(active_ids=False).run() + self.assertFalse(action["domain"][0][2]) + action = wizard_reminder.run() + self.assertTrue(action["domain"][0][2]) + advance_overdue_reminder = self.env["hr.advance.overdue.reminder"].browse( + action["domain"][0][2] + ) + self.assertEqual(advance_overdue_reminder.state, "draft") + # Test reminder by letter + with Form(advance_overdue_reminder) as av_overdue: + av_overdue.create_activity = True + av_overdue.reminder_definition_id = reminder + av_overdue.reminder_type = "letter" + self.assertFalse(av_overdue.letter_report) + with self.assertRaises(UserError): + advance_overdue_reminder.action_validate() + self.letter_report.model = "hr.advance.overdue.reminder" + with Form(advance_overdue_reminder) as av_overdue: + av_overdue.letter_report = self.letter_report + advance_overdue_reminder.action_validate() + self.assertEqual(advance_overdue_reminder.state, "done") + # Check name report + name_report = advance_overdue_reminder._get_report_base_filename() + self.assertEqual(name_report, "overdue_letter-Employee_A") + # Test reminder by email + advance_overdue_reminder.state = "draft" + with Form(advance_overdue_reminder) as av_overdue: + av_overdue.reminder_type = "mail" + # Check employee address private, not allow send email + advance_overdue_reminder.employee_id.address_home_id.type = "private" + with self.assertRaises(UserError): + advance_overdue_reminder.action_validate() + advance_overdue_reminder.employee_id.address_home_id.type = "contact" + mail_compose = advance_overdue_reminder.action_validate() + with Form( + self.mail_compose.with_context( + active_ids=mail_compose["context"].get("active_ids"), + default_model=mail_compose["context"].get("default_model"), + default_res_id=mail_compose["context"].get("default_res_id"), + default_template_id=mail_compose["context"].get("default_template_id"), + ) + ) as wiz: + wiz.body = "Test" + mail_wizard = wiz.save() + mail_wizard._action_send_mail() + self.assertEqual(advance_overdue_reminder.state, "done") + with self.assertRaises(UserError): + advance_overdue_reminder.unlink() + advance_overdue_reminder.action_cancel() + self.assertEqual(advance_overdue_reminder.state, "cancel") + advance_overdue_reminder.state = "draft" + advance_overdue_reminder.create_activity = True + advance_overdue_reminder.activity_scheduled_date = "2001-01-15" + advance_overdue_reminder.activity_user_id = self.env.user.id + mail_compose = advance_overdue_reminder.action_validate() + with Form( + self.mail_compose.with_context( + active_ids=mail_compose["context"].get("active_ids"), + default_model=mail_compose["context"].get("default_model"), + default_res_id=mail_compose["context"].get("default_res_id"), + default_template_id=mail_compose["context"].get("default_template_id"), + ) + ) as wiz: + wiz.body = "Test" + mail_wizard = wiz.save() + mail_wizard._action_send_mail() + self.assertEqual(advance_overdue_reminder.state, "done") + # Check reminder < today + self.advance.reminder_next_time = "2000-12-31" + self.assertTrue(self.advance.is_overdue) diff --git a/hr_expense_advance_overdue_reminder/views/hr_advance_overdue_view.xml b/hr_expense_advance_overdue_reminder/views/hr_advance_overdue_view.xml new file mode 100644 index 000000000..895755cf4 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/views/hr_advance_overdue_view.xml @@ -0,0 +1,196 @@ + + + + + hr.advance.overdue.reminder.form + hr.advance.overdue.reminder + +
+
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+
+ + + hr.advance.overdue.reminder.tree + hr.advance.overdue.reminder + + + + + + + + + + + + + hr.advance.overdue.reminder.search + hr.advance.overdue.reminder + + + + + + + + + + + + + + + + + + Overdue Reminder Action + hr.advance.overdue.reminder + tree,form + + + + + +
diff --git a/hr_expense_advance_overdue_reminder/views/hr_expense_views.xml b/hr_expense_advance_overdue_reminder/views/hr_expense_views.xml new file mode 100644 index 000000000..6144e3ab2 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/views/hr_expense_views.xml @@ -0,0 +1,107 @@ + + + + + hr.expense.sheet.view.search + hr.expense.sheet + + + + + + + + + + view.hr.expense.sheet.form + hr.expense.sheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + hr.expense.sheet.tree + hr.expense.sheet + + + + + + + + + + Expense Reports to Overdue + hr.expense.sheet + tree,kanban,form,pivot,graph,activity + + [] + {'search_default_advance_overdue': 1} + + + + + Overdue Reminder + ir.actions.server + + + code + +if records: + action = records.action_overdue_reminder() + + + + diff --git a/hr_expense_advance_overdue_reminder/views/reminder_definition_view.xml b/hr_expense_advance_overdue_reminder/views/reminder_definition_view.xml new file mode 100644 index 000000000..6aee730f7 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/views/reminder_definition_view.xml @@ -0,0 +1,99 @@ + + + + reminder.definition.tree + reminder.definition + + + + + + + + + + reminder.definition.form + reminder.definition + +
+ +
+ +
+ Name +

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + Reminder Definition + reminder.definition + tree,form + {'active_test': False} + + + + diff --git a/hr_expense_advance_overdue_reminder/wizard/__init__.py b/hr_expense_advance_overdue_reminder/wizard/__init__.py new file mode 100644 index 000000000..58a3791da --- /dev/null +++ b/hr_expense_advance_overdue_reminder/wizard/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import mail_compose_message +from . import hr_advance_overdue_reminder_wizard diff --git a/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py b/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py new file mode 100644 index 000000000..5340add47 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py @@ -0,0 +1,129 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from dateutil.relativedelta import relativedelta + +from odoo import _, api, fields, models + + +class HrAdvanceOverdueReminderWizard(models.TransientModel): + _name = "hr.advance.overdue.reminder.wizard" + _description = "Reminder Overdue Advance" + + employee_ids = fields.Many2many( + comodel_name="hr.employee", + string="Employee(s)", + ) + reminder_definition_id = fields.Many2one( + comodel_name="reminder.definition", + required=True, + ) + reminder_number = fields.Integer( + string="Reminder Every", + required=True, + ) + reminder_next_time = fields.Date( + string="Next Reminder", + compute="_compute_reminder_next_time", + store=True, + required=True, + readonly=False, + ) + reminder_type = fields.Selection(selection="_reminder_type_selection") + mail_template_id = fields.Many2one(comodel_name="mail.template") + letter_report = fields.Many2one(comodel_name="ir.actions.report") + company_id = fields.Many2one( + comodel_name="res.company", + string="Company", + default=lambda self: self.env.user.company_id.id, + ) + create_activity = fields.Boolean() + activity_type_id = fields.Many2one( + comodel_name="mail.activity.type", string="Activity" + ) + activity_summary = fields.Char(string="Summary") + activity_note = fields.Html(string="Note") + + @api.depends("reminder_number") + def _compute_reminder_next_time(self): + today = fields.Date.context_today(self) + for rec in self: + rec.reminder_next_time = today + relativedelta(days=rec.reminder_number) + + @api.model + def _reminder_type_selection(self): + return [("mail", _("E-mail")), ("letter", _("Letter"))] + + @api.onchange("reminder_definition_id") + def onchange_reminder_definition(self): + reminder = self.reminder_definition_id + if reminder: + self.write( + { + "reminder_number": reminder.reminder_number or 0, + "company_id": reminder.company_id.id or self.env.company.id, + "reminder_type": reminder.reminder_type, + "mail_template_id": reminder.mail_template_id.id, + "letter_report": reminder.letter_report.id, + "create_activity": reminder.create_activity, + "activity_type_id": reminder.activity_type_id.id, + "activity_summary": reminder.activity_summary, + "activity_note": reminder.activity_note, + } + ) + + def _prepare_reminder(self, date): + ExpenseSheet = self.env["hr.expense.sheet"] + active_ids = self._context.get("active_ids", False) + vals = [] + for employee in self.employee_ids: + expense_sheets = ExpenseSheet.search( + [ + ("id", "in", active_ids), + ("employee_id", "=", employee.id), + ] + ) + if not expense_sheets: + continue + vals.append( + { + "employee_id": employee.id, + "user_id": self.env.user.id, + "expense_sheet_ids": [(6, 0, expense_sheets.ids)], + "company_id": self.company_id.id, + "reminder_type": self.reminder_type, + "reminder_next_time": self.reminder_next_time, + "mail_template_id": self.mail_template_id.id, + "letter_report": self.letter_report.id, + "create_activity": self.create_activity, + "activity_type_id": self.activity_type_id.id, + "activity_scheduled_date": self.create_activity + and self.reminder_next_time + or False, + "activity_summary": self.create_activity and self.activity_summary, + "activity_note": self.create_activity and self.activity_note, + } + ) + return vals + + def run(self): + self.ensure_one() + AdvanceOverdue = self.env["hr.advance.overdue.reminder"].sudo() + today = self._context.get("manual_date", fields.Date.context_today(self)) + # Unlink data is not send yet + existing_actions = AdvanceOverdue.search( + [ + ("employee_id", "in", self.employee_ids.ids), + ("state", "=", "draft"), + ] + ) + existing_actions.unlink() + # Create new reminder + vals = self._prepare_reminder(today) + advance_overdue = AdvanceOverdue.create(vals) + # Open new view overdue reminder + action = self.env["ir.actions.act_window"]._for_xml_id( + "hr_expense_advance_overdue_reminder.action_hr_advance_overdue_reminder" + ) + action["domain"] = [("id", "in", advance_overdue.ids)] + return action diff --git a/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.xml b/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.xml new file mode 100644 index 000000000..64691d66a --- /dev/null +++ b/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.xml @@ -0,0 +1,70 @@ + + + + hr.advance.overdue.reminder.wizard.form + hr.advance.overdue.reminder.wizard + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + Advance Overdue Reminder + hr.advance.overdue.reminder.wizard + form + {'active_model': 'hr.expense.sheet'} + new + +
diff --git a/hr_expense_advance_overdue_reminder/wizard/mail_compose_message.py b/hr_expense_advance_overdue_reminder/wizard/mail_compose_message.py new file mode 100644 index 000000000..0e88669c8 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/wizard/mail_compose_message.py @@ -0,0 +1,15 @@ +# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class MailComposeMessage(models.TransientModel): + _inherit = "mail.compose.message" + + def _action_send_mail(self, **kwargs): + for wizard in self: + if wizard.model == "hr.advance.overdue.reminder": + overdue = self.env[wizard.model].sudo().browse(wizard.res_id) + overdue._update_overdue_advance() + return super()._action_send_mail(**kwargs) From d37bd441cfd17ca9cc43d97aa2a880edbdba8c15 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 10 Oct 2023 09:56:26 +0000 Subject: [PATCH 02/15] [UPD] Update hr_expense_advance_overdue_reminder.pot --- .../hr_expense_advance_overdue_reminder.pot | 644 ++++++++++++++++++ 1 file changed, 644 insertions(+) create mode 100644 hr_expense_advance_overdue_reminder/i18n/hr_expense_advance_overdue_reminder.pot diff --git a/hr_expense_advance_overdue_reminder/i18n/hr_expense_advance_overdue_reminder.pot b/hr_expense_advance_overdue_reminder/i18n/hr_expense_advance_overdue_reminder.pot new file mode 100644 index 000000000..db562a028 --- /dev/null +++ b/hr_expense_advance_overdue_reminder/i18n/hr_expense_advance_overdue_reminder.pot @@ -0,0 +1,644 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_advance_overdue_reminder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_expense_advance_overdue_reminder +#: model:mail.template,body_html:hr_expense_advance_overdue_reminder.email_template_overdue_reminder +msgid "" +"
\n" +"

\n" +" Dear ,\n" +"

\n" +" According to our books, the following expense advance 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" +"
Expense NumberExpense NameDateDue DateTotal AmountResidualPast Reminders
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" If you made a clearing for these advance a few days ago, please ignore this email.\n" +"

\n" +" Regards,
\n" +" \n" +"

\n" +"
\n" +" " +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.reminder_definition_view_form +msgid "Name" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.reminder_definition_view_form +msgid " days" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.reminder_definition_view_form +msgid "Action Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__active +msgid "Active" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__activity_type_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__activity_type_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__activity_type_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__activity_type_id +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.wizard_advance_overdue_reminder_form +msgid "Activity" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.actions.act_window,name:hr_expense_advance_overdue_reminder.action_advance_overdue_reminder +msgid "Advance Overdue Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:mail.template,name:hr_expense_advance_overdue_reminder.email_template_overdue_reminder +msgid "Advance: Overdue Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__activity_user_id +msgid "Assigned to" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.wizard_advance_overdue_reminder_form +msgid "Cancel" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields.selection,name:hr_expense_advance_overdue_reminder.selection__hr_advance_overdue_reminder__state__cancel +msgid "Cancelled" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__clearing_date_due +msgid "Clearing Due Date" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__clearing_terms_days +msgid "Clearing Terms" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__company_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__company_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__company_id +msgid "Company" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#, python-format +msgid "Compose Email" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__create_activity +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__create_activity +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__create_activity +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__create_activity +msgid "Create Activity" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__create_uid +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__create_uid +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__create_uid +msgid "Created by" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__create_date +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__create_date +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__create_date +msgid "Created on" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +msgid "Current Remind Counter" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__date +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +msgid "Date" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__name +msgid "Description" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__display_name +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__display_name +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__display_name +msgid "Display Name" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields.selection,name:hr_expense_advance_overdue_reminder.selection__hr_advance_overdue_reminder__state__done +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +msgid "Done" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields.selection,name:hr_expense_advance_overdue_reminder.selection__hr_advance_overdue_reminder__state__draft +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +msgid "Draft" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py:0 +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#: code:addons/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +#, python-format +msgid "E-mail" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__employee_email +msgid "Email" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__employee_id +msgid "Employee" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.ui.menu,name:hr_expense_advance_overdue_reminder.menu_hr_expense_overdue +msgid "Employee Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__employee_ids +msgid "Employee(s)" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_hr_expense_sheet +msgid "Expense Report" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.actions.act_window,name:hr_expense_advance_overdue_reminder.action_hr_expense_sheet_all_to_overdue +msgid "Expense Reports to Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__has_message +msgid "Has Message" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_hr_advance_overdue_reminder +msgid "Hr Advance Overdue Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__id +msgid "ID" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_needaction +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_unread +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_error +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__create_activity +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__create_activity +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_reminder_definition__create_activity +msgid "If set, system will be notified reminder next time." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_reminder_definition__clearing_terms_days +msgid "" +"In case this field is configured, the system will help calculate Clearing " +"Date Due according to the term." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__is_overdue +msgid "Is Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder____last_update +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard____last_update +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition____last_update +msgid "Last Modified on" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +msgid "Last Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__overdue_reminder_last_date +msgid "Last Reminder Date" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__write_uid +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__write_uid +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__write_date +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__write_date +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__write_date +msgid "Last Updated on" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/base_reminder_mixin.py:0 +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#: code:addons/hr_expense_advance_overdue_reminder/wizard/hr_advance_overdue_reminder_wizard.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +#, python-format +msgid "Letter" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__letter_report +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__letter_report +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__letter_report +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__letter_report +msgid "Letter Report" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#, python-format +msgid "Letter report is not use in '{}'" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__mail_template_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__mail_template_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__mail_template_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__mail_template_id +msgid "Mail Template" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_ids +msgid "Messages" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_base_reminder_mixin +msgid "Mixin used in base model that reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__name +msgid "Name" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py:0 +#, python-format +msgid "New Advance Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__reminder_next_time +msgid "Next Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__reminder_next_time +msgid "Next Reminder Date" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__activity_note +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__activity_note +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__activity_note +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__activity_note +msgid "Note" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_unread_counter +msgid "Number of unread messages" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +msgid "Order Ref" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__expense_sheet_ids +msgid "Overdue Expense Advance Sheet" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.actions.server,name:hr_expense_advance_overdue_reminder.action_hr_advance_overdue_server +#: model:ir.ui.menu,name:hr_expense_advance_overdue_reminder.menu_advance_overdue_reminder_view +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.view_hr_expense_sheet_form +msgid "Overdue Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.actions.act_window,name:hr_expense_advance_overdue_reminder.action_hr_advance_overdue_reminder +msgid "Overdue Reminder Action" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__overdue_reminder_ids +msgid "Overdue Reminder Action History" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py:0 +#, python-format +msgid "Please configured reminder definition before Post Journal Entries" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__reminder_type +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__reminder_type +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__reminder_type +msgid "Reminder" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__overdue_reminder_counter +msgid "Reminder Count" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.actions.act_window,name:hr_expense_advance_overdue_reminder.reminder_definition_action +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_reminder_definition +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__reminder_definition_id +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__reminder_definition_id +#: model:ir.ui.menu,name:hr_expense_advance_overdue_reminder.menu_hr_advance_overdue_setting +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.reminder_definition_view_form +msgid "Reminder Definition" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__reminder_number +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__reminder_number +msgid "Reminder Every" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__reminder_next_time +msgid "Reminder Next Time" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model,name:hr_expense_advance_overdue_reminder.model_hr_advance_overdue_reminder_wizard +msgid "Reminder Overdue Advance" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__reminder_type +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +msgid "Reminder Type" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.ui.menu,name:hr_expense_advance_overdue_reminder.menu_hr_expense_sheet_all_to_overdue +msgid "Reports to Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__activity_scheduled_date +msgid "Scheduled Date" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +msgid "Send or Print" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.wizard_advance_overdue_reminder_form +msgid "Start" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__state +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_search +msgid "State" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_base_reminder_mixin__activity_summary +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__activity_summary +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder_wizard__activity_summary +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_reminder_definition__activity_summary +msgid "Summary" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_expense_sheet__overdue_reminder_counter +msgid "This counter is increased when reminder." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_expense_sheet_view_search +msgid "To Overdue" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.hr_advance_overdue_reminder_form +msgid "Total" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_unread +msgid "Unread Messages" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__message_unread_counter +msgid "Unread Messages Counter" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__user_id +msgid "User" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,field_description:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:ir.model.fields,help:hr_expense_advance_overdue_reminder.field_hr_advance_overdue_reminder__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#, python-format +msgid "You are attempting to delete a record that has already been sent." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py:0 +#, python-format +msgid "You can not select clearing due date less than today." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_advance_overdue_reminder.py:0 +#, python-format +msgid "You can not sent email with address private contact." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: code:addons/hr_expense_advance_overdue_reminder/models/hr_expense_sheet.py:0 +#, python-format +msgid "You cannot remind this report." +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model_terms:ir.ui.view,arch_db:hr_expense_advance_overdue_reminder.wizard_advance_overdue_reminder_form +msgid "days" +msgstr "" + +#. module: hr_expense_advance_overdue_reminder +#: model:mail.template,subject:hr_expense_advance_overdue_reminder.email_template_overdue_reminder +msgid "" +"{{ object.company_id.name }} - Overdue advance reminder {{ object.name or " +"'n/a' }}" +msgstr "" From 37726a8916c7225468da47eb96b2bc919b8c4b68 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 10 Oct 2023 10:00:37 +0000 Subject: [PATCH 03/15] [BOT] post-merge updates --- .../README.rst | 15 +++--- .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 44 +++++++++--------- 3 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 hr_expense_advance_overdue_reminder/static/description/icon.png diff --git a/hr_expense_advance_overdue_reminder/README.rst b/hr_expense_advance_overdue_reminder/README.rst index 95f18e6da..8ee9f4e7f 100644 --- a/hr_expense_advance_overdue_reminder/README.rst +++ b/hr_expense_advance_overdue_reminder/README.rst @@ -2,10 +2,13 @@ Employee Advance Overdue Reminder ================================= -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c96c66abf06db30bcb2a9dd927d308f497b92cb708514c425342b2255185dcd5 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Employee Advance Overdue Reminder .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/hr-expense-15-0/hr-expense-15-0-hr_expense_advance_overdue_reminder :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/289/15.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr-expense&target_branch=15.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module allow company to send overdue advance reminders to the employee. it sends a reminder for an expense advance when it has past it's *Due Date* @@ -79,7 +82,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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/hr_expense_advance_overdue_reminder/static/description/icon.png b/hr_expense_advance_overdue_reminder/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/hr_expense_advance_overdue_reminder/static/description/index.html b/hr_expense_advance_overdue_reminder/static/description/index.html index e27ae2281..18de70ce7 100644 --- a/hr_expense_advance_overdue_reminder/static/description/index.html +++ b/hr_expense_advance_overdue_reminder/static/description/index.html @@ -1,20 +1,20 @@ - + - + Employee Advance Overdue Reminder