Merge branch 'feature/odoo18' into develop
This commit is contained in:
commit
ad3dc6f437
|
|
@ -1,9 +1,7 @@
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Payroll',
|
'name': 'Payroll',
|
||||||
'category': 'Human Resources/Payroll',
|
'category': 'Human Resources/Payroll',
|
||||||
'sequence': 290,
|
|
||||||
'summary': 'Manage your employee payroll records',
|
'summary': 'Manage your employee payroll records',
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'application': True,
|
'application': True,
|
||||||
|
|
@ -11,7 +9,7 @@
|
||||||
# 'hr_work_entry_contract_enterprise',
|
# 'hr_work_entry_contract_enterprise',
|
||||||
'mail',
|
'mail',
|
||||||
'web_editor',
|
'web_editor',
|
||||||
'hr_work_entry_contract',
|
'hr_work_entry_contract','web',
|
||||||
# 'hr_gantt'
|
# 'hr_gantt'
|
||||||
],
|
],
|
||||||
'data': [
|
'data': [
|
||||||
|
|
@ -59,6 +57,7 @@
|
||||||
'views/hr_payroll_menu.xml',
|
'views/hr_payroll_menu.xml',
|
||||||
# 'views/hr_work_entry_views.xml',
|
# 'views/hr_work_entry_views.xml',
|
||||||
'views/hr_work_entry_export_mixin_views.xml',
|
'views/hr_work_entry_export_mixin_views.xml',
|
||||||
|
'views/ftp_payslip.xml',
|
||||||
'report/hr_contract_history_report_views.xml',
|
'report/hr_contract_history_report_views.xml',
|
||||||
'wizard/hr_payroll_payment_report_wizard.xml',
|
'wizard/hr_payroll_payment_report_wizard.xml',
|
||||||
],
|
],
|
||||||
|
|
@ -82,6 +81,6 @@
|
||||||
# 'hr_payroll/static/tests/**/*.js',
|
# 'hr_payroll/static/tests/**/*.js',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'license': 'OEEL-1',
|
'license': 'LGPL-3',
|
||||||
'post_init_hook': '_post_init_hook',
|
'post_init_hook': '_post_init_hook',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<template id="report_payslip_ftp">
|
||||||
|
<t t-call="web.external_layout_boxed">
|
||||||
|
<hr class="border-top" />
|
||||||
|
|
||||||
|
<div class="page" style="font-size: 12px;">
|
||||||
|
<h2><span t-field="o.name"/></h2>
|
||||||
|
<div class="employee-section-title" style="font-weight: bold; margin-top: 20px;">Employee Information</div>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; font-size: 12px; margin-bottom: 10px;">
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Employee Name:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.display_name"/></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Employee ID:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.employee_id"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Job Position:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.job_id.display_name"/></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Department:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.department_id.display_name"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Date Of Joining:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.doj"/></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Date Of Birth:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.birthday"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">Bank Account:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.bank_account_id.acc_number"/></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">PAN:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.l10n_in_pan"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">UAN:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.l10n_in_uan"/></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; font-weight: bold;">ESIC:</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;" colspan="2"><t t-esc="o.employee_id.l10n_in_esic_number"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="employee-section-title" style="font-weight: bold; margin-top: 20px;">Pay Period & Leave Summary</div>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; font-size: 12px; margin-bottom: 10px;">
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;">
|
||||||
|
<strong>Pay Period:</strong> <t style="padding: 6px;" t-esc="o.date_from"/> - <t t-esc="o.date_to"/><br/>
|
||||||
|
<t t-set="days" t-value="(o.date_to - o.date_from).days + 1"/>
|
||||||
|
<strong>Number of Days:</strong> <t style="padding: 6px;" t-esc="days"/> Days<br/>
|
||||||
|
<strong>Worked Days:</strong> <t style="padding: 6px;" t-esc="days"/> Days
|
||||||
|
</td>
|
||||||
|
<t t-set="timeoff_data_table" t-value="o._get_employee_timeoff_data()"/>
|
||||||
|
<td t-if="timeoff_data_table" style="border: 1px solid #ccc; padding: 6px;">
|
||||||
|
<div t-foreach="timeoff_data_table" t-as="timeoff_data">
|
||||||
|
<strong t-out="timeoff_data[0] + ':'"/>
|
||||||
|
<t t-out="timeoff_data[1].get('remaining_leaves')"/> /
|
||||||
|
<t t-out="timeoff_data[1].get('max_leaves')"/>
|
||||||
|
<t t-if="timeoff_data[1].get('request_unit') == 'hour'">Hours</t>
|
||||||
|
<t t-else="">Days</t>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="employee-section-title" style="font-weight: bold; margin-top: 20px;">Salary Details</div>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; font-size: 12px;">
|
||||||
|
<tr>
|
||||||
|
<th style="border: 1px solid #ccc; padding: 6px; text-align: left;font-weight: bold;">Income</th>
|
||||||
|
<th style="border: 1px solid #ccc; padding: 6px; text-align: right;font-weight: bold;">Amount</th>
|
||||||
|
<th style="border: 1px solid #ccc; padding: 6px; text-align: left;font-weight: bold;">Contribution</th>
|
||||||
|
<th style="border: 1px solid #ccc; padding: 6px; text-align: right;font-weight: bold;">Amount</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;">
|
||||||
|
<t t-set="income" t-value="0"/>
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.code in ['BASIC','HRA','LTA','SPA'])" t-as="l">
|
||||||
|
<t t-esc="l.name"/><br/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; text-align: right;">
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.code in ['BASIC','HRA','LTA','SPA'])" t-as="l">
|
||||||
|
<t t-esc="l.amount"/><br/>
|
||||||
|
<t t-set="income" t-value="income + l.amount"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;">
|
||||||
|
<t t-set="contribution" t-value="0"/>
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.code in ['PFE','ESICF'])" t-as="l">
|
||||||
|
<t t-esc="l.name"/><br/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; text-align: right;">
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.code in ['PFE','ESICF'])" t-as="l">
|
||||||
|
<t t-esc="l.amount"/><br/>
|
||||||
|
<t t-set="contribution" t-value="contribution + l.amount"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="border: 1px solid #ccc;"></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;">
|
||||||
|
<t t-set="ded" t-value="0"/>
|
||||||
|
<strong>Cost To Company</strong><br/><br/>
|
||||||
|
<strong>Deductions</strong><br/>
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.category_id.code == 'DED')" t-as="l">
|
||||||
|
<t t-esc="l.name"/><br/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; text-align: right;">
|
||||||
|
<strong><t t-esc="contribution + income"/></strong><br/><br/>
|
||||||
|
<div t-foreach="o.line_ids.filtered(lambda l: l.appears_on_payslip and l.category_id.code == 'DED')" t-as="l">
|
||||||
|
<t t-esc="l.amount"/><br/>
|
||||||
|
<t t-set="ded" t-value="ded + l.amount"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;"><strong>Gross Salary</strong></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; text-align: right;"><strong><t t-esc="income"/></strong></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px;"><strong>Total Deduction</strong></td>
|
||||||
|
<td style="border: 1px solid #ccc; padding: 6px; text-align: right;"><strong><t t-esc="ded"/></strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="net-salary" colspan="3" style="border: 1px solid #ccc; padding: 6px;"><strong>Net Salary:</strong></td>
|
||||||
|
<td class="net-salary" colspan="1" style="border: 1px solid #ccc; padding: 6px; text-align: right;">
|
||||||
|
<t t-esc="(contribution + income) + ded"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="to-pay" style="margin-top: 20px;">
|
||||||
|
<p t-if="o.net_wage >= 0">
|
||||||
|
To pay <strong><span t-esc="(contribution + income) + ded"/></strong> (<span style="padding-right: 5px;" t-esc="o.env.company.currency_id.amount_to_text((contribution + income) + ded) "/> only) to <i><span t-field="o.employee_id.legal_name"/></i> - <b><span t-field="o.employee_id.bank_account_id.bank_id.name"/> Account : <span t-field="o.employee_id.bank_account_id.acc_number">XXXXXXXXXXXX</span></b>
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p style="padding: 8px;"><strong>NOTE:</strong> This is computer generated salary slip. Signature is not required.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<template id="report_payslip_ftps">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<t t-set="o" t-value="o.with_context(lang=o.employee_id.lang or o.env.lang)"/>
|
||||||
|
<t t-set="company" t-value="o.env.company"/>
|
||||||
|
<t t-call="hr_payroll.report_payslip_ftp" t-lang="o.env.lang"/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -13,6 +13,19 @@
|
||||||
<field name="attachment"></field>
|
<field name="attachment"></field>
|
||||||
<field name="attachment_use" eval="False"/>
|
<field name="attachment_use" eval="False"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="action_report_payslip_ftp" model="ir.actions.report">
|
||||||
|
<field name="name">Payslip Ftp</field>
|
||||||
|
<field name="model">hr.payslip</field>
|
||||||
|
<field name="report_type">qweb-pdf</field>
|
||||||
|
<field name="report_name">hr_payroll.report_payslip_ftps</field>
|
||||||
|
<field name="report_file">hr_payroll.report_payslip_ftps</field>
|
||||||
|
<field name="print_report_name">'Payslip - %s' % (object.name)</field>
|
||||||
|
<field name="binding_model_id" ref="model_hr_payslip"/>
|
||||||
|
<field name="binding_type">report</field>
|
||||||
|
<field name="attachment"></field>
|
||||||
|
<field name="attachment_use" eval="False"/>
|
||||||
|
</record>
|
||||||
<record id="action_report_light_payslip" model="ir.actions.report">
|
<record id="action_report_light_payslip" model="ir.actions.report">
|
||||||
<field name="name">Payslip (Light)</field>
|
<field name="name">Payslip (Light)</field>
|
||||||
<field name="model">hr.payslip</field>
|
<field name="model">hr.payslip</field>
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,6 @@ class BiometricDeviceDetails(models.Model):
|
||||||
device_password = fields.Integer(string='Password',
|
device_password = fields.Integer(string='Password',
|
||||||
help='Enter the device 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"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -172,39 +170,40 @@ class BiometricDeviceDetails(models.Model):
|
||||||
if conn:
|
if conn:
|
||||||
conn.disable_device()
|
conn.disable_device()
|
||||||
self.get_all_users()
|
self.get_all_users()
|
||||||
|
# self.action_set_timezone()
|
||||||
user = conn.get_users()
|
user = conn.get_users()
|
||||||
# fingers = conn.get_templates()
|
# get All Fingerprints
|
||||||
# for use in user:
|
fingers = conn.get_templates()
|
||||||
# for finger in fingers:
|
for use in user:
|
||||||
# if finger.uid == use.uid:
|
for finger in fingers:
|
||||||
# templates = conn.get_user_template(uid=use.uid,
|
if finger.uid == use.uid:
|
||||||
# temp_id=finger.fid,
|
templates = conn.get_user_template(uid=use.uid,
|
||||||
# user_id=use.user_id)
|
temp_id=finger.fid,
|
||||||
# hex_data = templates.template.hex()
|
user_id=use.user_id)
|
||||||
# # Convert hex data to binary
|
hex_data = templates.template.hex()
|
||||||
# binary_data = binascii.unhexlify(hex_data)
|
# Convert hex data to binary
|
||||||
# base64_data = base64.b64encode(binary_data).decode(
|
binary_data = binascii.unhexlify(hex_data)
|
||||||
# 'utf-8')
|
base64_data = base64.b64encode(binary_data).decode(
|
||||||
# employee = self.env['hr.employee'].search(
|
'utf-8')
|
||||||
# [('device_id_num', '=', use.user_id),('company_id', '=', self.env.company.id)],limit=1)
|
employee = self.env['hr.employee'].search(
|
||||||
# employee.device_ids |= self
|
[('device_id_num', '=', use.user_id), ('company_id', '=', self.env.company.id)],
|
||||||
# if str(finger.fid) in employee.fingerprint_ids.mapped(
|
limit=1)
|
||||||
# 'finger_id'):
|
employee.device_ids |= self
|
||||||
# employee.fingerprint_ids.search(
|
if str(finger.fid) in employee.fingerprint_ids.mapped(
|
||||||
# [('finger_id', '=', finger.fid)]).update({
|
'finger_id'):
|
||||||
# 'finger_template': base64_data,
|
employee.fingerprint_ids.search(
|
||||||
# })
|
[('finger_id', '=', finger.fid)]).update({
|
||||||
# else:
|
'finger_template': base64_data,
|
||||||
# employee.fingerprint_ids.create({
|
})
|
||||||
# 'finger_template': base64_data,
|
else:
|
||||||
# 'finger_id': finger.fid,
|
employee.fingerprint_ids.create({
|
||||||
# 'employee_bio_id': employee.id,
|
'finger_template': base64_data,
|
||||||
# 'filename': f'{employee.name}-finger-{finger.fid}'
|
'finger_id': finger.fid,
|
||||||
# })
|
'employee_bio_id': employee.id,
|
||||||
|
'filename': f'{employee.name}-finger-{finger.fid}'
|
||||||
|
})
|
||||||
# get all attendances
|
# get all attendances
|
||||||
print(help(zk.get_attendance))
|
|
||||||
attendance = conn.get_attendance()
|
attendance = conn.get_attendance()
|
||||||
print(attendance)
|
|
||||||
if attendance:
|
if attendance:
|
||||||
filtered_attendance = []
|
filtered_attendance = []
|
||||||
|
|
||||||
|
|
@ -240,50 +239,54 @@ 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:
|
||||||
employee = 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)],
|
||||||
('company_id', '=', self.env.company.id)
|
limit=1)
|
||||||
], limit=1)
|
check_in_today = hr_attendance.search([(
|
||||||
|
'employee_id', '=', get_user_id.id),
|
||||||
|
('check_in', '!=', False), ('check_out', '=', False)])
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
if not employee:
|
# Define the tolerance (10 minutes)
|
||||||
continue
|
tolerance = timedelta(minutes=10)
|
||||||
|
|
||||||
# Convert atten_time to datetime
|
# Convert the atten_time string to a datetime object
|
||||||
|
|
||||||
|
# Calculate the lower and upper bounds with the tolerance
|
||||||
atten_time_obj = datetime.datetime.strptime(atten_time, "%Y-%m-%d %H:%M:%S")
|
atten_time_obj = datetime.datetime.strptime(atten_time, "%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
# Find existing attendance for today
|
# Calculate the lower and upper bounds with the tolerance
|
||||||
start_of_day = atten_time_obj.replace(hour=0, minute=0, second=0, microsecond=0)
|
lower_bound = atten_time_obj - tolerance
|
||||||
end_of_day = atten_time_obj.replace(hour=23, minute=59, second=59, microsecond=999999)
|
upper_bound = atten_time_obj + tolerance
|
||||||
|
|
||||||
attendance_today = self.env['hr.attendance'].search([
|
# Ensure the 'check_in' and 'check_out' fields are datetime objects and compare them
|
||||||
('employee_id', '=', employee.id),
|
next_in = hr_attendance.search([
|
||||||
('check_in', '>=', start_of_day),
|
('employee_id', '=', get_user_id.id),
|
||||||
('check_in', '<=', end_of_day)
|
('check_in', '>=', lower_bound),
|
||||||
], limit=1)
|
('check_in', '<=', upper_bound)
|
||||||
|
])
|
||||||
|
|
||||||
# IN logic
|
next_out = hr_attendance.search([
|
||||||
if self.display_name == 'IN':
|
('employee_id', '=', get_user_id.id),
|
||||||
if not attendance_today:
|
('check_out', '>=', lower_bound),
|
||||||
# No attendance yet, create new with check_in only
|
('check_out', '<=', upper_bound)
|
||||||
self.env['hr.attendance'].create({
|
])
|
||||||
'employee_id': employee.id,
|
if get_user_id:
|
||||||
'check_in': atten_time_obj,
|
if self.display_name == 'IN' and not check_in_today:
|
||||||
})
|
if next_in:
|
||||||
employee.attendance_state = 'checked_in'
|
|
||||||
else:
|
|
||||||
attendance_today.check_out = False
|
|
||||||
employee.attendance_state = 'checked_in'
|
|
||||||
continue
|
continue
|
||||||
|
hr_attendance.create({
|
||||||
# OUT logic
|
'employee_id': get_user_id.id,
|
||||||
elif self.display_name != 'IN':
|
'check_in': atten_time,
|
||||||
if attendance_today:
|
|
||||||
# Only update checkout if it's not set or is earlier than current atten_time
|
|
||||||
if not attendance_today.check_out or attendance_today.check_out < atten_time_obj:
|
|
||||||
attendance_today.write({
|
|
||||||
'check_out': atten_time_obj,
|
|
||||||
})
|
})
|
||||||
employee.attendance_state = 'checked_out'
|
get_user_id.attendance_state = 'checked_in'
|
||||||
|
elif check_in_today and self.display_name != 'IN':
|
||||||
|
if fields.Datetime.to_string(check_in_today.check_in) > atten_time or next_out:
|
||||||
|
continue
|
||||||
|
check_in_today.write({
|
||||||
|
'check_out': atten_time,
|
||||||
|
})
|
||||||
|
get_user_id.attendance_state = 'checked_out'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
@ -293,7 +296,7 @@ class BiometricDeviceDetails(models.Model):
|
||||||
('company_id', '=', self.env.company.id)])
|
('company_id', '=', self.env.company.id)])
|
||||||
if not duplicate_atten_ids:
|
if not duplicate_atten_ids:
|
||||||
zk_attendance.create({
|
zk_attendance.create({
|
||||||
'employee_id': employee.id,
|
'employee_id': get_user_id.id,
|
||||||
'device_id_num': each.user_id,
|
'device_id_num': each.user_id,
|
||||||
'attendance_type': str(1),
|
'attendance_type': str(1),
|
||||||
'punch_type': '0' if self.display_name == 'IN' else '1',
|
'punch_type': '0' if self.display_name == 'IN' else '1',
|
||||||
|
|
@ -484,7 +487,6 @@ class BiometricDeviceDetails(models.Model):
|
||||||
else:
|
else:
|
||||||
raise UserError(_("Unable to establish a connection to the device."))
|
raise UserError(_("Unable to establish a connection to the device."))
|
||||||
|
|
||||||
|
|
||||||
def get_all_users(self):
|
def get_all_users(self):
|
||||||
"""Function to get all user's details"""
|
"""Function to get all user's details"""
|
||||||
for info in self:
|
for info in self:
|
||||||
|
|
@ -504,7 +506,7 @@ class BiometricDeviceDetails(models.Model):
|
||||||
users = conn.get_users()
|
users = conn.get_users()
|
||||||
for user in users:
|
for user in users:
|
||||||
employee = self.env['hr.employee'].search(
|
employee = self.env['hr.employee'].search(
|
||||||
[('device_id_num', '=', user.user_id) ])
|
[('device_id_num', '=', user.user_id)])
|
||||||
if employee:
|
if employee:
|
||||||
pass
|
pass
|
||||||
# employee.write({
|
# employee.write({
|
||||||
|
|
@ -563,7 +565,7 @@ class BiometricDeviceDetails(models.Model):
|
||||||
"group_id: %s\n"
|
"group_id: %s\n"
|
||||||
"user_id: %s\n"
|
"user_id: %s\n"
|
||||||
"Here is the debugging information:\n%s\n"
|
"Here is the debugging information:\n%s\n"
|
||||||
"Try Reqing the device")
|
"Try Restarting the device")
|
||||||
% (candidate_uid, employee.name, privilege, password,
|
% (candidate_uid, employee.name, privilege, password,
|
||||||
group_id, str(candidate_uid), e))
|
group_id, str(candidate_uid), e))
|
||||||
conn.enable_device()
|
conn.enable_device()
|
||||||
|
|
@ -697,7 +699,7 @@ class ZKBioAttendance(Thread):
|
||||||
live attendance data.
|
live attendance data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, machine_ip, port_no,password, 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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue