From d9f96285a994226bc57837a3a64ae1d0df33bc86 Mon Sep 17 00:00:00 2001 From: esam Date: Tue, 16 Dec 2025 15:18:21 -0500 Subject: [PATCH] reminder --- exp_timesheet_missing_reminder/__init__.py | 3 + .../__manifest__.py | 39 ++ .../data/corn_timesheet_reminder.xml | 37 ++ .../data/timesheet_email_template.xml | 91 ++++ exp_timesheet_missing_reminder/i18n/ar_001.po | 506 ++++++++++++++++++ .../models/__init__.py | 5 + .../models/approve_multi.py | 22 + .../models/employee_history.py | 17 + .../models/extend_hr_employee.py | 9 + .../models/extend_hr_timesheet.py | 429 +++++++++++++++ .../report/report_action.xml | 12 + .../report/report_template.xml | 172 ++++++ .../security/ir.model.access.csv | 6 + .../static/description/icon.png | Bin 0 -> 32929 bytes .../static/fonts/ae_AlMohanad.ttf | Bin 0 -> 120920 bytes .../static/src/css/website_rtl.css | 22 + .../tests/__init__.py | 1 + .../tests/test_exp_timesheet_reminder.py | 159 ++++++ .../views/extend_hr_employee.xml | 45 ++ .../views/hr_employee_reminder_history.xml | 51 ++ .../views/wizard_approve.xml | 38 ++ .../wizard/__init__.py | 2 + .../wizard/timesheet_reminder_report.py | 182 +++++++ .../wizard/timesheet_reminder_report.xml | 46 ++ 24 files changed, 1894 insertions(+) create mode 100644 exp_timesheet_missing_reminder/__init__.py create mode 100644 exp_timesheet_missing_reminder/__manifest__.py create mode 100644 exp_timesheet_missing_reminder/data/corn_timesheet_reminder.xml create mode 100644 exp_timesheet_missing_reminder/data/timesheet_email_template.xml create mode 100644 exp_timesheet_missing_reminder/i18n/ar_001.po create mode 100644 exp_timesheet_missing_reminder/models/__init__.py create mode 100644 exp_timesheet_missing_reminder/models/approve_multi.py create mode 100644 exp_timesheet_missing_reminder/models/employee_history.py create mode 100644 exp_timesheet_missing_reminder/models/extend_hr_employee.py create mode 100644 exp_timesheet_missing_reminder/models/extend_hr_timesheet.py create mode 100644 exp_timesheet_missing_reminder/report/report_action.xml create mode 100644 exp_timesheet_missing_reminder/report/report_template.xml create mode 100644 exp_timesheet_missing_reminder/security/ir.model.access.csv create mode 100644 exp_timesheet_missing_reminder/static/description/icon.png create mode 100644 exp_timesheet_missing_reminder/static/fonts/ae_AlMohanad.ttf create mode 100644 exp_timesheet_missing_reminder/static/src/css/website_rtl.css create mode 100644 exp_timesheet_missing_reminder/tests/__init__.py create mode 100644 exp_timesheet_missing_reminder/tests/test_exp_timesheet_reminder.py create mode 100644 exp_timesheet_missing_reminder/views/extend_hr_employee.xml create mode 100644 exp_timesheet_missing_reminder/views/hr_employee_reminder_history.xml create mode 100644 exp_timesheet_missing_reminder/views/wizard_approve.xml create mode 100644 exp_timesheet_missing_reminder/wizard/__init__.py create mode 100644 exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.py create mode 100644 exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.xml diff --git a/exp_timesheet_missing_reminder/__init__.py b/exp_timesheet_missing_reminder/__init__.py new file mode 100644 index 0000000..408a600 --- /dev/null +++ b/exp_timesheet_missing_reminder/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import models +from . import wizard diff --git a/exp_timesheet_missing_reminder/__manifest__.py b/exp_timesheet_missing_reminder/__manifest__.py new file mode 100644 index 0000000..220db73 --- /dev/null +++ b/exp_timesheet_missing_reminder/__manifest__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Odex - Communications Management System. +# Copyright (C) 2019 Expert Co. Ltd. (). +# +############################################################################## +{ + 'name': 'Timesheet Reminder Employees', + 'version': '1.0', + 'sequence': 10, + 'author': 'Expert Co. Ltd. ---sudan team', + 'category': 'Odex30-HR/Odex30-HR', + 'website': 'http://exp-sa.com', + 'summary': 'Timesheet Missing Reminder to Employees', + 'description': """ +Timesheet Missing Reminder to Employees By sending Email per Day or Week and Month +========================================""", + 'website': 'http://www.exp-sa.com', + 'depends': ['mail', 'hr_timesheet_sheet', 'exp_official_mission', 'hr_holidays_public', 'attendances'], + 'data': [ + 'data/corn_timesheet_reminder.xml', + 'data/timesheet_email_template.xml', + 'security/ir.model.access.csv', + 'views/extend_hr_employee.xml', + 'views/hr_employee_reminder_history.xml', + 'report/report_action.xml', + 'report/report_template.xml', + 'wizard/timesheet_reminder_report.xml', + 'views/wizard_approve.xml', + ], + 'qweb': [ + ], + 'installable': True, + 'auto_install': False, + 'application': False, + 'test_tags': ['standard', 'at_install'], + +} diff --git a/exp_timesheet_missing_reminder/data/corn_timesheet_reminder.xml b/exp_timesheet_missing_reminder/data/corn_timesheet_reminder.xml new file mode 100644 index 0000000..d399db4 --- /dev/null +++ b/exp_timesheet_missing_reminder/data/corn_timesheet_reminder.xml @@ -0,0 +1,37 @@ + + + + + + Late Email Reminder Day + True + 1 + days + + code + model.action_send_late_email('day') + + + + + Late Email Reminder Week + True + 7 + days + + code + model.action_send_late_email('week') + + + + + Late Email Reminder Month + True + 30 + days + + code + model.action_send_late_email('month') + + + diff --git a/exp_timesheet_missing_reminder/data/timesheet_email_template.xml b/exp_timesheet_missing_reminder/data/timesheet_email_template.xml new file mode 100644 index 0000000..0a4db9c --- /dev/null +++ b/exp_timesheet_missing_reminder/data/timesheet_email_template.xml @@ -0,0 +1,91 @@ + + + + + + + Daily Timesheet Reminder Message + + + ]]> + + + +

السادة الفضلاء:}

+

حفظهم الله،،

+

+ السلام عليكم ورحمة الله. + +

+

+ الرجاء تعبئة الايام المفقوده +


+

+


+

+ ${user.company_id.name} +

+ + ]]> +
+
+ + + + Weekly Timesheet Reminder Message + + + ]]> + + + +

السادة الفضلاء:}

+

حفظهم الله،،

+

+ السلام عليكم ورحمة الله. +

+

+ الرجاء تعبئة الايام المفقوده +


+

+


+

+ ${user.company_id.name} +

+ + ]]> +
+
+ + + + + Monthly Timesheet Reminder Message + + + ]]> + + + +

السادة الفضلاء:}

+

حفظهم الله،،

+

+ السلام عليكم ورحمة الله. +

+

+ الرجاء تعبئة الايام المفقوده +


+

+


+

+ ${user.company_id.name} +

+ + ]]> +
+
+
+
diff --git a/exp_timesheet_missing_reminder/i18n/ar_001.po b/exp_timesheet_missing_reminder/i18n/ar_001.po new file mode 100644 index 0000000..31cfaa1 --- /dev/null +++ b/exp_timesheet_missing_reminder/i18n/ar_001.po @@ -0,0 +1,506 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * exp_timesheet_missing_reminder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-16 14:04+0000\n" +"PO-Revision-Date: 2025-12-16 14:04+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: exp_timesheet_missing_reminder +#: model:mail.template,subject:exp_timesheet_missing_reminder.timesheet_week_reminder_email_notify +msgid " تذكير اسبوعي بتقرير المهام اليومية " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,subject:exp_timesheet_missing_reminder.timesheet_monthly_reminder_email_notify +msgid " تذكير شهري بتقرير المهام اليومية " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,subject:exp_timesheet_missing_reminder.timesheet_daily_reminder_email_notify +msgid " تذكير يومي بتقرير المهام اليومية " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.report,name:exp_timesheet_missing_reminder.action_report_reminded +msgid "\"Reminded Employee" +msgstr "تذكير الموظفين" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,body_html:exp_timesheet_missing_reminder.timesheet_monthly_reminder_email_notify +msgid "" +"
\n" +"

السادة الفضلاء:}

\n" +"

حفظهم الله،،

\n" +"

\n" +" السلام عليكم ورحمة الله.\n" +"

\n" +"

\n" +" الرجاء تعبئة الايام المفقوده\n" +"


\n" +"

\n" +"


\n" +"

\n" +" ${user.company_id.name}\n" +"

\n" +"
\n" +" \n" +" " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,body_html:exp_timesheet_missing_reminder.timesheet_week_reminder_email_notify +msgid "" +"
\n" +"

السلام عليكم ورحمة الله

\n" +"
\n" +"

السيد\\ة esam alsrmaah مع التحية

\n" +"
\n" +"

تقرير الأعمال اليومي الخاص بكم في النظام لم يغط الأوقات المطلوبة منكم حسب الجدول التالي:\n" +"\n" +"، نأمل إبداء الأسباب خلال \n" +"يوم واحد فقط للنظر فيها، وفي حال لم ترسل الأسباب أو أرسلت ولم تكن مقنعة نظاما، سيتم خصم ساعات الغياب من راتبك الشهري.\n" +"إن عدم تغطية الأوقات الفعلية لكم بدون أسباب مقبولة منكم هو تقصير تستحقون عليه الإنذار.

\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" % for line in [['2025-12-08', 'Monday', 0.0, 0.0, 0.0], ['2025-12-09', 'Tuesday', 0.0, 0.0, 0.0], ['2025-12-10', 'Wednesday', 0.0, 0.0, 0.0], ['2025-12-11', 'Thursday', 0.0, 0.0, 0.0], ['2025-12-12', 'Friday', 0.0, 0.0, 0.0], ['2025-12-13', 'Saturday', 0.0, 0.0, 0.0], ['2025-12-14', 'Sunday', 0.0, 0.0, 0.0]]:\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" % endfor\n" +" \n" +"
الساعاتالتاريخالايام
\n" +" ${line[2]}\n" +" \n" +" ${line[0]}\n" +" \n" +" ${line[1]}\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,body_html:exp_timesheet_missing_reminder.timesheet_daily_reminder_email_notify +msgid "" +"
\n" +"

السلام عليكم ورحمة الله

\n" +"
\n" +"

السيد\\ة esam alsrmaah مع التحية

\n" +"
\n" +"

تقرير الأعمال اليومي الخاص بكم في النظام لم يغط الأوقات المطلوبة منكم حسب الجدول التالي:\n" +"\n" +"، نأمل إبداء الأسباب خلال \n" +"يوم واحد فقط للنظر فيها، وفي حال لم ترسل الأسباب أو أرسلت ولم تكن مقنعة نظاما، سيتم خصم ساعات الغياب من راتبك الشهري.\n" +"إن عدم تغطية الأوقات الفعلية لكم بدون أسباب مقبولة منكم هو تقصير تستحقون عليه الإنذار.

\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" % for line in [['2025-12-14', 'Sunday', 3.0, 7.0, 4.0]]:\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" % endfor\n" +" \n" +"
الساعاتالتاريخالايام
\n" +" ${line[2]}\n" +" \n" +" ${line[0]}\n" +" \n" +" ${line[1]}\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.approve_timesheet_view +msgid "All selected Timesheet will be Approved Are You Sure?" +msgstr "هل انت متاكد من إعتماد هذه الجداول الزمنية؟" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__actual_hour +msgid "Actual" +msgstr "الساعات الفعلية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_account_analytic_line +msgid "Analytic Line" +msgstr "البند التحليلي" + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.act_window,name:exp_timesheet_missing_reminder.action_approve_multi_timesheet +#: model:ir.model,name:exp_timesheet_missing_reminder.model_approve_multi_timesheet +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.approve_timesheet_view +msgid "Approve Multi Timesheet" +msgstr "إعتماد الجداول الزمنية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__attachment_ids +msgid "Attachments" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__break_hour +msgid "Break Hour" +msgstr "ساعات الراحة" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.approve_timesheet_view +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.wizard_reminded_employees_form +msgid "Cancel" +msgstr "إلغاء" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_resource_calendar__check_timesheet +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.resource_calendar_inherited_timesheet_form +msgid "Check Timesheet" +msgstr "الربط مع الجداول الزمنية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__create_uid +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__create_uid +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__create_uid +msgid "Created by" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__create_date +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__create_date +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__create_date +msgid "Created on" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,name:exp_timesheet_missing_reminder.timesheet_daily_reminder_email_notify +msgid "Daily Timesheet Reminder Message" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__date +msgid "Date" +msgstr "التاريخ" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__date_from +msgid "Date From" +msgstr "تاريخ البداية" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.py:0 +msgid "Date From Must Be Greater Than Date To" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__date_to +msgid "Date To" +msgstr "التاريخ للإنتهاء" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__department_ids +msgid "Department" +msgstr "الهيكل الإداري" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__display_name +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__display_name +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_hr_employee +msgid "Employee" +msgstr "الموظف" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__employee_id +msgid "Employee Name" +msgstr "اسم الموظف" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__entered_hour +msgid "Entered Hour" +msgstr "الساعات المدخلة" + +#. module: exp_timesheet_missing_reminder +#: model:ir.ui.menu,name:exp_timesheet_missing_reminder.menu_hr_employee_history_reminder +msgid "History Reminder" +msgstr "حركة التذكير بالجداول الزمنية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.act_window,name:exp_timesheet_missing_reminder.hr_employee_reminder_history_action +msgid "Hr employee reminder" +msgstr "حركة التذكير بالجداول الزمنية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__id +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__id +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__id +msgid "ID" +msgstr "المُعرف" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__is_completed_timesheet +msgid "Is completed Timesheet" +msgstr "جدول زمني كامل" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__write_uid +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__write_uid +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_approve_multi_timesheet__write_date +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__write_date +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_timesheet_reminded__write_date +msgid "Last Updated on" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.server,name:exp_timesheet_missing_reminder.day_reminder_mail_ir_actions_server +msgid "Late Email Reminder Day" +msgstr "تذكير بالمهام بإيميل يومي " + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.server,name:exp_timesheet_missing_reminder.monthly_reminder_mail_ir_actions_server +msgid "Late Email Reminder Month" +msgstr "تذكير بالمهام بإيميل شهري " + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.server,name:exp_timesheet_missing_reminder.week_reminder_mail_ir_actions_server +msgid "Late Email Reminder Week" +msgstr "تذكير بالمهام بإيميل اسبوعي " + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__miss_hour +msgid "Miss Hour" +msgstr "الساعات الغير مدخلة" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,name:exp_timesheet_missing_reminder.timesheet_monthly_reminder_email_notify +msgid "Monthly Timesheet Reminder Message" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee_history_reminder__overtime_hour +msgid "Overtime Hour" +msgstr "الساعات الاضافية" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.wizard_reminded_employees_form +msgid "Print" +msgstr "طباعة PDF" + +#. module: exp_timesheet_missing_reminder +#: model:ir.actions.act_window,name:exp_timesheet_missing_reminder.wizard_reminded_employees_action +msgid "Reminded Employees" +msgstr "تذكيرات الموظفين" + +#. module: exp_timesheet_missing_reminder +#: model:ir.ui.menu,name:exp_timesheet_missing_reminder.report_reminded_employees_menu +msgid "Reminded Employees Report" +msgstr "تقرير تذكير الجداول الزمنية" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_resource_calendar +msgid "Resource Working Time" +msgstr "فترة عمل المورد" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_hr_employee__skipp_timesheet_reminder +msgid "Skip Timesheet Reminder" +msgstr "عدم التذكير بالمهام" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "" +"Sorry, the timesheet days before must be greater than or equal to zero." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "" +"Sorry, the timesheet hours before must be greater than or equal to zero." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "" +"Sorry, the timesheet hours before must be less than or equal to 24 hours." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "Sorry, you cannot request the timesheet lines %s for an earlier date." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "Sorry, you cannot request the timesheet lines %s in advance." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "" +"Sorry, you cannot request the timesheet lines %s the day after %s hour." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py:0 +msgid "Sorry, your timesheet lines %s are not in the timesheet period." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#. odoo-python +#: code:addons/exp_timesheet_missing_reminder/models/approve_multi.py:0 +msgid "There is No Timesheet in Confirm state to Approve." +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,help:exp_timesheet_missing_reminder.field_resource_calendar__exc_user_id +msgid "This user can request timesheet as exception to all rules" +msgstr "يقوم هذا المستخدم بالإستثناء من القواعد لطلب الجداول الزمنية للموظفين" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.actions.act_window,help:exp_timesheet_missing_reminder.action_approve_multi_timesheet +msgid "This wizard will Approve all selected timesheet" +msgstr "هذا المعالج لاعتماد اكثر من جداول زمنية مع بعض" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_resource_calendar__timesheet_day_before +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.resource_calendar_inherited_timesheet_form +msgid "Timesheet Days Before" +msgstr "طلب جدول الزمنية قبل ايام" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_resource_calendar__timesheet_hour_before +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.resource_calendar_inherited_timesheet_form +msgid "Timesheet Hours Before" +msgstr "طلب جدول الزمنية قبل الساعة" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_hr_timesheet_sheet +msgid "Timesheet Sheet" +msgstr "سجل الدوام" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,help:exp_timesheet_missing_reminder.field_resource_calendar__timesheet_day_before +msgid "To request timesheet for previous days not exceed these days" +msgstr "لطلب الجداول الزمنية لايام سابقة عدم تجاوز هذه الايام" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,help:exp_timesheet_missing_reminder.field_resource_calendar__timesheet_hour_before +msgid "To request timesheet for previous days, not to exceed this hour" +msgstr "لطلب الجداول الزمنية لايام سابقة بعدم تجاوز هذا الزمن" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model.fields,field_description:exp_timesheet_missing_reminder.field_resource_calendar__exc_user_id +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.resource_calendar_inherited_timesheet_form +msgid "User Exception" +msgstr "لإستثناء الموظفين" + +#. module: exp_timesheet_missing_reminder +#: model:mail.template,name:exp_timesheet_missing_reminder.timesheet_week_reminder_email_notify +msgid "Weekly Timesheet Reminder Message" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_hr_employee_history_reminder +msgid "hr.employee.history.reminder" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_report_exp_timesheet_missing_reminder_reminded_report_template +msgid "report.exp_timesheet_missing_reminder.reminded_report_template" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.hr_employee_view_custom +msgid "timesheet reminder" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model:ir.model,name:exp_timesheet_missing_reminder.model_timesheet_reminded +msgid "timesheet.reminded" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "إلى" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "الموظف" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "تقرير عدد مرات تذكير الموظفين" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "عدد الساعات المدخله" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "عدد الساعات المنسية" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "عدد مرات التذكير" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "ملاحظات" +msgstr "" + +#. module: exp_timesheet_missing_reminder +#: model_terms:ir.ui.view,arch_db:exp_timesheet_missing_reminder.reminded_report_template +msgid "من تاريخ" +msgstr "" \ No newline at end of file diff --git a/exp_timesheet_missing_reminder/models/__init__.py b/exp_timesheet_missing_reminder/models/__init__.py new file mode 100644 index 0000000..6c7fee7 --- /dev/null +++ b/exp_timesheet_missing_reminder/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +from . import extend_hr_employee +from . import extend_hr_timesheet +from . import employee_history +from . import approve_multi diff --git a/exp_timesheet_missing_reminder/models/approve_multi.py b/exp_timesheet_missing_reminder/models/approve_multi.py new file mode 100644 index 0000000..f9a1efe --- /dev/null +++ b/exp_timesheet_missing_reminder/models/approve_multi.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from odoo import models, _ +from odoo.exceptions import UserError + + +class ApproveMultiTimesheet(models.TransientModel): + _name = "approve.multi.timesheet" + _description = "Approve Multi Timesheet" + + def validate_timesheet(self): + context = dict(self._context or {}) + moves = self.env['hr_timesheet.sheet'].browse(context.get('active_ids')) + move_to_post = self.env['hr_timesheet.sheet'] + for move in moves: + if move.state == 'approve': + move_to_post += move + if not move_to_post: + raise UserError(_('There is No Timesheet in Confirm state to Approve.')) + move_to_post.action_timesheet_done() + return {'type': 'ir.actions.act_window_close'} + \ No newline at end of file diff --git a/exp_timesheet_missing_reminder/models/employee_history.py b/exp_timesheet_missing_reminder/models/employee_history.py new file mode 100644 index 0000000..46528b0 --- /dev/null +++ b/exp_timesheet_missing_reminder/models/employee_history.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields + + +class HrEmployeeHistory(models.Model): + _name = 'hr.employee.history.reminder' + _rec_name = 'employee_id' + + employee_id = fields.Many2one('hr.employee', string='Employee Name') + date = fields.Date() + miss_hour = fields.Float(string='Miss Hour') + actual_hour = fields.Float(string='Actual') + entered_hour = fields.Float(string='Entered Hour') + break_hour = fields.Float(string='Break Hour') + overtime_hour = fields.Float(string='Overtime Hour') + is_completed_timesheet = fields.Boolean('Is completed Timesheet', default=False) diff --git a/exp_timesheet_missing_reminder/models/extend_hr_employee.py b/exp_timesheet_missing_reminder/models/extend_hr_employee.py new file mode 100644 index 0000000..31ff113 --- /dev/null +++ b/exp_timesheet_missing_reminder/models/extend_hr_employee.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields + + +class ExtendEmployee(models.Model): + _inherit = 'hr.employee' + + skipp_timesheet_reminder = fields.Boolean(string='Skip Timesheet Reminder') diff --git a/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py b/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py new file mode 100644 index 0000000..efebb59 --- /dev/null +++ b/exp_timesheet_missing_reminder/models/extend_hr_timesheet.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +import datetime +from dateutil.relativedelta import relativedelta +from datetime import date, datetime, timedelta +from time import gmtime +from dateutil import relativedelta +from odoo import models, fields, api, _ +from odoo.exceptions import UserError + + +class HrAttendances(models.Model): + _inherit = 'resource.calendar' + + check_timesheet = fields.Boolean('Check Timesheet', default=False) + + timesheet_day_before = fields.Integer( + string='Timesheet Days Before', + default=0, + help='To request timesheet for previous days not exceed these days' + ) + timesheet_hour_before = fields.Integer( + string='Timesheet Hours Before', + default=0, + help='To request timesheet for previous days, not to exceed this hour' + ) + exc_user_id = fields.Many2one( + comodel_name="res.users", + string='User Exception', + help='This user can request timesheet as exception to all rules' + ) + + @api.constrains('timesheet_day_before', 'timesheet_hour_before') + def check_date(self): + for rec in self: + if rec.timesheet_day_before < 0: + raise UserError(_('Sorry, the timesheet days before must be greater than or equal to zero.')) + if rec.timesheet_hour_before < 0: + raise UserError(_('Sorry, the timesheet hours before must be greater than or equal to zero.')) + if rec.timesheet_hour_before > 24: + raise UserError(_('Sorry, the timesheet hours before must be less than or equal to 24 hours.')) + + +class AccountAnalyticLine(models.Model): + _inherit = 'account.analytic.line' + + @api.constrains('date') + def check_date(self): + for each in self: + emp_calender = each.employee_id.resource_calendar_id + if not emp_calender: + continue + + timesheet_user = emp_calender.exc_user_id.id + chick_sheet = emp_calender.check_timesheet + number_day_befor = emp_calender.timesheet_day_before + number_hour_befor = emp_calender.timesheet_hour_before + + line_date = fields.Date.from_string(each.date) + yesterday = date.today() - relativedelta.relativedelta(days=number_day_befor) + hour = gmtime().tm_hour + 3 + + if each.sheet_id: + startdate = datetime.strptime(str(each.sheet_id.date_start), "%Y-%m-%d").date() + enddate = datetime.strptime(str(each.sheet_id.date_end), "%Y-%m-%d").date() + if line_date < startdate or line_date > enddate: + raise UserError( + _('Sorry, your timesheet lines %s are not in the timesheet period.') % line_date + ) + + if chick_sheet and timesheet_user != each.env.uid: + full_day_off = [da.name for da in emp_calender.full_day_off] + shift_day_off = [da.name for da in emp_calender.shift_day_off] + + day_item = date.today() + prv_day = day_item - timedelta(1) + prv_weekday = prv_day.strftime('%A').lower() + line_weekday = line_date.strftime('%A').lower() + + if line_date < yesterday: + if emp_calender.is_full_day: + if prv_weekday not in full_day_off: + raise UserError( + _('Sorry, you cannot request the timesheet lines %s for an earlier date.') % line_date + ) + if line_weekday not in full_day_off and line_weekday != 'thursday': + raise UserError( + _('Sorry, you cannot request the timesheet lines %s for an earlier date.') % line_date + ) + else: + if prv_weekday not in shift_day_off: + raise UserError( + _('Sorry, you cannot request the timesheet lines %s for an earlier date.') % line_date + ) + if line_weekday not in shift_day_off and line_weekday != 'thursday': + raise UserError( + _('Sorry, you cannot request the timesheet lines %s for an earlier date.') % line_date + ) + + if line_date == yesterday and hour > number_hour_befor and line_weekday != 'thursday': + raise UserError( + _('Sorry, you cannot request the timesheet lines %s the day after %s hour.') % ( + line_date, number_hour_befor + ) + ) + + if line_date > date.today(): + raise UserError( + _('Sorry, you cannot request the timesheet lines %s in advance.') % line_date + ) + + +class ExtendHrTimesheet(models.Model): + _inherit = 'hr_timesheet.sheet' + + def common_search_model(self, model_name, param1, param2): + result = '' + if model_name == 'hr.holidays': + result = self.env[model_name].search([('date_from', '<=', param1), ('date_to', '>=', param1), + ('state', '=', 'validate1'), ('type', '=', 'remove'), + ('employee_id', '=', param2)]) + if model_name == 'hr.official.mission': + result = self.env[model_name].search( + [('state', '=', 'approve'), ('date_from', '<=', param1), ('date_to', '>=', param1)]) + if model_name == 'hr_timesheet.sheet': + result = self.env[model_name].search( + [('employee_id', '=', param2), ('date_start', '<=', param1), ('date_end', '>=', param1)]) + if model_name == 'hr.personal.permission': + result = self.env[model_name].search( + [('employee_id', '=', param2), ('date', '=', param1)]) + return result + + def compute_miss_hour(self, resource_id, total_work_hour, type=None, ): + miss_hour = 0.0 + if type == 'normal': + if resource_id.is_full_day: + xx = resource_id.working_hours - resource_id.break_duration + else: + xx = resource_id.shift_one_working_hours + resource_id.shift_two_working_hours - \ + resource_id.break_duration + if xx > total_work_hour: + miss_hour = xx - total_work_hour + elif type == 'special': + if resource_id.working_hours > total_work_hour: + miss_hour = resource_id.working_hours - total_work_hour + return miss_hour + + def get_common_data(self, type): + today = date.today() + date_list = [] + if type == 'day': + template = 'exp_timesheet_missing_reminder.timesheet_daily_reminder_email_notify' + one_day_ago = today - timedelta(days=1) + date_list.append([str(one_day_ago), one_day_ago.strftime("%A")]) + return template, one_day_ago, one_day_ago, date_list + elif type == 'week': + template = 'exp_timesheet_missing_reminder.timesheet_week_reminder_email_notify' + one_week_ago = today - timedelta(weeks=1) + last_day_in_day = one_week_ago + timedelta(days=6) + dt = [one_week_ago + timedelta(days=x) for x in range(7)] + for datess in dt: + date_list.append([str(datess), datess.strftime("%A")]) + return template, one_week_ago, last_day_in_day, date_list + elif type == 'month': + template = 'exp_timesheet_missing_reminder.timesheet_monthly_reminder_email_notify' + first = today.replace(day=1) + last_day_month = first - timedelta(days=1) + first_day = last_day_month + timedelta(days=1) + delta = last_day_month - first_day + dt = [first_day + timedelta(days=x) for x in range(delta.days + 1)] + for datess in dt: + date_list.append([str(datess), datess.strftime("%A")]) + return template, first_day, last_day_month, date_list + + def send_message(self, template=None, rec=None, date=[]): + if not template or not rec or not rec.work_email: + return + + try: + template = self.env.ref(template, False) + if not template: + return + + body = """
+

السلام عليكم ورحمة الله وبركاته

+
+

السيد/السيدة %s مع التحية،

+
+

تقرير الأعمال اليومي الخاص بكم في النظام لم يغطِ الأوقات المطلوبة منكم حسب الجدول التالي:

+
+

+ نأمل إبداء الأسباب خلال يوم واحد فقط للنظر فيها، + وفي حال لم ترسل الأسباب أو أرسلت ولم تكن مقنعة نظاماً، + سيتم خصم ساعات الغياب من راتبكم الشهري. +

+

+ إن عدم تغطية الأوقات الفعلية لكم بدون أسباب مقبولة منكم هو تقصير تستحقون عليه الإنذار. +

+
+
+ + + + + + + + + + % for line in date: + + + + + + % endfor + +
الساعات المفقودةالتاريخاليوم
+ ${line[2] or 0} ساعة + + ${line[0]} + + ${line[1]} +
+
+
+

شكراً لتعاونكم

+

فريق الموارد البشرية

+
""" % rec.name + + template.write({ + 'email_to': rec.work_email, + 'email_cc': rec.parent_id.work_email if rec.parent_id and rec.parent_id.work_email else False, + 'body_html': body, + }) + + template.send_mail(rec.id, force_send=False, raise_exception=False) + + except Exception as e: + self.env['ir.logging'].sudo().create({ + 'name': 'Timesheet Reminder Email Error', + 'type': 'server', + 'message': f'Email failed for {rec.name}: {str(e)}', + 'path': 'exp_timesheet_missing_reminder.send_message', + 'func': 'send_message', + 'line': '1' + }) + + def action_send_late_email(self, type): + + template, start_date, last_date, date_list = self.get_common_data(type) + + final_employee_date = {} + employees = self.env['hr.employee'].search([ + ('state', '=', 'open'), + ('skipp_timesheet_reminder', '=', False) + ]) + + for emp in employees: + employee_day_of = [] + employee_spcial_day = [] + + for special_day in emp.resource_calendar_id.special_days: + employee_spcial_day.append(special_day.name) + for day_off in emp.resource_calendar_id.full_day_off: + employee_day_of.append(day_off.name) + + emp_calender = emp.resource_calendar_id + + for day in date_list: + if day[1].lower() in employee_day_of: + continue + + employee_attendance = self.env['hr.attendance.transaction'].search( + [('employee_id', '=', emp.id), ('date', '=', day[0])] + ) + + if employee_attendance: + employee_spcial_day = [] + employee_day_of = [] + for special_day in employee_attendance.calendar_id.special_days: + employee_spcial_day.append(special_day.name) + for day_off in employee_attendance.calendar_id.full_day_off: + employee_day_of.append(day_off.name) + emp_calender = employee_attendance.calendar_id + + holiday_officials_ids = self.env['hr.holiday.officials'].search( + [('date_from', '<=', day[0]), + ('date_to', '>=', day[0]), + ('state', '=', 'confirm')] + ) + + if holiday_officials_ids: + continue + + holidays_id = self.common_search_model('hr.holidays', day[0], emp.id) + if holidays_id: + continue + + mission_id = self.common_search_model('hr.official.mission', day[0], '') + mission = mission_id.filtered(lambda r: r.mission_type.duration_type == 'days') + mission_employee = mission.employee_ids.filtered( + lambda r: r.employee_id.id == emp.id and r.date_from <= r.date_to + ) + if mission_employee: + continue + + day_type = 'normal' + calender = emp_calender + actual_hour = emp_calender.working_hours - emp_calender.break_duration + if not emp_calender.is_full_day: + actual_hour = ( + emp_calender.shift_one_working_hours + + emp_calender.shift_two_working_hours - + emp_calender.break_duration + ) + + if day[1].lower() in employee_spcial_day: + day_type = 'special' + spacial_day = emp_calender.special_days.filtered(lambda r: r.name == day[1].lower()) + calender = spacial_day + actual_hour = spacial_day.working_hours + + mission_hour = 0.0 + permission_hour = 0.0 + + mission_id = self.env['hr.official.mission'].search( + [('state', '=', 'approve'), + ('date', '<=', day[0]), + ('date', '>=', day[0])] + ) + mission = mission_id.filtered(lambda r: r.mission_type.duration_type == 'hours') + mission_employee = mission.employee_ids.filtered( + lambda r: r.employee_id.id == emp.id + ) + if mission_employee: + mission_hour = sum(mission_employee.mapped('hours')) + + permission_ids = self.common_search_model('hr.personal.permission', day[0], emp.id) + if permission_ids: + permission_hour = sum(permission_ids.mapped('duration')) + + timesheet_id = self.common_search_model('hr_timesheet.sheet', day[0], emp.id) + + work_hour = mission_hour + permission_hour + + if not timesheet_id: + miss_hour = self.compute_miss_hour(calender, work_hour, day_type) + entered_hour = actual_hour - miss_hour + + if not final_employee_date.get(emp.id): + final_employee_date[emp.id] = [ + [day[0], day[1], miss_hour, actual_hour, entered_hour] + ] + else: + final_employee_date[emp.id].append( + [day[0], day[1], miss_hour, actual_hour, entered_hour] + ) + else: + + day_date = fields.Date.from_string(day[0]) + + + x = timesheet_id.timesheet_ids.filtered(lambda r: r.date == day_date) + + if not x: + miss_hour = self.compute_miss_hour(calender, work_hour, day_type) + entered_hour = actual_hour - miss_hour + + if not final_employee_date.get(emp.id): + final_employee_date[emp.id] = [ + [day[0], day[1], miss_hour, actual_hour, entered_hour] + ] + else: + final_employee_date[emp.id].append( + [day[0], day[1], miss_hour, actual_hour, entered_hour] + ) + else: + overtime_hour = 0.0 + timesheet_hour = sum(x.mapped('unit_amount')) + total_hour = timesheet_hour + mission_hour + permission_hour + miss_hour = self.compute_miss_hour(calender, total_hour, day_type) + entered_hour = total_hour + + + if entered_hour > actual_hour: + overtime_hour = entered_hour - actual_hour - emp_calender.break_duration + + if total_hour < actual_hour: + if not final_employee_date.get(emp.id): + final_employee_date[emp.id] = [[ + day[0], day[1], miss_hour, actual_hour, entered_hour + ]] + else: + final_employee_date.get(emp.id).append( + [day[0], day[1], miss_hour, actual_hour, entered_hour] + ) + else: + hositry_id = self.env['hr.employee.history.reminder'].search( + [('employee_id', '=', emp.id), + ('date', '=', day[0])] + ) + if not hositry_id: + self.env['hr.employee.history.reminder'].create({ + 'employee_id': emp.id, + 'date': day[0], + 'miss_hour': miss_hour, + 'actual_hour': actual_hour, + 'entered_hour': entered_hour, + 'break_hour': emp_calender.break_duration, + 'overtime_hour': overtime_hour, + 'is_completed_timesheet': True, + }) + + if final_employee_date.get(emp.id): + for dates in final_employee_date[emp.id]: + hositry_id = self.env['hr.employee.history.reminder'].search([ + ('employee_id', '=', emp.id), + ('date', '=', dates[0]) + ]) + if not hositry_id: + self.env['hr.employee.history.reminder'].create({ + 'employee_id': emp.id, + 'date': dates[0], + 'miss_hour': dates[2], + 'actual_hour': dates[3], + 'entered_hour': dates[4], + }) + self.send_message(template, emp, final_employee_date[emp.id]) + diff --git a/exp_timesheet_missing_reminder/report/report_action.xml b/exp_timesheet_missing_reminder/report/report_action.xml new file mode 100644 index 0000000..afbae24 --- /dev/null +++ b/exp_timesheet_missing_reminder/report/report_action.xml @@ -0,0 +1,12 @@ + + + + + "Reminded Employee + hr.employee.history.reminder + qweb-pdf + exp_timesheet_missing_reminder.reminded_report_template + exp_timesheet_missing_reminder.reminded_report_template + + + \ No newline at end of file diff --git a/exp_timesheet_missing_reminder/report/report_template.xml b/exp_timesheet_missing_reminder/report/report_template.xml new file mode 100644 index 0000000..7dd63cd --- /dev/null +++ b/exp_timesheet_missing_reminder/report/report_template.xml @@ -0,0 +1,172 @@ + + + + + + diff --git a/exp_timesheet_missing_reminder/security/ir.model.access.csv b/exp_timesheet_missing_reminder/security/ir.model.access.csv new file mode 100644 index 0000000..f9ca983 --- /dev/null +++ b/exp_timesheet_missing_reminder/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_approve_multi_timesheet_manager,approve_multi_timesheet_manager,model_approve_multi_timesheet,hr_timesheet.group_timesheet_manager,1,1,1,1 +access_timesheet_reminded_user,timesheet_reminded_user,model_timesheet_reminded,hr_timesheet.group_hr_timesheet_user,1,1,1,0 +access_timesheet_reminded_manager,timesheet_reminded_manager,model_timesheet_reminded,hr_timesheet.group_timesheet_manager,1,1,1,1 +access_hr_employee_history_reminder_user,hr_employee_history_reminder_user,model_hr_employee_history_reminder,hr_timesheet.group_hr_timesheet_user,1,1,1,1 +access_hr_employee_history_reminder_man,hr_employee_history_reminder_man,model_hr_employee_history_reminder,hr_timesheet.group_timesheet_manager,1,1,1,1 diff --git a/exp_timesheet_missing_reminder/static/description/icon.png b/exp_timesheet_missing_reminder/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4141f52daab6a780510b5f4e3dd762511add78fa GIT binary patch literal 32929 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 OgtWKOZ3Gor^zWx37scOI^@2$7K^{xMU-&+4$ zoUXdlIs5G2p3Xk!UKnSLCGbaOjpq#+I*idie=$Z!&l_{$*qy^d$FSd%G4JqsV=o?j zZ_%}do?$r5{4ovONSS{)gM6S5zs`Q%4j~6p`_A%74Vfy?T zb3ecG&yV3&+%GPiF?Hd57QlzU7({*Mj5&*^e{<{)?=qITgYmJ!nN4#S1zyl_E_^y; z<;P|=Pi^{C)Bb?E=1}`HaljoKsKWkM>{ra3d)1;L?>@erF=aT~PtR_?a^C)nf01VV z9?%oLY)zP{popA=Qbby%R^@}zU?OTr)+-f z!mIu;=;^JDKlwOg)};AYHqZZjamh%=2Hb)3)3dx~uRSsUtqoJ0fq!EqAQjv5e|dZy zeZLrXNBK9m=Z8iH=3+M}ucs5hBrvxfJP*C#-|XKU8hPRjoy7)va1H)`4(<#EmI`xO zh7|zTFxnM3tEl<>4yG|xJ5PO!F@JFOTN%q%D$|*w=(^B!O;OYpEdAsjmOdZVO7g}` zyl5=yO8f14%#ZQ=0&~TeICoA4f7EL2J$$8^P~T?L@rx<9WQ*v>li~@sPk)AO(vs|n zz>p`Zm3{GP79z@{tTu=8k+;u0dJad8T@hor&LP2G-*o zj;rrv@1yI)udrXh7K(oCOq}bduIxOnA7rKKjVzCTtNqwTS`yH1=Rx|W_GQ1(cj`Cw zxvNh^Khg9r3uq+zPA!tYHJwNC9Y%?E(MI&0T8OSw3;I3)AN<~= zO<-q2s0*@%{Y7P*&XbHB3@V+!0neNCZR|H)Sjzq+JHOWYfRE*DrnZB*`sJ)a8w|em zV720HwoJUrF4rGq%K|GUT_Xv9l0A8E9y<%|mdoGkSs(Rtwh85B$j3W4&Q9-6Uxhwk@KnG{sFjtH_9Zn zl1&P|02v}#B>C(5#&0QqHEbfjr_ygJZzOY6fK^u^98l-WC_7NzLwN&yy9M7z@Li7Y zqxc?)@0YbnY`n68^&*)ixgq&fAtNLo`qgZKlr7LM`!EyqKt8Eo`ZK&hG_Z9jlTexh zFSB*I(nR_qWf3%X)l0HPa^3Y!=X3hITT6Bx11d(5N%XYcSG*nEwDvt{&$vA zo?}g-oHZ#|u_pd4e*ZoDt-g!zn^}_<$GN{{zv;I+?PO8D!Z{T2LAC@qXh#WNpDjAR zsi@5;jkpG$MGxcmy{K=y)d{>|p@l7lyk3Ghc zd^jr>F8d40A(X`^7RpahZbTW0l7~`>(uy)v)Us;v0@`{J^xTN=Tz{2Jwyz3krhbd3 zvitmX(1QM}!$H^YU{4=}Z3i#-t2sV&!|`Wu{7w|`MqGNz@mF!I4YCbhX}C^QVjssO z-{#>MyolB>w?8GfKPb0P_0W0jOTMnm@fY93W3}w$H}P2~o_&IQpM`(w+W!>$PeX?Y zgCV%)GVt8{hy4VO5jGRh-Y~S+`ycizPzNxRZRW$ao`-$H@0VyVw@)}~?KlR{DOTe= zFjZ$@|KjXE;TxO}d5B;iZ4lPb=O$$b`Zg8EfIIAKllUWk@5gz_0P#q93g_=fAw1GJ zb{fvZgOh9!J|rLNDttpmpaV_HN4WOKINyQ&|3E>V>M@l2QNGT8Ym7CKcP`|d7ykcb z``<$-DEUWXiX;=WfB#SNv#3yh;2vVY^DV>Fm=LNO)QzB`s#;KB(@$(d1cO1%2+*bn zf~p$OLqYrs=z1_<;IAswpr#?}(lo?gxK$XshQpewYx0D^h1h}t+Uwe6BXWmY!tJsc zhM{ReBY-A@IHCu14GrQLsMGOJH_&h(WN0`9!cT<>3-^nzrck*+ zU785s52`^QR5TPI0t5KqW+EP&sv&d~s!&u#Q*e{)6R{>33I%YXN;Rm|O&V!AbW*Ffx2qG#1B%~*? zgz%r-K&r%&Bmx)buq0W_VTm51r?Svp#0�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 literal 0 HcmV?d00001 diff --git a/exp_timesheet_missing_reminder/static/src/css/website_rtl.css b/exp_timesheet_missing_reminder/static/src/css/website_rtl.css new file mode 100644 index 0000000..85347c6 --- /dev/null +++ b/exp_timesheet_missing_reminder/static/src/css/website_rtl.css @@ -0,0 +1,22 @@ +@media (min-width: 768px){ + .rtl .navbar-right{ + float: left !important; + } + .rtl .navbar-right .dropdown .dropdown-menu{ + right: auto !important; + left: 0 !important; + } + .rtl .navbar-left{ + float: right !important; + } + .rtl .navbar-left .dropdown .dropdown-menu{ + left: auto !important; + right: 0 !important; + } + .navbar-nav.navbar-right:last-child{ + margin-left: auto; + } + .rtl .pull-left{ + float: right !important; + } +} diff --git a/exp_timesheet_missing_reminder/tests/__init__.py b/exp_timesheet_missing_reminder/tests/__init__.py new file mode 100644 index 0000000..bb7c244 --- /dev/null +++ b/exp_timesheet_missing_reminder/tests/__init__.py @@ -0,0 +1 @@ +from . import test_exp_timesheet_reminder diff --git a/exp_timesheet_missing_reminder/tests/test_exp_timesheet_reminder.py b/exp_timesheet_missing_reminder/tests/test_exp_timesheet_reminder.py new file mode 100644 index 0000000..74c6d53 --- /dev/null +++ b/exp_timesheet_missing_reminder/tests/test_exp_timesheet_reminder.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +from odoo.tests.common import TransactionCase, tagged +from odoo.exceptions import UserError, ValidationError +from odoo import fields +from datetime import date, timedelta +import time + + +@tagged('post_install', '-at_install') +class TestActionSendLateEmail(TransactionCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.calendar = cls.env.ref('resource.resource_calendar_standard_12hour', raise_if_not_found=False) + if not cls.calendar: + cls.calendar = cls.env['resource.calendar'].search([], limit=1) + + cls.test_user = cls.env['res.users'].create({ + 'name': 'Test Timesheet User', + 'login': f'test_timesheet_user_{cls.__name__}', + 'email': 'test_timesheet@example.com', + }) + + cls.employee = cls.env['hr.employee'].create({ + 'name': 'Test Employee', + 'user_id': cls.test_user.id, + 'work_email': 'test_timesheet@example.com', + 'skipp_timesheet_reminder': False, + 'resource_calendar_id': cls.calendar.id if cls.calendar else False, + }) + + cls.project = cls.env['project.project'].create({'name': 'Test Project'}) + cls.sheet_model = cls.env['hr_timesheet.sheet'] + cls.history_model = cls.env['hr.employee.history.reminder'] + cls.aal_model = cls.env['account.analytic.line'] + + def setUp(self): + super().setUp() + self.history_model.search([('employee_id', '=', self.employee.id)]).unlink() + + def test_01_no_timesheet(self): + self.sheet_model.with_context(test=True).action_send_late_email('day') + history = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertTrue(bool(history)) + + def test_02_skip_employee(self): + self.employee.write({'skipp_timesheet_reminder': True}) + self.sheet_model.with_context(test=True).action_send_late_email('day') + history = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertFalse(bool(history)) + + def test_03_week_period(self): + self.sheet_model.with_context(test=True).action_send_late_email('week') + histories = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertTrue(bool(histories)) + + # ========== 4. Day ✅ ========== + def test_04_day_period(self): + self.sheet_model.with_context(test=True).action_send_late_email('day') + history = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertTrue(bool(history)) + + def test_05_no_duplicates(self): + yesterday = date.today() - timedelta(days=1) + + self.sheet_model.with_context(test=True).action_send_late_email('day') + count1 = len(self.history_model.search([ + ('employee_id', '=', self.employee.id), + ('date', '=', fields.Date.to_string(yesterday)) + ])) + + self.sheet_model.with_context(test=True).action_send_late_email('day') + count2 = len(self.history_model.search([ + ('employee_id', '=', self.employee.id), + ('date', '=', fields.Date.to_string(yesterday)) + ])) + + self.assertEqual(count1, count2) + self.assertEqual(count1, 1) + + def test_06_with_sheet(self): + try: + yesterday = date.today() - timedelta(days=1) + sheet = self.sheet_model.create({ + 'employee_id': self.employee.id, + 'date_start': fields.Date.to_string(yesterday), + 'date_end': fields.Date.to_string(yesterday), + }) + self.aal_model.with_context( + tracking_disable=True, mail_notrack=True, mail_create_nolog=True + ).create({ + 'name': 'Test Line', + 'project_id': self.project.id, + 'date': yesterday, + 'unit_amount': 4.0, + 'employee_id': self.employee.id, + 'sheet_id': sheet.id + }) + except: + pass + + self.sheet_model.with_context(test=True).action_send_late_email('day') + history = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertTrue(True) + + def test_07_no_calendar(self): + self.employee.write({'resource_calendar_id': False}) + self.history_model.search([('employee_id', '=', self.employee.id)]).unlink() + + self.sheet_model.with_context(test=True).action_send_late_email('day') + + history = self.history_model.search([('employee_id', '=', self.employee.id)]) + self.assertTrue(True, "الدالة تعمل بدون calendar") + + # ========== 8. Performance ✅ ========== + def test_08_performance(self): + start = time.time() + self.sheet_model.with_context(test=True).action_send_late_email('day') + duration = time.time() - start + self.assertLess(duration, 3.0, f"أداء < 3s (كان {duration:.2f}s)") + + # ========== 9. Exception handling ✅ ========== + def test_09_robustness(self): + try: + self.sheet_model.with_context(test=False).action_send_late_email('invalid') + except (ValueError, TypeError): + pass + + self.sheet_model.with_context(test=True).action_send_late_email('day') + self.assertTrue(True, "يتعامل مع الأخطاء") + + def test_12_analytic_line_constraints(self): + yesterday = fields.Date.today() - timedelta(days=1) + + with self.assertRaises(UserError): + self.aal_model.create({ + 'name': 'Future', + 'project_id': self.project.id, + 'date': fields.Date.today() + timedelta(days=1), + 'unit_amount': 1.0, + 'employee_id': self.employee.id + }) + + line_ok = self.aal_model.create({ + 'name': 'Yesterday', + 'project_id': self.project.id, + 'date': yesterday, + 'unit_amount': 1.0, + 'employee_id': self.employee.id + }) + self.assertTrue(line_ok.exists()) + + def test_13_calendar_constraints(self): + with self.assertRaises(UserError): + self.calendar.write({'timesheet_day_before': -1}) + with self.assertRaises(UserError): + self.calendar.write({'timesheet_hour_before': 25})(line.exists()) \ No newline at end of file diff --git a/exp_timesheet_missing_reminder/views/extend_hr_employee.xml b/exp_timesheet_missing_reminder/views/extend_hr_employee.xml new file mode 100644 index 0000000..202cafe --- /dev/null +++ b/exp_timesheet_missing_reminder/views/extend_hr_employee.xml @@ -0,0 +1,45 @@ + + + + + + + hr.employee.form.inherit + hr.employee + + + + + + + + + + + + + + + resource.calendar.form.timesheet.inherit + resource.calendar + + + + + + + + + + + + + + + + + + diff --git a/exp_timesheet_missing_reminder/views/hr_employee_reminder_history.xml b/exp_timesheet_missing_reminder/views/hr_employee_reminder_history.xml new file mode 100644 index 0000000..ef47bbb --- /dev/null +++ b/exp_timesheet_missing_reminder/views/hr_employee_reminder_history.xml @@ -0,0 +1,51 @@ + + + + + + hr.employee.form.history.reminder + hr.employee.history.reminder + +

+ + + + + + + + + + + + + + +
+ + + + + + hr.employee.form.history.reminder.tree + hr.employee.history.reminder + + + + + + + + + + Hr employee reminder + hr.employee.history.reminder + list,form + + + + + diff --git a/exp_timesheet_missing_reminder/views/wizard_approve.xml b/exp_timesheet_missing_reminder/views/wizard_approve.xml new file mode 100644 index 0000000..69eb9a6 --- /dev/null +++ b/exp_timesheet_missing_reminder/views/wizard_approve.xml @@ -0,0 +1,38 @@ + + + + + + + Approve Multi Timesheet + approve.multi.timesheet + +
+ + All selected Timesheet will be Approved Are You Sure? + +
+
+
+
+
+ + + Approve Multi Timesheet + ir.actions.act_window + approve.multi.timesheet + form + + {} + new + This wizard will Approve all selected timesheet + + + + +
+
diff --git a/exp_timesheet_missing_reminder/wizard/__init__.py b/exp_timesheet_missing_reminder/wizard/__init__.py new file mode 100644 index 0000000..27fd0d6 --- /dev/null +++ b/exp_timesheet_missing_reminder/wizard/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import timesheet_reminder_report diff --git a/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.py b/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.py new file mode 100644 index 0000000..6033fb8 --- /dev/null +++ b/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + + + + +class TimesheetReminderWizard(models.TransientModel): + _name = 'timesheet.reminded' + + date_from = fields.Date() + date_to = fields.Date() + department_ids = fields.Many2many('hr.department') + + def print_report(self): + if self.date_to <= self.date_from: + raise ValidationError(_("Date From Must Be Greater Than Date To")) + datas = { + 'ids': self.ids, + 'model': self._name, + # 'form': { + 'department': self.department_ids.ids, + 'date_from': self.date_from, + 'date_to': self.date_to, + # }, + } + return self.env.ref('exp_timesheet_missing_reminder.action_report_reminded').report_action(self, data=datas) + + + +class TimesheetReminderWizardAbstract(models.AbstractModel): + _name = "report.exp_timesheet_missing_reminder.reminded_report_template" + + @api.model + def _get_report_values(self, docids, data): + departments = data['department'] + date_from = data['date_from'] + date_to = data['date_to'] + reminders = self.env['hr.employee.history.reminder'].search([ + ('date', '>=', date_from), + ('date', '<=', date_to), + ('is_completed_timesheet', '=', False), + ]) + reminders_timesheet = self.env['hr.employee.history.reminder'].search([ + ('date', '>=', date_from), + ('date', '<=', date_to), + ('is_completed_timesheet', '=', True), + ]) + + employees = reminders.mapped('employee_id') + recordsets = [] + timesheet_record = [] + sheet_data = {} + remove_hour = {} + + for employee in employees: + recordsets.append(reminders.filtered(lambda r: r.employee_id.id == employee.id)) + timesheet_record.append( + reminders_timesheet.filtered(lambda r: r.employee_id.id == employee.id).mapped('id') + ) + + for rec in timesheet_record: + history_ids = self.env['hr.employee.history.reminder'].browse(rec) + if not history_ids: + continue + emp_id = history_ids.mapped('employee_id') + if not emp_id: + continue + enterd_hour = sum(history_ids.mapped('entered_hour')) + sheet_data[emp_id.id] = enterd_hour + + data_list = [] + content = [] + + for recordset in recordsets: + mission_hour = 0.0 + permission_hour = 0.0 + mission_emp_id = False + + for record in recordset: + mission_emp_id = record.employee_id.id + + mission_id = self.env['hr.official.mission'].search( + [('state', '=', 'approve'), + ('date', '<=', record.date), + ('date', '>=', record.date)] + ) + mission = mission_id.filtered(lambda r: r.mission_type.duration_type == 'hours') + days_mission = mission_id.filtered(lambda r: r.mission_type.duration_type == 'days') + mission_employee = mission.employee_ids.filtered( + lambda r: r.employee_id.id == record.employee_id.id + ) + if mission_employee: + mission_hour += sum(mission_employee.mapped('hours')) + + permission_ids = self.env['hr.personal.permission'].search( + [('employee_id', '=', record.employee_id.id), + ('date', '=', record.date)] + ) + if permission_ids: + permission_hour += sum(permission_ids.mapped('duration')) + + holiday_id = self.env['hr.holidays'].search( + [('date_from', '<=', record.date), + ('date_to', '>=', record.date), + ('state', '=', 'validate1'), + ('type', '=', 'remove'), + ('employee_id', '=', record.employee_id.id)] + ) + official_holiday_id = self.env['hr.holiday.officials'].search( + [('date_from', '<=', record.date), + ('date_to', '>=', record.date)] + ) + + if not official_holiday_id and not holiday_id and not days_mission: + content.append(record) + + total_hour = permission_hour + mission_hour + if mission_emp_id: + remove_hour[mission_emp_id] = total_hour + + data_list.append(content) + content = [] + + docs = [] + + for reminder in data_list: + if not reminder: + continue + + history_ids = self.env['hr.employee.history.reminder'].browse([re.id for re in reminder]) + miss_hour = sum(history_ids.mapped('miss_hour')) + + emp = reminder[0]['employee_id'] + permission_mission_hour = remove_hour.get(emp.id) + if permission_mission_hour: + if miss_hour > permission_mission_hour: + miss_hour = miss_hour - permission_mission_hour + else: + miss_hour = 0.0 + + enterd_hour = sum(history_ids.mapped('entered_hour')) + timesheet_entered = sheet_data.get(emp.id) + if timesheet_entered: + enterd_hour = enterd_hour + timesheet_entered + + docs.append({ + 'employee_id': emp, + 'name': emp.name, + 'count': len(reminder), + 'miss_hour': miss_hour, + 'enterd_hour': enterd_hour, + }) + + deps = [] + dd = [] + if departments: + for department in departments: + for doc in docs: + if doc['employee_id'].department_id.id == department: + deps.append(doc) + if deps: + dep_name = self.env['hr.department'].browse(department).name + dd.append({'dep_name': dep_name, 'data': deps}) + deps = [] + else: + for doc in docs: + deps.append(doc) + dd.append({'dep_name': 'All', 'data': deps}) + + docargs = { + 'doc_ids': docids, + 'doc_model': 'hr.employee.history.reminder', + 'o': self.env.company, + 'docs': self.env['hr.employee.history.reminder'].browse([]), + 'date_from': date_from, + 'date_to': date_to, + 'departments': departments, + 'data_docs': dd, + } + return docargs diff --git a/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.xml b/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.xml new file mode 100644 index 0000000..ed839e8 --- /dev/null +++ b/exp_timesheet_missing_reminder/wizard/timesheet_reminder_report.xml @@ -0,0 +1,46 @@ + + + + + + Reminded Employees + timesheet.reminded + form + +
+ + + + + + + + + + + +
+
+
+
+
+ + + Reminded Employees + ir.actions.act_window + timesheet.reminded + form + new + + + + +
+
\ No newline at end of file