# -*- coding: utf-8 -*- from odoo import models, fields, api from odoo.exceptions import UserError class HrEmployeeTerminateWizard(models.TransientModel): _name = 'hr.employee.terminate.wizard' _description = 'Employee Termination Wizard' employee_id = fields.Many2one( 'hr.employee', string='Employee', required=True, ) last_day_of_work = fields.Date( string='Last Day of Work', required=True, default=fields.Date.today, ) roe_reason_code = fields.Selection( selection=[ # A - Shortage of Work ('A00', 'A00 - Shortage of work/End of contract or season'), ('A01', 'A01 - Employer bankruptcy or receivership'), # B - Strike/Lockout ('B00', 'B00 - Strike or lockout'), # D - Illness ('D00', 'D00 - Illness or injury'), # E - Quit ('E00', 'E00 - Quit'), ('E02', 'E02 - Quit/Follow spouse'), ('E03', 'E03 - Quit/Return to school'), ('E04', 'E04 - Quit/Health Reasons'), ('E05', 'E05 - Quit/Voluntary retirement'), ('E06', 'E06 - Quit/Take another job'), ('E09', 'E09 - Quit/Employer relocation'), ('E10', 'E10 - Quit/Care for a dependent'), ('E11', 'E11 - Quit/To become self-employed'), # F - Maternity ('F00', 'F00 - Maternity'), # G - Retirement ('G00', 'G00 - Mandatory retirement'), ('G07', 'G07 - Retirement/Approved workforce reduction'), # H - Work-Sharing ('H00', 'H00 - Work-Sharing'), # J - Apprentice ('J00', 'J00 - Apprentice training'), # K - Other ('K00', 'K00 - Other'), ('K12', 'K12 - Other/Change of payroll frequency'), ('K13', 'K13 - Other/Change of ownership'), ('K14', 'K14 - Other/Requested by Employment Insurance'), ('K15', 'K15 - Other/Canadian Forces - Queen\'s Regulations/Orders'), ('K16', 'K16 - Other/At the employee\'s request'), ('K17', 'K17 - Other/Change of Service Provider'), # M - Dismissal ('M00', 'M00 - Dismissal'), ('M08', 'M08 - Dismissal/Terminated within probationary period'), # N - Leave ('N00', 'N00 - Leave of absence'), # P - Parental ('P00', 'P00 - Parental'), # Z - Compassionate Care ('Z00', 'Z00 - Compassionate Care/Family Caregiver'), ], string='Reason for Termination', required=True, help='Record of Employment (ROE) reason code for Service Canada', ) show_in_employee_lists_only = fields.Boolean( string='Keep in Employee Lists', help='If unchecked, employee will be archived after termination', ) issue_roe_now = fields.Boolean( string='Issue ROE Now', default=False, help='Mark Record of Employment as issued immediately', ) notes = fields.Text( string='Termination Notes', ) def action_terminate(self): """Process employee termination""" self.ensure_one() if not self.employee_id: raise UserError('No employee selected.') # Map detailed ROE codes to simple reason codes for hr.roe model roe_code_mapping = { 'A00': 'A', 'A01': 'A', 'B00': 'B', 'D00': 'D', 'E00': 'E', 'E02': 'E', 'E03': 'E', 'E04': 'E', 'E05': 'E', 'E06': 'E', 'E09': 'E', 'E10': 'E', 'E11': 'E', 'F00': 'F', 'G00': 'G', 'G07': 'G', 'H00': 'H', 'J00': 'J', 'K00': 'K', 'K12': 'K', 'K13': 'K', 'K14': 'K', 'K15': 'K', 'K16': 'K', 'K17': 'K', 'M00': 'M', 'M08': 'M', 'N00': 'N', 'P00': 'P', 'Z00': 'Z', } values = { 'employment_status': 'terminated', 'last_day_of_work': self.last_day_of_work, 'roe_reason_code': self.roe_reason_code, 'show_in_employee_lists_only': self.show_in_employee_lists_only, } # Archive employee if not keeping in lists if not self.show_in_employee_lists_only: values['active'] = False self.employee_id.write(values) # End any running contracts running_contracts = self.env['hr.contract'].search([ ('employee_id', '=', self.employee_id.id), ('state', '=', 'open'), ]) if running_contracts: running_contracts.write({ 'date_end': self.last_day_of_work, 'state': 'close', }) # Log note if provided if self.notes: self.employee_id.message_post( body=f"Termination Notes:
{self.notes}", message_type='comment', ) # Create ROE if requested roe = None if self.issue_roe_now: simple_reason = roe_code_mapping.get(self.roe_reason_code, 'K') roe = self.env['hr.roe'].create({ 'employee_id': self.employee_id.id, 'last_day_paid': self.last_day_of_work, 'final_pay_period_end': self.last_day_of_work, 'reason_code': simple_reason, 'contact_name': self.env.user.name, 'communication_language': self.employee_id.communication_language or 'E', }) # Calculate earnings automatically roe.action_calculate_earnings() # Return action to open ROE if created, otherwise show notification if roe: return { 'type': 'ir.actions.act_window', 'name': 'Record of Employment', 'res_model': 'hr.roe', 'res_id': roe.id, 'view_mode': 'form', 'target': 'current', } return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': 'Employee Terminated', 'message': f'{self.employee_id.name} has been terminated. ROE Code: {self.roe_reason_code}', 'type': 'warning', 'sticky': True, } }