From bbc25c7550025925e780f10721f9650dcfa70f92 Mon Sep 17 00:00:00 2001 From: tgaullier Date: Wed, 24 Jan 2024 17:28:57 +0100 Subject: [PATCH] [WIP] #6 - Module migration --- timesheet_reminder_mail/__init__.py | 1 - timesheet_reminder_mail/__manifest__.py | 22 --- .../data/reminder_cron.xml | 30 --- timesheet_reminder_mail/i18n/fr.po | 147 --------------- timesheet_reminder_mail/models/__init__.py | 4 - timesheet_reminder_mail/models/hr_employee.py | 7 - timesheet_reminder_mail/models/res_users.py | 9 - .../models/timesheet_reminder.py | 60 ------ .../models/timesheet_summary.py | 130 ------------- .../static/description/icon.png | Bin 22498 -> 0 bytes timesheet_reminder_mail/views/hr_view.xml | 17 -- timesheet_reminder_mail/views/mail.xml | 176 ------------------ 12 files changed, 603 deletions(-) delete mode 100644 timesheet_reminder_mail/__init__.py delete mode 100755 timesheet_reminder_mail/__manifest__.py delete mode 100644 timesheet_reminder_mail/data/reminder_cron.xml delete mode 100644 timesheet_reminder_mail/i18n/fr.po delete mode 100755 timesheet_reminder_mail/models/__init__.py delete mode 100644 timesheet_reminder_mail/models/hr_employee.py delete mode 100644 timesheet_reminder_mail/models/res_users.py delete mode 100755 timesheet_reminder_mail/models/timesheet_reminder.py delete mode 100755 timesheet_reminder_mail/models/timesheet_summary.py delete mode 100644 timesheet_reminder_mail/static/description/icon.png delete mode 100755 timesheet_reminder_mail/views/hr_view.xml delete mode 100644 timesheet_reminder_mail/views/mail.xml diff --git a/timesheet_reminder_mail/__init__.py b/timesheet_reminder_mail/__init__.py deleted file mode 100644 index 9a7e03e..0000000 --- a/timesheet_reminder_mail/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import models \ No newline at end of file diff --git a/timesheet_reminder_mail/__manifest__.py b/timesheet_reminder_mail/__manifest__.py deleted file mode 100755 index f58f065..0000000 --- a/timesheet_reminder_mail/__manifest__.py +++ /dev/null @@ -1,22 +0,0 @@ -{ - 'name': 'Reminder_timesheet', - 'version': '14.0.0.0', - 'category': 'HR', - 'summary': 'Module to reminder timesheet', - 'description': """ -DESCRIPTION ------------ -This module send a notificaton by mail to each user doesn't wrote at least one of time on timesheet. -""", - 'author': 'Nuxly', - 'website': 'https://www.nuxly.com', - 'depends' : ['base', 'hr_timesheet', 'hr_holidays_public'], - 'data': [ - 'data/reminder_cron.xml', - 'views/mail.xml', - 'views/hr_view.xml', - ], - 'installable': True, - 'auto_install': True, - 'application': True, -} diff --git a/timesheet_reminder_mail/data/reminder_cron.xml b/timesheet_reminder_mail/data/reminder_cron.xml deleted file mode 100644 index 773a665..0000000 --- a/timesheet_reminder_mail/data/reminder_cron.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Reminder to fill timesheet - - code - model._cron_reminder() - - 1 - days - -1 - - - - - - Daily summary of time spent - - code - model._cron_timesheet_summary_manager() - - 1 - days - -1 - - - - - diff --git a/timesheet_reminder_mail/i18n/fr.po b/timesheet_reminder_mail/i18n/fr.po deleted file mode 100644 index 5499b46..0000000 --- a/timesheet_reminder_mail/i18n/fr.po +++ /dev/null @@ -1,147 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * timesheet_reminder_mail -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0+e\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-20 09:49+0000\n" -"PO-Revision-Date: 2023-03-20 09:49+0000\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: timesheet_reminder_mail -#: model:mail.template,body_html:timesheet_reminder_mail.mail_template_timesheet_summary_manager -msgid "" -"
\n" -"

Hello ${object.firstname or 'n/a'},

\n" -"


You will find below several tables summarizing the time spent by your employees.

\n" -" % set sum_analytic_lines = object.get_summarized_analytic_lines(object)\n" -" % for summary in sum_analytic_lines\n" -" % if summary[0]:\n" -" % set intervenants = summary[0][0]\n" -" % set projets = summary[0][1]\n" -" % set titre = summary[1]\n" -"
\n" -"

${titre}

\n" -"
\n" -"
\n" -"
Project | Intervenant
\n" -" % for intervenant in intervenants\n" -"
${intervenant}
\n" -" % endfor\n" -"
\n" -" % for nom_projet in projets\n" -" % if nom_projet == 'Total':\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % elif (loop.index % 2) == 0:\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % else\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % endif\n" -" % endfor\n" -"

\n" -" % endif\n" -" % endfor\n" -"
Thank you,
\n" -" % if user.signature\n" -" ${user.signature | safe}\n" -" % endif\n" -"
\n" -" " -msgstr "" -"
\n" -"

Bonjour ${object.firstname or 'n/a'},

\n" -"


Tu trouveras ci-dessous plusieurs tableaux récapitulant le temps passé sur chaque projet par tes employés.

\n" -" % set sum_analytic_lines = object.get_summarized_analytic_lines(object)\n" -" % for summary in sum_analytic_lines\n" -" % if summary[0]:\n" -" % set intervenants = summary[0][0]\n" -" % set projets = summary[0][1]\n" -" % set titre = summary[1]\n" -"
\n" -"

${titre}

\n" -"
\n" -"
\n" -"
Projet | Intervenant
\n" -" % for intervenant in intervenants\n" -"
${intervenant}
\n" -" % endfor\n" -"
\n" -" % for nom_projet in projets\n" -" % if nom_projet == 'Total':\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % elif (loop.index % 2) == 0:\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % else\n" -"
\n" -"
${nom_projet}
\n" -" % for intervenant in intervenants\n" -" % if intervenant in projets[nom_projet]:\n" -"
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
\n" -" % else\n" -"
\n" -" % endif\n" -" % endfor\n" -"
\n" -" % endif\n" -" % endfor\n" -"

\n" -" % endif\n" -" % endfor\n" -"
Merci,
\n" -" % if user.signature\n" -" ${user.signature | safe}\n" -" % endif\n" -"
\n" -" " diff --git a/timesheet_reminder_mail/models/__init__.py b/timesheet_reminder_mail/models/__init__.py deleted file mode 100755 index d91fab9..0000000 --- a/timesheet_reminder_mail/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from . import timesheet_reminder -from . import hr_employee -from . import timesheet_summary -from . import res_users diff --git a/timesheet_reminder_mail/models/hr_employee.py b/timesheet_reminder_mail/models/hr_employee.py deleted file mode 100644 index c27eb0d..0000000 --- a/timesheet_reminder_mail/models/hr_employee.py +++ /dev/null @@ -1,7 +0,0 @@ -from odoo import api, fields, models, _ - -class HrEmployeePrivate(models.Model): - _inherit = 'hr.employee' - - ignore_timesheet_reminder = fields.Boolean(string='Ignore timesheet reminder', store=True, - help="Do not send timesheet mail reminder if checked", groups="hr.group_hr_user", tracking=True) \ No newline at end of file diff --git a/timesheet_reminder_mail/models/res_users.py b/timesheet_reminder_mail/models/res_users.py deleted file mode 100644 index 927b01d..0000000 --- a/timesheet_reminder_mail/models/res_users.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import api, fields, models, _ - -class HrEmployeePrivate(models.Model): - _inherit = "res.users" - - # Retoune les différents tableaux de temps d'un manager - def get_summarized_analytic_lines(self, manager): - summary = self.env['timesheet.summary'] - return summary.get_summarized_analytic_lines(manager) \ No newline at end of file diff --git a/timesheet_reminder_mail/models/timesheet_reminder.py b/timesheet_reminder_mail/models/timesheet_reminder.py deleted file mode 100755 index 456a425..0000000 --- a/timesheet_reminder_mail/models/timesheet_reminder.py +++ /dev/null @@ -1,60 +0,0 @@ -from datetime import datetime, date -import logging -from odoo import models - -_logger = logging.getLogger(__name__) - - -class Reminder(models.TransientModel): - _name = 'timesheet.reminder' - _description = "Alert each user that doesn't wrote at least one line of time on timesheet" - - def _cron_reminder(self): - public_holiday = self.env['hr.holidays.public.line'] - leave = self.env['hr.leave'] - timesheet = self.env['account.analytic.line'] - hr_employee = self.env['hr.employee'] - - today = date.today() - today_time = datetime.now() - - # Checking working day (not weekend) - if today.weekday() in [0, 1, 2, 3, 4]: - # checking if day is a holiday - holiday = public_holiday.search([]).filtered(lambda x: x.date == today) - if not holiday: - # Check for all employees, if each one write at least one line of timesheet - employees = hr_employee.search([('ignore_timesheet_reminder', '=', False)]) - for employee in employees: - _logger.info("Check '%s'.", employee.name) - # Check if each one doesn't on leave - on_leave = leave.search([('employee_id', '=', employee.id)]).filtered(lambda - x: x.number_of_days == 1.0 and x.date_from == today_time or x.date_from <= today_time <= x.date_to) - if not on_leave: - # Check if each one write at least one line of timesheet, or do a alert - lines = timesheet.search([('date', '=', today), ('employee_id', '=', employee.id), ('state', '!=', 'draft')]) - if not lines: - self._cron_timesheet_send_reminder( - employee, - 'timesheet_reminder_mail.reminder_timesheet_fill', - 'hr_timesheet.act_hr_timesheet_line' - ) - - def _cron_timesheet_send_reminder(self, employees, template_xmlid, action_xmlid, additionnal_values=None): - """ Send the email reminder to specified users - :param user_ids : list of user identifier to send the reminder - :param template_xmlid : xml id of the reminder mail template - """ - action_url = '%s/web#menu_id=%s&action=%s' % ( - self.env['ir.config_parameter'].sudo().get_param('web.base.url'), - self.env.ref('hr_timesheet.timesheet_menu_root').id, - self.env.ref(action_xmlid).id, - ) - # send mail template to users having email address - template = self.env.ref(template_xmlid) - template_ctx = {'action_url': action_url} - if additionnal_values: - template_ctx.update(additionnal_values) - for employee in employees: - template.with_context(**template_ctx).send_mail(employee.id) - _logger.info("A reminder sent to user '%s'.", employee.name) diff --git a/timesheet_reminder_mail/models/timesheet_summary.py b/timesheet_reminder_mail/models/timesheet_summary.py deleted file mode 100755 index 67d2abe..0000000 --- a/timesheet_reminder_mail/models/timesheet_summary.py +++ /dev/null @@ -1,130 +0,0 @@ -from datetime import datetime, date, timedelta -from dateutil.relativedelta import relativedelta -import logging -from odoo import models - -logger = logging.getLogger(__name__) - - -class Summary(models.TransientModel): - _name = 'timesheet.summary' - - def _cron_timesheet_summary_manager(self): - managers = self.get_managers() - action_url = '%s/web#menu_id=%s&action=%s' % ( - self.env['ir.config_parameter'].sudo().get_param('web.base.url'), - self.env.ref('hr_timesheet.timesheet_menu_root').id, - self.env.ref('hr_timesheet.act_hr_timesheet_line').id, - ) - # send mail template to users having email address - template = self.env.ref('timesheet_reminder_mail.mail_template_timesheet_summary_manager') - template_ctx = {'action_url': action_url} - for manager in managers: - template.with_context(template_ctx).send_mail(manager.id) - logger.info("Summaries of time spent to send to the manager '%s'.", manager.name) - - - # Retoune les managers responsablent d'approuver les feuilles de temps - def get_managers(self): - hr_employee = self.env['hr.employee'] - managers = [] - - # Récupération des employés aillant un manager - employees = hr_employee.search([('timesheet_manager_id', "!=", False)]) - - # Parcours ces employés en sortant les managers - for employee in employees: - if employee['timesheet_manager_id'] not in managers: - managers += employee['timesheet_manager_id'] - return managers - - - # Retoune les différents tableaux de temps d'un manager - def get_summarized_analytic_lines(self, manager): - date_today = date.today() - - # Récupération des temps du jour - today = date_today.strftime("%Y-%m-%d") - daily_times = self.get_analytic_lines(today, today, manager) - daily_times_summarized = self.summarize_analytic_lines(daily_times), "Temps du jour" - - # Récupération des temps de la veille ouvrée - date_yesterday = date_today + relativedelta(days=-3) if date_today.weekday() == 0 else date_today + relativedelta(days=-1) - yesterday = date_yesterday.strftime("%Y-%m-%d") - yesterday_times = self.get_analytic_lines(yesterday, yesterday, manager) - yesterday_times_summarized = self.summarize_analytic_lines(yesterday_times), "Temps de la veille" - - # Récupération des temps de la semaine - date_monday = (date_today - timedelta(days=date_today.weekday()+2)).strftime("%Y-%m-%d") - weekly_times = self.get_analytic_lines(date_monday, date_today, manager) - weekly_times_summarized = self.summarize_analytic_lines(weekly_times), "Cumule de la semaine" - - # Récupération des temps du mois - date_start_month = date(date_today.year, date_today.month, 1).strftime("%Y-%m-%d") - monthly_times = self.get_analytic_lines(date_start_month, date_today, manager) - monthly_times_summarized = self.summarize_analytic_lines(monthly_times), "Cumule du mois" - - res = daily_times_summarized, yesterday_times_summarized, weekly_times_summarized, monthly_times_summarized - return res - - - # Retourne les temps passés des employées en fonction d'un manager et d'un plage données - def get_analytic_lines(self, date_start, date_end, manager): - employees = self.env['hr.employee'].search([ - ("timesheet_manager_id", "=", manager.id - )]) - employee_ids = [employee['id'] for employee in employees] - - aal = self.env['account.analytic.line'].search([ - ("employee_id", "in", employee_ids), - ("date",">=",date_start), - ("date","<=",date_end)]) - - return aal - - - # Retourne une synthèse des temps passés - def summarize_analytic_lines(self, aal): - if aal: - # tpi : total par intervenant - # tpp : total par projet - tpi = tpp = "Total" - intervenants = [] - projets = {} - # temps total des intervenants pour tous projets confondus - tpi_dict = {tpi: {tpp: 0}} - - for line in aal: - projet = line.project_id.name - intervenant = line.employee_id.user_partner_id.firstname - temps = line.unit_amount - - # Ajout de l'intervenant dans le tableau "intervenants" s'il n'existe pas déjà - if intervenant not in intervenants: - intervenants.append(intervenant) - # Ajout de le projet dans le tableau "projets" s'il n'existe pas déjà - if projet not in projets: - projets[projet] = {} - projets[projet][tpp] = 0 - # Si l’intervenant est déjà sur le projet du tableau "projets" alors on additionne le temps passé au temps déjà renseigné - if intervenant in projets[projet]: - projets[projet][intervenant] += temps - tpi_dict[tpi][intervenant] += temps - projets[projet][tpp] += temps - tpi_dict[tpi][tpp] += temps - # Sinon l’intervenant est ajouté sur le projet du tableau "projets" et son temps passé est renseigné - else: - projets[projet][intervenant] = temps - if intervenant not in tpi_dict[tpi]: - tpi_dict[tpi][intervenant] = temps - else: - tpi_dict[tpi][intervenant] += temps - projets[projet][tpp] += temps - tpi_dict[tpi][tpp] += temps - - # Ajout d'un intervenant "Total" - intervenants.append(tpp) - # Ajout d'une ligne de temps total des intervenants pour tous projets confondus au tableau des projets - projets.update(tpi_dict) - res = intervenants, projets - return res diff --git a/timesheet_reminder_mail/static/description/icon.png b/timesheet_reminder_mail/static/description/icon.png deleted file mode 100644 index 3946688480073e9400e4394b60209b47794dc28d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22498 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 IIn#Up5ATZqcK`qY diff --git a/timesheet_reminder_mail/views/hr_view.xml b/timesheet_reminder_mail/views/hr_view.xml deleted file mode 100755 index a9a7317..0000000 --- a/timesheet_reminder_mail/views/hr_view.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - hr.employee.form.timesheet.reminder - hr.employee - - - - - - - - - - \ No newline at end of file diff --git a/timesheet_reminder_mail/views/mail.xml b/timesheet_reminder_mail/views/mail.xml deleted file mode 100644 index e3116b6..0000000 --- a/timesheet_reminder_mail/views/mail.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Timesheet: Reminder to fill timesheet - - Rappel pour saisir vos temps - ${(object.user_id.company_id.partner_id.email_formatted or user.email_formatted) | safe} - ${object.work_email | safe} - - - - -
- - - - - - - - - - - - - - - -
- - - -
- Your Timesheets
- - ${object.name} - -
- ${object.company_id.name} -
-
-
-
- - - -
-
- Bonjour ${object.name},

- À l'heure actuelle, vous n'avez pas de temps "A valider" saisis pour aujourd'hui. Est-ce un oubli ou normal ? -
- % if ctx.get('action_url'): - - % endif -
Merci,
- % if user.signature - ${user.signature | safe} - % endif -
-
-
-
-
- - - -
- ${object.company_id.name} -
- ${object.company_id.phone} - % if object.company_id.email - | ${object.company_id.email} - % endif - % if object.company_id.website - | - ${object.company_id.website} - - % endif -
-
-
- - -
- Powered by Odoo -
-
-
- ${object.user_id.lang} - -
- - - - - - Timesheet - Daily summary of time spent - - ${(object.company_id.partner_id.email_formatted or object.email_formatted) |safe} - ${object.work_email | safe} - Daily summary of time spent - -
-

Hello ${object.firstname or 'n/a'},

-


You will find below several tables summarizing the time spent by your employees.

- % set sum_analytic_lines = object.get_summarized_analytic_lines(object) - % for summary in sum_analytic_lines - % if summary[0]: - % set intervenants = summary[0][0] - % set projets = summary[0][1] - % set titre = summary[1] -
-

${titre}

-
-
-
Project | Intervenant
- % for intervenant in intervenants -
${intervenant}
- % endfor -
- % for nom_projet in projets - % if nom_projet == 'Total': -
-
${nom_projet}
- % for intervenant in intervenants - % if intervenant in projets[nom_projet]: -
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
- % else -
- % endif - % endfor -
- % elif (loop.index % 2) == 0: -
-
${nom_projet}
- % for intervenant in intervenants - % if intervenant in projets[nom_projet]: -
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
- % else -
- % endif - % endfor -
- % else -
-
${nom_projet}
- % for intervenant in intervenants - % if intervenant in projets[nom_projet]: -
${'{:.2f}'.format(projets[nom_projet][intervenant]).replace('.',',')}
- % else -
- % endif - % endfor -
- % endif - % endfor -
- % endif - % endfor -
Thank you,
- % if user.signature - ${user.signature | safe} - % endif -
-
- ${object.lang} - -
- -
-