Browse Source

Dec 26: [FIX] Bug Fixed 'hr_biometric_attendance'

pull/254/merge
Cybrosys Technologies 4 months ago
parent
commit
504e75e3d1
  1. 3
      hr_biometric_attendance/__manifest__.py
  2. 5
      hr_biometric_attendance/doc/RELEASE_NOTES.md
  3. 55
      hr_biometric_attendance/models/biometric_device_details.py
  4. 11
      hr_biometric_attendance/models/daily_attendance.py
  5. 4
      hr_biometric_attendance/models/zk_machine_attendance.py
  6. 15
      hr_biometric_attendance/security/ir_rule.xml
  7. 2
      hr_biometric_attendance/views/biometric_device_details_views.xml
  8. 1
      hr_biometric_attendance/views/daily_attendance_views.xml

3
hr_biometric_attendance/__manifest__.py

@ -21,7 +21,7 @@
################################################################################ ################################################################################
{ {
'name': "HR Biometric Device Integration", 'name': "HR Biometric Device Integration",
'version': "15.0.1.0.0", 'version': "15.0.1.1.1",
'summary': "Integrating Zk Biometric Devices With HR Attendance", 'summary': "Integrating Zk Biometric Devices With HR Attendance",
'description': '''This module integrates Odoo with ZK biometric devices, 'description': '''This module integrates Odoo with ZK biometric devices,
incorporating features such as live capturing and user management''', incorporating features such as live capturing and user management''',
@ -33,6 +33,7 @@
'depends': ['base_setup', 'hr_attendance', 'web'], 'depends': ['base_setup', 'hr_attendance', 'web'],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/ir_rule.xml',
'data/ir_cron_data.xml', 'data/ir_cron_data.xml',
'data/ir_action_data.xml', 'data/ir_action_data.xml',
'wizards/user_management_views.xml', 'wizards/user_management_views.xml',

5
hr_biometric_attendance/doc/RELEASE_NOTES.md

@ -4,3 +4,8 @@
#### Version 15.0.1.0.0 #### Version 15.0.1.0.0
#### ADD #### ADD
- Initial commit for HR Biometric Device Integration - Initial commit for HR Biometric Device Integration
#### 20.12.2024
#### Version 15.0.1.1.1
#### ADD
- Verified Password before test connection, and set up multi company rules.

55
hr_biometric_attendance/models/biometric_device_details.py

@ -57,9 +57,8 @@ class BiometricDeviceDetails(models.Model):
"from the device", "from the device",
readonly=True) readonly=True)
company_id = fields.Many2one('res.company', string='Company', company_id = fields.Many2one('res.company', string='Company',
default=lambda help="Name of the Company",
self: self.env.user.company_id.id, default=lambda self: self.env.company)
help='Current Company')
stopwatch_time = fields.Float('Stopwatch timer', stopwatch_time = fields.Float('Stopwatch timer',
help='Time from Live capture enabled') help='Time from Live capture enabled')
device_name = fields.Char(String='Device Name', readonly=True, device_name = fields.Char(String='Device Name', readonly=True,
@ -75,6 +74,8 @@ class BiometricDeviceDetails(models.Model):
live_capture_start_time = fields.Datetime('Live Capture Time', live_capture_start_time = fields.Datetime('Live Capture Time',
help='The Time When Live ' help='The Time When Live '
'Capture Enabled') 'Capture Enabled')
device_password = fields.Integer(string='Password',
help='Enter the device password')
def device_connect(self, zk): def device_connect(self, zk):
"""Function for connecting the device with Odoo""" """Function for connecting the device with Odoo"""
@ -87,7 +88,7 @@ class BiometricDeviceDetails(models.Model):
def action_test_connection(self): def action_test_connection(self):
"""Checking the connection status""" """Checking the connection status"""
zk = ZK(self.device_ip, port=self.port_number, timeout=30, zk = ZK(self.device_ip, port=self.port_number, timeout=30,
password=False, ommit_ping=False) password=self.device_password, ommit_ping=False)
try: try:
if zk.connect(): if zk.connect():
zk.test_voice(index=0) zk.test_voice(index=0)
@ -114,7 +115,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device # Connecting with the device
zk = ZK(machine_ip, port=zk_port, timeout=30, zk = ZK(machine_ip, port=zk_port, timeout=30,
password=0, force_udp=False, ommit_ping=False) password=self.device_password, force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError(_( raise UserError(_(
"Please install it with 'pip3 install pyzk'.")) "Please install it with 'pip3 install pyzk'."))
@ -156,7 +157,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -183,7 +184,8 @@ class BiometricDeviceDetails(models.Model):
base64_data = base64.b64encode(binary_data).decode( base64_data = base64.b64encode(binary_data).decode(
'utf-8') 'utf-8')
employee = self.env['hr.employee'].search( employee = self.env['hr.employee'].search(
[('device_id_num', '=', use.user_id)]) [('device_id_num', '=', use.user_id),
('company_id', '=', self.env.company.id)])
employee.write({ employee.write({
'device_id': self.id, 'device_id': self.id,
}) })
@ -216,11 +218,13 @@ class BiometricDeviceDetails(models.Model):
for uid in user: for uid in user:
if uid.user_id == each.user_id: if uid.user_id == each.user_id:
get_user_id = self.env['hr.employee'].search( get_user_id = self.env['hr.employee'].search(
[('device_id_num', '=', each.user_id)]) [('device_id_num', '=', each.user_id),
('company_id', '=', self.env.company.id)])
if get_user_id: if get_user_id:
duplicate_atten_ids = zk_attendance.search( duplicate_atten_ids = zk_attendance.search(
[('device_id_num', '=', each.user_id), [('device_id_num', '=', each.user_id),
('punching_time', '=', atten_time)]) ('punching_time', '=', atten_time),
('company_id', '=', self.env.company.id)])
if not duplicate_atten_ids: if not duplicate_atten_ids:
zk_attendance.create({ zk_attendance.create({
'employee_id': get_user_id.id, 'employee_id': get_user_id.id,
@ -228,7 +232,8 @@ class BiometricDeviceDetails(models.Model):
'attendance_type': str(each.status), 'attendance_type': str(each.status),
'punch_type': str(each.punch), 'punch_type': str(each.punch),
'punching_time': atten_time, 'punching_time': atten_time,
'address_id': info.address_id.id 'address_id': info.address_id.id,
'company_id': self.env.company.id
}) })
att_var = hr_attendance.search([( att_var = hr_attendance.search([(
'employee_id', '=', get_user_id.id), 'employee_id', '=', get_user_id.id),
@ -257,7 +262,8 @@ class BiometricDeviceDetails(models.Model):
employee = self.env['hr.employee'].create({ employee = self.env['hr.employee'].create({
'device_id_num': each.user_id, 'device_id_num': each.user_id,
'device_id': self.id, 'device_id': self.id,
'name': uid.name 'name': uid.name,
'company_id': self.env.company.id
}) })
zk_attendance.create({ zk_attendance.create({
'employee_id': employee.id, 'employee_id': employee.id,
@ -265,7 +271,8 @@ class BiometricDeviceDetails(models.Model):
'attendance_type': str(each.status), 'attendance_type': str(each.status),
'punch_type': str(each.punch), 'punch_type': str(each.punch),
'punching_time': atten_time, 'punching_time': atten_time,
'address_id': info.address_id.id 'address_id': info.address_id.id,
'company_id': self.company_id.id
}) })
hr_attendance.create({ hr_attendance.create({
'employee_id': employee.id, 'employee_id': employee.id,
@ -290,7 +297,7 @@ class BiometricDeviceDetails(models.Model):
def action_restart_device(self): def action_restart_device(self):
"""For restarting the device""" """For restarting the device"""
zk = ZK(self.device_ip, port=self.port_number, timeout=15, zk = ZK(self.device_ip, port=self.port_number, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
if self.device_connect(zk): if self.device_connect(zk):
if self.is_live_capture: if self.is_live_capture:
@ -324,10 +331,11 @@ class BiometricDeviceDetails(models.Model):
for info in self: for info in self:
machine_ip = info.device_ip machine_ip = info.device_ip
zk_port = info.port_number zk_port = info.port_number
password = info.device_password
try: try:
self.is_live_capture = True self.is_live_capture = True
self.action_set_timezone() self.action_set_timezone()
instance = ZKBioAttendance(machine_ip, zk_port, info) instance = ZKBioAttendance(machine_ip, zk_port,password, info)
global live_capture_thread global live_capture_thread
live_capture_thread = instance live_capture_thread = instance
live_capture_thread.start() live_capture_thread.start()
@ -362,7 +370,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -397,7 +405,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -433,7 +441,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -479,7 +487,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -514,7 +522,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -553,7 +561,7 @@ class BiometricDeviceDetails(models.Model):
try: try:
# Connecting with the device with the ip and port provided # Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15, zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0, password=self.device_password,
force_udp=False, ommit_ping=False) force_udp=False, ommit_ping=False)
except NameError: except NameError:
raise UserError( raise UserError(
@ -569,8 +577,7 @@ class BiometricDeviceDetails(models.Model):
else: else:
raise UserError(_( raise UserError(_(
"Please Check the Connection")) "Please Check the Connection"))
#
#
class ZKBioAttendance(Thread): class ZKBioAttendance(Thread):
""" """
Represents a thread for capturing live attendance data from a ZKTeco Represents a thread for capturing live attendance data from a ZKTeco
@ -584,7 +591,7 @@ class ZKBioAttendance(Thread):
live attendance data. live attendance data.
""" """
def __init__(self, machine_ip, port_no, record): def __init__(self, machine_ip, port_no,password, record):
"""Function to Initialize the thread""" """Function to Initialize the thread"""
Thread.__init__(self) Thread.__init__(self)
self.machine_ip = machine_ip self.machine_ip = machine_ip
@ -597,7 +604,7 @@ class ZKBioAttendance(Thread):
machine_ip, machine_ip,
port=port_no, port=port_no,
timeout=5, timeout=5,
password=0, password=password,
force_udp=False, force_udp=False,
ommit_ping=False, ommit_ping=False,
) )

11
hr_biometric_attendance/models/daily_attendance.py

@ -45,6 +45,9 @@ class DailyAttendance(models.Model):
help='The Punching Type of attendance') help='The Punching Type of attendance')
punching_time = fields.Datetime(string='Punching Time', punching_time = fields.Datetime(string='Punching Time',
help='Punching time in the device') help='Punching time in the device')
company_id = fields.Many2one('res.company', string='Company',
help="Name of the Company",
default=lambda self: self.env.company)
def init(self): def init(self):
"""Retrieve the data's for attendance report""" """Retrieve the data's for attendance report"""
@ -58,16 +61,18 @@ class DailyAttendance(models.Model):
z.address_id as address_id, z.address_id as address_id,
z.attendance_type as attendance_type, z.attendance_type as attendance_type,
z.punching_time as punching_time, z.punching_time as punching_time,
z.punch_type as punch_type z.punch_type as punch_type,
e.company_id as company_id
from zk_machine_attendance z from zk_machine_attendance z
join hr_employee e on (z.employee_id=e.id) join hr_employee e on (z.employee_id = e.id)
GROUP BY GROUP BY
z.employee_id, z.employee_id,
z.write_date, z.write_date,
z.address_id, z.address_id,
z.attendance_type, z.attendance_type,
z.punch_type, z.punch_type,
z.punching_time z.punching_time,
e.company_id
) )
""" """
self._cr.execute(query) self._cr.execute(query)

4
hr_biometric_attendance/models/zk_machine_attendance.py

@ -50,3 +50,7 @@ class ZkMachineAttendance(models.Model):
help="Punching time in the device") help="Punching time in the device")
address_id = fields.Many2one('res.partner', string='Working Address', address_id = fields.Many2one('res.partner', string='Working Address',
help="Working address of the employee") help="Working address of the employee")
company_id = fields.Many2one('res.company', string='Company',
help="Name of the Company",
default=lambda self: self.env.company)

15
hr_biometric_attendance/security/ir_rule.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="zk_machine_rule_multi_company" model="ir.rule">
<field name="name">ZK Machine Multi-Company Rule</field>
<field name="model_id" ref="model_biometric_device_details"/>
<field name="domain_force">[('company_id', 'in', user.company_ids.ids)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="zk_machine_attendance_multi_company" model="ir.rule">
<field name="name">ZK Machine Daily Attendance Multi-Company Rule</field>
<field name="model_id" ref="model_daily_attendance"/>
<field name="domain_force">[('company_id', 'in', user.company_ids.ids)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
</odoo>

2
hr_biometric_attendance/views/biometric_device_details_views.xml

@ -52,6 +52,8 @@
<field name="device_ip"/> <field name="device_ip"/>
<field name="port_number"/> <field name="port_number"/>
<field name="address_id"/> <field name="address_id"/>
<field name="device_password"/>
<field name="company_id"/>
</group> </group>
<button name="action_test_connection" <button name="action_test_connection"

1
hr_biometric_attendance/views/daily_attendance_views.xml

@ -12,6 +12,7 @@
<field name="attendance_type"/> <field name="attendance_type"/>
<field name="punching_time"/> <field name="punching_time"/>
<field name="address_id"/> <field name="address_id"/>
<field name="company_id"/>
</tree> </tree>
</field> </field>
</record> </record>

Loading…
Cancel
Save