From 931f4e5c191d9912d33c726eefaaefc6dc8cb249 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 11:19:03 +0530 Subject: [PATCH 01/43] FIX; Whatsapp issue --- addons_extensions/whatsapp/models/discuss_channel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons_extensions/whatsapp/models/discuss_channel.py b/addons_extensions/whatsapp/models/discuss_channel.py index 80ec5e3fa..e2989c112 100644 --- a/addons_extensions/whatsapp/models/discuss_channel.py +++ b/addons_extensions/whatsapp/models/discuss_channel.py @@ -202,6 +202,7 @@ class DiscussChannel(models.Model): ) 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))) 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 -- 2.43.0 From b7ccb5a3e0c190ba34967af56f04d1bad9132032 Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 11:35:35 +0530 Subject: [PATCH 02/43] 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 -- 2.43.0 From e4e6fc9709b370ec10913685105062b369b1f5bc Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 12:54:38 +0530 Subject: [PATCH 03/43] 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 -- 2.43.0 From 24f440a6fdaeabdcd032dfce6b1d6710503f4daf Mon Sep 17 00:00:00 2001 From: Pranay Date: Mon, 24 Mar 2025 13:10:34 +0530 Subject: [PATCH 04/43] Recruitment Changes --- .../models/candidate_experience.py | 19 ++++++++++--------- .../models/hr_job_recruitment.py | 2 ++ .../views/candidate_experience.xml | 6 +++--- .../views/hr_job_recruitment.xml | 6 ++++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/addons_extensions/hr_recruitment_extended/models/candidate_experience.py b/addons_extensions/hr_recruitment_extended/models/candidate_experience.py index e98a694f6..2b6bfdbba 100644 --- a/addons_extensions/hr_recruitment_extended/models/candidate_experience.py +++ b/addons_extensions/hr_recruitment_extended/models/candidate_experience.py @@ -13,14 +13,15 @@ class CandidateExperience(models.Model): experience_code = fields.Char('Experience Code') experience_from = fields.Integer(string="Experience From (Years)") experience_to = fields.Integer(string="Experience To (Years)") - + # display_name = fields.Char(string="Display Name") # active = fields.Boolean() - def name_get(self): - """ Override name_get to display a custom name based on recruitment_sequence and job_id """ - result = [] - for record in self: - # Combine recruitment_sequence and job_id name for the display name - name = f"{record.experience_code} - {record.experience_from} - {record.experience_To} years" - result.append((record.id, name)) - return result \ No newline at end of file + # def name_get(self): + # for record in self: + # name = f"{record.experience_code} ({record.experience_from} - {record.experience_to})" + # return name + + @api.depends('experience_code', 'experience_from', 'experience_to') + def _compute_display_name(self): + for template in self: + template.display_name = False if not template.experience_code else f"{template.experience_code} ({template.experience_from} - {template.experience_to} Years)" \ No newline at end of file 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 bdb06bcc8..72ad8c302 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py @@ -202,6 +202,8 @@ class HRJobRecruitment(models.Model): help='Number of Refused Application submissions for this job position during recruitment phase.', ) + 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( diff --git a/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml b/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml index 54a31e858..688638feb 100644 --- a/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml +++ b/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml @@ -7,9 +7,9 @@ candidate.experience - - - + + + diff --git a/addons_extensions/hr_recruitment_extended/views/hr_job_recruitment.xml b/addons_extensions/hr_recruitment_extended/views/hr_job_recruitment.xml index ae59a9f21..0f402a015 100644 --- a/addons_extensions/hr_recruitment_extended/views/hr_job_recruitment.xml +++ b/addons_extensions/hr_recruitment_extended/views/hr_job_recruitment.xml @@ -18,6 +18,7 @@ + @@ -164,6 +165,7 @@ new Employees to hire + @@ -228,7 +230,7 @@ - +
@@ -288,7 +290,7 @@
-
+
-- 2.43.0 From d85cf4822b0463bb4dd5ef5b40ab78e0a54647a8 Mon Sep 17 00:00:00 2001 From: raman Date: Tue, 25 Mar 2025 10:51:50 +0530 Subject: [PATCH 05/43] cwf time sheets --- addons_extensions/cwf_timesheet/__init__.py | 1 + .../cwf_timesheet/__manifest__.py | 20 ++++ .../cwf_timesheet/controllers/controller.py | 9 ++ .../cwf_timesheet/data/email_template.xml | 109 ++++++++++++++++++ .../cwf_timesheet/models/__init__.py | 1 + .../cwf_timesheet/models/timesheet.py | 85 ++++++++++++++ .../security/ir.model.access.csv | 4 + .../static/src/js/timesheet_form.js | 48 ++++++++ .../cwf_timesheet/views/timesheet_form.xml | 27 +++++ .../cwf_timesheet/views/timesheet_view.xml | 83 +++++++++++++ 10 files changed, 387 insertions(+) create mode 100644 addons_extensions/cwf_timesheet/__init__.py create mode 100644 addons_extensions/cwf_timesheet/__manifest__.py create mode 100644 addons_extensions/cwf_timesheet/controllers/controller.py create mode 100644 addons_extensions/cwf_timesheet/data/email_template.xml create mode 100644 addons_extensions/cwf_timesheet/models/__init__.py create mode 100644 addons_extensions/cwf_timesheet/models/timesheet.py create mode 100644 addons_extensions/cwf_timesheet/security/ir.model.access.csv create mode 100644 addons_extensions/cwf_timesheet/static/src/js/timesheet_form.js create mode 100644 addons_extensions/cwf_timesheet/views/timesheet_form.xml create mode 100644 addons_extensions/cwf_timesheet/views/timesheet_view.xml diff --git a/addons_extensions/cwf_timesheet/__init__.py b/addons_extensions/cwf_timesheet/__init__.py new file mode 100644 index 000000000..43559cd9a --- /dev/null +++ b/addons_extensions/cwf_timesheet/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/addons_extensions/cwf_timesheet/__manifest__.py b/addons_extensions/cwf_timesheet/__manifest__.py new file mode 100644 index 000000000..6b23ded8f --- /dev/null +++ b/addons_extensions/cwf_timesheet/__manifest__.py @@ -0,0 +1,20 @@ +{ + 'name': 'CWF Timesheet Update', + 'version': '1.0', + 'category': 'Human Resources', + 'summary': 'Manage and update weekly timesheets for CWF department', + 'author': 'Your Name or Company', + 'depends': ['hr_attendance_extended','web', 'mail', 'base','hr_emp_dashboard'], + 'data': [ + # 'views/timesheet_form.xml', + 'security/ir.model.access.csv', + 'views/timesheet_view.xml', + 'data/email_template.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'cwf_timesheet/static/src/js/timesheet_form.js', + ], + }, + 'application': True, +} diff --git a/addons_extensions/cwf_timesheet/controllers/controller.py b/addons_extensions/cwf_timesheet/controllers/controller.py new file mode 100644 index 000000000..65377f44e --- /dev/null +++ b/addons_extensions/cwf_timesheet/controllers/controller.py @@ -0,0 +1,9 @@ +from odoo import http +from odoo.http import request + +class TimesheetController(http.Controller): + + @http.route('/timesheet/form', auth='user', website=True) + def timesheet_form(self, **kw): + # This will render the template for the timesheet form + return request.render('timesheet_form', {}) diff --git a/addons_extensions/cwf_timesheet/data/email_template.xml b/addons_extensions/cwf_timesheet/data/email_template.xml new file mode 100644 index 000000000..57410b9e2 --- /dev/null +++ b/addons_extensions/cwf_timesheet/data/email_template.xml @@ -0,0 +1,109 @@ + + + + Timesheet Update Reminder + ${(user.email or '')} + Reminder: Update Your Weekly Timesheet + + + + + + + + + diff --git a/addons_extensions/cwf_timesheet/models/__init__.py b/addons_extensions/cwf_timesheet/models/__init__.py new file mode 100644 index 000000000..63ae5f202 --- /dev/null +++ b/addons_extensions/cwf_timesheet/models/__init__.py @@ -0,0 +1 @@ +from . import timesheet \ No newline at end of file diff --git a/addons_extensions/cwf_timesheet/models/timesheet.py b/addons_extensions/cwf_timesheet/models/timesheet.py new file mode 100644 index 000000000..7688a8301 --- /dev/null +++ b/addons_extensions/cwf_timesheet/models/timesheet.py @@ -0,0 +1,85 @@ +from odoo import models, fields, api +from odoo.exceptions import ValidationError, UserError +from datetime import timedelta + +from odoo import _ + +class CwfTimesheet(models.Model): + _name = 'cwf.timesheet' + _description = 'CWF Weekly Timesheet' + + name = fields.Char(string='Week Name', required=True) + department_id = fields.Many2one('hr.department', string='Department') + week_start_date = fields.Date(string='Week Start Date', required=True) + week_end_date = fields.Date(string='Week End Date', required=True) + total_hours = fields.Float(string='Total Hours', required=True) + status = fields.Selection([ + ('draft', 'Draft'), + ('submitted', 'Submitted') + ], default='draft', string='Status') + lines = fields.One2many('cwf.timesheet.line','week_id') + + + + def send_timesheet_update_email(self): + template = self.env.ref('cwf_timesheet.email_template_timesheet_update') + # Ensure that we have a valid employee email + current_date = fields.Date.from_string(self.week_start_date) + end_date = fields.Date.from_string(self.week_end_date) + + if current_date > end_date: + raise UserError('The start date cannot be after the end date.') + + # Get all employees in the department + employees = self.env['hr.employee'].search([('department_id', '=', self.department_id.id)]) + + # Loop through each day of the week and create timesheet lines for each employee + while current_date <= end_date: + for employee in employees: + self.env['cwf.timesheet.line'].create({ + 'week_id': self.id, + 'employee_id': employee.id, + 'week_day':current_date, + }) + current_date += timedelta(days=1) + self.status = 'submitted' + for employee in employees: + if employee.work_email: + email_values = { + 'email_to': employee.work_email, + 'body_html': template.body_html, # Email body from template + 'subject': 'Timesheet Update Notification', + } + + template.send_mail(self.id, email_values=email_values, force_send=True) + + +class CwfTimesheetLine(models.Model): + _name = 'cwf.timesheet.line' + _description = 'CWF Weekly Timesheet Lines' + + employee_id = fields.Many2one('hr.employee', string='Employee') + week_id = fields.Many2one('cwf.timesheet', 'Week') + week_day = fields.Date(string='Date') + check_in_date = fields.Datetime(string='Checkin') + check_out_date = fields.Datetime(string='Checkout ') + is_updated = fields.Boolean('Attendance Updated') + state_type = fields.Selection([('draft','Draft'),('holiday', 'Holiday'),('time_off','Time Off'),('present','Present')], default='draft') + + def action_submit(self): + if self.state_type == 'draft' or not self.state_type: + raise ValidationError(_('State type should not Draft or Empty')) + if self.state_type not in ['holiday','time_off'] and not (self.check_in_date or self.check_out_date): + raise ValidationError(_('Please enter Check details')) + self._update_attendance() + + + def _update_attendance(self): + attendance_obj = self.env['hr.attendance'] + for record in self: + attendance_obj.sudo().create({ + 'employee_id': record.employee_id.id, + 'check_in': record.check_in_date, + 'check_out': record.check_out_date, + }) + record.is_updated = True diff --git a/addons_extensions/cwf_timesheet/security/ir.model.access.csv b/addons_extensions/cwf_timesheet/security/ir.model.access.csv new file mode 100644 index 000000000..6623ea460 --- /dev/null +++ b/addons_extensions/cwf_timesheet/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_cwf_timesheet_user,access.cwf.timesheet,model_cwf_timesheet,,1,1,1,1 +access_cwf_timesheet_line_user,access.cwf.timesheet.line,model_cwf_timesheet_line,,1,1,1,1 + diff --git a/addons_extensions/cwf_timesheet/static/src/js/timesheet_form.js b/addons_extensions/cwf_timesheet/static/src/js/timesheet_form.js new file mode 100644 index 000000000..52e4a134a --- /dev/null +++ b/addons_extensions/cwf_timesheet/static/src/js/timesheet_form.js @@ -0,0 +1,48 @@ +/** @odoo-module **/ + +import { patch } from "@web/core/utils/patch"; +import { NetflixProfileContainer } from "@hr_emp_dashboard/js/profile_component"; + +// Apply patch to NetflixProfileContainer prototype +patch(NetflixProfileContainer.prototype, { + /** + * @override + */ + setup() { + // Call parent setup method + + super.setup(...arguments); + + // Log the department of the logged-in employee (check if data is available) +// if (this.state && this.state.login_employee) { +// console.log(this.state.login_employee['department_id']); +// } else { +// console.error('Employee or department data is unavailable.'); +// } + }, + + /** + * Override the hr_timesheets method + */ + hr_timesheets() { + // Check the department of the logged-in employee + if (this.state.login_employee.department_id == 'CWF') { + // If the department is 'CWF', perform the action to open the timesheets + this.action.doAction({ + name: "Timesheets", + type: 'ir.actions.act_window', + res_model: 'cwf.timesheet.line', // Ensure this model exists + view_mode: 'list,form', + views: [[false, 'list'], [false, 'form']], + context: { + 'search_default_week_id': true, + }, + domain: [['employee_id.user_id','=', this.props.action.context.user_id]], + target: 'current', + }); + } else { + // If not 'CWF', call the base functionality + return super.hr_timesheets(); + } + }, +}); diff --git a/addons_extensions/cwf_timesheet/views/timesheet_form.xml b/addons_extensions/cwf_timesheet/views/timesheet_form.xml new file mode 100644 index 000000000..03a3b1d4f --- /dev/null +++ b/addons_extensions/cwf_timesheet/views/timesheet_form.xml @@ -0,0 +1,27 @@ + + + +
+

Weekly Timesheet

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
diff --git a/addons_extensions/cwf_timesheet/views/timesheet_view.xml b/addons_extensions/cwf_timesheet/views/timesheet_view.xml new file mode 100644 index 000000000..57f80f01e --- /dev/null +++ b/addons_extensions/cwf_timesheet/views/timesheet_view.xml @@ -0,0 +1,83 @@ + + + + CWF Timesheet + cwf.timesheet + list,form + + + cwf.timesheet.form + cwf.timesheet + +
+
+
+ +
+
+ + + + + + + + + + + + +
+
+
+
+ + + + + CWF Timesheet Lines + cwf.timesheet.line + list + {'search_default_group_by_employee_id':1} + + + cwf.timesheet.line.list + cwf.timesheet.line + + + + + + + +
@@ -126,17 +127,18 @@ - -