From 8877a4ebc4686b90ad511dcacd9ea0bb76832e15 Mon Sep 17 00:00:00 2001 From: Bhagya-K Date: Mon, 15 Jun 2026 10:59:42 +0530 Subject: [PATCH] DEV: Sequence genartion for Employee Code --- .../grace_period/models/__init__.py | 2 +- .../grace_period/models/attendance_data.py | 22 +++++++--- .../models/hr_employee_inherit.py | 6 ++- .../models/resource_calendar_period.py | 11 ++++- .../grace_period/views/attendance_data.xml | 9 +++- .../views/late_coming_request.xml | 10 +++-- .../grace_period/views/ot_request.xml | 2 +- .../views/resource_calendar_period.xml | 20 +++++++-- .../hr_employee_extended/__manifest__.py | 1 + .../hr_employee_extended/data/sequence.xml | 11 +++++ .../models/hr_employee.py | 43 +++++++++++++++++++ 11 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 addons_extensions/hr_employee_extended/data/sequence.xml diff --git a/addons_extensions/grace_period/models/__init__.py b/addons_extensions/grace_period/models/__init__.py index dfcf996f8..95729dee9 100644 --- a/addons_extensions/grace_period/models/__init__.py +++ b/addons_extensions/grace_period/models/__init__.py @@ -1,5 +1,5 @@ from . import resource_calendar_period from . import late_coming_request from . import ot_request -from . import attendance_data from . import hr_employee_inherit +from . import attendance_data diff --git a/addons_extensions/grace_period/models/attendance_data.py b/addons_extensions/grace_period/models/attendance_data.py index 336536635..5ee94ae00 100644 --- a/addons_extensions/grace_period/models/attendance_data.py +++ b/addons_extensions/grace_period/models/attendance_data.py @@ -104,6 +104,19 @@ class AttendanceAnalytics(models.Model): shift_name = fields.Char( string='Shift' ) + attendance_mode = fields.Selection( + related='employee_id.attendance_mode', + string='Attendance Mode', + store=True, + readonly=True, + ) + work_mode = fields.Selection( + [ + ('office', 'Office'), + ('wfh', 'Work From Home'), + ], + string='Work Mode' + ) @api.depends('late_minutes') def _compute_late_time(self): @@ -305,17 +318,12 @@ class AttendanceAnalytics(models.Model): self.env.cr.execute(""" CREATE OR REPLACE VIEW attendance_analytics AS ( - WITH employee_dates AS ( - SELECT - emp.id AS employee_id, - emp.department_id, - emp.resource_calendar_id, - + emp.attendance_mode, generate_series( DATE(emp.create_date), CURRENT_DATE, @@ -323,7 +331,6 @@ class AttendanceAnalytics(models.Model): )::date AS date FROM hr_employee emp - WHERE emp.active = true ), @@ -430,6 +437,7 @@ class AttendanceAnalytics(models.Model): row_number() OVER() AS id, ed.employee_id, ed.department_id, + ed.attendance_mode AS attendance_mode, rc.id AS shift_id, rc.name AS shift_name, ed.date, diff --git a/addons_extensions/grace_period/models/hr_employee_inherit.py b/addons_extensions/grace_period/models/hr_employee_inherit.py index 88425b45f..9ca031513 100644 --- a/addons_extensions/grace_period/models/hr_employee_inherit.py +++ b/addons_extensions/grace_period/models/hr_employee_inherit.py @@ -10,7 +10,7 @@ class HREmployee(models.Model): ) attendance_mode = fields.Selection( [ - ('office', 'Office Based'), + ('office', 'Office'), ('remote', 'Remote'), ('hybrid', 'Hybrid'), ('shift', 'Shift Based'), @@ -19,6 +19,10 @@ class HREmployee(models.Model): default='office', tracking=True, ) + work_mode = fields.Selection([ + ('office', 'Office'), + ('wfh', 'Work From Home'), + ], default='office') def _compute_attendance_analytics_count(self): diff --git a/addons_extensions/grace_period/models/resource_calendar_period.py b/addons_extensions/grace_period/models/resource_calendar_period.py index 114183196..77f2e74da 100644 --- a/addons_extensions/grace_period/models/resource_calendar_period.py +++ b/addons_extensions/grace_period/models/resource_calendar_period.py @@ -51,6 +51,7 @@ class ResourceCalendar(models.Model): 'dayofweek': day.code, 'hour_from': rec.shift_start_time, 'hour_to': rec.shift_end_time, + 'work_mode': 'office', })) # Single write operation @@ -110,4 +111,12 @@ class ResourceCalendarDepartmentGrace(models.Model): grace_period = fields.Integer( string="Grace Period (Minutes)", required=True - ) \ No newline at end of file + ) + +class ResourceCalendarAttendance(models.Model): + _inherit = 'resource.calendar.attendance' + + work_mode = fields.Selection([ + ('office', 'Office'), + ('wfh', 'Work From Home'), + ]) \ No newline at end of file diff --git a/addons_extensions/grace_period/views/attendance_data.xml b/addons_extensions/grace_period/views/attendance_data.xml index 2ddccc894..badbd4118 100644 --- a/addons_extensions/grace_period/views/attendance_data.xml +++ b/addons_extensions/grace_period/views/attendance_data.xml @@ -23,6 +23,7 @@ + + \ No newline at end of file diff --git a/addons_extensions/grace_period/views/late_coming_request.xml b/addons_extensions/grace_period/views/late_coming_request.xml index 7e2ca66ca..b98b701f3 100644 --- a/addons_extensions/grace_period/views/late_coming_request.xml +++ b/addons_extensions/grace_period/views/late_coming_request.xml @@ -97,10 +97,14 @@ ] - + \ No newline at end of file diff --git a/addons_extensions/grace_period/views/ot_request.xml b/addons_extensions/grace_period/views/ot_request.xml index 277d9bcd2..173a83c0d 100644 --- a/addons_extensions/grace_period/views/ot_request.xml +++ b/addons_extensions/grace_period/views/ot_request.xml @@ -92,7 +92,7 @@ diff --git a/addons_extensions/grace_period/views/resource_calendar_period.xml b/addons_extensions/grace_period/views/resource_calendar_period.xml index 6027a441c..a5e698a86 100644 --- a/addons_extensions/grace_period/views/resource_calendar_period.xml +++ b/addons_extensions/grace_period/views/resource_calendar_period.xml @@ -77,10 +77,22 @@ - - + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/addons_extensions/hr_employee_extended/__manifest__.py b/addons_extensions/hr_employee_extended/__manifest__.py index 32ead39b3..a5f8939f3 100644 --- a/addons_extensions/hr_employee_extended/__manifest__.py +++ b/addons_extensions/hr_employee_extended/__manifest__.py @@ -26,6 +26,7 @@ 'security/ir.model.access.csv', 'data/cron.xml', 'data/mail.xml', + 'data/sequence.xml', 'views/res_config_settings.xml', 'views/hr_employee.xml', 'views/bank_details.xml', diff --git a/addons_extensions/hr_employee_extended/data/sequence.xml b/addons_extensions/hr_employee_extended/data/sequence.xml new file mode 100644 index 000000000..480b2d81c --- /dev/null +++ b/addons_extensions/hr_employee_extended/data/sequence.xml @@ -0,0 +1,11 @@ + + + + + + Employee Sequence + hr.employee.running + 4 + + + \ No newline at end of file diff --git a/addons_extensions/hr_employee_extended/models/hr_employee.py b/addons_extensions/hr_employee_extended/models/hr_employee.py index abd75a991..acc19bd66 100644 --- a/addons_extensions/hr_employee_extended/models/hr_employee.py +++ b/addons_extensions/hr_employee_extended/models/hr_employee.py @@ -33,7 +33,19 @@ class HrEmployeeBase(models.AbstractModel): ('AB-', 'AB-'), ], string="Blood Group") + @api.constrains('employee_id') + def _check_employee_code_unique(self): + for rec in self: + if rec.employee_id: + duplicate = self.search([ + ('id', '!=', rec.id), + ('employee_id', '=', rec.employee_id) + ], limit=1) + if duplicate: + raise ValidationError( + _("Employee Code '%s' already exists.") % rec.employee_id + ) @api.constrains('identification_id') def _check_identification_id(self): @@ -158,6 +170,37 @@ class HrEmployee(models.Model): previous_company_pf_no = fields.Char(string='Previous Company PF No') previous_company_uan_no = fields.Char(string='Previous Company UAN No') + def _generate_employee_code(self, vals): + + location = self.env['hr.work.location'].browse( + vals.get('work_location_id') + ) + + department = self.env['hr.department'].browse( + vals.get('department_id') + ) + + loc_code = location.location_number or location.name or "GEN" + + dept_code = getattr(department, 'code', False) or department.name or "GEN" + + year = fields.Date.today().year + + seq = self.env['ir.sequence'].next_by_code( + 'hr.employee.running' + ) or '0001' + + return f"{loc_code}-{dept_code}-{year}-{seq}" + + @api.model_create_multi + def create(self, vals_list): + + for vals in vals_list: + if not vals.get('employee_id'): + vals['employee_id'] = self._generate_employee_code(vals) + + return super().create(vals_list) + def hr_employee_event_remainder(self): self.send_birthday_reminders() today = fields.Date.today()