Adds x_fclk_nfc_kiosk_location_id (Many2one → fusion.clock.location) to res.company so each company can designate which NFC kiosk location it uses. Two tests cover field assignment and default-false behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests.common import TransactionCase, tagged
|
|
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)
|
|
|
|
|
|
@tagged('-at_install', 'post_install', 'fusion_clock')
|
|
class TestNfcAttendanceFields(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.employee = cls.env['hr.employee'].create({
|
|
'name': 'NFC Test Employee',
|
|
'x_fclk_enable_clock': True,
|
|
})
|
|
|
|
def test_clock_source_includes_nfc_kiosk(self):
|
|
attendance = self.env['hr.attendance'].create({
|
|
'employee_id': self.employee.id,
|
|
'check_in': '2026-05-13 08:00:00',
|
|
'x_fclk_clock_source': 'nfc_kiosk',
|
|
})
|
|
self.assertEqual(attendance.x_fclk_clock_source, 'nfc_kiosk')
|
|
|
|
def test_photo_fields_accept_binary(self):
|
|
# 1x1 transparent PNG as base64
|
|
png_b64 = (
|
|
b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAA'
|
|
b'C0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
|
|
)
|
|
attendance = self.env['hr.attendance'].create({
|
|
'employee_id': self.employee.id,
|
|
'check_in': '2026-05-13 08:00:00',
|
|
'x_fclk_check_in_photo': png_b64,
|
|
})
|
|
self.assertTrue(attendance.x_fclk_check_in_photo)
|
|
|
|
def test_activity_log_accepts_new_selections(self):
|
|
log = self.env['fusion.clock.activity.log'].create({
|
|
'employee_id': self.employee.id,
|
|
'log_type': 'card_enrollment',
|
|
'source': 'nfc_kiosk',
|
|
'description': 'Test enrollment log',
|
|
})
|
|
self.assertEqual(log.log_type, 'card_enrollment')
|
|
self.assertEqual(log.source, 'nfc_kiosk')
|
|
|
|
log2 = self.env['fusion.clock.activity.log'].create({
|
|
'employee_id': self.employee.id,
|
|
'log_type': 'unknown_card_tap',
|
|
'source': 'nfc_kiosk',
|
|
'description': 'Test unknown card log',
|
|
})
|
|
self.assertEqual(log2.log_type, 'unknown_card_tap')
|
|
|
|
|
|
@tagged('-at_install', 'post_install', 'fusion_clock')
|
|
class TestNfcKioskCompanyField(TransactionCase):
|
|
|
|
def test_company_has_nfc_kiosk_location(self):
|
|
company = self.env.company
|
|
location = self.env['fusion.clock.location'].create({
|
|
'name': 'Plant 1',
|
|
'latitude': 43.65,
|
|
'longitude': -79.38,
|
|
'radius': 100,
|
|
})
|
|
company.x_fclk_nfc_kiosk_location_id = location.id
|
|
self.assertEqual(company.x_fclk_nfc_kiosk_location_id, location)
|
|
|
|
def test_company_field_defaults_to_false(self):
|
|
new_company = self.env['res.company'].create({'name': 'Test Co NFC'})
|
|
self.assertFalse(new_company.x_fclk_nfc_kiosk_location_id)
|