diff --git a/setup/shift_attendance/odoo/addons/shift_attendance b/setup/shift_attendance/odoo/addons/shift_attendance new file mode 120000 index 000000000..815c9af7f --- /dev/null +++ b/setup/shift_attendance/odoo/addons/shift_attendance @@ -0,0 +1 @@ +../../../../shift_attendance \ No newline at end of file diff --git a/setup/shift_attendance/setup.py b/setup/shift_attendance/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/shift_attendance/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shift_attendance/README.rst b/shift_attendance/README.rst new file mode 100644 index 000000000..27a8fed55 --- /dev/null +++ b/shift_attendance/README.rst @@ -0,0 +1,73 @@ +====================== +Shift Attendance Sheet +====================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:41330284c2edb9171c31179edc34bf2bc1f3510cfd5f226cec22583b0f18a591 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-beescoop%2FObeesdoo-lightgray.png?logo=github + :target: https://github.com/beescoop/Obeesdoo/tree/16.0/shift_attendance + :alt: beescoop/Obeesdoo + +|badge1| |badge2| |badge3| + +Volunteer Timetable Management + +**Table of contents** + +.. contents:: + :local: + +Changelog +========= + +12.0.1.2.0 (2022-12-16) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Repair UI bug where there are two left-hand entries for changing shifts settings + in the settings interface. (`#488 `_) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Elouan Le Bars +* Coop IT Easy SC + +Contributors +~~~~~~~~~~~~ + +* BEES coop - Cellule IT +* Coop IT Easy SC + +Maintainers +~~~~~~~~~~~ + +This module is part of the `beescoop/Obeesdoo `_ project on GitHub. + +You are welcome to contribute. diff --git a/shift_attendance/__init__.py b/shift_attendance/__init__.py new file mode 100644 index 000000000..9b4296142 --- /dev/null +++ b/shift_attendance/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/shift_attendance/__manifest__.py b/shift_attendance/__manifest__.py new file mode 100644 index 000000000..34a67d9e6 --- /dev/null +++ b/shift_attendance/__manifest__.py @@ -0,0 +1,37 @@ +# This module depends on `shift_worker_status`. +# If someone needs this module but has another worker_status rules +# this module can be splitted into a generic part, and a specific part +# that implement the worker_status rules. +{ + "name": "Shift Attendance Sheet", + "summary": """ + Volunteer Timetable Management""", + "author": "Elouan Le Bars, Coop IT Easy SC, Odoo Community Association (OCA)", + "website": "https://github.com/beescoop/Obeesdoo", + "category": "Cooperative management", + "version": "16.0.1.0.0", + "depends": [ + "eater", + "member_card", + "shift", + "shift_worker_status", + "mail", + "barcodes", + ], + "data": [ + "data/system_parameter.xml", + "data/cron.xml", + "data/mail_template.xml", + "security/group.xml", + "security/ir.model.access.csv", + "views/res_config_settings_view.xml", + "wizard/validate_attendance_sheet.xml", + "wizard/generate_missing_attendance_sheets.xml", + "views/attendance_sheet.xml", + ], + "demo": [ + "demo/users.xml", + "demo/workers.xml", + ], + "license": "AGPL-3", +} diff --git a/shift_attendance/data/cron.xml b/shift_attendance/data/cron.xml new file mode 100644 index 000000000..e20c8140b --- /dev/null +++ b/shift_attendance/data/cron.xml @@ -0,0 +1,31 @@ + + + + Generate Attendance Sheets + + code + model._generate_attendance_sheet() + + 4 + minutes + -1 + + + + + + Check for non-validated sheets + + code + model._cron_non_validated_sheets() + 1 + days + -1 + + + + + diff --git a/shift_attendance/data/mail_template.xml b/shift_attendance/data/mail_template.xml new file mode 100644 index 000000000..da3d88089 --- /dev/null +++ b/shift_attendance/data/mail_template.xml @@ -0,0 +1,160 @@ + + + + + Shift Non-attendance + Non-attendance to your last shift + {{ object.replaced_id.id or object.worker_id.id }} + + + {{ object.worker_id.lang }} + + + +

Hello ,

+ +

+ You have been recorded as non-attended during your last shift + (), + and you were supposed to replace + . +

+
+ + + +

Hello ,

+ +

+ You have been recorded as non-attended during your last shift + (). +

+
+ + + +

+ Super-cooperator assigned you 0 compensation, so you + won't have any additionnal shift to do before your + next regular shift. +

+ +

+ Super-cooperator assigned you 1 compensation, so you + have to attend one additionnal shift before your + next regular shift. +

+ +

+ Super-cooperator assigned you 2 compensations, so + you have to attend two additionnal shifts before + your next regular shift. +

+ +

+ You were supposed to replace . + You have to do + + shifts before your next regular shift. +

+ +

+ You have to do + + shifts before your next regular shift. +

+
+ + +

+ Your shift counter is at + . +

+

+ It should be superior or equal to 1 before the + . +

+
+ +

+ Your current status is + "". +

+ +

+ Your current status is + "". +

+ +

+ If you have any question regarding this non-attendance, + just answer this e-mail. +

+ +

+ Cooperatively yours,
+ The Members' office volunteers +

+ +

+
+
+
+
+ + +
+
+ + Phone: 
+
+ + + Web: 
+
+ + + +

+ +
+
+ + + Non-validated sheet + [{{object.day}}] Non-validated sheet {{object.time_slot}} + + + + +

+

The attendance sheet for is not validated.

+

Please, do it as soon as possible so as to update workers' status.

+ +
+
+
diff --git a/shift_attendance/data/system_parameter.xml b/shift_attendance/data/system_parameter.xml new file mode 100644 index 000000000..486f7e3a9 --- /dev/null +++ b/shift_attendance/data/system_parameter.xml @@ -0,0 +1,11 @@ + + + + shift_attendance.card_support + False + + + shift_attendance.attendance_sheet_generation_interval + 15 + + diff --git a/shift_attendance/demo/users.xml b/shift_attendance/demo/users.xml new file mode 100644 index 000000000..bd0dde6c3 --- /dev/null +++ b/shift_attendance/demo/users.xml @@ -0,0 +1,42 @@ + + + + + + + Generic Account + Demo + generic@demo.net + + + + Permanent Member + Demo + + permanent@demo.net + Ixelles + 1050 + + + + + + generic + demo + + + + + + permanent + demo + + + + diff --git a/shift_attendance/demo/workers.xml b/shift_attendance/demo/workers.xml new file mode 100644 index 000000000..36cb32b0a --- /dev/null +++ b/shift_attendance/demo/workers.xml @@ -0,0 +1,55 @@ + + + + + + 521457731741 + Demo data + + + + + + + 529919251493 + Demo data + + + + + + + 521457731742 + Demo data + + + + + + + 521457731743 + Demo data + + + + + + + 521457731744 + Demo data + + + + + + + 521457731745 + Demo data + + + + + diff --git a/shift_attendance/i18n/fr_BE.po b/shift_attendance/i18n/fr_BE.po new file mode 100644 index 000000000..c31c1b59c --- /dev/null +++ b/shift_attendance/i18n/fr_BE.po @@ -0,0 +1,1185 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * shift_attendance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-17 12:45+0000\n" +"PO-Revision-Date: 2020-08-17 12:45+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_attendance +msgid "" +"\n" +"
\n" +"\n" +" % if object.replaced_id:\n" +"

Hello ${object.replaced_id.name},\n" +"\n" +"

You have been recorded as non-attended during your " +"last shift (${format_tz(object.start_time,object.replaced_id.tz or 'Europe/" +"Brussels','%d.%m.%Y - %H:%M')}),\n" +" and you were supposed to replace ${object.worker_id." +"name}.\n" +" % endif\n" +"\n" +" % if not object.replaced_id:\n" +"

Hello ${object.worker_id.name},

\n" +"\n" +"

You have been recorded as non-attended during your last " +"shift (${format_tz(object.start_time,object.worker_id.tz or 'Europe/" +"Brussels','%d.%m.%Y - %H:%M')}).\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'regular':\n" +" % if object.state == 'absent_0':\n" +"

Super-cooperator assigned you 0 " +"compensation, so you won't have any additionnal shift to do before your next " +"regular shift.\n" +" % endif\n" +" % if object.state == 'absent_1':\n" +"

Super-cooperator assigned you 1 " +"compensation, so you have to attend one additionnal shift before your next " +"regular shift.\n" +" % endif\n" +" % if object.state == 'absent_2':\n" +"

Super-cooperator assigned you 2 " +"compensations, so you have to attend two additionnal shifts before your next " +"regular shift.\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" You were supposed to replace ${object.worker_id." +"name}.\n" +" You have to do ${(object.replaced_id." +"cooperative_status_ids.sr + object.replaced_id.cooperative_status_ids.sc) * " +"-1 } shifts before your next regular shift.
\n" +" % else:\n" +" You have to do ${(object.worker_id." +"cooperative_status_ids.sr + object.worker_id.cooperative_status_ids.sc) * " +"-1 } shifts before your next regular shift.
\n" +" % endif\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'irregular':\n" +" Your shift counter is at ${object.worker_id." +"cooperative_status_ids.sr}.\n" +"\n" +" % if object.worker_id.cooperative_status_ids." +"future_alert_date:\n" +" It should be superior or equal to 1 before the\n" +" ${object.worker_id.cooperative_status_ids." +"future_alert_date}.\n" +" % endif\n" +"
\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" Your current status is \"${object.replaced_id." +"cooperative_status_ids.get_status_value()}\".\n" +" % else:\n" +"

Your current status is \"${object.worker_id." +"cooperative_status_ids.get_status_value()}\".\n" +" % endif\n" +"\n" +"
If you have any question regarding this non-" +"attendance, just answer this e-mail.\n" +"

\n" +"
\n" +"

Cooperatively yours,
\n" +" The Members' office volunteers

\n" +"

${object.worker_id.company_id.name}.

\n" +"\n" +" % if object.worker_id.company_id.street:\n" +" ${object.worker_id.company_id.street}\n" +" % endif\n" +" % if object.worker_id.company_id.street2:\n" +" ${object.worker_id.company_id.street2}
\n" +" % endif\n" +" % if object.worker_id.company_id.city or object.worker_id." +"company_id.zip:\n" +" ${object.worker_id.company_id.zip} ${object.worker_id." +"company_id.city}
\n" +" % endif\n" +" % if object.worker_id.company_id.country_id:\n" +" ${object.worker_id.company_id.state_id and ('%s, ' % " +"object.worker_id.company_id.state_id.name) or ''} ${object.worker_id." +"company_id.country_id.name or ''}
\n" +" % endif\n" +" % if object.worker_id.company_id.phone:\n" +" Phone:  ${object.worker_id.company_id.phone}\n" +" % endif\n" +"\n" +" % if object.worker_id.company_id.website:\n" +" \n" +" %endif\n" +" % if object.worker_id.company_id.logo_url:\n" +"
\n" +" \n" +"
\n" +" %endif\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:45 +#, python-format +msgid "" +"\n" +"%s attended its shift as a normal one but was not expected. Something may be " +"wrong in his/her personal informations.\n" +" " +msgstr "" +"%s a effectué son shift comme un shift normal mais n'était pas attendu(e). " +"Veuillez vérifier son inscription à ce créneau." + +#. module: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_validated_sheet +msgid "" +"\n" +"
\n" +"\n" +"

${object.day}\n" +"

The attendance sheet for ${object.time_slot} is not " +"validated.\n" +"

Please, do it as soon as possible so as to update workers' " +"status.\n" +"

\n" +"\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:532 +#, python-format +msgid "%s (added)" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:396 +#, python-format +msgid "%s is registered as replaced." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:383 +#, python-format +msgid "%s's working mode is %s and should be regular or irregular. " +msgstr "Le régime de %s est %s et devrait être régulier ou volant." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +#, fuzzy +msgid "" +"\n" +" Attendance Sheets Generation Interval\n" +" " +msgstr "" +"\n" +" Intervalle de temps pour la " +"génération des feuilles de présence\n" +" " + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +#, fuzzy +msgid "" +"\n" +" Default Shift Attendance Status\n" +" " +msgstr "" +"\n" +" Type de tâche par défaut\n" +" " + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +#, fuzzy +msgid "" +"\n" +" Default Task Type\n" +" " +msgstr "" +"\n" +" Type de tâche par défaut\n" +" " + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:345 +#, python-format +msgid "A validated attendance sheet can't be modified" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 0 Compensation" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 1 Compensation" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 2 Compensations" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction +msgid "Action Needed" +msgstr "A besoin d'une action" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__active +msgid "Active" +msgstr "Actif" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__active_sheet +msgid "Active Sheet" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_added +msgid "Added Shift" +msgstr "Shift ajouté" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__added_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Added Shifts" +msgstr "Shifts ajoutés" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_list +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_list +msgid "All sheets" +msgstr "Toutes les feuilles" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (read)" +msgstr "Annotées (lues)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (unread)" +msgstr "Annotées (non lues)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Archived" +msgstr "Archivé" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_attachment_count +msgid "Attachment Count" +msgstr "Nombre de pièces jointes" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__attendance_sheet_id +msgid "Attendance Sheet" +msgstr "Feuille de présence" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet +msgid "Attendance Sheet Generic Access" +msgstr "Feuilles de présence" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet_validation +msgid "Attendance Sheet Validation" +msgstr "Feuille de présence - Validation" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_top +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Attendance Sheets" +msgstr "Feuilles de présence" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet +msgid "Attendance sheet" +msgstr "Feuille de présence" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:563 +#, python-format +msgid "Attendance sheet can only be validated once the shifts have started. " +msgstr "" +"Vous devez attendre que le créneau ait débuté pour valider la feuille de " +"présence." + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__barcode +msgid "Barcode" +msgstr "Code Barre" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Barcode Scanned" +msgstr "Code barre scanné" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "" +"Beware : a validated sheet cannot be edited " +"anymore and you won't be able to add any " +"latecomers. The counters of those who didn't " +"attend will be updated and they will get warning " +"emails." +msgstr "" +"Attention : une feuille de présence validée ne peut plus être modifiée et tu " +"ne pourras pas ajouter de retardataires. Le compteur des travailleurs " +"absents sera mis à jour et ils recevront un e-mail d'avertissement." + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:375 +#, python-format +msgid "" +"Beware, you are recorded as resigning. Please contact member's office if " +"this is incorrect. Thank you. " +msgstr "" +"Attention, ton compte est \"en démission\". Contacte le Bureau des Membres " +"si c'est incorrect. Merci" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:365 +#, python-format +msgid "" +"Beware, your account is frozen because your shift counter is at %s. Please " +"contact Members Office to unfreeze it. If you want to attend this shift, " +"your supercoop can write your name in the notes field during validation." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Cancel" +msgstr "Annuler" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__card_support +msgid "Card validation" +msgstr "Validation par carte" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_check_non_validated_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_check_non_validated_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_check_non_validated_sheet +msgid "Check for non-validated sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_validate +msgid "" +"Check the user name and validate sheet.\n" +" Useless for users in group_shift_attendance" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__feedback +msgid "Comments about the shift" +msgstr "Commentaires à propos du shift" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:602 +#, python-format +msgid "Compensation number is missing for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Compensation shift ?" +msgstr "Shift de compensation ?" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__week +msgid "Computed from planning name" +msgstr "Calculé à partir du nom du planning" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_shift +msgid "Copy of an actual shift into an attendance sheet" +msgstr "Copie d'un shift réel dans une feuille de présence" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_daily +#: model:ir.ui.menu,name:shift_attendance.menu_sheet +msgid "Daily attendance sheets" +msgstr "Feuilles de présence du jour" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Day" +msgstr "Jour" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day_abbrevation +msgid "Day Abbrevation" +msgstr "Abbrévation du jour" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +#, fuzzy +msgid "Default Shift State" +msgstr "État du shift" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__pre_filled_task_type_id +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Default Task Type" +msgstr "Type de tâche par défaut" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +#, fuzzy +msgid "Default state set for shifts on attendance sheets" +msgstr "" +"Type de shift par défaut pour le remplissage automatique des feuilles de " +"présence" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__pre_filled_task_type_id +msgid "Default task type for attendance sheet pre-filling" +msgstr "" +"Type de shift par défaut pour le remplissage automatique des feuilles de " +"présence" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__end_time +msgid "End Time" +msgstr "Date et horaire de fin" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_end +msgid "End date" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Enough workers" +msgstr " Assez de travailleurs" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_expected +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_expected_view_form +msgid "Expected Shift" +msgstr "Shift attendu" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__expected_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Expected Shifts" +msgstr "Shifts attendus" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Feedback" +msgstr "Discussion" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Feedback on number of workers" +msgstr "Votre ressenti sur le nombre de travailleurs" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_follower_ids +msgid "Followers" +msgstr "Abonnés" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_channel_ids +msgid "Followers (Channels)" +msgstr "Abonnés (Canaux)" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_partner_ids +msgid "Followers (Partners)" +msgstr "Abonnés (Partenaires)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "For attendance sheets automatic pre-filling." +msgstr "Pour le remplissage automatique des feuilles de présence." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate" +msgstr "Générer" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_generate_attendance_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_generate_attendance_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_generate_attendance_sheet +msgid "Generate Attendance Sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_missing_attendance_sheets +msgid "Generate Missing Sheets" +msgstr "Générer les feuilles de présence manquantes" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Generate attendance sheets before shifts start." +msgstr "Générer les feuilles de présences avant le début du shift" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate missing attendance sheets in a given time interval" +msgstr "" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_missing_attendance_sheets +msgid "Generate missing past attendance sheets" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:46 +#, python-format +msgid "Generated Missing Sheets" +msgstr "Générer les feuilles manquantes" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Group By" +msgstr "Regrouper par" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__has_missing_worker +msgid "Has missing worker ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__is_read +msgid "Has notes been read by an administrator ?" +msgstr "La note a-t-elle été lue par un administrateur ?" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "I was not there during the shift" +msgstr "Je n'étais pas là durant le shift" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__id +msgid "ID" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread +msgid "If checked new messages require your attention." +msgstr "Si coché, de nouveaux messages demandent votre attention." + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction +msgid "If checked, new messages require your attention." +msgstr "si elle est cochée, de nouveaux messages requièrent votre attention." + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "Si actif, certains messages ont une erreur de livraison." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +#, fuzzy +msgid "" +"If not checked, user credentials are\n" +" asked." +msgstr "Si non coché, le login/mot de passe de l'utilisateur sont requis." + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__max_worker_no +msgid "Indicative maximum number of workers." +msgstr "Nombre de travailleurs maximal indicatif." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Interval (minutes)" +msgstr "Intervalle (minutes)" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_is_follower +msgid "Is Follower" +msgstr "Est un abonné" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_annotated +msgid "Is annotated" +msgstr "Est annotée" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Is any regular worker doing its regular shift as an added one ?" +msgstr "" +"Est-ce que le travailleur régulier réalise son shift habituel sans être " +"attendu ?" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_uid +msgid "Last Updated by" +msgstr "Mis à jour par" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_date +msgid "Last Updated on" +msgstr "Mis à jour le" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__login +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Login" +msgstr "Identifiant" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_main_attachment_id +msgid "Main Attachment" +msgstr "Pièce jointe principale" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_read +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Mark as read" +msgstr "Marquer comme lu" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__max_worker_no +msgid "Maximum number of workers" +msgstr "Nombre de travailleurs maximal" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error +msgid "Message Delivery error" +msgstr "Erreur d'envoi du message" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_ids +msgid "Messages" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:356 +#, python-format +msgid "" +"Multiple workers are corresponding this barcode. \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_name +msgid "Name" +msgstr "Nom" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:228 +#: sql_constraint:shift.sheet:0 +#, python-format +msgid "Non-annotated sheets can't be marked as read." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_attendance +msgid "Non-attendance to your last shift." +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_non_validated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_non_validated +msgid "Non-validated sheets" +msgstr "Non-validées" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Not Validated" +msgstr "Non validée" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Not enough workers" +msgstr "Pas assez de travailleurs" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__notes +msgid "Notes" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__notes +msgid "Notes about the attendance for the Members Office" +msgstr "Information importante à transmettre au bureau des membres" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of Actions" +msgstr "Nombre d'Actions" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of error" +msgstr "Nombre d'erreurs" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "Nombre de messages demandant une action" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "Nombre de messages avec des erreurs d'envoi" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Number of unread messages" +msgstr "Nombre de messages non lus" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__attended_worker_no +msgid "Number of workers present" +msgstr "Nombre de travailleurs présents" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Only for regular workers" +msgstr "Seulement pour les travailleurs réguliers" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:58 +#, python-format +msgid "Only past attendance sheets can be generated" +msgstr "Seuls les feuilles de présence du passé peuvent être générées." + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:119 +#, python-format +msgid "" +"Only super-cooperators and administrators can validate attendance sheets. " +msgstr "" +"Seuls les supercoopérateurs et les administrateurs peuvent valider les " +"feuilles de présence." + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__password +msgid "Password" +msgstr "Mot de passe" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:108 +#, python-format +msgid "Please enter your login." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:612 +#, python-format +msgid "Please give your feedback about the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:97 +#, python-format +msgid "Please give your feedback on the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:103 +#, python-format +msgid "Please set a correct barcode." +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Present" +msgstr "Présent" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker" +msgstr "Travailleur remplaçant" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker (must be regular)" +msgstr "Travailleur remplaçant (doit être régulier)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Save" +msgstr "Sauvegarder" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Scan cards for validation" +msgstr "Scanner la carte pour valider" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__card_support +msgid "Scan cooperators cards instead of login for sheets validation" +msgstr "" +"Scanner les cartes de membres à la place du login pour la validation des " +"feuilles de présence." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Scan your card" +msgstr "Scannez votre carte" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_shift_settings +msgid "Settings" +msgstr "Configuration" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_shift_settings +msgid "Shift Settings" +msgstr "Configuration des shifts" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__state +msgid "Shift State" +msgstr "État du shift" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:598 +#, python-format +msgid "Shift State is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:575 +#, python-format +msgid "Shift State is missing or wrong for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__start_time +msgid "Start Time" +msgstr "Date et horaire de début" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_start +msgid "Start date" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__state +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "State" +msgstr "État" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__super_coop_id +msgid "Super Cooperative" +msgstr "Supercoopérateur" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_id +msgid "Task" +msgstr "Tâche" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_type_id +msgid "Task Type" +msgstr "Type de tâche" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:580 +#, python-format +msgid "Task Type is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:463 +#, python-format +msgid "The sheet has already been marked as read." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:332 +#, python-format +msgid "The sheet has already been validated and can't be edited." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:469 +#: code:addons/shift_attendance/models/attendance_sheet.py:560 +#, python-format +msgid "The sheet has already been validated." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:483 +#, python-format +msgid "" +"The shift linked to the expected shift of %s does exist anymore.This " +"expected shift is ignored in the validation process." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__time_slot +msgid "Time Slot" +msgstr "Horaire" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval expressed in minutes" +msgstr "Intervalle de temps exprimé en minutes" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval for attendance sheet generation" +msgstr "" +"Générer les feuilles de présences ... minutes avant le début des shifts" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Too many workers" +msgstr "Trop de travailleurs" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread +msgid "Unread Messages" +msgstr "Messages non lus" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Unread Messages Counter" +msgstr "Compteur de messages non lus" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_annotated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_annotated +msgid "Unread notes" +msgstr "Notes non lues" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validate" +msgstr "Valider" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Validate Sheet" +msgstr "Valider la feuille" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Validated" +msgstr "Validée" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__validated_by +msgid "Validated by" +msgstr "Validée par" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Value of the last barcode scanned." +msgstr "Valeur du dernier code-barres scanné" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Warning" +msgstr "Avertissement" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:588 +#, python-format +msgid "Warning : Working mode for %s is %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__worker_nb_feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__worker_nb_feedback +msgid "Was your team big enough ? *" +msgstr "L'équipe était-elle assez nombreuse ? *" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website Messages" +msgstr "Messages du site web" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website communication history" +msgstr "Historique de communication du site web" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__week +msgid "Week" +msgstr "Semaine" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_id +msgid "Worker" +msgstr "Travailleur" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:572 +#, python-format +msgid "Worker name is missing for an added shift." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:351 +#, python-format +msgid "" +"Worker not found (invalid barcode or status). \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__working_mode +msgid "Working Mode" +msgstr "Régime de travail" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:584 +#, python-format +msgid "Working mode is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:316 +#, python-format +msgid "You can't add the same worker more than once to an attendance sheet. " +msgstr "" +"Vous ne pouvez pas ajouter le même travailleur plus d'une fois à une feuille " +"de présence." + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:338 +#, python-format +msgid "" +"You must be logged as 'Attendance Sheet Generic Access' if you want to scan " +"cards." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_validated_sheet +msgid "[${object.day}] Non-validated sheet ${object.time_slot} " +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_generate_missing_attendance_sheets +msgid "shift.generate_missing_attendance_sheets" +msgstr "" + +#~ msgid "Shifts Management" +#~ msgstr "Gestion des shifts" diff --git a/shift_attendance/i18n/nl_BE.po b/shift_attendance/i18n/nl_BE.po new file mode 100644 index 000000000..9d6166dce --- /dev/null +++ b/shift_attendance/i18n/nl_BE.po @@ -0,0 +1,1159 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * shift_attendance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-17 12:44+0000\n" +"PO-Revision-Date: 2020-08-17 12:44+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_attendance +msgid "" +"\n" +"
\n" +"\n" +" % if object.replaced_id:\n" +"

Hello ${object.replaced_id.name},\n" +"\n" +"

You have been recorded as non-attended during your " +"last shift (${format_tz(object.start_time,object.replaced_id.tz or 'Europe/" +"Brussels','%d.%m.%Y - %H:%M')}),\n" +" and you were supposed to replace ${object.worker_id." +"name}.\n" +" % endif\n" +"\n" +" % if not object.replaced_id:\n" +"

Hello ${object.worker_id.name},

\n" +"\n" +"

You have been recorded as non-attended during your last " +"shift (${format_tz(object.start_time,object.worker_id.tz or 'Europe/" +"Brussels','%d.%m.%Y - %H:%M')}).\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'regular':\n" +" % if object.state == 'absent_0':\n" +"

Super-cooperator assigned you 0 " +"compensation, so you won't have any additionnal shift to do before your next " +"regular shift.\n" +" % endif\n" +" % if object.state == 'absent_1':\n" +"

Super-cooperator assigned you 1 " +"compensation, so you have to attend one additionnal shift before your next " +"regular shift.\n" +" % endif\n" +" % if object.state == 'absent_2':\n" +"

Super-cooperator assigned you 2 " +"compensations, so you have to attend two additionnal shifts before your next " +"regular shift.\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" You were supposed to replace ${object.worker_id." +"name}.\n" +" You have to do ${(object.replaced_id." +"cooperative_status_ids.sr + object.replaced_id.cooperative_status_ids.sc) * " +"-1 } shifts before your next regular shift.
\n" +" % else:\n" +" You have to do ${(object.worker_id." +"cooperative_status_ids.sr + object.worker_id.cooperative_status_ids.sc) * " +"-1 } shifts before your next regular shift.
\n" +" % endif\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'irregular':\n" +" Your shift counter is at ${object.worker_id." +"cooperative_status_ids.sr}.\n" +"\n" +" % if object.worker_id.cooperative_status_ids." +"future_alert_date:\n" +" It should be superior or equal to 1 before the\n" +" ${object.worker_id.cooperative_status_ids." +"future_alert_date}.\n" +" % endif\n" +"
\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" Your current status is \"${object.replaced_id." +"cooperative_status_ids.get_status_value()}\".\n" +" % else:\n" +"

Your current status is \"${object.worker_id." +"cooperative_status_ids.get_status_value()}\".\n" +" % endif\n" +"\n" +"
If you have any question regarding this non-" +"attendance, just answer this e-mail.\n" +"

\n" +"
\n" +"

Cooperatively yours,
\n" +" The Members' office volunteers

\n" +"

${object.worker_id.company_id.name}.

\n" +"\n" +" % if object.worker_id.company_id.street:\n" +" ${object.worker_id.company_id.street}\n" +" % endif\n" +" % if object.worker_id.company_id.street2:\n" +" ${object.worker_id.company_id.street2}
\n" +" % endif\n" +" % if object.worker_id.company_id.city or object.worker_id." +"company_id.zip:\n" +" ${object.worker_id.company_id.zip} ${object.worker_id." +"company_id.city}
\n" +" % endif\n" +" % if object.worker_id.company_id.country_id:\n" +" ${object.worker_id.company_id.state_id and ('%s, ' % " +"object.worker_id.company_id.state_id.name) or ''} ${object.worker_id." +"company_id.country_id.name or ''}
\n" +" % endif\n" +" % if object.worker_id.company_id.phone:\n" +" Phone:  ${object.worker_id.company_id.phone}\n" +" % endif\n" +"\n" +" % if object.worker_id.company_id.website:\n" +" \n" +" %endif\n" +" % if object.worker_id.company_id.logo_url:\n" +"
\n" +" \n" +"
\n" +" %endif\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:45 +#, python-format +msgid "" +"\n" +"%s attended its shift as a normal one but was not expected. Something may be " +"wrong in his/her personal informations.\n" +" " +msgstr "" +"%s voerde zijn shift uit als een normale shift, maar werd niet verwacht. " +"Controleer zijn registratie voor dit tijdslot." + +#. module: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_validated_sheet +msgid "" +"\n" +"
\n" +"\n" +"

${object.day}\n" +"

The attendance sheet for ${object.time_slot} is not " +"validated.\n" +"

Please, do it as soon as possible so as to update workers' " +"status.\n" +"

\n" +"\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:532 +#, python-format +msgid "%s (added)" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:396 +#, python-format +msgid "%s is registered as replaced." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:383 +#, python-format +msgid "%s's working mode is %s and should be regular or irregular. " +msgstr "%s's working mode is %s and should be regular or irregular." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "" +"\n" +" Attendance Sheets Generation Interval\n" +" " +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "" +"\n" +" Default Shift Attendance Status\n" +" " +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "" +"\n" +" Default Task Type\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:345 +#, python-format +msgid "A validated attendance sheet can't be modified" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 0 Compensation" +msgstr "Afwezig - 0 compensatie" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 1 Compensation" +msgstr "Afwezig - 1 compensatie" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Absent - 2 Compensations" +msgstr "Afwezig - 2 compensatie" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction +msgid "Action Needed" +msgstr "Vereist actie" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__active +msgid "Active" +msgstr "Actief" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__active_sheet +msgid "Active Sheet" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_added +msgid "Added Shift" +msgstr "Toegevoegde shift" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__added_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Added Shifts" +msgstr "Toegevoegde shift" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_list +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_list +msgid "All sheets" +msgstr "Alle lijsten" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (read)" +msgstr "Geannoteerd (gelezen)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (unread)" +msgstr "Geannoteerd (ongelezen)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Archived" +msgstr "Gearchiveerd" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_attachment_count +msgid "Attachment Count" +msgstr "Aantal bijlagen" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__attendance_sheet_id +msgid "Attendance Sheet" +msgstr "Aanwezigheidslijsten" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet +msgid "Attendance Sheet Generic Access" +msgstr "Aanwezigheidslijsten" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet_validation +msgid "Attendance Sheet Validation" +msgstr "Aanwezigheidslijsten - Validatie" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_top +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Attendance Sheets" +msgstr "Aanwezigheidslijsten" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet +msgid "Attendance sheet" +msgstr "Aanwezigheidslijsten" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:563 +#, python-format +msgid "Attendance sheet can only be validated once the shifts have started. " +msgstr "" +"Aanwezigheidslijsten kunnen pas worden gevalideerd nadat de shifts begonnen " +"zijn." + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__barcode +msgid "Barcode" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Barcode Scanned" +msgstr "Barcode gescand" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "" +"Beware : a validated sheet cannot be edited " +"anymore and you won't be able to add any " +"latecomers. The counters of those who didn't " +"attend will be updated and they will get warning " +"emails." +msgstr "" +"Pas op: een gevalideerde aanwezigheidslijst kan niet meer worden gewijzigd " +"en je kunt geen laatkomers meer toevoegene tellers van de afwezige werkers " +"zullen worden bijgewerkt en ze zullen een waarschuwing ontvangen per email." + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:375 +#, python-format +msgid "" +"Beware, you are recorded as resigning. Please contact member's office if " +"this is incorrect. Thank you. " +msgstr "" +"Pas op: uw account is \"resigning\". Neem contact op met het Ledenbureau als " +"dit niet correct is. Dank u." + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:365 +#, python-format +msgid "" +"Beware, your account is frozen because your shift counter is at %s. Please " +"contact Members Office to unfreeze it. If you want to attend this shift, " +"your supercoop can write your name in the notes field during validation." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Cancel" +msgstr "Annuleren" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__card_support +msgid "Card validation" +msgstr "Kaartvalidatie" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_check_non_validated_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_check_non_validated_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_check_non_validated_sheet +msgid "Check for non-validated sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_validate +msgid "" +"Check the user name and validate sheet.\n" +" Useless for users in group_shift_attendance" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__feedback +msgid "Comments about the shift" +msgstr "Opmerkingen over jouw shift" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:602 +#, python-format +msgid "Compensation number is missing for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Compensation shift ?" +msgstr "Compensatie shift ?" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__week +msgid "Computed from planning name" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_shift +msgid "Copy of an actual shift into an attendance sheet" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_daily +#: model:ir.ui.menu,name:shift_attendance.menu_sheet +msgid "Daily attendance sheets" +msgstr "Aanwezigheidslijsten van de dag" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Day" +msgstr "Dag" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day_abbrevation +msgid "Day Abbrevation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +#, fuzzy +msgid "Default Shift State" +msgstr "Shift Staat" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__pre_filled_task_type_id +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Default Task Type" +msgstr "Standaard Soort taak" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +#, fuzzy +msgid "Default state set for shifts on attendance sheets" +msgstr "" +"Standaard soort taak toe te kennen bij voor-invullen van aanwezigheidslijst" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__pre_filled_task_type_id +msgid "Default task type for attendance sheet pre-filling" +msgstr "" +"Standaard soort taak toe te kennen bij voor-invullen van aanwezigheidslijst" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__display_name +msgid "Display Name" +msgstr "Schermnaam" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__end_time +msgid "End Time" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_end +msgid "End date" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Enough workers" +msgstr "Genoeg werkers" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_expected +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_expected_view_form +msgid "Expected Shift" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__expected_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Expected Shifts" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Feedback" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Feedback on number of workers" +msgstr "Was het team groot genoeg ?" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_follower_ids +msgid "Followers" +msgstr "Volgers" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_channel_ids +msgid "Followers (Channels)" +msgstr "Volgers (Kanalen)" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_partner_ids +msgid "Followers (Partners)" +msgstr "Volgers (Relaties)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "For attendance sheets automatic pre-filling." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_generate_attendance_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_generate_attendance_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_generate_attendance_sheet +msgid "Generate Attendance Sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_missing_attendance_sheets +msgid "Generate Missing Sheets" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Generate attendance sheets before shifts start." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate missing attendance sheets in a given time interval" +msgstr "" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_missing_attendance_sheets +msgid "Generate missing past attendance sheets" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:46 +#, python-format +msgid "Generated Missing Sheets" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Group By" +msgstr "Groepeer op" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__has_missing_worker +msgid "Has missing worker ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__is_read +msgid "Has notes been read by an administrator ?" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "I was not there during the shift" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__id +msgid "ID" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread +msgid "If checked new messages require your attention." +msgstr "Indien aangevinkt zullen nieuwe berichten uw aandacht vragen." + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction +msgid "If checked, new messages require your attention." +msgstr "Indien aangevinkt vragen nieuwe berichten uw aandacht." + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "indien aangevinkt hebben sommige leveringen een fout." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "" +"If not checked, user credentials are\n" +" asked." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__max_worker_no +msgid "Indicative maximum number of workers." +msgstr "Indicatief max. aantal werkers." + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Interval (minutes)" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_is_follower +msgid "Is Follower" +msgstr "Is een volger" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_annotated +msgid "Is annotated" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Is any regular worker doing its regular shift as an added one ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate____last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__login +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Login" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_main_attachment_id +msgid "Main Attachment" +msgstr "Hoofd bijlage" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_read +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Mark as read" +msgstr "Markeer als gelezen" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__max_worker_no +msgid "Maximum number of workers" +msgstr "Max. aantal werkers" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error +msgid "Message Delivery error" +msgstr "Bericht afleverfout" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_ids +msgid "Messages" +msgstr "Berichten" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:356 +#, python-format +msgid "" +"Multiple workers are corresponding this barcode. \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_name +msgid "Name" +msgstr "Naam" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:228 +#: sql_constraint:shift.sheet:0 +#, python-format +msgid "Non-annotated sheets can't be marked as read." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_attendance +msgid "Non-attendance to your last shift." +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_non_validated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_non_validated +msgid "Non-validated sheets" +msgstr "Niet-gevalideerde lijsten" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Not Validated" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Not enough workers" +msgstr "Niet genoeg werkers" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__notes +msgid "Notes" +msgstr "Notities" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__notes +msgid "Notes about the attendance for the Members Office" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of Actions" +msgstr "Aantal acties" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of error" +msgstr "Aantal foutmeldingen" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "Aantal berichten die actie vereisen" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "Aantal berichten met leveringsfout" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Number of unread messages" +msgstr "Aantal ongelezen berichten" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__attended_worker_no +msgid "Number of workers present" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Only for regular workers" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:58 +#, python-format +msgid "Only past attendance sheets can be generated" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:119 +#, python-format +msgid "" +"Only super-cooperators and administrators can validate attendance sheets. " +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__password +msgid "Password" +msgstr "Wachtwoord" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:108 +#, python-format +msgid "Please enter your login." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:612 +#, python-format +msgid "Please give your feedback about the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:97 +#, python-format +msgid "Please give your feedback on the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:103 +#, python-format +msgid "Please set a correct barcode." +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet.added,state:0 selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +msgid "Present" +msgstr "Aanwezig" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker" +msgstr "Vervangingswerker" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker (must be regular)" +msgstr "Vervangingswerker (regelmatig werkregime vereist)" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Save" +msgstr "Opslaan" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Scan cards for validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__card_support +msgid "Scan cooperators cards instead of login for sheets validation" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Scan your card" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_shift_settings +msgid "Settings" +msgstr "Instellingen" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_shift_settings +msgid "Shift Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__state +msgid "Shift State" +msgstr "Shift Staat" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:598 +#, python-format +msgid "Shift State is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:575 +#, python-format +msgid "Shift State is missing or wrong for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__start_time +msgid "Start Time" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_start +msgid "Start date" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__state +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "State" +msgstr "Staat/Provincie" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__super_coop_id +msgid "Super Cooperative" +msgstr "Supercoöperant" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_id +msgid "Task" +msgstr "Taak" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_type_id +msgid "Task Type" +msgstr "Soort taak" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:580 +#, python-format +msgid "Task Type is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:463 +#, python-format +msgid "The sheet has already been marked as read." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:332 +#, python-format +msgid "The sheet has already been validated and can't be edited." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:469 +#: code:addons/shift_attendance/models/attendance_sheet.py:560 +#, python-format +msgid "The sheet has already been validated." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:483 +#, python-format +msgid "" +"The shift linked to the expected shift of %s does exist anymore.This " +"expected shift is ignored in the validation process." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__time_slot +msgid "Time Slot" +msgstr "Tijdslot" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval expressed in minutes" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval for attendance sheet generation" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Too many workers" +msgstr "Te veel werkers" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread +msgid "Unread Messages" +msgstr "Ongelezen berichten" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Unread Messages Counter" +msgstr "Aantal ongelezen berichten" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_annotated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_annotated +msgid "Unread notes" +msgstr "Ongelezen notities" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validate" +msgstr "Bevestig" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Validate Sheet" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Validated" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__validated_by +msgid "Validated by" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validation" +msgstr "Validatie" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Value of the last barcode scanned." +msgstr "Waarde van de laatst gescande barcode." + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Warning" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:588 +#, python-format +msgid "Warning : Working mode for %s is %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__worker_nb_feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__worker_nb_feedback +msgid "Was your team big enough ? *" +msgstr "Was het team groot genoeg? *" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website Messages" +msgstr "Websiteberichten" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website communication history" +msgstr "Websitecommunicatiehistoriek" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__week +msgid "Week" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_id +msgid "Worker" +msgstr "Vervangingswerker" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:572 +#, python-format +msgid "Worker name is missing for an added shift." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:351 +#, python-format +msgid "" +"Worker not found (invalid barcode or status). \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__working_mode +msgid "Working Mode" +msgstr "Werkregime" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:584 +#, python-format +msgid "Working mode is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:316 +#, python-format +msgid "You can't add the same worker more than once to an attendance sheet. " +msgstr "" +"Je kunt dezelfde werker niet meer dan één keer aan een aanwezigheidslijst " +"toevoegen." + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:338 +#, python-format +msgid "" +"You must be logged as 'Attendance Sheet Generic Access' if you want to scan " +"cards." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_validated_sheet +msgid "[${object.day}] Non-validated sheet ${object.time_slot} " +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_generate_missing_attendance_sheets +msgid "shift.generate_missing_attendance_sheets" +msgstr "" diff --git a/shift_attendance/i18n/shift_attendance.pot b/shift_attendance/i18n/shift_attendance.pot new file mode 100644 index 000000000..5e76077c3 --- /dev/null +++ b/shift_attendance/i18n/shift_attendance.pot @@ -0,0 +1,1088 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * shift_attendance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.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: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_attendance +msgid "\n" +"
\n" +"\n" +" % if object.replaced_id:\n" +"

Hello ${object.replaced_id.name},\n" +"\n" +"

You have been recorded as non-attended during your last shift (${format_tz(object.start_time,object.replaced_id.tz or 'Europe/Brussels','%d.%m.%Y - %H:%M')}),\n" +" and you were supposed to replace ${object.worker_id.name}.\n" +" % endif\n" +"\n" +" % if not object.replaced_id:\n" +"

Hello ${object.worker_id.name},

\n" +"\n" +"

You have been recorded as non-attended during your last shift (${format_tz(object.start_time,object.worker_id.tz or 'Europe/Brussels','%d.%m.%Y - %H:%M')}).\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'regular':\n" +" % if object.state == 'absent_0':\n" +"

Super-cooperator assigned you 0 compensation, so you won't have any additionnal shift to do before your next regular shift.\n" +" % endif\n" +" % if object.state == 'absent_1':\n" +"

Super-cooperator assigned you 1 compensation, so you have to attend one additionnal shift before your next regular shift.\n" +" % endif\n" +" % if object.state == 'absent_2':\n" +"

Super-cooperator assigned you 2 compensations, so you have to attend two additionnal shifts before your next regular shift.\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" You were supposed to replace ${object.worker_id.name}.\n" +" You have to do ${(object.replaced_id.cooperative_status_ids.sr + object.replaced_id.cooperative_status_ids.sc) * -1 } shifts before your next regular shift.
\n" +" % else:\n" +" You have to do ${(object.worker_id.cooperative_status_ids.sr + object.worker_id.cooperative_status_ids.sc) * -1 } shifts before your next regular shift.
\n" +" % endif\n" +" % endif\n" +"\n" +" % if object.worker_id.working_mode == 'irregular':\n" +" Your shift counter is at ${object.worker_id.cooperative_status_ids.sr}.\n" +"\n" +" % if object.worker_id.cooperative_status_ids.future_alert_date:\n" +" It should be superior or equal to 1 before the\n" +" ${object.worker_id.cooperative_status_ids.future_alert_date}.\n" +" % endif\n" +"
\n" +" % endif\n" +"\n" +" % if object.replaced_id:\n" +" Your current status is \"${object.replaced_id.cooperative_status_ids.get_status_value()}\".\n" +" % else:\n" +"

Your current status is \"${object.worker_id.cooperative_status_ids.get_status_value()}\".\n" +" % endif\n" +"\n" +"
If you have any question regarding this non-attendance, just answer this e-mail.\n" +"

\n" +"
\n" +"

Cooperatively yours,
\n" +" The Members' office volunteers

\n" +"

${object.worker_id.company_id.name}.

\n" +"\n" +" % if object.worker_id.company_id.street:\n" +" ${object.worker_id.company_id.street}\n" +" % endif\n" +" % if object.worker_id.company_id.street2:\n" +" ${object.worker_id.company_id.street2}
\n" +" % endif\n" +" % if object.worker_id.company_id.city or object.worker_id.company_id.zip:\n" +" ${object.worker_id.company_id.zip} ${object.worker_id.company_id.city}
\n" +" % endif\n" +" % if object.worker_id.company_id.country_id:\n" +" ${object.worker_id.company_id.state_id and ('%s, ' % object.worker_id.company_id.state_id.name) or ''} ${object.worker_id.company_id.country_id.name or ''}
\n" +" % endif\n" +" % if object.worker_id.company_id.phone:\n" +" Phone:  ${object.worker_id.company_id.phone}\n" +" % endif\n" +"\n" +" % if object.worker_id.company_id.website:\n" +" \n" +" %endif\n" +" % if object.worker_id.company_id.logo_url:\n" +"
\n" +" \n" +"
\n" +" %endif\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:45 +#, python-format +msgid "\n" +"%s attended its shift as a normal one but was not expected. Something may be wrong in his/her personal informations.\n" +" " +msgstr "" + +#. module: shift_attendance +#: model:mail.template,body_html:shift_attendance.email_template_non_validated_sheet +msgid "\n" +"
\n" +"\n" +"

${object.day}\n" +"

The attendance sheet for ${object.time_slot} is not validated.\n" +"

Please, do it as soon as possible so as to update workers' status.\n" +"

\n" +"\n" +"
\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:530 +#, python-format +msgid "%s (added)" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:394 +#, python-format +msgid "%s is registered as replaced." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:381 +#, python-format +msgid "%s's working mode is %s and should be regular or irregular. " +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "\n" +" Attendance Sheets Generation Interval\n" +" " +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "\n" +" Default Shift Attendance Status\n" +" " +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "\n" +" Default Task Type\n" +" " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:343 +#, python-format +msgid "A validated attendance sheet can't be modified" +msgstr "" + +#. module: shift_attendance +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +#: selection:shift.sheet.added,state:0 +#: selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +msgid "Absent - 0 Compensation" +msgstr "" + +#. module: shift_attendance +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +#: selection:shift.sheet.added,state:0 +#: selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +msgid "Absent - 1 Compensation" +msgstr "" + +#. module: shift_attendance +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +#: selection:shift.sheet.added,state:0 +#: selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +msgid "Absent - 2 Compensations" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__active +msgid "Active" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__active_sheet +msgid "Active Sheet" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_added +msgid "Added Shift" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__added_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Added Shifts" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_list +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_list +msgid "All sheets" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (read)" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Annotated (unread)" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Archived" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__attendance_sheet_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__attendance_sheet_id +msgid "Attendance Sheet" +msgstr "" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet +msgid "Attendance Sheet Generic Access" +msgstr "" + +#. module: shift_attendance +#: model:res.groups,name:shift_attendance.group_shift_attendance_sheet_validation +msgid "Attendance Sheet Validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_top +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Attendance Sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet +msgid "Attendance sheet" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:561 +#, python-format +msgid "Attendance sheet can only be validated once the shifts have started. " +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__barcode +msgid "Barcode" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Barcode Scanned" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Beware : a validated sheet cannot be edited anymore and you won't be able to add any latecomers. The counters of those who didn't attend will be updated and they will get warning emails." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:373 +#, python-format +msgid "Beware, you are recorded as resigning. Please contact member's office if this is incorrect. Thank you. " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:363 +#, python-format +msgid "Beware, your account is frozen because your shift counter is at %s. Please contact Members Office to unfreeze it. If you want to attend this shift, your supercoop can write your name in the notes field during validation." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Cancel" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__card_support +msgid "Card validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_check_non_validated_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_check_non_validated_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_check_non_validated_sheet +msgid "Check for non-validated sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_validate +msgid "Check the user name and validate sheet.\n" +" Useless for users in group_shift_attendance" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__feedback +msgid "Comments about the shift" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:600 +#, python-format +msgid "Compensation number is missing for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Compensation shift ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__week +msgid "Computed from planning name" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_shift +msgid "Copy of an actual shift into an attendance sheet" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_uid +msgid "Created by" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__create_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__create_date +msgid "Created on" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_daily +#: model:ir.ui.menu,name:shift_attendance.menu_sheet +msgid "Daily attendance sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Day" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__day_abbrevation +msgid "Day Abbrevation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +msgid "Default Shift State" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__pre_filled_task_type_id +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Default Task Type" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_default_shift_state +msgid "Default state set for shifts on attendance sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__pre_filled_task_type_id +msgid "Default task type for attendance sheet pre-filling" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__display_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__display_name +msgid "Display Name" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__end_time +msgid "End Time" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_end +msgid "End date" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Enough workers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_sheet_expected +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_expected_view_form +msgid "Expected Shift" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__expected_shift_ids +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Expected Shifts" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Feedback" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Feedback on number of workers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_channel_ids +msgid "Followers (Channels)" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "For attendance sheets automatic pre-filling." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.server,name:shift_attendance.ir_cron_generate_attendance_sheet_ir_actions_server +#: model:ir.cron,cron_name:shift_attendance.ir_cron_generate_attendance_sheet +#: model:ir.cron,name:shift_attendance.ir_cron_generate_attendance_sheet +msgid "Generate Attendance Sheets" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_missing_attendance_sheets +msgid "Generate Missing Sheets" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Generate attendance sheets before shifts start." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.generate_attendance_sheet_form +msgid "Generate missing attendance sheets in a given time interval" +msgstr "" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_missing_attendance_sheets +msgid "Generate missing past attendance sheets" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:46 +#, python-format +msgid "Generated Missing Sheets" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_search +msgid "Group By" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__has_missing_worker +msgid "Has missing worker ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__is_read +msgid "Has notes been read by an administrator ?" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "I was not there during the shift" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__id +msgid "ID" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread +msgid "If checked new messages require your attention." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "If not checked, user credentials are\n" +" asked." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__max_worker_no +msgid "Indicative maximum number of workers." +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Interval (minutes)" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_annotated +msgid "Is annotated" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Is any regular worker doing its regular shift as an added one ?" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift____last_update +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate____last_update +msgid "Last Modified on" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_uid +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__write_date +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__write_date +msgid "Last Updated on" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__login +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Login" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__is_read +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Mark as read" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__max_worker_no +msgid "Maximum number of workers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_ids +msgid "Messages" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:354 +#, python-format +msgid "Multiple workers are corresponding this barcode. \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_name +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_name +msgid "Name" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:226 +#: sql_constraint:shift.sheet:0 +#, python-format +msgid "Non-annotated sheets can't be marked as read." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_attendance +msgid "Non-attendance to your last shift." +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_non_validated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_non_validated +msgid "Non-validated sheets" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Not Validated" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Not enough workers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__notes +msgid "Notes" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__notes +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate__notes +msgid "Notes about the attendance for the Members Office" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of error" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Number of unread messages" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__attended_worker_no +msgid "Number of workers present" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_added__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__is_compensation +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_shift__is_compensation +msgid "Only for regular workers" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/generate_missing_attendance_sheets.py:58 +#, python-format +msgid "Only past attendance sheets can be generated" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:119 +#, python-format +msgid "Only super-cooperators and administrators can validate attendance sheets. " +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__password +msgid "Password" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:108 +#, python-format +msgid "Please enter your login." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:610 +#, python-format +msgid "Please give your feedback about the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:97 +#, python-format +msgid "Please give your feedback on the number of workers." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/wizard/validate_attendance_sheet.py:103 +#, python-format +msgid "Please set a correct barcode." +msgstr "" + +#. module: shift_attendance +#: selection:res.config.settings,attendance_sheet_default_shift_state:0 +#: selection:shift.sheet.added,state:0 +#: selection:shift.sheet.expected,state:0 +#: selection:shift.sheet.shift,state:0 +msgid "Present" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_expected__replaced_id +msgid "Replacement Worker (must be regular)" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Save" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "Scan cards for validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__card_support +msgid "Scan cooperators cards instead of login for sheets validation" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Scan your card" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_shift_settings +msgid "Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.ui.menu,name:shift_attendance.menu_shift_settings +msgid "Shift Settings" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__state +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__state +msgid "Shift State" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:596 +#, python-format +msgid "Shift State is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:573 +#, python-format +msgid "Shift State is missing or wrong for %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__start_time +msgid "Start Time" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_generate_missing_attendance_sheets__date_start +msgid "Start date" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__state +#: model_terms:ir.ui.view,arch_db:shift_attendance.res_config_settings_view_form +msgid "State" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__super_coop_id +msgid "Super Cooperative" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_id +msgid "Task" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__task_type_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__task_type_id +msgid "Task Type" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:578 +#, python-format +msgid "Task Type is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:461 +#, python-format +msgid "The sheet has already been marked as read." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:330 +#, python-format +msgid "The sheet has already been validated and can't be edited." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:467 +#: code:addons/shift_attendance/models/attendance_sheet.py:558 +#, python-format +msgid "The sheet has already been validated." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:481 +#, python-format +msgid "The shift linked to the expected shift of %s does exist anymore.This expected shift is ignored in the validation process." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__time_slot +msgid "Time Slot" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval expressed in minutes" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_res_config_settings__attendance_sheet_generation_interval +msgid "Time interval for attendance sheet generation" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,worker_nb_feedback:0 +msgid "Too many workers" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread +msgid "Unread Messages" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__message_unread_counter +msgid "Unread Messages Counter" +msgstr "" + +#. module: shift_attendance +#: model:ir.actions.act_window,name:shift_attendance.action_sheet_admin_annotated +#: model:ir.ui.menu,name:shift_attendance.menu_sheet_admin_annotated +msgid "Unread notes" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validate" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.sheet_view_form +msgid "Validate Sheet" +msgstr "" + +#. module: shift_attendance +#: selection:shift.sheet,state:0 +msgid "Validated" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__validated_by +msgid "Validated by" +msgstr "" + +#. module: shift_attendance +#: model_terms:ir.ui.view,arch_db:shift_attendance.validate_attendance_sheet_form +msgid "Validation" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet___barcode_scanned +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet_validate___barcode_scanned +msgid "Value of the last barcode scanned." +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__warning_regular_workers +msgid "Warning" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:586 +#, python-format +msgid "Warning : Working mode for %s is %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__worker_nb_feedback +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_validate__worker_nb_feedback +msgid "Was your team big enough ? *" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,help:shift_attendance.field_shift_sheet__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet__week +msgid "Week" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__worker_id +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__worker_id +msgid "Worker" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:570 +#, python-format +msgid "Worker name is missing for an added shift." +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:349 +#, python-format +msgid "Worker not found (invalid barcode or status). \n" +"Barcode : %s" +msgstr "" + +#. module: shift_attendance +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_added__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_expected__working_mode +#: model:ir.model.fields,field_description:shift_attendance.field_shift_sheet_shift__working_mode +msgid "Working Mode" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:582 +#, python-format +msgid "Working mode is missing for %s" +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:314 +#, python-format +msgid "You can't add the same worker more than once to an attendance sheet. " +msgstr "" + +#. module: shift_attendance +#: code:addons/shift_attendance/models/attendance_sheet.py:336 +#, python-format +msgid "You must be logged as 'Attendance Sheet Generic Access' if you want to scan cards." +msgstr "" + +#. module: shift_attendance +#: model:mail.template,subject:shift_attendance.email_template_non_validated_sheet +msgid "[${object.day}] Non-validated sheet ${object.time_slot} " +msgstr "" + +#. module: shift_attendance +#: model:ir.model,name:shift_attendance.model_shift_generate_missing_attendance_sheets +msgid "shift.generate_missing_attendance_sheets" +msgstr "" + diff --git a/shift_attendance/models/__init__.py b/shift_attendance/models/__init__.py new file mode 100644 index 000000000..800e01c22 --- /dev/null +++ b/shift_attendance/models/__init__.py @@ -0,0 +1,2 @@ +from . import attendance_sheet +from . import res_config_settings diff --git a/shift_attendance/models/attendance_sheet.py b/shift_attendance/models/attendance_sheet.py new file mode 100644 index 000000000..e0d35469a --- /dev/null +++ b/shift_attendance/models/attendance_sheet.py @@ -0,0 +1,665 @@ +import logging +from datetime import date, datetime, timedelta + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class AttendanceSheetShift(models.Model): + """ + Partial copy of Task class to use in AttendanceSheet, + actual Task is updated at validation. + + Should be Abstract and not used alone (common code for + AttendanceSheetShiftAdded and AttendanceSheetShiftExpected), + but create() method from res.partner raise error + when class is Abstract. + """ + + _name = "shift.sheet.shift" + _description = "Copy of an actual shift into an attendance sheet" + _order = "task_type_id, worker_name" + + @api.model + def pre_filled_task_type_id(self): + parameters = self.env["ir.config_parameter"].sudo() + tasktype_id = int( + parameters.get_param("shift_attendance.pre_filled_task_type_id", default=1) + ) + task_types = self.env["shift.type"] + return task_types.browse(tasktype_id) + + @api.model + def _default_attendance_sheet_shift_sheet(self): + parameters = self.env["ir.config_parameter"].sudo() + return parameters.get_param( + "shift_attendance.attendance_sheet_default_shift_state", + default="absent_2", + ) + + # Related actual shift + task_id = fields.Many2one("shift.shift", string="Task") + attendance_sheet_id = fields.Many2one( + "shift.sheet", + string="Attendance Sheet", + required=True, + ondelete="cascade", + ) + state = fields.Selection( + [ + ("done", "Present"), + ("absent_0", "Absent - 0 Compensation"), + ("absent_1", "Absent - 1 Compensation"), + ("absent_2", "Absent - 2 Compensations"), + ], + string="Shift State", + required=True, + default=lambda self: self._default_attendance_sheet_shift_sheet(), + ) + worker_id = fields.Many2one( + "res.partner", + string="Worker", + domain=[ + ("is_worker", "=", True), + ("working_mode", "in", ("regular", "irregular")), + ("state", "not in", ("unsubscribed", "resigning")), + ], + required=True, + ) + worker_name = fields.Char(related="worker_id.name", store=True) + task_type_id = fields.Many2one( + "shift.type", + string="Task Type", + default=pre_filled_task_type_id, + ) + working_mode = fields.Selection( + related="worker_id.working_mode", string="Working Mode" + ) + # The two exclusive booleans are gathered in a simple one + is_compensation = fields.Boolean( + string="Compensation shift ?", help="Only for regular workers" + ) + + +class AttendanceSheetShiftExpected(models.Model): + """ + Shifts already expected. + """ + + _name = "shift.sheet.expected" + _description = "Expected Shift" + _inherit = ["shift.sheet.shift"] + + super_coop_id = fields.Many2one(related="task_id.super_coop_id", store=True) + replaced_id = fields.Many2one( + "res.partner", + string="Replacement Worker", + help="Replacement Worker (must be regular)", + domain=[ + ("eater", "=", "worker_eater"), + ("working_mode", "=", "regular"), + ("state", "not in", ("unsubscribed", "resigning")), + ], + ) + + @api.onchange("replaced_id") + def on_change_replacement_worker(self): + if self.replaced_id: + self.state = "done" + + +class AttendanceSheetShiftAdded(models.Model): + """ + Shifts added during time slot. + """ + + _name = "shift.sheet.added" + _description = "Added Shift" + _inherit = ["shift.sheet.shift"] + + @api.onchange("working_mode") + def on_change_working_mode(self): + self.state = "done" + self.is_compensation = self.working_mode == "regular" + + +class AttendanceSheet(models.Model): + _name = "shift.sheet" + _inherit = ["mail.thread", "barcodes.barcode_events_mixin"] + _description = "Attendance sheet" + _order = "start_time" + + name = fields.Char(compute="_compute_name") + time_slot = fields.Char( + compute="_compute_time_slot", + store=True, + readonly=True, + ) + active = fields.Boolean(default=1) + state = fields.Selection( + [("not_validated", "Not Validated"), ("validated", "Validated")], + readonly=True, + index=True, + default="not_validated", + tracking=True, + ) + start_time = fields.Datetime(required=True, readonly=True) + end_time = fields.Datetime(required=True, readonly=True) + day = fields.Date(compute="_compute_day", store=True) + day_abbrevation = fields.Char(compute="_compute_day_abbrevation") + week = fields.Char( + help="Computed from planning name", + compute="_compute_week", + ) + + expected_shift_ids = fields.One2many( + "shift.sheet.expected", + "attendance_sheet_id", + string="Expected Shifts", + ) + added_shift_ids = fields.One2many( + "shift.sheet.added", + "attendance_sheet_id", + string="Added Shifts", + ) + + max_worker_no = fields.Integer( + string="Maximum number of workers", + default=0, + readonly=True, + help="Indicative maximum number of workers.", + ) + attended_worker_no = fields.Integer( + string="Number of workers present", default=0, readonly=True + ) + notes = fields.Text( + default="", + help="Notes about the attendance for the Members Office", + ) + is_annotated = fields.Boolean( + compute="_compute_is_annotated", + readonly=True, + store=True, + ) + is_read = fields.Boolean( + string="Mark as read", + help="Has notes been read by an administrator ?", + default=False, + tracking=True, + ) + feedback = fields.Text("Comments about the shift") + worker_nb_feedback = fields.Selection( + [ + ("not_enough", "Not enough workers"), + ("enough", "Enough workers"), + ("too_many", "Too many workers"), + ("empty", "I was not there during the shift"), + ], + string="Was your team big enough ? *", + ) + validated_by = fields.Many2one( + "res.partner", + domain=[ + ("eater", "=", "worker_eater"), + ("super", "=", True), + ("working_mode", "=", "regular"), + ("state", "not in", ("unsubscribed", "resigning")), + ], + tracking=True, + readonly=True, + ) + + _sql_constraints = [ + ( + "check_not_annotated_mark_as_read", + "CHECK ((is_annotated=FALSE AND is_read=FALSE) OR is_annotated=TRUE)", + _("Non-annotated sheets can't be marked as read."), + ) + ] + + # True if there are one or more missing workers + has_missing_worker = fields.Boolean( + string="Has missing worker ?", + compute="_compute_has_missing_worker", + ) + + @api.depends("start_time", "end_time") + def _compute_time_slot(self): + for rec in self: + start_time = fields.Datetime.context_timestamp(rec, rec.start_time) + end_time = fields.Datetime.context_timestamp(rec, rec.end_time) + rec.time_slot = ( + start_time.strftime("%H:%M") + "-" + end_time.strftime("%H:%M") + ) + + @api.depends("start_time", "end_time", "week", "day_abbrevation") + def _compute_name(self): + for rec in self: + start_time = fields.Datetime.context_timestamp(rec, rec.start_time) + name = "[%s] " % fields.Date.to_string(start_time) + if rec.week: + name += rec.week + " " + if rec.day_abbrevation: + name += rec.day_abbrevation + " " + if rec.time_slot: + name += "(%s)" % rec.time_slot + rec.name = name + + @api.depends("start_time") + def _compute_day(self): + for rec in self: + rec.day = rec.start_time.date() + + @api.depends("expected_shift_ids") + def _compute_day_abbrevation(self): + """ + Compute Day Abbrevation from Planning Name + of first expected shift with one. + """ + for rec in self: + for shift in rec.expected_shift_ids: + if shift.task_id.task_template_id.day_nb_id.name: + rec.day_abbrevation = shift.task_id.task_template_id.day_nb_id.name + + @api.depends("expected_shift_ids") + def _compute_week(self): + """ + Compute Week Name from Planning Name + of first expected shift with one. + """ + for rec in self: + for shift in rec.expected_shift_ids: + if shift.task_id.planning_id.name: + rec.week = shift.task_id.planning_id.name + + @api.depends("notes") + def _compute_is_annotated(self): + for rec in self: + if rec.notes: + rec.is_annotated = bool(rec.notes.strip()) + + @api.depends("expected_shift_ids.state", "added_shift_ids.state") + def _compute_has_missing_worker(self): + for rec in self: + rec.has_missing_worker = False + if any(s.state != "done" for s in rec.expected_shift_ids): + rec.has_missing_worker = True + continue + if any(s.state != "done" for s in rec.added_shift_ids): + rec.has_missing_worker = True + continue + + @api.constrains("expected_shift_ids", "added_shift_ids") + def _constrain_unique_worker(self): + # Warning : map return generator in python3 (for Odoo 12) + added_ids = [s.worker_id.id for s in self.added_shift_ids] + expected_ids = [s.worker_id.id for s in self.expected_shift_ids] + replacement_ids = [ + s.replaced_id.id for s in self.expected_shift_ids if s.replaced_id.id + ] + ids = added_ids + expected_ids + replacement_ids + + if (len(ids) - len(set(ids))) > 0: + raise UserError( + _( + "You can't add the same worker more than once to an " + "attendance sheet. " + ) + ) + + @api.constrains( + "expected_shift_ids", + "added_shift_ids", + "notes", + "feedback", + "worker_nb_feedback", + ) + def _lock_after_validation(self): + if self.state == "validated": + raise UserError( + _("The sheet has already been validated and can't be edited.") + ) + + def on_barcode_scanned(self, barcode): + if self.env.user.has_group("shift_attendance.group_shift_attendance"): + raise UserError( + _( + "You must be logged as 'Attendance Sheet Generic Access' " + " if you want to scan cards." + ) + ) + + if self.state == "validated": + raise UserError(_("A validated attendance sheet can't be modified")) + + worker = self.env["res.partner"].search([("barcode", "=", barcode)]) + + if not len(worker): + raise UserError( + _("Worker not found (invalid barcode or status). \nBarcode : %s") + % barcode + ) + if len(worker) > 1: + raise UserError( + _("Multiple workers are corresponding this barcode. \nBarcode : %s") + % barcode + ) + + if worker.state == "unsubscribed": + shift_counter = ( + worker.cooperative_status_ids.sc + worker.cooperative_status_ids.sr + ) + raise UserError( + _( + "Beware, your account is frozen because your shift counter " + "is at %s. Please contact Members Office to unfreeze it. " + "If you want to attend this shift, your supercoop " + "can write your name in the notes field during validation." + ) + % shift_counter + ) + if worker.state == "resigning": + raise UserError( + _( + "Beware, you are recorded as resigning. " + "Please contact member's office if this is incorrect. " + "Thank you. " + ) + ) + if worker.working_mode not in ("regular", "irregular"): + raise UserError( + _( + "%(name)s's working mode is %(working_mode)s and " + "should be regular or irregular." + ) + % {"name": worker.name, "working_mode": worker.working_mode} + ) + + # Expected shifts status update + for id_ in self.expected_shift_ids.ids: + shift = self.env["shift.sheet.expected"].browse(id_) + if ( + shift.worker_id == worker and not shift.replaced_id + ) or shift.replaced_id == worker: + shift.state = "done" + return + if shift.worker_id == worker and shift.replaced_id: + raise UserError(_("%s is registered as replaced.") % worker.name) + + is_compensation = worker.working_mode == "regular" + + added_ids = [s.worker_id.id for s in self.added_shift_ids] + + if worker.id not in added_ids: + # Added shift creation + self.added_shift_ids |= self.added_shift_ids.new( + { + "task_type_id": (self.added_shift_ids.pre_filled_task_type_id()), + "state": "done", + "attendance_sheet_id": self._origin.id, + "worker_id": worker.id, + "is_compensation": is_compensation, + } + ) + + @api.model_create_multi + def create(self, vals_list): + new_sheets = super(AttendanceSheet, self).create(vals_list) + for new_sheet in new_sheets: + # Creation and addition of the expected shifts corresponding + # to the time range + tasks = self.env["shift.shift"] + expected_shift = self.env["shift.sheet.expected"] + # Fix issues with equality check on datetime + # by searching on a small interval instead + delta = timedelta(minutes=1) + + tasks = tasks.search( + [ + ("start_time", ">", new_sheet.start_time - delta), + ("start_time", "<", new_sheet.start_time + delta), + ("end_time", ">", new_sheet.end_time - delta), + ("end_time", "<", new_sheet.end_time + delta), + ] + ) + + workers = [] + + for task in tasks: + # Only one shift is added if multiple similar exist + if ( + task.worker_id + and task.worker_id not in workers + and (task.state != "cancel") + ): + expected_shift.create( + { + "attendance_sheet_id": new_sheet.id, + "task_id": task.id, + "worker_id": task.worker_id.id, + "replaced_id": task.replaced_id.id, + "task_type_id": task.task_type_id.id, + "working_mode": task.working_mode, + "is_compensation": task.is_compensation, + } + ) + workers.append(task.worker_id) + # Maximum number of workers calculation (count empty shifts) + new_sheet.max_worker_no = len(tasks) + return new_sheets + + def button_mark_as_read(self): + if self.is_read: + raise UserError(_("The sheet has already been marked as read.")) + self.is_read = True + + def _validate(self, user): + self.ensure_one() + if self.state == "validated": + raise UserError(_("The sheet has already been validated.")) + + # Expected shifts status update + for expected_shift in self.expected_shift_ids: + actual_shift = expected_shift.task_id + if not actual_shift: + _logger.warning( + "The shift linked to the expected shift with id %s " + "for the partner id %s does not exist anymore." + "The expected shift is ignored during the validation " + "process of the attendance sheet." + % (expected_shift.id, expected_shift.worker_id.id) + ) + self._message_log( + body=_( + "The shift linked to the expected shift of %s " + "does exist anymore." + "This expected shift is ignored in the " + "validation process." % expected_shift.worker_id.name + ) + ) + continue + actual_shift.replaced_id = expected_shift.replaced_id + actual_shift.state = expected_shift.state + + if expected_shift.state == "done": + self.attended_worker_no += 1 + + if expected_shift.state != "done": + mail_template = self.env.ref( + "shift_attendance.email_template_non_attendance", + False, + ) + mail_template.send_mail(expected_shift.task_id.id, True) + + # Added shifts status update + for added_shift in self.added_shift_ids: + is_regular_worker = added_shift.worker_id.working_mode == "regular" + is_compensation = added_shift.is_compensation + + # Edit a non-assigned shift or create one if none + + # Fix issues with equality check on datetime + # by searching on a small intervall instead + delta = timedelta(minutes=1) + + non_assigned_shifts = self.env["shift.shift"].search( + [ + ("worker_id", "=", False), + ("start_time", ">", self.start_time - delta), + ("start_time", "<", self.start_time + delta), + ("end_time", ">", self.end_time - delta), + ("end_time", "<", self.end_time + delta), + ("task_type_id", "=", added_shift.task_type_id.id), + ], + limit=1, + ) + + if len(non_assigned_shifts): + actual_shift = non_assigned_shifts[0] + else: + actual_shift = self.env["shift.shift"].create( + { + "name": _("%s (added)" % self.name), + "task_type_id": added_shift.task_type_id.id, + "start_time": self.start_time, + "end_time": self.end_time, + } + ) + actual_shift.write( + { + "state": added_shift.state, + "worker_id": added_shift.worker_id.id, + "is_regular": not is_compensation and is_regular_worker, + "is_compensation": is_compensation and is_regular_worker, + } + ) + added_shift.task_id = actual_shift.id + + if actual_shift.state == "done": + self.attended_worker_no += 1 + + self.validated_by = user + self.state = "validated" + return + + def validate_with_checks(self): + self.ensure_one() + + if self.state == "validated": + raise UserError(_("The sheet has already been validated.")) + if self.start_time > datetime.now(): + raise UserError( + _( + "Attendance sheet can only be validated once the shifts " + "have started. " + ) + ) + + # Fields validation + for added_shift in self.added_shift_ids: + if not added_shift.worker_id: + raise UserError(_("Worker name is missing for an added shift.")) + if added_shift.state != "done": + raise UserError( + _("Shift State is missing or wrong for %s") + % added_shift.worker_id.name + ) + if not added_shift.task_type_id: + raise UserError( + _("Task Type is missing for %s") % added_shift.worker_id.name + ) + if not added_shift.working_mode: + raise UserError( + _("Working mode is missing for %s") % added_shift.worker_id.name + ) + if added_shift.working_mode not in ["regular", "irregular"]: + raise UserError( + _("Warning : Working mode for %(name)s is %(working_mode)s") + % { + "name": added_shift.worker_id.name, + "working_mode": added_shift.worker_id.working_mode, + } + ) + + for expected_shift in self.expected_shift_ids: + if not expected_shift.state: + raise UserError( + _("Shift State is missing for %s") % expected_shift.worker_id.name + ) + if expected_shift.state == "absent" and not expected_shift.compensation_no: + raise UserError( + _("Compensation number is missing for %s") + % expected_shift.worker_id.name + ) + + # Open a validation wizard only if not admin + if self.env.user.has_group( + "shift_attendance.group_shift_attendance_sheet_validation" + ): + if not self.worker_nb_feedback: + raise UserError( + _("Please give your feedback about the number of workers.") + ) + self._validate(self.env.user.partner_id) + return + return { + "type": "ir.actions.act_window", + "res_model": "shift.sheet.validate", + "view_type": "form", + "view_mode": "form", + "target": "new", + } + + @api.model + def _generate_attendance_sheet(self): + """ + Generate sheets with shifts in the time interval + defined from corresponding CRON time interval. + """ + tasks = self.env["shift.shift"] + sheets = self.env["shift.sheet"] + current_time = datetime.now() + generation_interval_setting = int( + self.env["ir.config_parameter"] + .sudo() + .get_param("shift_attendance.attendance_sheet_generation_interval") + ) + + allowed_time_range = timedelta(minutes=generation_interval_setting) + + tasks = tasks.search( + [ + ("start_time", ">", str(current_time)), + ("start_time", "<", str(current_time + allowed_time_range)), + ] + ) + + for task in tasks: + start_time = task.start_time + end_time = task.end_time + sheets = sheets.search( + [("start_time", "=", start_time), ("end_time", "=", end_time)] + ) + + if not sheets: + sheets.create({"start_time": start_time, "end_time": end_time}) + + @api.model + def _cron_non_validated_sheets(self): + sheets = self.env["shift.sheet"] + non_validated_sheets = sheets.search( + [ + ("day", "=", date.today() - timedelta(days=1)), + ("state", "=", "not_validated"), + ] + ) + + if non_validated_sheets: + mail_template = self.env.ref( + "shift_attendance.email_template_non_validated_sheet", + False, + ) + for rec in non_validated_sheets: + mail_template.send_mail(rec.id, True) diff --git a/shift_attendance/models/res_config_settings.py b/shift_attendance/models/res_config_settings.py new file mode 100644 index 000000000..b0fb87577 --- /dev/null +++ b/shift_attendance/models/res_config_settings.py @@ -0,0 +1,39 @@ +# Copyright 2019-2020 Elouan Le Bars +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + card_support = fields.Boolean( + string="Scan cooperators cards instead of login for sheets validation", + config_parameter="shift_attendance.card_support", + ) + pre_filled_task_type_id = fields.Many2one( + comodel_name="shift.type", + string="Default Task Type", + help="Default task type for attendance sheet pre-filling", + required=True, + config_parameter="shift_attendance.pre_filled_task_type_id", + default=False, + ) + attendance_sheet_generation_interval = fields.Integer( + string="Time interval for attendance sheet generation", + help="Time interval expressed in minutes", + required=True, + config_parameter=("shift_attendance.attendance_sheet_generation_interval"), + ) + attendance_sheet_default_shift_state = fields.Selection( + [ + ("done", "Present"), + ("absent_0", "Absent - 0 Compensation"), + ("absent_1", "Absent - 1 Compensation"), + ("absent_2", "Absent - 2 Compensations"), + ], + string="Default Shift State", + required=True, + config_parameter=("shift_attendance.attendance_sheet_default_shift_state"), + help="Default state set for shifts on attendance sheets", + ) diff --git a/shift_attendance/readme/CONTRIBUTORS.rst b/shift_attendance/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..5cf09c295 --- /dev/null +++ b/shift_attendance/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* BEES coop - Cellule IT +* Coop IT Easy SC diff --git a/shift_attendance/readme/DESCRIPTION.rst b/shift_attendance/readme/DESCRIPTION.rst new file mode 100644 index 000000000..435cc3b25 --- /dev/null +++ b/shift_attendance/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Volunteer Timetable Management diff --git a/shift_attendance/readme/HISTORY.rst b/shift_attendance/readme/HISTORY.rst new file mode 100644 index 000000000..e2a82f2f1 --- /dev/null +++ b/shift_attendance/readme/HISTORY.rst @@ -0,0 +1,7 @@ +12.0.1.2.0 (2022-12-16) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Repair UI bug where there are two left-hand entries for changing shifts settings + in the settings interface. (`#488 `_) diff --git a/shift_attendance/security/group.xml b/shift_attendance/security/group.xml new file mode 100644 index 000000000..c778db0af --- /dev/null +++ b/shift_attendance/security/group.xml @@ -0,0 +1,15 @@ + + + Attendance Sheet Generic Access + + + + Attendance Sheet Validation + + + + + + + + diff --git a/shift_attendance/security/ir.model.access.csv b/shift_attendance/security/ir.model.access.csv new file mode 100644 index 000000000..d9ce570e7 --- /dev/null +++ b/shift_attendance/security/ir.model.access.csv @@ -0,0 +1,14 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +create_shift_shift,create_edit_shift_shift,shift.model_shift_shift,group_shift_attendance_sheet,1,1,1,0 +read_shift_sheet_shift,read_shift_sheet_shift,model_shift_sheet_shift,group_shift_attendance_sheet,1,0,0,0 +create_shift_sheet_shift,create_shift_sheet_shift,model_shift_sheet_shift,group_shift_attendance_sheet,1,1,1,0 +create_shift_sheet_expected,create_shift_sheet_expected,model_shift_sheet_expected,group_shift_attendance_sheet,1,1,1,0 +manage_shift_sheet_added,manage_shift_sheet_added,model_shift_sheet_added,group_shift_attendance_sheet,1,1,1,1 +create_shift_sheet,create_shift_sheet,model_shift_sheet,group_shift_attendance_sheet,1,1,1,0 +sheet_access_shift_template,sheet_access_shift_template,shift.model_shift_template,group_shift_attendance_sheet,1,0,0,0 +sheet_access_shift_type,sheet_access_shift_type,shift.model_shift_type,,1,0,0,0 +access_shift_daynumber,access_shift_daynumber,shift.model_shift_daynumber,group_shift_attendance_sheet,1,0,0,0 +manage_shift_sheet_shift,shift_sheet_shift,model_shift_sheet_shift,shift.group_shift_attendance,1,1,1,1 +manage_shift_sheet_expected,manage_shift_sheet_expected,model_shift_sheet_expected,shift.group_shift_attendance,1,1,1,1 +read_shift_generate_missing_attendance_sheets,read_shift_generate_missing_attendance_sheets,model_shift_generate_missing_attendance_sheets,base.group_user,1,0,0,0 +read_shift_sheet_validate,read_shift_sheet_validate,model_shift_sheet_validate,base.group_user,1,0,0,0 diff --git a/shift_attendance/static/description/index.html b/shift_attendance/static/description/index.html new file mode 100644 index 000000000..c4e20cf19 --- /dev/null +++ b/shift_attendance/static/description/index.html @@ -0,0 +1,433 @@ + + + + + +Shift Attendance Sheet + + + +
+

Shift Attendance Sheet

+ + +

Beta License: AGPL-3 beescoop/Obeesdoo

+

Volunteer Timetable Management

+

Table of contents

+ +
+

Changelog

+
+

12.0.1.2.0 (2022-12-16)

+

Bugfixes

+
    +
  • Repair UI bug where there are two left-hand entries for changing shifts settings +in the settings interface. (#488)
  • +
+
+
+
+

Bug Tracker

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Elouan Le Bars
  • +
  • Coop IT Easy SC
  • +
+
+
+

Contributors

+
    +
  • BEES coop - Cellule IT
  • +
  • Coop IT Easy SC
  • +
+
+
+

Maintainers

+

This module is part of the beescoop/Obeesdoo project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/shift_attendance/tests/__init__.py b/shift_attendance/tests/__init__.py new file mode 100644 index 000000000..f63e62069 --- /dev/null +++ b/shift_attendance/tests/__init__.py @@ -0,0 +1 @@ +from . import test_shift diff --git a/shift_attendance/tests/test_shift.py b/shift_attendance/tests/test_shift.py new file mode 100644 index 000000000..f1e3fe6b1 --- /dev/null +++ b/shift_attendance/tests/test_shift.py @@ -0,0 +1,330 @@ +# Copyright 2019 - Today Coop IT Easy SC () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import time +from datetime import datetime, timedelta + +from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase + + +class TestShift(TransactionCase): + def setUp(self): + super(TestShift, self).setUp() + self.shift_model = self.env["shift.shift"] + self.shift_template_model = self.env["shift.template"] + self.attendance_sheet_model = self.env["shift.sheet"] + self.attendance_sheet_shift_model = self.env["shift.sheet.shift"] + self.shift_expected_model = self.env["shift.sheet.expected"] + self.shift_added_model = self.env["shift.sheet.added"] + self.pre_filled_task_type_id = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("shift_attendance.pre_filled_task_type_id") + ) + + self.current_time = datetime.now() + self.user_admin = self.env.ref("base.user_root") + self.user_generic = self.env.ref("shift_attendance.shift_user_1_demo") + self.user_permanent = self.env.ref("shift_attendance.shift_user_2_demo") + + self.setting_wizard = self.env["res.config.settings"].with_user(self.user_admin) + + self.worker_regular_1 = self.env.ref("shift.res_partner_worker_6_demo") + self.worker_regular_2 = self.env.ref("shift.res_partner_worker_5_demo") + self.worker_regular_3 = self.env.ref("shift.res_partner_worker_3_demo") + self.worker_regular_super_1 = self.env.ref("shift.res_partner_worker_1_demo") + self.worker_irregular_1 = self.env.ref("shift.res_partner_worker_2_demo") + self.worker_irregular_2 = self.env.ref("shift.res_partner_worker_4_demo") + + self.task_type_1 = self.env.ref("shift.shift_task_type_1_demo") + self.task_type_2 = self.env.ref("shift.shift_task_type_2_demo") + self.task_type_3 = self.env.ref("shift.shift_task_type_3_demo") + + self.task_template_1 = self.env.ref( + "shift_worker_status.shift_task_template_1_demo" + ) + self.task_template_2 = self.env.ref( + "shift_worker_status.shift_task_template_2_demo" + ) + + # Set time in and out of generation interval parameter + self.start_in_1 = self.current_time + timedelta(seconds=2) + self.end_in_1 = self.current_time + timedelta(minutes=10) + self.start_in_2 = self.current_time + timedelta(minutes=9) + self.end_in_2 = self.current_time + timedelta(minutes=21) + self.start_out_1 = self.current_time - timedelta(minutes=50) + self.end_out_1 = self.current_time - timedelta(minutes=20) + self.start_out_2 = self.current_time + timedelta(minutes=40) + self.end_out_2 = self.current_time + timedelta(minutes=50) + + self.shift_regular_regular_1 = self.shift_model.create( + { + "task_template_id": self.task_template_1.id, + "task_type_id": self.task_type_1.id, + "worker_id": self.worker_regular_1.id, + "start_time": self.start_in_1, + "end_time": self.end_in_1, + "is_regular": True, + "is_compensation": False, + } + ) + self.shift_regular_regular_2 = self.shift_model.create( + { + "task_type_id": self.task_type_2.id, + "worker_id": self.worker_regular_2.id, + "start_time": self.start_out_1, + "end_time": self.end_out_1, + "is_regular": True, + "is_compensation": False, + } + ) + self.shift_regular_regular_replaced_1 = self.shift_model.create( + { + "task_template_id": self.task_template_1.id, + "task_type_id": self.task_type_3.id, + "worker_id": self.worker_regular_3.id, + "start_time": self.start_in_1, + "end_time": self.end_in_1, + "is_regular": True, + "is_compensation": False, + "replaced_id": self.worker_regular_2.id, + } + ) + self.future_shift_regular = self.shift_model.create( + { + "task_template_id": self.task_template_2.id, + "task_type_id": self.task_type_1.id, + "worker_id": self.worker_regular_super_1.id, + "start_time": self.start_in_2, + "end_time": self.end_in_2, + "is_regular": False, + "is_compensation": True, + } + ) + self.shift_irregular_1 = self.shift_model.create( + { + "task_template_id": self.task_template_1.id, + "task_type_id": self.task_type_2.id, + "worker_id": self.worker_irregular_1.id, + "start_time": self.start_in_1, + "end_time": self.end_in_1, + } + ) + self.shift_irregular_2 = self.shift_model.create( + { + "task_type_id": self.task_type_3.id, + "worker_id": self.worker_irregular_2.id, + "start_time": self.start_out_2, + "end_time": self.end_out_2, + } + ) + self.shift_empty_1 = self.shift_model.create( + { + "task_template_id": self.task_template_1.id, + "task_type_id": self.task_type_1.id, + "start_time": self.start_in_1, + "end_time": self.end_in_1, + } + ) + + def search_sheets(self, start_time, end_time): + if (type(start_time) and type(end_time)) == datetime: + return self.attendance_sheet_model.search( + [("start_time", "=", start_time), ("end_time", "=", end_time)] + ) + + def test_attendance_sheet_creation(self): + "Test creation of an attendance sheet with all its expected shifts" + + # Set generation interval setting + setting_wizard_1 = self.setting_wizard.create( + { + "pre_filled_task_type_id": self.task_type_1.id, + "attendance_sheet_generation_interval": 15, + "attendance_sheet_default_shift_state": "done", + } + ) + setting_wizard_1.execute() + + # Test attendance sheets creation + self.attendance_sheet_model._generate_attendance_sheet() + + self.assertEqual(len(self.search_sheets(self.start_in_1, self.end_in_1)), 1) + self.assertEqual(len(self.search_sheets(self.start_in_2, self.end_in_2)), 1) + self.assertEqual(len(self.search_sheets(self.start_out_1, self.end_out_1)), 0) + self.assertEqual(len(self.search_sheets(self.start_out_2, self.end_out_2)), 0) + + # Test expected shifts creation + # Sheet 1 starts at current time + 2 secs, ends at current time + 10 min + # Sheet 2 starts at current time + 9 min, ends at current time + 21 min + + sheet_1 = self.search_sheets(self.start_in_1, self.end_in_1) + sheet_2 = self.search_sheets(self.start_in_2, self.end_in_2) + + self.assertTrue(sheet_1.start_time) + self.assertTrue(sheet_1.end_time) + + # Empty shift should not be added + self.assertEqual(len(sheet_1.expected_shift_ids), 3) + self.assertEqual(len(sheet_1.added_shift_ids), 0) + self.assertEqual(len(sheet_2.expected_shift_ids), 1) + + # Test consistency with actual shift for sheet 1 + for shift in sheet_1.expected_shift_ids: + self.assertEqual(shift.worker_id, shift.task_id.worker_id) + self.assertEqual(shift.replaced_id, shift.task_id.replaced_id) + self.assertEqual(shift.task_type_id, shift.task_id.task_type_id) + self.assertEqual(shift.super_coop_id, shift.task_id.super_coop_id) + self.assertEqual(shift.working_mode, shift.task_id.working_mode) + self.assertEqual(shift.state, "done") # cf settings + + # Empty shift should be considered in max worker number calculation + self.assertEqual(sheet_1.max_worker_no, 4) + + # Test default values creation + self.assertTrue(sheet_1.time_slot) + self.assertEqual(sheet_1.day, self.start_in_1.date()) + self.assertEqual(sheet_1.day_abbrevation, "Lundi") + self.assertEqual(sheet_1.week, "Semaine A") + self.assertTrue(sheet_1.name) + self.assertFalse(sheet_1.notes) + self.assertFalse(sheet_1.is_annotated) + + def test_attendance_sheet_barcode_scan(self): + """ + Edition of an attendance sheet + with barcode scanner, as a generic user" + """ + + # Attendance sheet generation + self.attendance_sheet_model.with_user( + self.user_generic + )._generate_attendance_sheet() + sheet_1 = self.search_sheets(self.start_in_1, self.end_in_1) + sheet_1 = sheet_1.with_user(self.user_generic) + + # Expected workers are : + # worker_regular_1 (barcode : 521457731745) + # worker_regular_3 replaced by worker_regular_2 (barcode : 521457731744)) + # worker_irregular_1 (barcode : 529919251493) + + # Scan barcode for expected workers + for barcode in [521457731745, 521457731744, 529919251493]: + sheet_1.on_barcode_scanned(barcode) + + # Check expected shifts update + for id_ in sheet_1.expected_shift_ids.ids: + shift = sheet_1.expected_shift_ids.browse(id_) + self.assertEqual(shift.state, "done") + + # Added workers are : + # worker_regular_super_1 (barcode : 521457731741) + # worker_irregular_2 (barcode : 521457731743) + + # Scan barcode for added workers + sheet_1.on_barcode_scanned(521457731741) + self.assertEqual(len(sheet_1.added_shift_ids), 1) + sheet_1.on_barcode_scanned(521457731743) + # Scan an already added worker should not change anything + sheet_1.on_barcode_scanned(521457731743) + self.assertEqual(len(sheet_1.added_shift_ids), 2) + + # Check added shifts fields + for id_ in sheet_1.added_shift_ids.ids: + shift = sheet_1.added_shift_ids.browse(id_) + self.assertEqual(sheet_1, shift.attendance_sheet_id) + self.assertEqual(shift.state, "done") + self.assertEqual( + shift.task_type_id, + self.attendance_sheet_shift_model.pre_filled_task_type_id(), + ) + if shift.working_mode == "regular": + self.assertTrue(shift.is_compensation) + else: + self.assertFalse(shift.is_compensation) + + # Add a worker that should be replaced + with self.assertRaises(UserError): + sheet_1.on_barcode_scanned(521457731742) + # Wrong barcode + with self.assertRaises(UserError): + sheet_1.on_barcode_scanned(101010) + + # Add an unsubscribed worker + self.worker_regular_1.cooperative_status_ids.sr = -2 + self.worker_regular_1.cooperative_status_ids.sc = -2 + with self.assertRaises(UserError): + sheet_1.on_barcode_scanned(521457731745) + + def test_attendance_sheet_edition(self): + + # Attendance sheet generation + self.attendance_sheet_model.with_user( + self.user_generic + )._generate_attendance_sheet() + sheet_1 = self.search_sheets(self.start_in_1, self.end_in_1) + + # Expected shifts edition + sheet_1.expected_shift_ids[1].state = "done" + sheet_1.expected_shift_ids[2].state = "absent_1" + + # Added shits addition + sheet_1.added_shift_ids |= sheet_1.added_shift_ids.new( + { + "task_type_id": self.task_type_2.id, + "state": "done", + "attendance_sheet_id": sheet_1.id, + "worker_id": self.worker_irregular_2.id, + "is_compensation": False, + } + ) + # Same task type as empty shift (should edit it on validation) + sheet_1.added_shift_ids |= sheet_1.added_shift_ids.new( + { + "task_type_id": self.task_type_1.id, + "state": "done", + "attendance_sheet_id": sheet_1.id, + "worker_id": self.worker_regular_super_1.id, + "is_compensation": True, + } + ) + + # Validation without wizard (as admin user) + sheet_1 = sheet_1.with_user(self.user_admin) + + # Wait necessary time for shifts to begin + waiting_time = (self.start_in_1 - datetime.now()).total_seconds() + if waiting_time > 0: + with self.assertRaises(UserError) as econtext: + sheet_1.validate_with_checks() + self.assertIn("once the shifts have started", str(econtext.exception)) + time.sleep(waiting_time) + + sheet_1.worker_nb_feedback = "enough" + sheet_1.feedback = "Great session." + sheet_1.notes = "Important information." + + sheet_1.validate_with_checks() + + with self.assertRaises(UserError) as econtext: + sheet_1.validate_with_checks() + self.assertIn("already been validated", str(econtext.exception)) + + self.assertEqual(sheet_1.state, "validated") + self.assertEqual(sheet_1.validated_by, self.user_admin.partner_id) + self.assertTrue(sheet_1.is_annotated) + self.assertFalse(sheet_1.is_read) + + # Check actual shifts update + workers = sheet_1.expected_shift_ids.mapped( + "worker_id" + ) | sheet_1.added_shift_ids.mapped("worker_id") + self.assertEqual(len(workers), 5) + for expected_shift in sheet_1.expected_shift_ids: + self.assertEqual(expected_shift.task_id.state, expected_shift.state) + for added_shift in sheet_1.added_shift_ids: + self.assertEqual(added_shift.task_id.state, added_shift.state) + + # Empty shift should have been updated + self.assertEqual(sheet_1.added_shift_ids[0].task_id, self.shift_empty_1) diff --git a/shift_attendance/views/attendance_sheet.xml b/shift_attendance/views/attendance_sheet.xml new file mode 100644 index 000000000..45da1cdf5 --- /dev/null +++ b/shift_attendance/views/attendance_sheet.xml @@ -0,0 +1,329 @@ + + + + + + + Attendance Sheet Search + shift.sheet + + + + + + + + + + + + + + + + + + Expected Shifts List + shift.sheet.expected + + + + + + + + + + + + + + Added Shifts List + shift.sheet.added + + + + + + + + + + + + + Expected Shifts Form + shift.sheet.expected + +
+ + + + + + + +
+
+
+ + + Added Shifts Form + shift.sheet.added + +
+ + + + + + + +
+
+
+ + + + + Attendance Sheet List + shift.sheet + + + + + + + + + + + + + + + + Attendance Sheet Form + shift.sheet + +
+ +
+ +
+ +
+
+ + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + + Non-valiated sheets + shift.sheet + tree,form + [('state','=','not_validated')] + + + + + Unread notes + shift.sheet + tree,form + [('is_annotated','=',True), ('is_read','=',False)] + + + + All sheets + shift.sheet + tree,form + + + + Daily attendance sheets + shift.sheet + tree,form + [('end_time','>', context_today().strftime('%Y-%m-%d 00:00:00')), ('start_time','<', context_today().strftime('%Y-%m-%d 23:59:59'))] + + + + + + + + + + +
diff --git a/shift_attendance/views/res_config_settings_view.xml b/shift_attendance/views/res_config_settings_view.xml new file mode 100644 index 000000000..e2abfcd11 --- /dev/null +++ b/shift_attendance/views/res_config_settings_view.xml @@ -0,0 +1,134 @@ + + + + + + + res.config.settings.view.form.inherit.shift + + res.config.settings + + + + +

Attendance Sheets

+
+
+
+ +
+
+
+
+
+
+
+
+ + Attendance Sheets Generation Interval + +
+ Generate attendance sheets before shifts start. +
+
+
+
+
+
+
+
+
+
+
+ + Default Task Type + +
+ For attendance sheets automatic pre-filling. +
+
+
+
+
+
+
+
+
+
+
+ + Default Shift Attendance Status + +
+ For attendance sheets automatic pre-filling. +
+
+
+
+
+
+
+
+
+
+
+ + + Settings + ir.actions.act_window + res.config.settings + form + inline + {'module' : 'shift'} + + + + +
diff --git a/shift_attendance/wizard/__init__.py b/shift_attendance/wizard/__init__.py new file mode 100644 index 000000000..7b48387d1 --- /dev/null +++ b/shift_attendance/wizard/__init__.py @@ -0,0 +1,2 @@ +from . import generate_missing_attendance_sheets +from . import validate_attendance_sheet diff --git a/shift_attendance/wizard/generate_missing_attendance_sheets.py b/shift_attendance/wizard/generate_missing_attendance_sheets.py new file mode 100644 index 000000000..61be44e17 --- /dev/null +++ b/shift_attendance/wizard/generate_missing_attendance_sheets.py @@ -0,0 +1,57 @@ +from datetime import datetime + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class GenerateMissingAttendanceSheets(models.TransientModel): + """ + Generate missing past sheets + """ + + _name = "shift.generate_missing_attendance_sheets" + _description = "shift.generate_missing_attendance_sheets" + + date_start = fields.Datetime("Start date", required=True) + date_end = fields.Datetime("End date", required=True) + + def generate_missing_attendance_sheets(self): + self.ensure_one() + tasks = self.env["shift.shift"] + sheets = self.env["shift.sheet"] + + tasks = tasks.search( + [ + ("start_time", ">", self.date_start), + ("start_time", "<", self.date_end), + ] + ) + + # We should not loop on task with same start_time and end_time + # To improve performances + for task in tasks: + start_time = task.start_time + end_time = task.end_time + sheet = sheets.search( + [("start_time", "=", start_time), ("end_time", "=", end_time)] + ) + + if not sheet: + sheets |= sheets.create( + {"start_time": start_time, "end_time": end_time} + ) + + return { + "name": _("Generated Missing Sheets"), + "type": "ir.actions.act_window", + "view_type": "form", + "view_mode": "tree,form", + "res_model": "shift.sheet", + "target": "current", + "domain": [("id", "in", sheets.ids)], + } + + @api.constrains("date_start", "date_end") + def constrains_dates(self): + if self.date_start > datetime.now() or self.date_end > datetime.now(): + raise UserError(_("Only past attendance sheets can be generated")) diff --git a/shift_attendance/wizard/generate_missing_attendance_sheets.xml b/shift_attendance/wizard/generate_missing_attendance_sheets.xml new file mode 100644 index 000000000..e86c93349 --- /dev/null +++ b/shift_attendance/wizard/generate_missing_attendance_sheets.xml @@ -0,0 +1,44 @@ + + + + Generate Missing Attendance Sheets + shift.generate_missing_attendance_sheets + +
+ + +
+
+
+
+
+ + + Generate Missing Past Attendance Sheets + shift.generate_missing_attendance_sheets + form + new + + + +
diff --git a/shift_attendance/wizard/validate_attendance_sheet.py b/shift_attendance/wizard/validate_attendance_sheet.py new file mode 100644 index 000000000..a565dc852 --- /dev/null +++ b/shift_attendance/wizard/validate_attendance_sheet.py @@ -0,0 +1,127 @@ +import ast + +from odoo import _, fields, models +from odoo.exceptions import UserError + + +class ValidateAttendanceSheet(models.TransientModel): + _name = "shift.sheet.validate" + _description = """Check the user name and validate sheet. + Useless for users in group_shift_attendance""" + _inherit = ["barcodes.barcode_events_mixin"] + + def _get_active_sheet(self): + sheet_id = self._context.get("active_id") + sheet_model = self._context.get("active_model") + + if sheet_id and sheet_model: + return self.env[sheet_model].browse(sheet_id) + + def _get_card_support_setting(self): + return ast.literal_eval( + self.env["ir.config_parameter"] + .sudo() + .get_param("shift_attendance.card_support") + ) + + def _get_warning_regular_workers(self): + """ + A warning is shown if some regular workers were not expected + but should be doing their regular shifts. This warning is added + to sheet's notes at validation. + """ + sheet = self._get_active_sheet() + + warning_message = "" + if sheet: + for added_shift in sheet.added_shift_ids: + is_regular_worker = added_shift.worker_id.working_mode == "regular" + is_compensation = added_shift.is_compensation + + if is_regular_worker and not is_compensation: + warning_message += ( + _( + "\n%s attended its shift as a normal one but was " + "not expected. Something may be wrong in his/her " + "personal informations.\n " + ) + % added_shift.worker_id.name + ) + return warning_message + + active_sheet = fields.Many2one("shift.sheet", default=_get_active_sheet) + card_support = fields.Boolean( + default=_get_card_support_setting, string="Card validation" + ) + login = fields.Char() + password = fields.Char() + barcode = fields.Char() + warning_regular_workers = fields.Text( + "Warning", + default=_get_warning_regular_workers, + help="Is any regular worker doing its regular shift as an added one ?", + ) + notes = fields.Text( + related="active_sheet.notes", + string="Notes about the attendance for the Members Office", + default="", + readonly=False, + ) + feedback = fields.Text( + related="active_sheet.feedback", + string="Comments about the shift", + default="", + readonly=False, + ) + worker_nb_feedback = fields.Selection( + related="active_sheet.worker_nb_feedback", readonly=False + ) + + def on_barcode_scanned(self, barcode): + self.barcode = barcode + + def save(self): + sheet = self.active_sheet + sheet.notes = self.notes + sheet.feedback = self.feedback + sheet.worker_nb_feedback = self.worker_nb_feedback + + def validate_sheet(self): + sheet = self.active_sheet + + if not self.worker_nb_feedback: + raise UserError(_("Please give your feedback on the number of workers.")) + + if self.card_support: + # Login with barcode + card = self.env["member.card"].search([("barcode", "=", self.barcode)]) + if not len(card): + raise UserError(_("Please set a correct barcode.")) + partner = card[0].partner_id + else: + # Login with credentials + if not self.login: + raise UserError(_("Please enter your login.")) + user = self.env["res.users"].search([("login", "=", self.login)]) + user.with_user(user.id)._check_credentials(self.password) + partner = user.partner_id + + can_validate = partner.user_ids.has_group( + "shift_attendance.group_shift_attendance_sheet_validation" + ) + + if not partner.super and not can_validate: + raise UserError( + _( + "Only super-cooperators and administrators can validate " + "attendance sheets. " + ) + ) + + if self.notes and self.warning_regular_workers: + self.notes += self.warning_regular_workers + elif self.warning_regular_workers: + self.notes = self.warning_regular_workers + + self.save() + sheet._validate(partner or self.env.user.partner_id) diff --git a/shift_attendance/wizard/validate_attendance_sheet.xml b/shift_attendance/wizard/validate_attendance_sheet.xml new file mode 100644 index 000000000..e7a1b1eff --- /dev/null +++ b/shift_attendance/wizard/validate_attendance_sheet.xml @@ -0,0 +1,52 @@ + + + + Validate Attendance Sheet + shift.sheet.validate + +
+ + + + + + + +
+
+
+