feat(fusion_clock): add x_fclk_nfc_card_uid to hr.employee
Adds the NFC card UID field (Char, unique, manager-only) that the kiosk will use to identify employees by card tap. Includes the tests package with three post-install tests covering write, uniqueness, and nullable multi-row behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,25 @@ class HrEmployee(models.Model):
|
|||||||
groups="fusion_clock.group_fusion_clock_manager",
|
groups="fusion_clock.group_fusion_clock_manager",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# NFC card (kiosk identification)
|
||||||
|
x_fclk_nfc_card_uid = fields.Char(
|
||||||
|
string='NFC Card UID',
|
||||||
|
index=True,
|
||||||
|
copy=False,
|
||||||
|
groups="fusion_clock.group_fusion_clock_manager",
|
||||||
|
help="Hex UID of the NFC card assigned to this employee. "
|
||||||
|
"Format: uppercase, colon-separated, e.g. 04:A2:B5:62:C1:80. "
|
||||||
|
"Same card the employee uses for door access.",
|
||||||
|
)
|
||||||
|
|
||||||
|
_sql_constraints = [
|
||||||
|
(
|
||||||
|
'fclk_nfc_card_uid_unique',
|
||||||
|
'UNIQUE(x_fclk_nfc_card_uid)',
|
||||||
|
'This NFC card is already assigned to another employee.',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
# On-time streak
|
# On-time streak
|
||||||
x_fclk_ontime_streak = fields.Integer(
|
x_fclk_ontime_streak = fields.Integer(
|
||||||
string='On-Time Streak',
|
string='On-Time Streak',
|
||||||
|
|||||||
3
fusion_clock/tests/__init__.py
Normal file
3
fusion_clock/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import test_nfc_models
|
||||||
34
fusion_clock/tests/test_nfc_models.py
Normal file
34
fusion_clock/tests/test_nfc_models.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo.tests.common import TransactionCase, tagged
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from psycopg2 import IntegrityError
|
||||||
|
from odoo.tools.misc import mute_logger
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('-at_install', 'post_install', 'fusion_clock')
|
||||||
|
class TestNfcModels(TransactionCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.Employee = cls.env['hr.employee']
|
||||||
|
cls.alice = cls.Employee.create({'name': 'Alice NFC', 'x_fclk_enable_clock': True})
|
||||||
|
cls.bob = cls.Employee.create({'name': 'Bob NFC', 'x_fclk_enable_clock': True})
|
||||||
|
|
||||||
|
def test_card_uid_is_writable(self):
|
||||||
|
self.alice.x_fclk_nfc_card_uid = '04:A2:B5:62:C1:80'
|
||||||
|
self.assertEqual(self.alice.x_fclk_nfc_card_uid, '04:A2:B5:62:C1:80')
|
||||||
|
|
||||||
|
def test_card_uid_is_unique_when_set(self):
|
||||||
|
self.alice.x_fclk_nfc_card_uid = '04:A2:B5:62:C1:80'
|
||||||
|
with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'):
|
||||||
|
with self.env.cr.savepoint():
|
||||||
|
self.bob.x_fclk_nfc_card_uid = '04:A2:B5:62:C1:80'
|
||||||
|
self.bob.flush_recordset(['x_fclk_nfc_card_uid'])
|
||||||
|
|
||||||
|
def test_card_uid_can_be_null_for_multiple_employees(self):
|
||||||
|
self.alice.x_fclk_nfc_card_uid = False
|
||||||
|
self.bob.x_fclk_nfc_card_uid = False
|
||||||
|
self.assertFalse(self.alice.x_fclk_nfc_card_uid)
|
||||||
|
self.assertFalse(self.bob.x_fclk_nfc_card_uid)
|
||||||
Reference in New Issue
Block a user