diff --git a/hr_attendance_rfid/README.rst b/hr_attendance_rfid/README.rst new file mode 100644 index 00000000..12407bef --- /dev/null +++ b/hr_attendance_rfid/README.rst @@ -0,0 +1,118 @@ +================== +HR Attendance RFID +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ba61dae08726a27391dce81b89daadfbfa0e51538f59faf7820d0cd8016b981d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr--attendance-lightgray.png?logo=github + :target: https://github.com/OCA/hr-attendance/tree/17.0/hr_attendance_rfid + :alt: OCA/hr-attendance +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-attendance-17-0/hr-attendance-17-0-hr_attendance_rfid + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr-attendance&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of HR Attendance in order to allow +the logging of employee attendances using an RFID based employee +attendance system. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To use this module, you need to use an external system that calls the +method 'register_attendance' of the model 'hr.employee' passing as +parameter the code of the RFID card. + +Developers of a compatible RFID based employee attendance system should +be familiar with the outputs of this method and implement proper calls +and management of responses. + +It is advisory to create an exclusive user to perform this task. As user +doesn't need several access, it is just essential to perform the check +in/out, a group has been created. Add your attendance device user to +RFID Attendance group. + +Usage +===== + +1. The HR employee responsible to set up new employees should go to + 'Attendances -> Manage Attendances -> Employees' and register the + RFID card code of each of your employees. You can use an USB plugged + RFID reader connected to your computer for this purpose. +2. The employee should put his/her card to the RFID based employee + attendance system. It is expected that the system will provide some + form of output of the registration event. + +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 +------- + +* Comunitea +* ForgeFlow + +Contributors +------------ + +- Omar Catiñeira Saavedra + +- Héctor Villarreal Ortega + +- Jordi Ballester Alomar + +- Brian McMaster + +- `Tecnativa `__: + + - Víctor Martínez + +- Juany Davila + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/hr-attendance `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_attendance_rfid/__init__.py b/hr_attendance_rfid/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/hr_attendance_rfid/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_attendance_rfid/__manifest__.py b/hr_attendance_rfid/__manifest__.py new file mode 100644 index 00000000..2bb58690 --- /dev/null +++ b/hr_attendance_rfid/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2017 Comunitea Servicios Tecnológicos S.L. +# Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +{ + "name": "HR Attendance RFID", + "version": "17.0.1.0.0", + "category": "Human Resources", + "website": "https://github.com/OCA/hr-attendance", + "author": "Comunitea, ForgeFlow, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": ["hr_attendance"], + "data": [ + "security/hr_attendance_rfid.xml", + "security/ir.model.access.csv", + "data/ir_rule.xml", + "views/hr_employee_view.xml", + ], +} diff --git a/hr_attendance_rfid/data/ir_rule.xml b/hr_attendance_rfid/data/ir_rule.xml new file mode 100644 index 00000000..4a4b9365 --- /dev/null +++ b/hr_attendance_rfid/data/ir_rule.xml @@ -0,0 +1,16 @@ + + + RFID Attendance Rule + + + [(1, '=', 1)] + + + + + + + diff --git a/hr_attendance_rfid/i18n/es.po b/hr_attendance_rfid/i18n/es.po new file mode 100644 index 00000000..f61c80bc --- /dev/null +++ b/hr_attendance_rfid/i18n/es.po @@ -0,0 +1,62 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_attendance_rfid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-15 17:37+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "Attendance recorded for employee %s" +msgstr "Asistencia registrada para el empleado %s" + +#. module: hr_attendance_rfid +#: model:ir.model,name:hr_attendance_rfid.model_hr_employee_base +msgid "Basic Employee" +msgstr "Empleado básico" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No attendance was recorded for employee %s" +msgstr "No se registró asistencia para el empleado %s" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No employee found with card %s" +msgstr "No se encontró ningún empleado con la tarjeta %s" + +#. module: hr_attendance_rfid +#: model:res.groups,name:hr_attendance_rfid.group_hr_attendance_rfid +msgid "RFID Attendance" +msgstr "Asistencia RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_base__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_public__rfid_card_code +msgid "RFID Card Code" +msgstr "Código de Tarjeta RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_base_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_public_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_rfid_card_code_uniq +msgid "The rfid code should be unique." +msgstr "El código de la tarjeta RFID debe ser único." diff --git a/hr_attendance_rfid/i18n/es_ES.po b/hr_attendance_rfid/i18n/es_ES.po new file mode 100644 index 00000000..71dac2d0 --- /dev/null +++ b/hr_attendance_rfid/i18n/es_ES.po @@ -0,0 +1,60 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_attendance_rfid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "Attendance recorded for employee %s" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model,name:hr_attendance_rfid.model_hr_employee_base +msgid "Basic Employee" +msgstr "" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No attendance was recorded for employee %s" +msgstr "" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No employee found with card %s" +msgstr "" + +#. module: hr_attendance_rfid +#: model:res.groups,name:hr_attendance_rfid.group_hr_attendance_rfid +msgid "RFID Attendance" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_base__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_public__rfid_card_code +msgid "RFID Card Code" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_base_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_public_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_rfid_card_code_uniq +msgid "The rfid code should be unique." +msgstr "" diff --git a/hr_attendance_rfid/i18n/fr.po b/hr_attendance_rfid/i18n/fr.po new file mode 100644 index 00000000..6b40d81e --- /dev/null +++ b/hr_attendance_rfid/i18n/fr.po @@ -0,0 +1,62 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_attendance_rfid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-05-23 20:19+0000\n" +"Last-Translator: Kévin Allard \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.6.1\n" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "Attendance recorded for employee %s" +msgstr "Présence enregistrée pour l'employé(e) %s" + +#. module: hr_attendance_rfid +#: model:ir.model,name:hr_attendance_rfid.model_hr_employee_base +msgid "Basic Employee" +msgstr "" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No attendance was recorded for employee %s" +msgstr "Aucune présence n'a été enregistrée pour l'employé(e) %s" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No employee found with card %s" +msgstr "Aucun employé(e) trouvé avec la carte %s" + +#. module: hr_attendance_rfid +#: model:res.groups,name:hr_attendance_rfid.group_hr_attendance_rfid +msgid "RFID Attendance" +msgstr "Présence RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_base__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_public__rfid_card_code +msgid "RFID Card Code" +msgstr "Code de carte RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_base_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_public_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_rfid_card_code_uniq +msgid "The rfid code should be unique." +msgstr "Le code rfid doit être unique." diff --git a/hr_attendance_rfid/i18n/hr_attendance_rfid.pot b/hr_attendance_rfid/i18n/hr_attendance_rfid.pot new file mode 100644 index 00000000..a60aa209 --- /dev/null +++ b/hr_attendance_rfid/i18n/hr_attendance_rfid.pot @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_attendance_rfid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "Attendance recorded for employee %s" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model,name:hr_attendance_rfid.model_hr_employee_base +msgid "Basic Employee" +msgstr "" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No attendance was recorded for employee %s" +msgstr "" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No employee found with card %s" +msgstr "" + +#. module: hr_attendance_rfid +#: model:res.groups,name:hr_attendance_rfid.group_hr_attendance_rfid +msgid "RFID Attendance" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_base__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_public__rfid_card_code +msgid "RFID Card Code" +msgstr "" + +#. module: hr_attendance_rfid +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_base_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_public_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_rfid_card_code_uniq +msgid "The rfid code should be unique." +msgstr "" diff --git a/hr_attendance_rfid/i18n/it.po b/hr_attendance_rfid/i18n/it.po new file mode 100644 index 00000000..cf453db6 --- /dev/null +++ b/hr_attendance_rfid/i18n/it.po @@ -0,0 +1,62 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_attendance_rfid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-07-04 15:09+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "Attendance recorded for employee %s" +msgstr "Presenza registrata per il dipendente %s" + +#. module: hr_attendance_rfid +#: model:ir.model,name:hr_attendance_rfid.model_hr_employee_base +msgid "Basic Employee" +msgstr "Dipendente base" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No attendance was recorded for employee %s" +msgstr "Nessuna presenza registrata per il dipendente %s" + +#. module: hr_attendance_rfid +#. odoo-python +#: code:addons/hr_attendance_rfid/models/hr_employee.py:0 +#, python-format +msgid "No employee found with card %s" +msgstr "Nessun dipendete trovato con tesserino %s" + +#. module: hr_attendance_rfid +#: model:res.groups,name:hr_attendance_rfid.group_hr_attendance_rfid +msgid "RFID Attendance" +msgstr "Presenza RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_base__rfid_card_code +#: model:ir.model.fields,field_description:hr_attendance_rfid.field_hr_employee_public__rfid_card_code +msgid "RFID Card Code" +msgstr "Codice tesserino RFID" + +#. module: hr_attendance_rfid +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_base_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_public_rfid_card_code_uniq +#: model:ir.model.constraint,message:hr_attendance_rfid.constraint_hr_employee_rfid_card_code_uniq +msgid "The rfid code should be unique." +msgstr "Il codice RFID deve essere univoco." diff --git a/hr_attendance_rfid/models/__init__.py b/hr_attendance_rfid/models/__init__.py new file mode 100644 index 00000000..e11a62f9 --- /dev/null +++ b/hr_attendance_rfid/models/__init__.py @@ -0,0 +1 @@ +from . import hr_employee diff --git a/hr_attendance_rfid/models/hr_employee.py b/hr_attendance_rfid/models/hr_employee.py new file mode 100644 index 00000000..e046a0b6 --- /dev/null +++ b/hr_attendance_rfid/models/hr_employee.py @@ -0,0 +1,76 @@ +# Copyright 2017 Comunitea Servicios Tecnológicos S.L. +# Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com) +# Copyright 2020 Tecnativa - Víctor Martínez +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +import logging + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class HrEmployeeBase(models.AbstractModel): + _inherit = "hr.employee.base" + _sql_constraints = [ + ( + "rfid_card_code_uniq", + "UNIQUE(rfid_card_code)", + "The rfid code should be unique.", + ) + ] + + rfid_card_code = fields.Char("RFID Card Code", copy=False) + + @api.model + def register_attendance(self, card_code): + """Register the attendance of the employee. + :returns: dictionary + 'rfid_card_code': char + 'employee_name': char + 'employee_id': int + 'error_message': char + 'logged': boolean + 'action': check_in/check_out + """ + + res = { + "rfid_card_code": card_code, + "employee_name": "", + "employee_id": False, + "error_message": "", + "logged": False, + "action": "FALSE", + } + # We need to apply sudo() because a RFID basic user does not have access to + # hr.employee. Hr.employee.public model does not have the + # _attendance_action_change() method that will be used later. + employee = self.sudo().search([("rfid_card_code", "=", card_code)], limit=1) + if employee: + res["employee_name"] = employee.name + res["employee_id"] = employee.id + else: + msg = _("No employee found with card %s") % card_code + _logger.warning(msg) + res["error_message"] = msg + return res + try: + attendance = employee._attendance_action_change() + if attendance: + msg = _("Attendance recorded for employee %s") % employee.name + _logger.debug(msg) + res["logged"] = True + if attendance.check_out: + res["action"] = "check_out" + else: + res["action"] = "check_in" + return res + else: + msg = _("No attendance was recorded for employee %s") % employee.name + _logger.error(msg) + res["error_message"] = msg + return res + except Exception as e: + res["error_message"] = repr(e) + _logger.error(repr(e)) + return res diff --git a/hr_attendance_rfid/pyproject.toml b/hr_attendance_rfid/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/hr_attendance_rfid/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_attendance_rfid/readme/CONFIGURE.md b/hr_attendance_rfid/readme/CONFIGURE.md new file mode 100644 index 00000000..8ab65e88 --- /dev/null +++ b/hr_attendance_rfid/readme/CONFIGURE.md @@ -0,0 +1,12 @@ +To use this module, you need to use an external system that calls the +method 'register_attendance' of the model 'hr.employee' passing as +parameter the code of the RFID card. + +Developers of a compatible RFID based employee attendance system should +be familiar with the outputs of this method and implement proper calls +and management of responses. + +It is advisory to create an exclusive user to perform this task. As user +doesn't need several access, it is just essential to perform the check +in/out, a group has been created. Add your attendance device user to +RFID Attendance group. diff --git a/hr_attendance_rfid/readme/CONTRIBUTORS.md b/hr_attendance_rfid/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..178e1b97 --- /dev/null +++ b/hr_attendance_rfid/readme/CONTRIBUTORS.md @@ -0,0 +1,13 @@ +- Omar Catiñeira Saavedra \<\> + +- Héctor Villarreal Ortega \<\> + +- Jordi Ballester Alomar \<\> + +- Brian McMaster \<\> + +- [Tecnativa](https://www.tecnativa.com): + + > - Víctor Martínez + +- Juany Davila \<\> diff --git a/hr_attendance_rfid/readme/DESCRIPTION.md b/hr_attendance_rfid/readme/DESCRIPTION.md new file mode 100644 index 00000000..9478cda7 --- /dev/null +++ b/hr_attendance_rfid/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module extends the functionality of HR Attendance in order to allow +the logging of employee attendances using an RFID based employee +attendance system. diff --git a/hr_attendance_rfid/readme/USAGE.md b/hr_attendance_rfid/readme/USAGE.md new file mode 100644 index 00000000..e3a8a164 --- /dev/null +++ b/hr_attendance_rfid/readme/USAGE.md @@ -0,0 +1,7 @@ +1. The HR employee responsible to set up new employees should go to + 'Attendances -\> Manage Attendances -\> Employees' and register the + RFID card code of each of your employees. You can use an USB plugged + RFID reader connected to your computer for this purpose. +2. The employee should put his/her card to the RFID based employee + attendance system. It is expected that the system will provide some + form of output of the registration event. diff --git a/hr_attendance_rfid/security/hr_attendance_rfid.xml b/hr_attendance_rfid/security/hr_attendance_rfid.xml new file mode 100644 index 00000000..8b0b2e69 --- /dev/null +++ b/hr_attendance_rfid/security/hr_attendance_rfid.xml @@ -0,0 +1,7 @@ + + + + RFID Attendance + + + diff --git a/hr_attendance_rfid/security/ir.model.access.csv b/hr_attendance_rfid/security/ir.model.access.csv new file mode 100644 index 00000000..1ddc7a90 --- /dev/null +++ b/hr_attendance_rfid/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_hr_attendance_rfid,access.hr.attendance.rfid,hr_attendance.model_hr_attendance,hr_attendance_rfid.group_hr_attendance_rfid,1,1,1,0 +access_hr_employee_rfid,access.hr.employee.rfid,hr.model_hr_employee,hr_attendance_rfid.group_hr_attendance_rfid,1,0,0,0 +access_hr_employee_public_rfid,access.hr.employee.rfid,hr.model_hr_employee_public,hr_attendance_rfid.group_hr_attendance_rfid,1,0,0,0 +access_resources_resource_rfid,access.resource.resource.rfid,resource.model_resource_resource,hr_attendance_rfid.group_hr_attendance_rfid,1,0,0,0 diff --git a/hr_attendance_rfid/static/description/icon.png b/hr_attendance_rfid/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/hr_attendance_rfid/static/description/icon.png differ diff --git a/hr_attendance_rfid/static/description/index.html b/hr_attendance_rfid/static/description/index.html new file mode 100644 index 00000000..a30f085b --- /dev/null +++ b/hr_attendance_rfid/static/description/index.html @@ -0,0 +1,466 @@ + + + + + +HR Attendance RFID + + + +
+

HR Attendance RFID

+ + +

Beta License: AGPL-3 OCA/hr-attendance Translate me on Weblate Try me on Runboat

+

This module extends the functionality of HR Attendance in order to allow +the logging of employee attendances using an RFID based employee +attendance system.

+

Table of contents

+ +
+

Configuration

+

To use this module, you need to use an external system that calls the +method ‘register_attendance’ of the model ‘hr.employee’ passing as +parameter the code of the RFID card.

+

Developers of a compatible RFID based employee attendance system should +be familiar with the outputs of this method and implement proper calls +and management of responses.

+

It is advisory to create an exclusive user to perform this task. As user +doesn’t need several access, it is just essential to perform the check +in/out, a group has been created. Add your attendance device user to +RFID Attendance group.

+
+
+

Usage

+
    +
  1. The HR employee responsible to set up new employees should go to +‘Attendances -> Manage Attendances -> Employees’ and register the +RFID card code of each of your employees. You can use an USB plugged +RFID reader connected to your computer for this purpose.
  2. +
  3. The employee should put his/her card to the RFID based employee +attendance system. It is expected that the system will provide some +form of output of the registration event.
  4. +
+
+
+

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

+
    +
  • Comunitea
  • +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

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

+

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

+
+
+
+ + diff --git a/hr_attendance_rfid/tests/__init__.py b/hr_attendance_rfid/tests/__init__.py new file mode 100644 index 00000000..b0903706 --- /dev/null +++ b/hr_attendance_rfid/tests/__init__.py @@ -0,0 +1 @@ +from . import test_hr_attendance_rfid_process diff --git a/hr_attendance_rfid/tests/test_hr_attendance_rfid_process.py b/hr_attendance_rfid/tests/test_hr_attendance_rfid_process.py new file mode 100644 index 00000000..9041cc78 --- /dev/null +++ b/hr_attendance_rfid/tests/test_hr_attendance_rfid_process.py @@ -0,0 +1,86 @@ +# Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com) +# Copyright 2023 Tecnativa - Víctor Martínez +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +from datetime import datetime, timedelta +from unittest.mock import patch + +from odoo import fields +from odoo.tests import new_test_user +from odoo.tests.common import TransactionCase, users +from odoo.tools.misc import mute_logger + +from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT + + +class TestHrAttendance(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT)) + user = new_test_user( + cls.env, + login="hr_attendance_rfid-user", + groups="hr_attendance_rfid.group_hr_attendance_rfid,base.group_user", + ) + cls.rfid_card_code = "5b3f5" + cls.env["hr.employee"].create( + {"user_id": user.id, "rfid_card_code": cls.rfid_card_code} + ) + cls.employee_model = cls.env["hr.employee"] + + @users("hr_attendance_rfid-user") + def test_valid_employee(self): + """Valid employee""" + self.employee_model = self.employee_model.with_user(self.env.user) + res = self.employee_model.register_attendance(self.rfid_card_code) + self.assertTrue("action" in res and res["action"] == "check_in") + self.assertTrue("logged" in res and res["logged"]) + self.assertTrue( + "rfid_card_code" in res and res["rfid_card_code"] == self.rfid_card_code + ) + res = self.employee_model.register_attendance(self.rfid_card_code) + self.assertTrue("action" in res and res["action"] == "check_out") + self.assertTrue("logged" in res and res["logged"]) + + @users("hr_attendance_rfid-user") + @mute_logger("odoo.addons.hr_attendance_rfid.models.hr_employee") + def test_exception_code(self): + """Checkout is created for a future datetime""" + self.employee_model = self.employee_model.with_user(self.env.user) + employee = self.env.user.employee_id + self.env["hr.attendance"].create( + { + "employee_id": employee.id, + "check_in": fields.Date.today(), + "check_out": fields.Datetime.to_string( + datetime.today() + timedelta(hours=8) + ), + } + ) + employee.update({"attendance_state": "checked_in"}) + res = self.employee_model.register_attendance(self.rfid_card_code) + self.assertNotEqual(res["error_message"], "") + + @users("hr_attendance_rfid-user") + def test_invalid_code(self): + """Invalid employee""" + self.employee_model = self.employee_model.with_user(self.env.user) + invalid_code = "029238d" + res = self.employee_model.register_attendance(invalid_code) + self.assertTrue("action" in res and res["action"] == "FALSE") + self.assertTrue("logged" in res and not res["logged"]) + self.assertTrue( + "rfid_card_code" in res and res["rfid_card_code"] == invalid_code + ) + + @users("hr_attendance_rfid-user") + @mute_logger("odoo.addons.hr_attendance_rfid.models.hr_employee") + def test_no_attendance_recorded(self): + """No record found to record the attendance""" + self.employee_model = self.employee_model.with_user(self.env.user) + with patch( + "odoo.addons.hr_attendance.models.hr_employee.HrEmployee._attendance_action_change" + ) as attendance_action_change_returns_none: + attendance_action_change_returns_none.return_value = None + res = self.employee_model.register_attendance(self.rfid_card_code) + self.assertNotEqual(res["error_message"], "") diff --git a/hr_attendance_rfid/views/hr_employee_view.xml b/hr_attendance_rfid/views/hr_employee_view.xml new file mode 100644 index 00000000..796f346f --- /dev/null +++ b/hr_attendance_rfid/views/hr_employee_view.xml @@ -0,0 +1,19 @@ + + + + hr.employee.form.add_rfid + hr.employee + + + + + + + +