Browse Source

[ADD] Initial Commit

pull/45/head
SHEREEF PT 8 years ago
parent
commit
43b172bdb9
  1. 28
      hr_zk_attendance/README.rst
  2. 23
      hr_zk_attendance/__init__.py
  3. 43
      hr_zk_attendance/__manifest__.py
  4. 25
      hr_zk_attendance/models/__init__.py
  5. 99
      hr_zk_attendance/models/machine_analysis.py
  6. 268
      hr_zk_attendance/models/zk_machine.py
  7. 4
      hr_zk_attendance/security/ir.model.access.csv
  8. BIN
      hr_zk_attendance/static/description/attendance_log.png
  9. BIN
      hr_zk_attendance/static/description/banner.gif
  10. BIN
      hr_zk_attendance/static/description/cybro_logo.png
  11. BIN
      hr_zk_attendance/static/description/devicelog.png
  12. BIN
      hr_zk_attendance/static/description/employee.png
  13. BIN
      hr_zk_attendance/static/description/icon.png
  14. 159
      hr_zk_attendance/static/description/index.html
  15. BIN
      hr_zk_attendance/static/description/zk_config.png
  16. BIN
      hr_zk_attendance/static/description/zk_warn2.png
  17. BIN
      hr_zk_attendance/static/description/zk_warning.png
  18. 41
      hr_zk_attendance/views/zk_machine_attendance_view.xml
  19. 69
      hr_zk_attendance/views/zk_machine_view.xml

28
hr_zk_attendance/README.rst

@ -0,0 +1,28 @@
Biometric Device Integration v10
================================
This Cybrosys's module integrates Odoo attendance with biometric device attendance.
Features
========
* Ingrates biometric device(Face+Thumb) with HR attendance.
* Managing attendance automatically
* Keeps zk machine history in Odoo
* Option to configure multiple zk devices
* Option to clear all zk history from both device and Odoo
Technical Notes
===============
Used Libraries:
*This integration is only applicable for the the device ZKteco model 'uFace 202'
* zklib
you can install zklib library using "sudo pip install zklib"
Author
=======
* Cybrosys Techno Solutions <https://www.cybrosys.com>
Credits
=======
Developer: Jesni Banu @ cybrosys, jesni@cybrosys.in

23
hr_zk_attendance/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
import models

43
hr_zk_attendance/__manifest__.py

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
{
'name': 'Biometric Device Integration',
'version': '10.0.1.0.0',
'summary': """Integrating Biometric Device With HR Attendance (Face + Thumb)""",
'description': 'This module integrates Odoo with the biometric device(Model: ZKteco uFace 202)',
'category': 'Generic Modules/Human Resources',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'website': "http://www.cybrosys.com",
'depends': ['base_setup', 'hr_attendance'],
'data': [
'security/ir.model.access.csv',
'views/zk_machine_view.xml',
'views/zk_machine_attendance_view.xml',
],
'images': ['static/description/banner.gif'],
'license': 'AGPL-3',
'demo': [],
'installable': True,
'auto_install': False,
'application': False,
}

25
hr_zk_attendance/models/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
import zk_machine
import machine_analysis

99
hr_zk_attendance/models/machine_analysis.py

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
from odoo import tools
from odoo import models, fields, api, _
class HrEmployee(models.Model):
_inherit = 'hr.employee'
device_id = fields.Char(string='Biometric Device ID')
class ZkMachine(models.Model):
_name = 'zk.machine.attendance'
_inherit = 'hr.attendance'
@api.constrains('check_in', 'check_out', 'employee_id')
def _check_validity(self):
"""overriding the __check_validity function for employee attendance."""
pass
device_id = fields.Char(string='Biometric Device ID')
punch_type = fields.Selection([('0', 'Check In'),
('1', 'Check Out'),
('2', 'Break Out'),
('3', 'Break In'),
('4', 'Overtime In'),
('5', 'Overtime Out')],
string='Punching Type')
attendance_type = fields.Selection([('1', 'Thump'),
('15', 'Face')], string='Category')
punching_time = fields.Datetime(string='Punching Time')
address_id = fields.Many2one('res.partner', string='Working Address')
class ReportZkDevice(models.Model):
_name = 'zk.report.daily.attendance'
_auto = False
_order = 'punching_day desc'
name = fields.Many2one('hr.employee', string='Employee')
punching_day = fields.Date(string='Date')
address_id = fields.Many2one('res.partner', string='Working Address')
attendance_type = fields.Selection([('1', 'Thump'),
('15', 'Face')],
string='Category')
punch_type = fields.Selection([('0', 'Check In'),
('1', 'Check Out'),
('2', 'Break Out'),
('3', 'Break In'),
('4', 'Overtime In'),
('5', 'Overtime Out')], string='Punching Type')
punching_time = fields.Datetime(string='Punching Time')
def init(self):
tools.drop_view_if_exists(self._cr, 'zk_report_daily_attendance')
self._cr.execute("""
create or replace view zk_report_daily_attendance as (
select
min(z.id) as id,
z.employee_id as name,
z.write_date as punching_day,
z.address_id as address_id,
z.attendance_type as attendance_type,
z.punching_time as punching_time,
z.punch_type as punch_type
from zk_machine_attendance z
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
)
""")

268
hr_zk_attendance/models/zk_machine.py

@ -0,0 +1,268 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
import pytz
import sys
import datetime
from zklib import zklib
from zklib.zkconst import *
from struct import unpack
from odoo import api, fields, models
from odoo import _
from odoo.exceptions import UserError, ValidationError
sys.path.append("zklib")
class HrAttendance(models.Model):
_inherit = 'hr.attendance'
device_id = fields.Char(string='Biometric Device ID')
class ZkMachine(models.Model):
_name = 'zk.machine'
name = fields.Char(string='Machine IP', required=True)
port_no = fields.Integer(string='Port No', required=True)
address_id = fields.Many2one('res.partner', string='Working Address')
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id.id)
@api.multi
def device_connect(self, zk):
command = CMD_CONNECT
command_string = ''
chksum = 0
session_id = 0
reply_id = -1 + USHRT_MAX
buf = zk.createHeader(command, chksum, session_id,
reply_id, command_string)
zk.zkclient.sendto(buf, zk.address)
try:
zk.data_recv, addr = zk.zkclient.recvfrom(1024)
zk.session_id = unpack('HHHH', zk.data_recv[:8])[2]
command = unpack('HHHH', zk.data_recv[:8])[0]
if command == 2005:
conn = True
else:
conn = False
except:
conn = False
return conn
@api.multi
def clear_attendance(self):
for info in self:
try:
machine_ip = info.name
port = info.port_no
zk = zklib.ZKLib(machine_ip, port)
conn = self.device_connect(zk)
if conn:
zk.enableDevice()
clear_data = zk.getAttendance()
if clear_data:
zk.clearAttendance()
self._cr.execute("""delete from zk_machine_attendance""")
else:
raise UserError(_('Unable to get the attendance log, please try again later.'))
else:
raise UserError(_('Unable to connect, please check the parameters and network connections.'))
except:
raise ValidationError('Warning !!! Machine is not connected')
def getSizeUser(self, zk):
"""Checks a returned packet to see if it returned CMD_PREPARE_DATA,
indicating that data packets are to be sent
Returns the amount of bytes that are going to be sent"""
command = unpack('HHHH', zk.data_recv[:8])[0]
if command == CMD_PREPARE_DATA:
size = unpack('I', zk.data_recv[8:12])[0]
return size
else:
return False
def zkgetuser(self, zk):
"""Start a connection with the time clock"""
command = CMD_USERTEMP_RRQ
command_string = '\x05'
chksum = 0
session_id = zk.session_id
reply_id = unpack('HHHH', zk.data_recv[:8])[3]
buf = zk.createHeader(command, chksum, session_id, reply_id, command_string)
zk.zkclient.sendto(buf, zk.address)
try:
zk.data_recv, addr = zk.zkclient.recvfrom(1024)
if self.getSizeUser(zk):
bytes = self.getSizeUser(zk)
while bytes > 0:
data_recv, addr = zk.zkclient.recvfrom(1032)
zk.userdata.append(data_recv)
bytes -= 1024
zk.session_id = unpack('HHHH', zk.data_recv[:8])[2]
data_recv = zk.zkclient.recvfrom(8)
users = {}
if len(zk.userdata) > 0:
userdata = ''.join(zk.userdata[0])
userdata = userdata[11:]
while len(userdata) > 72:
uid, role, password, name, userid = unpack('2s2s8s28sx31s', userdata.ljust(72)[:72])
uid = int(uid.encode("hex"), 16)
# Clean up some messy characters from the user name
password = password.split('\x00', 1)[0]
password = unicode(password.strip('\x00|\x01\x10x|\x000'), errors='ignore')
# uid = uid.split('\x00', 1)[0]
userid = unicode(userid.strip('\x00|\x01\x10x|\x000|\x9aC'), errors='ignore')
name = name.split('\x00', 1)[0]
if name.strip() == "":
name = uid
users[uid] = (userid, name, int(role.encode("hex"), 16), password)
userdata = userdata[72:]
return users
except:
return False
@api.multi
def download_attendance(self):
zk_attendance = self.env['zk.machine.attendance']
att_obj = self.env['hr.attendance']
for info in self:
machine_ip = info.name
port = info.port_no
zk = zklib.ZKLib(machine_ip, port)
conn = self.device_connect(zk)
if conn:
zk.enableDevice()
user = self.zkgetuser(zk)
command = CMD_ATTLOG_RRQ
command_string = ''
chksum = 0
session_id = zk.session_id
reply_id = unpack('HHHH', zk.data_recv[:8])[3]
buf = zk.createHeader(command, chksum, session_id,
reply_id, command_string)
zk.zkclient.sendto(buf, zk.address)
try:
zk.data_recv, addr = zk.zkclient.recvfrom(1024)
command = unpack('HHHH', zk.data_recv[:8])[0]
if command == CMD_PREPARE_DATA:
size = unpack('I', zk.data_recv[8:12])[0]
zk_size = size
else:
zk_size = False
if zk_size:
bytes = zk_size
while bytes > 0:
data_recv, addr = zk.zkclient.recvfrom(1032)
zk.attendancedata.append(data_recv)
bytes -= 1024 # 1024
zk.session_id = unpack('HHHH', zk.data_recv[:8])[2]
data_recv = zk.zkclient.recvfrom(8)
attendance = []
if len(zk.attendancedata) > 0:
# The first 4 bytes don't seem to be related to the user
for x in xrange(len(zk.attendancedata)):
if x > 0:
zk.attendancedata[x] = zk.attendancedata[x][8:]
attendancedata = ''.join(zk.attendancedata)
attendancedata = attendancedata[14:]
while len(attendancedata) > 0:
uid, state, timestamp, space = unpack('24s1s4s11s', attendancedata.ljust(40)[:40])
pls = unpack('c', attendancedata[29:30])
uid = uid.split('\x00', 1)[0]
tmp = ''
for i in reversed(xrange(len(timestamp.encode('hex')) / 2)):
tmp += timestamp.encode('hex')[i * 2:(i * 2) + 2]
attendance.append((uid, int(state.encode('hex'), 16),
decode_time(int(tmp, 16)), unpack('HHHH', space[:8])[0]))
attendancedata = attendancedata[40:]
except:
attendance = False
if attendance:
for each in attendance:
atten_time = each[2]
atten_time = datetime.strptime(
atten_time.strftime('%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S')
local_tz = pytz.timezone(
self.env.user.partner_id.tz or 'GMT')
local_dt = local_tz.localize(atten_time, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
utc_dt = utc_dt.strftime("%Y-%m-%d %H:%M:%S")
atten_time = datetime.strptime(
utc_dt, "%Y-%m-%d %H:%M:%S")
atten_time = fields.Datetime.to_string(atten_time)
if user:
for uid in user:
if user[uid][0] == str(each[0]):
get_user_id = self.env['hr.employee'].search(
[('device_id', '=', str(each[0]))])
if get_user_id:
duplicate_atten_ids = zk_attendance.search(
[('device_id', '=', str(each[0])), ('punching_time', '=', atten_time)])
if duplicate_atten_ids:
continue
else:
zk_attendance.create({'employee_id': get_user_id.id,
'device_id': each[0],
'attendance_type': str(each[1]),
'punch_type': str(each[3]),
'punching_time': atten_time,
'address_id': info.address_id.id})
att_var = att_obj.search([('employee_id', '=', get_user_id.id),
('check_out', '=', False)])
if each[3] == 0:
if not att_var:
att_obj.create({'employee_id': get_user_id.id,
'check_in': atten_time})
if each[3] == 1:
if len(att_var) == 1:
att_var.write({'check_out': atten_time})
else:
att_var1 = att_obj.search([('employee_id', '=', get_user_id.id)])
if att_var1:
att_var1[-1].write({'check_out': atten_time})
else:
employee = self.env['hr.employee'].create(
{'device_id': str(each[0]), 'name': user[uid][1]})
zk_attendance.create({'employee_id': employee.id,
'device_id': each[0],
'attendance_type': str(each[1]),
'punch_type': str(each[3]),
'punching_time': atten_time,
'address_id': info.address_id.id})
att_obj.create({'employee_id': employee.id,
'check_in': atten_time})
else:
pass
zk.enableDevice()
zk.disconnect()
return True
else:
raise UserError(_('Unable to get the attendance log, please try again later.'))
else:
raise UserError(_('Unable to connect, please check the parameters and network connections.'))

4
hr_zk_attendance/security/ir.model.access.csv

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_zk_machine_user,zk.machine.hr_biometric_machine,model_zk_machine,hr_attendance.group_hr_attendance_user,1,1,1,1
access_hr_zk_machine_user1,zk.machine.hr_biometric_machine1,model_zk_machine_attendance,hr_attendance.group_hr_attendance_user,1,1,1,1
access_hr_zk_machine_user2,zk.machine.hr_biometric_machine2,model_zk_report_daily_attendance,hr_attendance.group_hr_attendance_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_zk_machine_user zk.machine.hr_biometric_machine model_zk_machine hr_attendance.group_hr_attendance_user 1 1 1 1
3 access_hr_zk_machine_user1 zk.machine.hr_biometric_machine1 model_zk_machine_attendance hr_attendance.group_hr_attendance_user 1 1 1 1
4 access_hr_zk_machine_user2 zk.machine.hr_biometric_machine2 model_zk_report_daily_attendance hr_attendance.group_hr_attendance_user 1 1 1 1

BIN
hr_zk_attendance/static/description/attendance_log.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
hr_zk_attendance/static/description/banner.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

BIN
hr_zk_attendance/static/description/cybro_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
hr_zk_attendance/static/description/devicelog.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

BIN
hr_zk_attendance/static/description/employee.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
hr_zk_attendance/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

159
hr_zk_attendance/static/description/index.html

@ -0,0 +1,159 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Biometric Device Integration</h2>
<h3 class="oe_slogan">This Module Integrating Biometric Device With HR Attendance</h3>
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a> </h4>
</div>
<div class="oe_row oe_spaced" style="padding-left:65px;">
<div>
<span style="color:green;"> &#9745; </span> Ingrates biometric device(Face+Thumb) with HR attendance.<br/>
<span style="color:green;"> &#9745; </span> Option to keep the device attendance log in Odoo.<br/>
<span style="color:green;"> &#9745; </span> Option to clear the device attendance log from both device and Odoo.<br/>
<span style="color:green;"> &#9745; </span> Automating HR attendance.<br/>
<span style="color:green;"> &#9745; </span> Option to configure multiple devices.<br/>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_picture">
<h3 class="oe_slogan">Overview</h3>
<p class="oe_mt32 text-justify" style="text-align: center;">
Automation is an implementation factor for a successful ERP. With this module,
HR attendance can automate by integrating Thumb / Face detection device with Odoo.
We can configure a user both from thumbing device or Odoo employee form.
</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align: center">
<p>
<h4>Biometric Device Configuration</h4>
<p>
</div>
<div style="text-align: center">
<span>Here you can configure your all devices with it's IP address and port number.</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="zk_config.png">
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div style="text-align: center">
<p>
<h4>Download/Clear Device Attendance Log</h4>
<p>
</div>
<div style="text-align: center">
<span>After configuration, you can download your device attendance log into Odoo through
'Download' button.If the device is connected, then the Odoo will download all device
attendance log.
Otherwise, the Odoo will show you a warning message as follow.</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="zk_warning.png">
</div>
</div>
<div style="text-align: center">
<span>You can also clear all attendance log from both Odoo and device via 'Clear' button.
If the device is not connected it will show you a warning message as follow.</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="zk_warn2.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align: center">
<p>
<h4>Biometric Device Attendance Log</h4>
<p>
</div>
<div style="text-align: center">
<span>Here you can see all device attendance log</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="devicelog.png">
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div style="text-align: center">
<p>
<h4>HR Attendance</h4>
<p>
</div>
<div style="text-align: center">
<span>Here, Odoo automatically generates HR attendance log while downloading the device attendance.</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="attendance_log.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align: center">
<p>
<h4>Employee Configuration</h4>
<p>
</div>
<div style="text-align: center">
<span>You can update existing employees with the 'Device Id' which are the id in the biometric device.
If there is no match with the biometric device id then system will automatically create corresponding employee.</span>
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="employee.png">
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="" style="text-align: center">
<span><b><i>Note:- This integration is only applicable for the the device ZKteco model 'uFace 202'<br/>
Please install zklib library (sudo pip install zklib)</i></b></span>
</div>
</section>
<section class="oe_container">
<h5 class="oe_slogan" style="margin-bottom:0px !important;font-weight: 400;margin-top:20px; color:#bb0706; font-size:20px;" >Having any trouble in using the app? Or Do you need any further assistance?</h5>
<h5 class="oe_slogan" style="font-size:20px;margin-top: 11px;">Give a Request Mail to:&nbsp;&nbsp;<i class="fa fa-envelope" aria-hidden="true"></i>&nbsp;&nbsp;<a href="#" style="color:blue;">odoo@cybrosys.com</a></h5>
</section>
<section class="oe_container oe_dark">
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2>
<div class="oe_slogan" style="margin-top:10px !important;">
<div>
<a class="btn btn-primary btn-lg mt8"
style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i
class="fa fa-envelope"></i> Email </a> <a
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;"
href="https://www.cybrosys.com/contact/"><i
class="fa fa-phone"></i> Contact Us </a> <a
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;"
href="https://www.cybrosys.com/odoo-customization-and-installation/"><i
class="fa fa-check-square"></i> Request Customization </a>
</div>
<br>
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block">
<div>
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td>
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td>
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td>
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td>
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td>
</div>
</div>
</section>

BIN
hr_zk_attendance/static/description/zk_config.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
hr_zk_attendance/static/description/zk_warn2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
hr_zk_attendance/static/description/zk_warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

41
hr_zk_attendance/views/zk_machine_attendance_view.xml

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_zk_report_daily_attendance_search" model="ir.ui.view">
<field name="name">zk.report.daily.attendance.search</field>
<field name="model">zk.report.daily.attendance</field>
<field name="arch" type="xml" >
<search string="Hr Attendance Search">
<filter icon="terp-stock_align_left_24" string="My Attendance" name="my_attendance"
domain="[('name.user_id.id', '=', uid)]" />
<field name="name"/>
</search>
</field>
</record>
<record id="view_zk_report_daily_attendance_tree" model="ir.ui.view">
<field name="name">zk.report.daily.attendance.tree</field>
<field name="model">zk.report.daily.attendance</field>
<field name="arch" type="xml" >
<tree string="Attendance" create="false" delete="false" colors="green:punch_type in ('0');red:punch_type in ('1');">
<field name="punching_day"/>
<field name="name"/>
<field name="punch_type"/>
<field name="attendance_type"/>
<field name="punching_time"/>
<field name="address_id"/>
</tree>
</field>
</record>
<record id="action_zk_report_daily_attendance" model="ir.actions.act_window">
<field name="name">Attendance Analysis</field>
<field name="res_model">zk.report.daily.attendance</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="context">{'search_default_my_attendance':1}</field>
<field name="search_view_id" ref="view_zk_report_daily_attendance_search" />
</record>
<menuitem id="menu_zk_attendance_view" name="Attendance log" action="action_zk_report_daily_attendance" parent="zk_machine_menu"
sequence="2" groups="hr_attendance.group_hr_attendance_user"/>
</odoo>

69
hr_zk_attendance/views/zk_machine_view.xml

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_zk_machine_form" model="ir.ui.view">
<field name="name">zk.machine.form</field>
<field name="model">zk.machine</field>
<field name="arch" type="xml">
<form string="Biometric Device">
<header>
<button name="clear_attendance" type="object" string="Clear Data" class="oe_highlight"
icon="fa-remove " confirm="Are you sure you want to do this?"/>
<button name="download_attendance" type="object" string="Download Data" class="oe_highlight"
icon="fa-download " confirm="Are you sure you want to do this?" />
</header>
<sheet>
<div class="oe_title">
<label for="name" />
<h1>
<field name="name" placeholder="Machine IP"/>
</h1>
</div>
<group>
<group>
<field name="port_no"/>
<field name="address_id"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_zk_machine_tree" model="ir.ui.view">
<field name="name">zk.machine.tree</field>
<field name="model">zk.machine</field>
<field name="arch" type="xml">
<tree string="Biometric Machine">
<field name="name"/>
<field name="port_no"/>
<field name="address_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="zk_machine_action" model="ir.actions.act_window">
<field name="name">Attendances</field>
<field name="res_model">zk.machine</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record id="hr_employee_inherit_form_view" model="ir.ui.view">
<field name="name">hr.employee.form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="device_id"/>
</field>
</field>
</record>
<menuitem id="zk_machine_menu" parent="hr_attendance.menu_hr_attendance_root" sequence="3" name="Biometric Device Manager" />
<menuitem id="zk_machine_sub_menu" parent="zk_machine_menu" name="Device Configuration" action="zk_machine_action" sequence="1"/>
</odoo>
Loading…
Cancel
Save