diff --git a/hr_recruitment_ux/README.rst b/hr_recruitment_ux/README.rst index 98c5aeb0..6150c7b7 100644 --- a/hr_recruitment_ux/README.rst +++ b/hr_recruitment_ux/README.rst @@ -16,10 +16,12 @@ HR Recruitment UX This module adds: -* Automatically archives applicants when they are added to a talent pool +* Automatically archives an applicant when adding it to a talent pool creates a new talent, + and logs an internal note with the pools, the job position and the stage. + Applicants already directly linked to a talent are not archived. * Per-vacancy rotting SLA: allows configuring specific "days to rot" on each job position, - overriding the stage threshold when needed. When enabled on a vacancy, applicants in that - position use the vacancy's threshold instead of the pipeline stage's. + overriding the stage threshold when needed. When enabled on a stage, applicants of a + configured position use the position's threshold instead of the stage's. Installation ============ @@ -40,7 +42,8 @@ Usage To use this module, you need to: -#. Go to ... +#. In debug mode, go to Recruitment > Configuration > Job Positions > Stages and open a stage. +#. Enable "¿Días para deteriorarse por posición?" and add the job positions with their days to rot. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot diff --git a/hr_recruitment_ux/__manifest__.py b/hr_recruitment_ux/__manifest__.py index 0fdc6aaf..66047e26 100644 --- a/hr_recruitment_ux/__manifest__.py +++ b/hr_recruitment_ux/__manifest__.py @@ -19,7 +19,7 @@ ############################################################################## { "name": "Recruitment UX", - "version": "19.0.1.1.0", + "version": "20.0.1.0.0", "category": "Human Resources", "sequence": 14, "author": "ADHOC SA", @@ -30,11 +30,11 @@ "hr_recruitment", ], "data": [ - "security/ir.model.access.csv", + "security/ir.access.csv", "views/hr_recruitment_stage_views.xml", ], "demo": [], - "installable": False, + "installable": True, "auto_install": True, "application": False, } diff --git a/hr_recruitment_ux/i18n/es.po b/hr_recruitment_ux/i18n/es.po new file mode 100644 index 00000000..3a4502a2 --- /dev/null +++ b/hr_recruitment_ux/i18n/es.po @@ -0,0 +1,222 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_recruitment_ux +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 20.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-10-30 16:34+0000\n" +"PO-Revision-Date: 2026-10-30 16:34+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: hr_recruitment_ux +#: model:ir.module.module,description:base.module_hr_recruitment_ux +msgid "" +".. |company| replace:: ADHOC SA\n" +"\n" +".. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png\n" +" :alt: ADHOC SA\n" +" :target: https://www.adhoc.com.ar\n" +"\n" +".. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png\n" +"\n" +".. image:: https://img.shields.io/badge/license-AGPL--3-blue.png\n" +" :target: https://www.gnu.org/licenses/agpl\n" +" :alt: License: AGPL-3\n" +"\n" +"==================\n" +"HR Recruitment UX\n" +"==================\n" +"\n" +"This module adds:\n" +"\n" +"* Automatically archives an applicant when adding it to a talent pool creates a new talent,\n" +" and logs an internal note with the pools, the job position and the stage.\n" +" Applicants already directly linked to a talent are not archived.\n" +"* Per-vacancy rotting SLA: allows configuring specific \"days to rot\" on each job position,\n" +" overriding the stage threshold when needed. When enabled on a stage, applicants of a\n" +" configured position use the position's threshold instead of the stage's.\n" +"\n" +"Installation\n" +"============\n" +"\n" +"To install this module, you need to:\n" +"\n" +"#. Just install this module\n" +"\n" +"Configuration\n" +"=============\n" +"\n" +"To configure this module, you need to:\n" +"\n" +"#. Nothing to configure\n" +"\n" +"Usage\n" +"=====\n" +"\n" +"To use this module, you need to:\n" +"\n" +"#. In debug mode, go to Recruitment > Configuration > Job Positions > Stages and open a stage.\n" +"#. Enable \"¿Días para deteriorarse por posición?\" and add the job positions with their days to rot.\n" +"\n" +".. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas\n" +" :alt: Try me on Runbot\n" +" :target: http://runbot.adhoc.com.ar/\n" +"\n" +"Bug Tracker\n" +"===========\n" +"\n" +"Bugs are tracked on `GitHub Issues\n" +"`_. In case of trouble, please\n" +"check there if your issue has already been reported. If you spotted it first,\n" +"help us smashing it by providing a detailed and welcomed feedback.\n" +"\n" +"Credits\n" +"=======\n" +"\n" +"Images\n" +"------\n" +"\n" +"* |company| |icon|\n" +"\n" +"Contributors\n" +"------------\n" +"\n" +"Maintainer\n" +"----------\n" +"\n" +"|company_logo|\n" +"\n" +"This module is maintained by ADHOC SA.\n" +"\n" +"To contribute to this module, please visit https://www.adhoc.com.ar.\n" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,help:hr_recruitment_ux.field_hr_job_stage_rotting__rotting_days +msgid "0 = sin deterioro para esta combinación de vacante y etapa." +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model,name:hr_recruitment_ux.model_talent_pool_add_applicants +msgid "Add applicants to talent pool" +msgstr "Agregar postulantes a la base de talentos" + +#. module: hr_recruitment_ux +#: model:ir.model,name:hr_recruitment_ux.model_hr_applicant +msgid "Applicant" +msgstr "Postulante" + +#. module: hr_recruitment_ux +#. odoo-python +#: code:addons/hr_recruitment_ux/models/talent_pool_add_applicants.py:0 +msgid "" +"Candidato derivado a Talent Pool: %(pools)s (vacante: %(job)s — etapa: " +"%(stage)s)" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_applicant__display_name +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__display_name +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_recruitment_stage__display_name +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_talent_pool_add_applicants__display_name +msgid "Display Name" +msgstr "Mostrar nombre" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__rotting_days +#: model_terms:ir.ui.view,arch_db:hr_recruitment_ux.hr_recruitment_stage_form_inherit_ux +msgid "Días para deteriorarse" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_recruitment_stage__job_rotting_ids +msgid "Días para deteriorarse por posición" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model,name:hr_recruitment_ux.model_hr_job_stage_rotting +msgid "Días para deteriorarse por vacante y etapa" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_applicant__id +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__id +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_recruitment_stage__id +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_talent_pool_add_applicants__id +msgid "ID" +msgstr "ID" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__job_id +msgid "Job" +msgstr "Puesto" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: hr_recruitment_ux +#: model_terms:ir.ui.view,arch_db:hr_recruitment_ux.hr_recruitment_stage_form_inherit_ux +msgid "Posición" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model,name:hr_recruitment_ux.model_hr_recruitment_stage +msgid "Recruitment Stage" +msgstr "Etapa de reclutamiento" + +#. module: hr_recruitment_ux +#: model:ir.module.module,shortdesc:base.module_hr_recruitment_ux +msgid "Recruitment UX" +msgstr "Reclutamiento UX" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_job_stage_rotting__stage_id +msgid "Stage" +msgstr "Etapa" + +#. module: hr_recruitment_ux +#: model:ir.model.constraint,message:hr_recruitment_ux.constraint_hr_job_stage_rotting_unique_job_stage +msgid "Ya existe una configuración para esta vacante y etapa." +msgstr "" + +#. module: hr_recruitment_ux +#. odoo-python +#: code:addons/hr_recruitment_ux/models/talent_pool_add_applicants.py:0 +msgid "sin etapa" +msgstr "" + +#. module: hr_recruitment_ux +#. odoo-python +#: code:addons/hr_recruitment_ux/models/talent_pool_add_applicants.py:0 +msgid "sin vacante" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.model.fields,field_description:hr_recruitment_ux.field_hr_recruitment_stage__use_rotting_per_job +msgid "¿Días para deteriorarse por posición?" +msgstr "" diff --git a/hr_recruitment_ux/i18n/hr_recruitment_ux.pot b/hr_recruitment_ux/i18n/hr_recruitment_ux.pot index 3f2f112f..03b1d4bf 100644 --- a/hr_recruitment_ux/i18n/hr_recruitment_ux.pot +++ b/hr_recruitment_ux/i18n/hr_recruitment_ux.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 19.0+e\n" +"Project-Id-Version: Odoo Server 20.0+e\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-18 17:23+0000\n" -"PO-Revision-Date: 2026-06-18 17:23+0000\n" +"POT-Creation-Date: 2026-10-30 16:34+0000\n" +"PO-Revision-Date: 2026-10-30 16:34+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -15,6 +15,89 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: hr_recruitment_ux +#: model:ir.module.module,description:base.module_hr_recruitment_ux +msgid "" +".. |company| replace:: ADHOC SA\n" +"\n" +".. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png\n" +" :alt: ADHOC SA\n" +" :target: https://www.adhoc.com.ar\n" +"\n" +".. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png\n" +"\n" +".. image:: https://img.shields.io/badge/license-AGPL--3-blue.png\n" +" :target: https://www.gnu.org/licenses/agpl\n" +" :alt: License: AGPL-3\n" +"\n" +"==================\n" +"HR Recruitment UX\n" +"==================\n" +"\n" +"This module adds:\n" +"\n" +"* Automatically archives an applicant when adding it to a talent pool creates a new talent,\n" +" and logs an internal note with the pools, the job position and the stage.\n" +" Applicants already directly linked to a talent are not archived.\n" +"* Per-vacancy rotting SLA: allows configuring specific \"days to rot\" on each job position,\n" +" overriding the stage threshold when needed. When enabled on a stage, applicants of a\n" +" configured position use the position's threshold instead of the stage's.\n" +"\n" +"Installation\n" +"============\n" +"\n" +"To install this module, you need to:\n" +"\n" +"#. Just install this module\n" +"\n" +"Configuration\n" +"=============\n" +"\n" +"To configure this module, you need to:\n" +"\n" +"#. Nothing to configure\n" +"\n" +"Usage\n" +"=====\n" +"\n" +"To use this module, you need to:\n" +"\n" +"#. In debug mode, go to Recruitment > Configuration > Job Positions > Stages and open a stage.\n" +"#. Enable \"¿Días para deteriorarse por posición?\" and add the job positions with their days to rot.\n" +"\n" +".. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas\n" +" :alt: Try me on Runbot\n" +" :target: http://runbot.adhoc.com.ar/\n" +"\n" +"Bug Tracker\n" +"===========\n" +"\n" +"Bugs are tracked on `GitHub Issues\n" +"`_. In case of trouble, please\n" +"check there if your issue has already been reported. If you spotted it first,\n" +"help us smashing it by providing a detailed and welcomed feedback.\n" +"\n" +"Credits\n" +"=======\n" +"\n" +"Images\n" +"------\n" +"\n" +"* |company| |icon|\n" +"\n" +"Contributors\n" +"------------\n" +"\n" +"Maintainer\n" +"----------\n" +"\n" +"|company_logo|\n" +"\n" +"This module is maintained by ADHOC SA.\n" +"\n" +"To contribute to this module, please visit https://www.adhoc.com.ar.\n" +msgstr "" + #. module: hr_recruitment_ux #: model:ir.model.fields,help:hr_recruitment_ux.field_hr_job_stage_rotting__rotting_days msgid "0 = sin deterioro para esta combinación de vacante y etapa." @@ -102,7 +185,12 @@ msgstr "" #. module: hr_recruitment_ux #: model:ir.model,name:hr_recruitment_ux.model_hr_recruitment_stage -msgid "Recruitment Stages" +msgid "Recruitment Stage" +msgstr "" + +#. module: hr_recruitment_ux +#: model:ir.module.module,shortdesc:base.module_hr_recruitment_ux +msgid "Recruitment UX" msgstr "" #. module: hr_recruitment_ux diff --git a/hr_recruitment_ux/models/talent_pool_add_applicants.py b/hr_recruitment_ux/models/talent_pool_add_applicants.py index df0e189c..70795d64 100644 --- a/hr_recruitment_ux/models/talent_pool_add_applicants.py +++ b/hr_recruitment_ux/models/talent_pool_add_applicants.py @@ -7,8 +7,8 @@ class TalentPoolAddApplicants(models.TransientModel): _inherit = "talent.pool.add.applicants" def _add_applicants_to_pool(self): - # Capture originals before super creates copies in the pool - originals_to_archive = self.applicant_ids.filtered(lambda a: not a.talent_pool_ids) + # Same condition super uses to copy the applicant into a new talent + originals_to_archive = self.applicant_ids.filtered(lambda a: not a.talent_pool_ids and not a.pool_applicant_id) for applicant in originals_to_archive: pool_names = ", ".join(self.talent_pool_ids.mapped("name")) applicant.message_post( @@ -21,15 +21,5 @@ def _add_applicants_to_pool(self): subtype_xmlid="mail.mt_note", ) talents = super()._add_applicants_to_pool() - for original in originals_to_archive: - new_record = talents.filtered(lambda t: t.partner_id.id == original.partner_id.id) - if not new_record: - continue - self.env["ir.attachment"].sudo().search( - [ - ("res_model", "=", "hr.applicant"), - ("res_id", "=", original.id), - ] - ).write({"res_id": new_record[0].id}) originals_to_archive.write({"active": False}) return talents diff --git a/hr_recruitment_ux/security/ir.access.csv b/hr_recruitment_ux/security/ir.access.csv new file mode 100644 index 00000000..07e16146 --- /dev/null +++ b/hr_recruitment_ux/security/ir.access.csv @@ -0,0 +1,3 @@ +id,name,model_id,group_id/id,operation,domain +access_hr_job_stage_rotting_user,hr.job.stage.rotting user,hr.job.stage.rotting,hr_recruitment.group_hr_recruitment_user,crud, +access_hr_job_stage_rotting_interviewer,hr.job.stage.rotting interviewer,hr.job.stage.rotting,hr_recruitment.group_hr_recruitment_interviewer,r, diff --git a/hr_recruitment_ux/security/ir.model.access.csv b/hr_recruitment_ux/security/ir.model.access.csv deleted file mode 100644 index b9b465a6..00000000 --- a/hr_recruitment_ux/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_hr_job_stage_rotting_user,hr.job.stage.rotting user,model_hr_job_stage_rotting,hr_recruitment.group_hr_recruitment_user,1,1,1,1 -access_hr_job_stage_rotting_interviewer,hr.job.stage.rotting interviewer,model_hr_job_stage_rotting,hr_recruitment.group_hr_recruitment_interviewer,1,0,0,0 diff --git a/hr_recruitment_ux/tests/__init__.py b/hr_recruitment_ux/tests/__init__.py new file mode 100644 index 00000000..f9d5f9fd --- /dev/null +++ b/hr_recruitment_ux/tests/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_rotting_per_job +from . import test_talent_pool diff --git a/hr_recruitment_ux/tests/test_rotting_per_job.py b/hr_recruitment_ux/tests/test_rotting_per_job.py new file mode 100644 index 00000000..a3046905 --- /dev/null +++ b/hr_recruitment_ux/tests/test_rotting_per_job.py @@ -0,0 +1,63 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import timedelta + +from odoo.tests import TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestRottingPerJob(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.stage = cls.env["hr.recruitment.stage"].create( + { + "name": "Stage with per-job rotting", + "rotting_threshold_days": 5, + "use_rotting_per_job": True, + } + ) + cls.job_with_rule, cls.job_without_rule = cls.env["hr.job"].create( + [{"name": "Job with own threshold"}, {"name": "Job without own threshold"}] + ) + cls.job_rule = cls.env["hr.job.stage.rotting"].create( + {"job_id": cls.job_with_rule.id, "stage_id": cls.stage.id, "rotting_days": 10} + ) + + def _applicant_in_stage_since(self, job, days): + # Applicant that entered the stage `days` days ago + applicant = self.env["hr.applicant"].create( + {"partner_name": "Rotting applicant", "job_id": job.id, "stage_id": self.stage.id} + ) + applicant.date_last_stage_update = self.env.cr.now() - timedelta(days=days) + applicant.invalidate_recordset(["is_rotting", "rotting_days"]) + return applicant + + def _assert_rotting(self, applicant, expected_days): + # Rotting flag and day count must agree + self.assertTrue(applicant.is_rotting) + self.assertEqual(applicant.rotting_days, expected_days) + + def _assert_not_rotting(self, applicant): + self.assertFalse(applicant.is_rotting) + self.assertEqual(applicant.rotting_days, 0) + + def test_job_threshold_overrides_stage_threshold(self): + """The threshold of the job, when the stage enables it, replaces the one of the stage.""" + with self.subTest("job threshold not reached, stage threshold passed: not rotting"): + self._assert_not_rotting(self._applicant_in_stage_since(self.job_with_rule, 7)) + + with self.subTest("job threshold passed: rotting since the stage change"): + self._assert_rotting(self._applicant_in_stage_since(self.job_with_rule, 12), 12) + + with self.subTest("job without its own threshold: the stage threshold applies"): + self._assert_rotting(self._applicant_in_stage_since(self.job_without_rule, 7), 7) + + with self.subTest("per-job rotting disabled on the stage: the stage threshold applies"): + self.stage.use_rotting_per_job = False + self._assert_rotting(self._applicant_in_stage_since(self.job_with_rule, 7), 7) + self.stage.use_rotting_per_job = True + + with self.subTest("job threshold set to 0: never rotting"): + self.job_rule.rotting_days = 0 + self._assert_not_rotting(self._applicant_in_stage_since(self.job_with_rule, 30)) diff --git a/hr_recruitment_ux/tests/test_talent_pool.py b/hr_recruitment_ux/tests/test_talent_pool.py new file mode 100644 index 00000000..8baf31f8 --- /dev/null +++ b/hr_recruitment_ux/tests/test_talent_pool.py @@ -0,0 +1,68 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests import Form, TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestTalentPool(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.pool_1, cls.pool_2 = cls.env["hr.talent.pool"].create([{"name": "Pool One"}, {"name": "Pool Two"}]) + cls.job = cls.env["hr.job"].create({"name": "Developer"}) + cls.applicant = cls.env["hr.applicant"].create( + {"partner_name": "Pool applicant", "email_from": "pool.applicant@example.com", "job_id": cls.job.id} + ) + cls.cv = cls.env["ir.attachment"].create( + { + "name": "cv.pdf", + "raw": b"cv", + "res_model": "hr.applicant", + "res_id": cls.applicant.id, + } + ) + + def _add_to_pool(self, applicants, pools): + wizard = Form(self.env["talent.pool.add.applicants"]) + wizard.applicant_ids = applicants + wizard.talent_pool_ids = pools + # Same entry point as the button, which runs with sudo + wizard.save().action_add_applicants_to_pool() + return applicants.pool_applicant_id + + def test_add_to_talent_pool_archives_original(self): + """Only applicants copied into a new talent are archived, and attachments are not duplicated.""" + with self.subTest("new applicant: the talent is created and the original archived with a note"): + talent = self._add_to_pool(self.applicant, self.pool_1) + self.assertNotEqual(talent, self.applicant) + self.assertEqual(talent.talent_pool_ids, self.pool_1) + self.assertFalse(self.applicant.active) + self.assertTrue(talent.active) + note = self.applicant.message_ids.filtered(lambda m: "Pool One" in (m.body or "")) + self.assertEqual(len(note), 1) + self.assertEqual(note.subtype_id, self.env.ref("mail.mt_note")) + + with self.subTest("attachments: the original keeps its own and the talent gets a single copy"): + self.assertEqual(self.applicant.attachment_ids, self.cv) + self.assertEqual(len(talent.attachment_ids), 1) + self.assertNotEqual(talent.attachment_ids, self.cv) + + with self.subTest("applicant already linked to the talent: not archived, the talent gets the pool"): + linked = self.env["hr.applicant"].create( + {"partner_name": "Pool applicant", "job_id": self.job.id, "pool_applicant_id": talent.id} + ) + result = self._add_to_pool(linked, self.pool_2) + self.assertEqual(result, talent) + self.assertTrue(linked.active) + self.assertEqual(talent.talent_pool_ids, self.pool_1 | self.pool_2) + + with self.subTest("applicant linked to the talent only by email: a new talent is created and it is archived"): + same_person = self.env["hr.applicant"].create( + {"partner_name": "Pool applicant", "email_from": "pool.applicant@example.com", "job_id": self.job.id} + ) + self.assertTrue(same_person.is_applicant_in_pool) + new_talent = self._add_to_pool(same_person, self.pool_2) + self.assertTrue(new_talent) + self.assertNotEqual(new_talent, talent) + self.assertEqual(new_talent.talent_pool_ids, self.pool_2) + self.assertFalse(same_person.active) diff --git a/hr_recruitment_ux/views/hr_recruitment_stage_views.xml b/hr_recruitment_ux/views/hr_recruitment_stage_views.xml index 29fb9045..00002ef2 100644 --- a/hr_recruitment_ux/views/hr_recruitment_stage_views.xml +++ b/hr_recruitment_ux/views/hr_recruitment_stage_views.xml @@ -6,10 +6,10 @@ hr.recruitment.stage - + - - + + @@ -18,7 +18,7 @@ - +