I created a custom module called recruit ink that I wanted to put on top of the recruitment module, it's like a recruitment request process to start the actual recruitment. In it I have a Many2one field called requested_job_id in my form view that you fill to ask for a job
What I wanted to happen is when the job field is populated a tree view in a notebook page gets filled with employees of that job but as I tried to implement this I failed over and over again sometimes the employee record just gets deleted and I have no idea why.
I also tried Many2many and creating a rel table but its the same thing as soon as I save it's getting deleted.
Here is my code module code:
from markupsafe import Markup
from odoo import api, models, fields , _
from odoo.exceptions import ValidationError, UserError
class RecruitInkDemande(models.Model):
_name = "recruit_ink.demande"
_description = "Demande de recrutement"
_rec_name = "reference"
_inherit = ["mail.thread"]
reference = fields.Char(string="Référence" ,copy=False, readonly=True,index='trigram',default=lambda self: _('Nouveau'))
recruitment_topic = fields.Char(string="Sujet de recrutement", required=True,tracking=True)
expected_employees = fields.Char(string="Employé attendu",tracking=True,required=True)
user_group = fields.Char(string="Current User", compute="_compute_check_user_group",store=False)
requester_id = fields.Many2one('res.users',string="Demandeur", required=True,readonly=False,default= lambda self : self.env.user)
departement_id = fields.Many2one('hr.department', string="Département", required=True, readonly=False,default=lambda self: self.env.user.department_id)
requested_job_id = fields.Many2one(comodel_name='hr.job', string="Poste demandé", tracking=True)
employee_ids = fields.One2many('hr.employee', 'demande_id', string="Employees",readonly=True)
submission_date = fields.Datetime(string="Date de soumission", readonly=True, tracking=True)
job_description = fields.Html(string="Déscription du poste", required=True)
requirements = fields.Html(string="Exigences", required=True)
update_job_description_requirements = fields.Boolean(string="",default=False,help="Cochez cette case pour mettre à jour la description et les requirements lors du choix du poste")
status = fields.Selection([
('brouillon', 'BROUILLON'),
('en_attente', 'EN ATTENTE'),
('validé', 'VALIDÉ'),
('en_recrutement', 'EN RECRUTEMENT'),
('rejeté', 'REJETÉ'),
('cloturé', 'CLOTURÉ')
], string="status", default='brouillon', tracking=True)
@api.onchange('requested_job_id')
def _onchange_requested_job_id(self):
for record in self:
if record.update_job_description_requirements:
if record.requested_job_id:
record.job_description = record.requested_job_id.description
record.requirements = record.requested_job_id.requirements
else:
# Clear the fields if no requested_job_id is selected
record.job_description = False
record.requirements = False
if record.requested_job_id:
record.employee_ids = self.env["hr.employee"].search([("job_id", "=", record.requested_job_id.id)])
else:
record.employee_ids = False
@api.ondelete(at_uninstall=False)
def _unlink_if_brouillon(self):
for record in self:
if record.status != 'brouillon' and self.env.user.name !='Administrator':
raise ValidationError("Vous ne pouvez pas supprimer les demandes qui ne sont pas dans l'état 'brouillon'.\nVous êtes pas l'administrateur ")
def _compute_check_user_group(self):
user=self.env.user
if user.has_group('hr_recruitment.group_hr_recruitment_manager'):
self.user_group = "Administrator"
elif user.has_group('hr_recruitment.group_hr_recruitment_user'):
self.user_group = "RH"
elif user.has_group('hr_recruitment.group_hr_recruitment_interviewer'):
self.user_group = "Interviewer"
@api.model
def get_email_to(self):
# Retrieve the recruitment user group and the manager group
user_group = self.env.ref("hr_recruitment.group_hr_recruitment_user")
manager_group = self.env.ref("hr_recruitment.group_hr_recruitment_manager")
# Filter users who belong to the user group, not the manager group, and have a valid email
email_list = [
usr.partner_id.email for usr in user_group.users
if usr.partner_id.email and manager_group not in usr.groups_id
]
# Join the emails into a comma-separated string
return ",".join(email_list)
# Workflow buttons
def action_submit(self):
for record in self:
if record.status == 'brouillon':
record.status = 'en_attente'
record.submission_date = fields.Datetime.now()
if record.requester_id == self.env.user:
self.env.ref('recruit_ink.soumission_email_template').send_mail(record.id)
def action_validate(self):
for record in self:
if record.status == 'en_attente' :
if record.requested_job_id:
record.status = 'validé'
else:
raise ValidationError("Veuillez choisir un poste de travail valide ")
def action_reject(self):
for record in self:
if record.status == 'en_attente':
record.status = 'rejeté'
def action_reset(self):
for record in self:
if record.status == 'en_attente':
record.status = 'brouillon'
def action_recruit(self):
for record in self:
if record.status =='validé':
record.status = 'en_recrutement'
def action_close(self):
for record in self:
if record.status in ['validé', 'en_recrutement']:
record.status = 'cloturé'
#smart buttons
def action_open_job_configuration(self):
self.ensure_one() # Ensure only one record is being processed
if self.requested_job_id:
return {
'type': 'ir.actions.act_window',
'name': _('Configuration du Poste'),
'res_model': 'hr.job', # The model of the job
'view_mode': 'form',
'res_id': self.requested_job_id.id, # Open the selected job's form view
'target': 'current',
}
def action_see_applications(self):
print("hello")
# default methodes
@api.model
def create(self,vals):
if vals.get('reference',_('Nouveau'))==_('Nouveau'):
vals['reference'] = self.env['ir.sequence'].next_by_code('recruit_ink.demande_de_recrutement.sequence') or _("Nouveau")
return super(RecruitInkDemande,self).create(vals)
def write(self, vals):
# Initialize an empty list to collect the messages
messages = []
# Check if job_description is being updated
if 'job_description' in vals:
for record in self:
if record.job_description != vals['job_description']:
# Log a message to the chatter
messages.append(
f'<li>'
f'La description du poste a été modifiée'
f'</li>'
)
if 'requirements' in vals:
for record in self:
if record.job_description != vals['requirements']:
# Log a message to the chatter
messages.append(
f'<li>'
f'Les requirements du poste on été modifiée'
f'</li>'
)
# If there are messages to log, post them in the chatter
if messages:
# Combine all messages into a list and format it as a single message
message = Markup("".join(messages))
for record in self:
record.message_post(
body=message
)
# Call the super method to perform the actual write operation
return super(RecruitInkDemande, self).write(vals)
and here is the Many2one field that I created in a inherited hr.employee class
from odoo import models, fields
class RecruitInkHrEmployee(models.Model):
_inherit = 'hr.employee'
demande_id= fields.Many2one("recruit_ink.demande","Recruit ink demande" )
the One 2 many field is employee_ids and the implementation is in onchange_requested_job_id
When I choose the job the tree view does get populated but when I save the records disappear.