Browse Source

Dec 21: [FIX] Bug Fixed 'hr_biometric_attendance'

pull/309/head
Cybrosys Technologies 4 months ago
parent
commit
93e51ec475
  1. 1
      hr_biometric_attendance/__manifest__.py
  2. 7
      hr_biometric_attendance/doc/RELEASE_NOTES.md
  3. 53
      hr_biometric_attendance/models/biometric_device_details.py
  4. 11
      hr_biometric_attendance/models/daily_attendance.py
  5. 3
      hr_biometric_attendance/models/zk_machine_attendance.py
  6. 15
      hr_biometric_attendance/security/ir_rule.xml
  7. 15
      hr_biometric_attendance/static/description/index.html
  8. 31
      hr_biometric_attendance/views/biometric_device_details_views.xml
  9. 1
      hr_biometric_attendance/views/daily_attendance_views.xml

1
hr_biometric_attendance/__manifest__.py

@ -33,6 +33,7 @@
'depends': ['base_setup', 'hr_attendance', 'web'],
'data': [
'security/ir.model.access.csv',
'security/ir_rule.xml',
'data/ir_cron_data.xml',
'data/ir_action_data.xml',
'wizards/user_management_views.xml',

7
hr_biometric_attendance/doc/RELEASE_NOTES.md

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

53
hr_biometric_attendance/models/biometric_device_details.py

@ -29,6 +29,7 @@ import time
import pytz
from odoo import api, fields, models, registry, _
from odoo.exceptions import UserError, ValidationError
live_capture_thread = None
_logger = logging.getLogger(__name__)
try:
@ -56,9 +57,8 @@ class BiometricDeviceDetails(models.Model):
"from the device",
readonly=True)
company_id = fields.Many2one('res.company', string='Company',
default=lambda
self: self.env.user.company_id.id,
help='Current Company')
help="Name of the Company",
default=lambda self: self.env.company)
stopwatch_time = fields.Float('Stopwatch timer',
help='Time from Live capture enabled')
device_name = fields.Char(String='Device Name', readonly=True,
@ -74,6 +74,10 @@ class BiometricDeviceDetails(models.Model):
live_capture_start_time = fields.Datetime('Live Capture Time',
help='The Time When Live '
'Capture Enabled')
device_password = fields.Integer(string='Password',
help='Enter the device password')
def device_connect(self, zk):
"""Function for connecting the device with Odoo"""
@ -86,7 +90,7 @@ class BiometricDeviceDetails(models.Model):
def action_test_connection(self):
"""Checking the connection status"""
zk = ZK(self.device_ip, port=self.port_number, timeout=30,
password=False, ommit_ping=False)
password=self.device_password, ommit_ping=False)
try:
if zk.connect():
zk.test_voice(index=0)
@ -113,7 +117,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device
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:
raise UserError(_(
"Please install it with 'pip3 install pyzk'."))
@ -155,7 +159,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -182,7 +186,7 @@ class BiometricDeviceDetails(models.Model):
base64_data = base64.b64encode(binary_data).decode(
'utf-8')
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({
'device_id': self.id,
})
@ -215,11 +219,12 @@ class BiometricDeviceDetails(models.Model):
for uid in user:
if uid.user_id == each.user_id:
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:
duplicate_atten_ids = zk_attendance.search(
[('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:
zk_attendance.create({
'employee_id': get_user_id.id,
@ -227,7 +232,8 @@ class BiometricDeviceDetails(models.Model):
'attendance_type': str(each.status),
'punch_type': str(each.punch),
'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([(
'employee_id', '=', get_user_id.id),
@ -256,7 +262,8 @@ class BiometricDeviceDetails(models.Model):
employee = self.env['hr.employee'].create({
'device_id_num': each.user_id,
'device_id': self.id,
'name': uid.name
'name': uid.name,
'company_id': self.company_id.id
})
zk_attendance.create({
'employee_id': employee.id,
@ -264,7 +271,8 @@ class BiometricDeviceDetails(models.Model):
'attendance_type': str(each.status),
'punch_type': str(each.punch),
'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({
'employee_id': employee.id,
@ -289,7 +297,7 @@ class BiometricDeviceDetails(models.Model):
def action_restart_device(self):
"""For restarting the device"""
zk = ZK(self.device_ip, port=self.port_number, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
if self.device_connect(zk):
if self.is_live_capture:
@ -323,10 +331,11 @@ class BiometricDeviceDetails(models.Model):
for info in self:
machine_ip = info.device_ip
zk_port = info.port_number
password = info.device_password
try:
self.is_live_capture = True
self.action_set_timezone()
instance = ZKBioAttendance(machine_ip, zk_port, info)
instance = ZKBioAttendance(machine_ip, zk_port, password, info)
global live_capture_thread
live_capture_thread = instance
live_capture_thread.start()
@ -361,7 +370,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -396,7 +405,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -432,7 +441,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -491,7 +500,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -526,7 +535,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -568,7 +577,7 @@ class BiometricDeviceDetails(models.Model):
try:
# Connecting with the device with the ip and port provided
zk = ZK(machine_ip, port=zk_port, timeout=15,
password=0,
password=self.device_password,
force_udp=False, ommit_ping=False)
except NameError:
raise UserError(
@ -599,7 +608,7 @@ class ZKBioAttendance(Thread):
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"""
Thread.__init__(self)
self.machine_ip = machine_ip
@ -612,7 +621,7 @@ class ZKBioAttendance(Thread):
machine_ip,
port=port_no,
timeout=5,
password=0,
password=password,
force_udp=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')
punching_time = fields.Datetime(string='Punching Time',
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):
"""Retrieve the data's for attendance report"""
@ -58,16 +61,18 @@ class DailyAttendance(models.Model):
z.address_id as address_id,
z.attendance_type as attendance_type,
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
join hr_employee e on (z.employee_id=e.id)
join hr_employee e on (z.employee_id = e.id)
GROUP BY
z.employee_id,
z.write_date,
z.address_id,
z.attendance_type,
z.punch_type,
z.punching_time
z.punching_time,
e.company_id
)
"""
self._cr.execute(query)

3
hr_biometric_attendance/models/zk_machine_attendance.py

@ -50,3 +50,6 @@ class ZkMachineAttendance(models.Model):
help="Punching time in the device")
address_id = fields.Many2one('res.partner', string='Working Address',
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>

15
hr_biometric_attendance/static/description/index.html

@ -899,6 +899,21 @@
</div>
</section>
</div>
<div class="tab-pane w-100">
<section class="oe_container mt48">
<div style="margin-bottom:4%">
<div class="relese-note w-100 pt-3 pb-2 pl-3 mb-4 pr-3 float-left"
style="border:1px solid #ccc; box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75);">
<p><b> Version 17.0.1.1.1<span
style="color:#3363c1; font-size: 14px;"> Released
on : 20th Dec 2024</span></b>
</p>
<p> Verified Password before test connection, and set up multi company rules. </p>
</div>
</div>
</section>
</div>
</div>

31
hr_biometric_attendance/views/biometric_device_details_views.xml

@ -21,7 +21,8 @@
<header>
<button name="action_download_attendance"
string="Download Data"
type="object" class="oe_highlight" invisible="is_live_capture"/>
type="object" class="oe_highlight"
invisible="is_live_capture"/>
<button name="action_clear_attendance" string="Clear Data"
type="object" class="oe_highlight"
invisible="is_live_capture"/>
@ -29,30 +30,37 @@
type="object" class="oe_highlight"
confirm="Are you sure you want Restart the Biometric Device?"/>
<button name="action_live_capture" string="Live Capture"
type="object" class="oe_highlight" invisible="is_live_capture == True"/>
<button name="action_stop_live_capture" string=" Stop Live Capture"
type="object" class="btn btn-secondary" invisible="is_live_capture == False"/>
type="object" class="oe_highlight"
invisible="is_live_capture == True"/>
<button name="action_stop_live_capture"
string=" Stop Live Capture"
type="object" class="btn btn-secondary"
invisible="is_live_capture == False"/>
<button name="action_set_timezone" string=" Set Time"
type="object" class="oe_highlight"/>
<button name="%(hr_biometric_attendance.action_view_zk_user_management)d" string="User Management"
<button name="%(hr_biometric_attendance.action_view_zk_user_management)d"
string="User Management"
type="action" class="oe_highlight"/>
</header>
<sheet>
<div>
<label for="is_live_capture" name="is_live_capture" string="Live Capture"/>
<field name="is_live_capture" widget="boolean_toggle" string="Live Capture"/>
<field name="stopwatch_time" widget="stopwatch" readonly="True"
<label for="is_live_capture" name="is_live_capture"
string="Live Capture"/>
<field name="is_live_capture" widget="boolean_toggle"
string="Live Capture"/>
<field name="stopwatch_time" widget="stopwatch"
readonly="True"
style="font-size: 15px; font-weight: 600;font-family: monospace;"
invisible="not is_live_capture"/>
<field name="live_capture_start_time" invisible="1"/>
</div>
<group>
<field name="name"/>
<field name="device_ip"/>
<field name="port_number"/>
<field name="address_id"/>
<field name="device_password"/>
<field name="company_id"/>
</group>
<button name="action_test_connection"
type="object" class="btn btn-secondary">
@ -72,7 +80,8 @@
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" groups="base.group_user"/>
<field name="message_follower_ids"
groups="base.group_user"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>

1
hr_biometric_attendance/views/daily_attendance_views.xml

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

Loading…
Cancel
Save