From 95e7fedfbd22c86accef65ef5b8f88d97801efaf Mon Sep 17 00:00:00 2001 From: raman Date: Tue, 3 Jun 2025 17:09:15 +0530 Subject: [PATCH 01/49] bio-metric speed --- .../models/biometric_device_details.py | 428 +++++++++--------- 1 file changed, 217 insertions(+), 211 deletions(-) diff --git a/third_party_addons/hr_biometric_attendance/models/biometric_device_details.py b/third_party_addons/hr_biometric_attendance/models/biometric_device_details.py index b42d201e5..144184d6e 100644 --- a/third_party_addons/hr_biometric_attendance/models/biometric_device_details.py +++ b/third_party_addons/hr_biometric_attendance/models/biometric_device_details.py @@ -149,220 +149,221 @@ class BiometricDeviceDetails(models.Model): raise ValidationError(f'{error}') def action_download_attendance(self): - """Function to download attendance records from the device""" + """Download attendance records from the device and process them""" _logger.info("++++++++++++Cron Executed++++++++++++++++++++++") + zk_attendance = self.env['zk.machine.attendance'] hr_attendance = self.env['hr.attendance'] - for info in self: - machine_ip = info.device_ip - zk_port = info.port_number + + for device in self: try: - # Connecting with the device with the ip and port provided - zk = ZK(machine_ip, port=zk_port, timeout=15, - password=self.device_password, - force_udp=False, ommit_ping=False) - except NameError: - raise UserError( - _("Pyzk module not Found. Please install it" - "with 'pip3 install pyzk'.")) - conn = self.device_connect(zk) - self.get_device_information() - if conn: + # Connect to the device + zk = ZK( + device.device_ip, + port=device.port_number, + timeout=15, + password=device.device_password, + force_udp=False, + ommit_ping=False + ) + conn = device.device_connect(zk) + if not conn: + raise UserError( + _('Unable to connect to the device. Please check parameters and network connection.')) + + # Get device information and users + device.get_device_information() conn.disable_device() - self.get_all_users() - # self.action_set_timezone() - user = conn.get_users() - # get All Fingerprints - fingers = conn.get_templates() - for use in user: - for finger in fingers: - if finger.uid == use.uid: - templates = conn.get_user_template(uid=use.uid, - temp_id=finger.fid, - user_id=use.user_id) - hex_data = templates.template.hex() - # Convert hex data to binary - binary_data = binascii.unhexlify(hex_data) - base64_data = base64.b64encode(binary_data).decode( - 'utf-8') - employee = self.env['hr.employee'].search( - [('device_id_num', '=', use.user_id), ('company_id', '=', self.env.company.id)], - limit=1) - employee.device_ids |= self - if str(finger.fid) in employee.fingerprint_ids.mapped( - 'finger_id'): - employee.fingerprint_ids.search( - [('finger_id', '=', finger.fid)]).update({ - 'finger_template': base64_data, - }) - else: - employee.fingerprint_ids.create({ - 'finger_template': base64_data, - 'finger_id': finger.fid, - 'employee_bio_id': employee.id, - 'filename': f'{employee.name}-finger-{finger.fid}' - }) - # get all attendances - attendance = conn.get_attendance() - if attendance: - filtered_attendance = [] + device.get_all_users() - for each in attendance: - atten_time = each.timestamp + # Process fingerprints + self._process_fingerprints(conn, device) - # Localize and convert to UTC - 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_str = utc_dt.strftime("%Y-%m-%d %H:%M:%S") - - # Convert to datetime and then to Odoo string format - atten_time = datetime.datetime.strptime(utc_dt_str, "%Y-%m-%d %H:%M:%S") - atten_time = fields.Datetime.to_string(atten_time) - - # Filter for today's date - if atten_time[:10] == datetime.datetime.today().date().strftime("%Y-%m-%d"): - filtered_attendance.append(each) - attendance = filtered_attendance - for each in attendance: - atten_time = each.timestamp - - # Localize and convert to UTC - 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_str = utc_dt.strftime("%Y-%m-%d %H:%M:%S") - - # Convert to datetime and then to Odoo string format - atten_time = datetime.datetime.strptime(utc_dt_str, "%Y-%m-%d %H:%M:%S") - atten_time = fields.Datetime.to_string(atten_time) - - 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), ('company_id', '=', self.env.company.id)], - limit=1) - check_in_today = hr_attendance.search([( - 'employee_id', '=', get_user_id.id), - ('check_in', '!=', False), ('check_out', '=', False)]) - from datetime import timedelta - - # Define the tolerance (10 minutes) - tolerance = timedelta(minutes=10) - - # 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") - - # Calculate the lower and upper bounds with the tolerance - lower_bound = atten_time_obj - tolerance - upper_bound = atten_time_obj + tolerance - - # Ensure the 'check_in' and 'check_out' fields are datetime objects and compare them - next_in = hr_attendance.search([ - ('employee_id', '=', get_user_id.id), - ('check_in', '>=', lower_bound), - ('check_in', '<=', upper_bound) - ]) - - next_out = hr_attendance.search([ - ('employee_id', '=', get_user_id.id), - ('check_out', '>=', lower_bound), - ('check_out', '<=', upper_bound) - ]) - if get_user_id: - if self.display_name == 'IN' and not check_in_today: - if next_in: - continue - hr_attendance.create({ - 'employee_id': get_user_id.id, - 'check_in': atten_time, - }) - 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: - pass - duplicate_atten_ids = zk_attendance.search( - [('device_id_num', '=', each.user_id), - ('punching_time', '=', atten_time), - ('company_id', '=', self.env.company.id)]) - if not duplicate_atten_ids: - zk_attendance.create({ - 'employee_id': get_user_id.id, - 'device_id_num': each.user_id, - 'attendance_type': str(1), - 'punch_type': '0' if self.display_name == 'IN' else '1', - 'punching_time': atten_time, - 'address_id': info.address_id.id, - 'company_id': self.env.company.id - }) - # att_var = hr_attendance.search([( - # 'employee_bio_id', '=', get_user_id.id), - # ('check_out', '=', False)]) - # if self.display_name == 'IN': # check-in - # if not att_var: - # hr_attendance.create({ - # 'employee_id': - # get_user_id.id, - # 'check_in': atten_time - # }) - # else: # check-out - # if len(att_var) == 1: - # att_var.write({ - # 'check_out': atten_time - # }) - # else: - # att_var1 = hr_attendance.search( - # [('employee_id', '=', - # str(get_user_id.device_id_num))]) - # if att_var1: - # att_var1[-1].write({ - # 'check_out': atten_time - # }) - else: - continue - employee = self.env['hr.employee'].create({ - 'device_id_num': each.user_id, - 'device_ids': self.id, - 'name': uid.name, - 'company_id': self.company_id.id - }) - zk_attendance.create({ - 'employee_id': employee.id, - 'device_id_num': each.user_id, - 'attendance_type': str(1), - 'punch_type': '0' if self.display_name == 'IN' else '1', - 'punching_time': atten_time, - 'address_id': info.address_id.id, - 'company_id': self.company_id.id - }) - hr_attendance.create({ - 'employee_id': employee.id, - 'check_in': atten_time - }) - if not self.is_live_capture: - current_time = fields.datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') - message = (f'Downloaded data from the device on ' - f'{current_time} by {self.env.user.name}') - self.message_post(body=message) - conn.disconnect() - return True - else: + # Process attendance data + attendance_data = conn.get_attendance() + if not attendance_data: zk.test_voice(index=4) - 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.')) + raise UserError(_('No attendance records found on the device.')) + + self._process_attendance_data(attendance_data, conn, device, zk_attendance, hr_attendance) + + # Post success message if not live capture + if not device.is_live_capture: + current_time = fields.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + message = f'Downloaded data from the device on {current_time} by {self.env.user.name}' + device.message_post(body=message) + + conn.disconnect() + return True + + except NameError: + raise UserError(_("Pyzk module not found. Please install it with 'pip3 install pyzk'.")) + except Exception as e: + _logger.error(f"Error processing device {device.device_ip}: {str(e)}") + raise UserError(_(f"Error processing device: {str(e)}")) + + def _process_fingerprints(self, conn, device): + """Process fingerprint data from the device""" + users = conn.get_users() + fingers = conn.get_templates() + + for user in users: + for finger in fingers: + if finger.uid == user.uid: + templates = conn.get_user_template( + uid=user.uid, + temp_id=finger.fid, + user_id=user.user_id + ) + + # Convert template data + hex_data = templates.template.hex() + binary_data = binascii.unhexlify(hex_data) + base64_data = base64.b64encode(binary_data).decode('utf-8') + + # Find or create employee + employee = self.env['hr.employee'].search([ + ('device_id_num', '=', user.user_id), + ('company_id', '=', self.env.company.id) + ], limit=1) + + if not employee: + continue + + employee.device_ids |= device + + # Update or create fingerprint record + fingerprint = employee.fingerprint_ids.filtered(lambda f: f.finger_id == str(finger.fid)) + if fingerprint: + fingerprint.finger_template = base64_data + else: + self.env['hr.employee.fingerprint'].create({ + 'finger_template': base64_data, + 'finger_id': finger.fid, + 'employee_bio_id': employee.id, + 'filename': f'{employee.name}-finger-{finger.fid}' + }) + + def _process_attendance_data(self, attendance_data, conn, device, zk_attendance, hr_attendance): + """Process attendance data from the device""" + users = conn.get_users() + today = datetime.datetime.today().date().strftime("%Y-%m-%d") + tolerance = datetime.timedelta(minutes=10) + + # Filter today's attendance + filtered_attendance = [ + att for att in attendance_data + if att.timestamp.date().strftime("%Y-%m-%d") == today + ] + + for attendance in filtered_attendance: + # Convert time to UTC + atten_time = self._convert_to_utc(attendance.timestamp, self.env.user.partner_id.tz or 'GMT') + atten_time_str = fields.Datetime.to_string(atten_time) + + # Find matching user + user = next((u for u in users if u.user_id == attendance.user_id), None) + if not user: + continue + + # Find or create employee + employee = self.env['hr.employee'].search([ + ('device_id_num', '=', attendance.user_id), + ('company_id', '=', self.env.company.id) + ], limit=1) + + if not employee: + continue + employee = self._create_employee_from_device(user, device) + + # Process attendance record + self._process_attendance_record( + device, + employee, + atten_time_str, + zk_attendance, + hr_attendance, + tolerance + ) + + def _convert_to_utc(self, timestamp, timezone_str): + """Convert local timestamp to UTC""" + local_tz = pytz.timezone(timezone_str) + local_dt = local_tz.localize(timestamp, is_dst=None) + return local_dt.astimezone(pytz.utc) + + def _create_employee_from_device(self, user, device): + """Create new employee from device user data""" + return self.env['hr.employee'].create({ + 'device_id_num': user.user_id, + 'device_ids': device.id, + 'name': user.name, + 'company_id': device.company_id.id + }) + + def _process_attendance_record(self, device, employee, atten_time_str, zk_attendance, hr_attendance, tolerance): + """Process a single attendance record""" + # Convert string back to datetime for comparison + atten_time = fields.Datetime.from_string(atten_time_str) + + # Check for existing attendance records + check_in_today = hr_attendance.search([ + ('employee_id', '=', employee.id), + ('check_in', '!=', False), + ('check_out', '=', False) + ]) + + # Check for nearby records + lower_bound = atten_time - tolerance + upper_bound = atten_time + tolerance + + nearby_in = hr_attendance.search([ + ('employee_id', '=', employee.id), + ('check_in', '>=', lower_bound), + ('check_in', '<=', upper_bound) + ]) + + nearby_out = hr_attendance.search([ + ('employee_id', '=', employee.id), + ('check_out', '>=', lower_bound), + ('check_out', '<=', upper_bound) + ]) + + # Process based on punch type + if device.display_name == 'IN' and not check_in_today and not nearby_in: + try: + hr_attendance.create({ + 'employee_id': employee.id, + 'check_in': atten_time_str, + }) + employee.attendance_state = 'checked_in' + except: + pass + elif check_in_today and device.display_name != 'IN' and not nearby_out: + if fields.Datetime.from_string(check_in_today.check_in) <= atten_time: + try: + check_in_today.write({ + 'check_out': atten_time_str, + }) + employee.attendance_state = 'checked_out' + except: + pass + + # Create zk attendance record if not exists + if not zk_attendance.search([ + ('device_id_num', '=', employee.device_id_num), + ('punching_time', '=', atten_time_str), + ('company_id', '=', self.env.company.id) + ]): + zk_attendance.create({ + 'employee_id': employee.id, + 'device_id_num': employee.device_id_num, + 'attendance_type': str(1), + 'punch_type': '0' if device.display_name == 'IN' else '1', + 'punching_time': atten_time_str, + 'address_id': device.address_id.id, + 'company_id': self.env.company.id + }) def action_restart_device(self): """For restarting the device""" @@ -676,11 +677,16 @@ class BiometricDeviceDetails(models.Model): "with 'pip3 install pyzk'.")) conn = self.device_connect(zk) if conn: - self.device_name = conn.get_device_name() - self.device_firmware = conn.get_firmware_version() - self.device_serial_no = conn.get_serialnumber() - self.device_platform = conn.get_platform() - self.device_mac = conn.get_mac() + if not self.device_name: + self.device_name = conn.get_device_name() + if not self.device_firmware: + self.device_firmware = conn.get_firmware_version() + if not self.device_serial_no: + self.device_serial_no = conn.get_serialnumber() + if not self.device_platform: + self.device_platform = conn.get_platform() + if not self.device_mac: + self.device_mac = conn.get_mac() else: raise UserError(_( "Please Check the Connection")) From a6c3bbc3bc2b40d9cf6966736306a4055446ff95 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 02/49] Initial commit From 69b502124fcc512357f7f1792611e828b9077fc1 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 03/49] Initial commit From 25d9b0b464d1a9e02a9cfa427bff0b3e044dba32 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 04/49] Initial commit From 1933ea81950f552fb5ac170eaf3210c73c44b532 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 05/49] Initial commit From a58d0fa86383cb19a50d34b88b52d52c23e0d3f8 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 06/49] Initial commit From cf45af32e9981ff4c171cad1834b314fdbf721ea Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 07/49] Initial commit From 20a006b714c3f9630609ef0e42c4f72ae9238d98 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 08/49] Initial commit From ee9434a2246faf4eefd95df66dc486feeb2d5992 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 09/49] Initial commit From 3730ea8e2f14d2631efddd011d7b56f0a064e1a5 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 10/49] Initial commit From 7c8779c01ff33962df42e19ad652badc10d36f35 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 11/49] Initial commit From 811d7b01e195fbfdd4daacbc9dd35e21d7076c14 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 12/49] Initial commit From c138aa19bdb7ad5eb7092450912e07a27d6d79fc Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 13/49] Initial commit From e123ee062a438523ba9c1f0f7c74a7d415d7161e Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 14/49] Initial commit From f8ec754f238293f53fcbbd175af21e56902616c4 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 15/49] Initial commit From 52c2084ca58aefb19f0ddc11c4f6db5eeae093f9 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 16/49] Initial commit From 1c34616fe2f6c2c274c6807988471200a62a29f8 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 17/49] Initial commit From dc5884b49bf2ff24007a999a3c14049beca6f16e Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 18/49] Initial commit From a1dd936e924e94e89c06b457f7299f5e49c29834 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 19/49] Initial commit From 5ab7206139b1de8637023ebb8314503f74f799d6 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 20/49] Initial commit From 72b993938f6329762a80209cb83a348249adaa54 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 21/49] Initial commit From a2fa677510c111a70bed7575e64b8c7c84e7973b Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 11:35:35 +0530 Subject: [PATCH 22/49] update whatsapp code --- addons_extensions/whatsapp/models/discuss_channel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons_extensions/whatsapp/models/discuss_channel.py b/addons_extensions/whatsapp/models/discuss_channel.py index e2989c112..7fb18c9cf 100644 --- a/addons_extensions/whatsapp/models/discuss_channel.py +++ b/addons_extensions/whatsapp/models/discuss_channel.py @@ -201,8 +201,7 @@ class DiscussChannel(models.Model): subtype_xmlid='mail.mt_note', ) if partners_to_notify == channel.whatsapp_partner_id and wa_account_id.notify_user_ids.partner_id: - partners_to_notify += wa_account_id.notify_user_ids.partner_id - partners_to_notify = self.env['res.partner'].browse(list(set(partners_to_notify.ids))) + partners_to_notify |= wa_account_id.notify_user_ids.partner_id channel.channel_member_ids = [Command.clear()] + [Command.create({'partner_id': partner.id}) for partner in partners_to_notify] channel._broadcast(partners_to_notify.ids) return channel From 5f1279027fffa1bb8fa201d7c5be9fd94eeb5c37 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 12:54:38 +0530 Subject: [PATCH 23/49] fix whatsapp --- addons_extensions/whatsapp/models/discuss_channel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons_extensions/whatsapp/models/discuss_channel.py b/addons_extensions/whatsapp/models/discuss_channel.py index 7fb18c9cf..e2989c112 100644 --- a/addons_extensions/whatsapp/models/discuss_channel.py +++ b/addons_extensions/whatsapp/models/discuss_channel.py @@ -201,7 +201,8 @@ class DiscussChannel(models.Model): subtype_xmlid='mail.mt_note', ) if partners_to_notify == channel.whatsapp_partner_id and wa_account_id.notify_user_ids.partner_id: - partners_to_notify |= wa_account_id.notify_user_ids.partner_id + partners_to_notify += wa_account_id.notify_user_ids.partner_id + partners_to_notify = self.env['res.partner'].browse(list(set(partners_to_notify.ids))) channel.channel_member_ids = [Command.clear()] + [Command.create({'partner_id': partner.id}) for partner in partners_to_notify] channel._broadcast(partners_to_notify.ids) return channel From 4cbb45bb35c0ffb3bcd337f3714eca255bdcd3c5 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 13:10:34 +0530 Subject: [PATCH 24/49] Recruitment Changes --- .../hr_recruitment_extended/models/hr_job_recruitment.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py b/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py index 97b114a76..d546a3cde 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py @@ -256,6 +256,8 @@ class HRJobRecruitment(models.Model): rec.submission_status = 'zero' + experience = fields.Many2one('candidate.experience', string="Experience") + @api.depends('application_ids.submitted_to_client') def _compute_no_of_submissions(self): counts = dict(self.env['hr.applicant']._read_group( From 7975c10a8d7f21e13ec22e0f3fc9ec057f366ca1 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 7 Apr 2025 16:08:02 +0530 Subject: [PATCH 25/49] time-off FIX --- addons_extensions/hr_timeoff_extended/models/hr_timeoff.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py b/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py index 593c2a541..fea92e9e5 100644 --- a/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py +++ b/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py @@ -1,3 +1,4 @@ +from asyncore import write from calendar import month from dateutil.utils import today From 215efe83b0f74db75966dee82159ae93bac23aa4 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 7 Apr 2025 16:34:42 +0530 Subject: [PATCH 26/49] TimeOff Fix --- addons_extensions/hr_timeoff_extended/models/hr_timeoff.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py b/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py index fea92e9e5..593c2a541 100644 --- a/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py +++ b/addons_extensions/hr_timeoff_extended/models/hr_timeoff.py @@ -1,4 +1,3 @@ -from asyncore import write from calendar import month from dateutil.utils import today From 18587884d3c2230e62dc42a2cc6119d20bc99396 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 27/49] Initial commit From 12906c27b71ec507a2e283bfcf67b6967da32cbe Mon Sep 17 00:00:00 2001 From: administrator Date: Mon, 2 Jun 2025 15:19:52 +0530 Subject: [PATCH 28/49] pull commit --- addons_extensions/hr_employee_extended/__manifest__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons_extensions/hr_employee_extended/__manifest__.py b/addons_extensions/hr_employee_extended/__manifest__.py index ec27233ec..ee072e92c 100644 --- a/addons_extensions/hr_employee_extended/__manifest__.py +++ b/addons_extensions/hr_employee_extended/__manifest__.py @@ -18,8 +18,12 @@ 'version': '0.1', # any module necessary for this one to work correctly + 'depends': ['base','hr','account','mail','hr_skills', 'hr_contract'], + + + # always loaded 'data': [ 'security/security.xml', From cc099dcf658b4ccb68877b76acc73045d81d8614 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 29/49] Initial commit From 69ff3fc472ae274bf1ad195f8c551d3cbeefaed6 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 30/49] Initial commit From 9d2ccd7bf61f65aec913804b4762d1fea9acd661 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 31/49] Initial commit From 5665434c06285dfbb97e52da3acb36451fe123b0 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 32/49] Initial commit From b5c0db13b3282a27c02b6f4925217699756639b9 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 33/49] Initial commit From d3cb63931fd62775069f7d8549301b34c0f21f91 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 34/49] Initial commit From 40cf14cfedd5267e3f199ef3ddf3d074cffddcfc Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 35/49] Initial commit From f4c7dbca2f08a5d4d01d5dc9b104c70d54acdb03 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 36/49] Initial commit From b31e1ca05de4151c35307ee6bf1bf5b393fc100c Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 37/49] Initial commit From bebdf67b85fb0790bd9a3de30f343baacd710dc7 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 38/49] Initial commit From 0b094d5d91e45c48348145e38e3748b7cc3c3c97 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 39/49] Initial commit From e99290e9236045a6b5e629c8afb17c17cad724d5 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 40/49] Initial commit From fafe56f11ed2695d7e6e833301247456bd070469 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 41/49] Initial commit From a1e38df43fef0e326fc0d49598b3ab6e68d66b04 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 42/49] Initial commit From e61817542b3d6864d8750c44cc1c35ebe9a15dd8 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 43/49] Initial commit From 229947f7e754e31b43a032bae66031e20937e990 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 44/49] Initial commit From 9954df10637208e04094b000d9d469417244181a Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 45/49] Initial commit From 14bb2bc740775f66715e7cb5d14b9de5f2a5ac32 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 46/49] Initial commit From 7667090b96d05be8069b3dd8eb0093fd41980e04 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 47/49] Initial commit From d22519d53c1dde6231a4a08f7f96831b7ba97d59 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 48/49] Initial commit From 49e7b97e0982c2dcb18e5006dbf44d8f07be0354 Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 7 Jan 2025 09:29:28 +0530 Subject: [PATCH 49/49] Initial commit