Skip to content

Prescripteur : permettre la création de compte candidat sans candidater#5462

Merged
EwenKorr merged 11 commits into
masterfrom
ewen/create-jobseeker-standalone
Feb 6, 2025
Merged

Prescripteur : permettre la création de compte candidat sans candidater#5462
EwenKorr merged 11 commits into
masterfrom
ewen/create-jobseeker-standalone

Conversation

@EwenKorr

@EwenKorr EwenKorr commented Jan 24, 2025

Copy link
Copy Markdown
Contributor

🤔 Pourquoi ?

On veut permettre aux prescripteurs de créer un compte candidat, sans forcément postuler pour le candidat dans l'immédiat.

(pour le Contexte et besoin métier, voir la carte Notion)

🍰 Comment ?

Grâce à l'extraction du parcours de création de compte candidat, on peut maintenant ajouter assez facilement un nouveau tunnel 🎉

Il y a plusieurs modifications (voir commits et messages de commits pour plus de détails) :

  • ajout d'un attribut created_by_presciber_organization dans le profil du candidat
  • sur la page Candidats, afficher tous les candidats
    • pour qui on a candidaté
    • qui ont été créés par un membre de notre organisation prescriptrice actuelle
  • à la création d'un candidat, soit on trouve un compte existant, soit on en crée un nouveau, et dans tous les cas on arrive à la fiche candidat.

🏝️ Comment tester ?

En tant que prescripteur, aller à la page Candidats, cliquer sur Créer un compte candidat. Essayer les cas suivant :

  • un vrai nouveau candidat : à la fin du processus, on retourne à la page Candidats avec un message toast de succès
  • un candidat qui existe déjà (retrouvé par son NIR ou son adresse email) : on a un message qui confirme qu'on l'a trouvé, et on "Postule pour ce candidat" (le bandeau "Vous postulez actuellement pour XX" est présent)

💻 Captures d'écran

@EwenKorr EwenKorr added 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC ajouté Ajouté dans le changelog. labels Jan 24, 2025
@EwenKorr EwenKorr self-assigned this Jan 24, 2025
@EwenKorr

Copy link
Copy Markdown
Contributor Author

Il n'y a pas les tests, mais c'est fonctionnellement testable. Je passerai lundi en recette.

Comment thread itou/www/job_seekers_views/views.py
Comment thread itou/www/job_seekers_views/views.py Outdated
Comment thread itou/www/job_seekers_views/views.py
Comment thread itou/www/job_seekers_views/views.py Outdated
@github-actions

Copy link
Copy Markdown

🥁 La recette jetable est prête ! 👉 Je veux tester cette PR !

@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch 6 times, most recently from c5f7c9f to b2f411a Compare January 28, 2025 15:31
Comment thread itou/www/job_seekers_views/views.py Outdated
Comment thread itou/www/job_seekers_views/views.py Outdated
@EwenKorr

Copy link
Copy Markdown
Contributor Author

Je vais proposer un commit en plus : changer la modale "candidat trouvé avec le nir ou l'email" en fonction de l'existence d'un candidat dans la liste Mes candidats. Cf https://www.notion.so/plateforme-inclusion/Apr-s-avoir-tent-de-cr-er-un-compte-candidat-qui-existe-d-j-dans-ma-liste-188e8fa5c35b809699c7ef55931c4913?pvs=4

Je n'aurais pas le temps de le finir aujourd'hui.

@EwenKorr
EwenKorr marked this pull request as ready for review January 28, 2025 16:31
@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch from b2f411a to 1c00d55 Compare January 28, 2025 16:41

@tonial tonial left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jolie PR avec plein de petits commits ❤️ .

J'ai tout relu sauf TestStandaloneCreateAsPrescriber que je relirai demain dès l'aube.
En attendant je pousse déjà ces commentaires pour ne pas risquer de les perdre.

EDIT: c'est bon, j'ai fini ma relecture

Comment thread itou/templates/job_seekers_views/submit_base_two_columns.html
Comment thread itou/users/migrations/0023_jobseekerprofile_created_by_prescriber_organization.py Outdated
Comment thread itou/www/job_seekers_views/views.py Outdated
Comment thread tests/www/job_seekers_views/test_list.py Outdated
Comment thread tests/www/job_seekers_views/test_list.py Outdated
Comment thread tests/www/job_seekers_views/test_list.py Outdated
Comment thread itou/www/job_seekers_views/views.py
Comment thread tests/www/job_seekers_views/test_list.py Outdated
{% if is_gps|default:False %}
Si ce n'est pas le bénéficiaire que vous souhaitez suivre, cliquez sur « Suivre un autre bénéficiaire » afin de modifier le numéro de sécurité sociale.
{% elif standalone_creation|default:False %}
Le compte de ce candidat sera ajouté à votre liste une fois que vous aurez postulé pour lui.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il n'est pas affiché dès qu'on le crée, même sans candidature créée ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Le texte de cette modale n'apparaît que quand on a trouvé un candidat, déjà créé.
Et donc, pour l'utilisateur qui voit cette modale, il faut effectivement qu'il postule pour lui pour qu'il soit ajouté à sa liste.

Je travaille à une autre version de cette modale, cf ce retour de recette https://www.notion.so/gip-inclusion/Apr-s-avoir-tent-de-cr-er-un-compte-candidat-qui-existe-d-j-dans-ma-liste-18a5f321b60481779b76f24cb930f7e4?pvs=4

En gros, on aurait :

  • le cas GPS
  • le cas postuler classique
  • le cas "le candidat existe, mais n'est pas dans votre liste" => postulez pour lui pour le voir apparaître
  • le cas "le candidat existe, et est déjà dans votre liste"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce sera dans une autre PR.

Comment thread itou/templates/job_seekers_views/list.html
Comment thread itou/www/job_seekers_views/views.py Outdated
Comment thread itou/www/job_seekers_views/views.py Outdated
Comment on lines +161 to +165
if self.request.user.is_prescriber and self.request.current_organization is not None:
return Q(jobseeker_profile__created_by_prescriber_organization=self.request.current_organization)
elif self.request.user.is_prescriber:
# Prescriber without organization: display job seekers created by them, without organization
return Q(created_by=self.request.user, jobseeker_profile__created_by_prescriber_organization=None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je trouve ces règles perturbantes: rejoindre une organisation fait perdre la visibilité sur les candidats que l'on suivait individuellement.
Cela me semblerait plus logique de suivre les même règles que pour les candidatures:

if user.is_prescriber:
if organization:
return self.filter(
(Q(sender=user) & Q(sender_prescriber_organization__isnull=True))
| Q(sender_prescriber_organization=organization)
)
else:
return self.filter(sender=user)

Ou encore mieux: donner accès à tous et rajouter un filtre sur l'organisation créatrice.

Ensuite, à une époque le métier avait émis le besoin de pouvoir "archiver" un candidat (que l'on sait par exemple ne plus suivre): on met ce besoin en attente pour le moment j'imagine ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ou encore mieux: donner accès à tous et rajouter un filtre sur l'organisation créatrice.

Gros +1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Les règles métier sur la carte Notion (mais je vais en rediscuter avec Marion) :

Règles d’affichage du candidat créé :

  • Si j’ai créé le candidat sans être rattaché à une orga -> il s’affiche dans la liste
  • Si j’ai créé le candidat à partir d’une orga à laquelle j’appartiens -> il s’affiche dans la liste
  • Si j’ai créé le candidat à partir d’une orga à laquelle je n’appartiens plus -> il ne s’affiche plus dans ma liste

Ou encore mieux: donner accès à tous et rajouter un filtre sur l'organisation créatrice.

Je ne suis pas sûr de comprendre : donner accès à tous les prescripteurs (= tous les prescripteurs voient leurs candidats, created_by=request.user) et filtre sur orga créatrice (created_by_prescriber_organization=request.current_organization). Comment joindre les deux ?


Ensuite, à une époque le métier avait émis le besoin de pouvoir "archiver" un candidat (que l'on sait par exemple ne plus suivre): on met ce besoin en attente pour le moment j'imagine ?

Je pense qu'on verra ça après oui.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moi je verrais bien:

filter = Q(created_by=self.request.user)
if self.request.current_organization:
    filter |= Q(jobseeker_profile__created_by_prescriber_organization=self.request.current_organization))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai fait un petit fixup qui sera fusionné au commit précédent avec cette règle.
Elle est un petit peu différente de la règle des candidatures (dans laquelle on ne voit que ses candidatures "individuelles" et les candidatures faites pour une orga, pas les candidatures qu'on a faites pour d'autres orga).

Au pire, ça pourra assez facilement être adapté au besoin.

Comment thread itou/www/job_seekers_views/views.py Outdated
self.hire_process = None
self.prescription_proces = None
self.auto_prescription_process = None
self.standalone_creation = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tous ces booléens ressemblent beaucoup à la liste des tunnels.
Si on sépare/spécialise sender en prescription & auto_prescription on aura du 1 pour 1, et on s'évitera tous ces not self.hire_process and not self.is_gps and ... en cascade dans le setup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je suis pour !
Je me note de nettoyer ça après.

@notion-workspace

Copy link
Copy Markdown

Comment thread itou/users/models.py
Comment on lines +1016 to +1022
created_by_prescriber_organization = models.ForeignKey(
PrescriberOrganization,
verbose_name="créé par un membre de l'organisation",
on_delete=models.RESTRICT,
null=True,
blank=True,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si en effet ça ne devrait concerner que les candidats, je ne suis pas convaincu par le fait de stocker created_by et created_by_org dans deux tables différentes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Et donc il faudrait déplacer created_by dans JobSeekerProfile ?
(vu qu'on va être amenés à ajouter d'autres infos du même style dans ce modèle, cf https://www.notion.so/gip-inclusion/infos-perso-candidat-Afficher-l-auteur-de-la-mise-jour-de-chaque-section-de-donn-es-perso-du-cand-18a5f321b604810688edfbb413cf7c49

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plutôt l'inverse car created_by est utilisé pour tout type de profil.

C'est pas critique, mais ce sont 2 données assez proches que j'aurais bien stocké au même endroit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En vrai, je me demande si le created_by est pertinent pour les autres types d'utilisateur 😅
Audit mis à part (mais des logs techniques pourraient faire l'affaire), il n'est utilisé que pour savoir si tel autre utilisateur a le droit de modifier les infos d'un candidat...

@EwenKorr EwenKorr Jan 30, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Et puis à created_by_org s'ajouterait created_by_company
Deux attributs inutiles pour tous les utilisateurs à part les candidats. ⚖️ 🤷

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> select kind, count(*) from users_user where created_by_id is not null group by kind;
    kind    |  count  
------------+---------
 employer   |       9
 job_seeker | 1050212
 prescriber |      32
(3 rows)

👀

@notion-workspace

Copy link
Copy Markdown

@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch 5 times, most recently from 26ee65b to c09b6b3 Compare January 30, 2025 14:29
@xavfernandez

Copy link
Copy Markdown
Contributor

Tu as un un ChickNIR dans un des messages de commit :)

@EwenKorr
EwenKorr requested a review from xavfernandez January 31, 2025 07:41
Comment thread tests/www/job_seekers_views/test_list.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
Comment thread tests/www/job_seekers_views/test_create_or_update.py Outdated
@EwenKorr

EwenKorr commented Feb 5, 2025

Copy link
Copy Markdown
Contributor Author

Est-ce que vous voyez autre chose à améliorer ? cc @xavfernandez notamment 😁

Comment thread tests/www/job_seekers_views/test_list.py Outdated
Comment thread tests/www/job_seekers_views/test_list.py Outdated
@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch 2 times, most recently from ebdef42 to a1cc39d Compare February 5, 2025 13:40
The code says that employers cannot acces `job_seekers_views:list`,
let's test that.
It is used in job_seekers_views only.
…mplates

In CheckNIR and SearchByEmail views, we used to hide the company block for
GPS only, but in another case there is no company as well: the
standalone creation of a job seeker.
In order to be able to list job seekers created by our colleagues in a
prescriber organization.
Refactor an assertContains(…, html=True) test with lots of html classes.
In `job_seekers_views:list`, show not only the job seekers that we
applied for, but also the ones that were created by members of my
prescriber organization, as saved in
`job_seeker.jobseeker_profile.created_by_prescriber_organization`.

The rule is the following:
- display all job seekers created by the user
- display all job seekers created for the organization
  (ie. the users had this orga as `current_organization` at creation)
When a job seeker is created by a prescriber (for a prescription or GPS
or any tunnel), save the current organization in the job seeker's profile.
@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch from a1cc39d to 367d791 Compare February 6, 2025 07:42
…dats"

A prescriber can create a new job seeker, without applying for them
directly from the "Mes candidats" page.

If a job seeker is found at step CheckNIR or SearchByEmail, then we
follow the "Postuler pour ce candidat" process.
Otherwise, we create the job seeker, set
`created_by_prescriber_organization` to the current organization and
redirect to "Mes candidats".
Add matomo tags in:
- button Créer un compte candidat (list page)
- button Créer le compte candidat (creation step end page)
@EwenKorr
EwenKorr force-pushed the ewen/create-jobseeker-standalone branch from 367d791 to 4341952 Compare February 6, 2025 08:29

@xavfernandez xavfernandez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il faudrait squasher le dernier commit "parse_response_to_soup" dans son commit correspondant :)

@EwenKorr

EwenKorr commented Feb 6, 2025

Copy link
Copy Markdown
Contributor Author

Il faudrait squasher le dernier commit "parse_response_to_soup" dans son commit correspondant :)

Dans le commit refactor a test ? 09bee26#diff-d2c2e892eba8da698987a07a5c1148e8c1078704c9870f4b824085027e7f5540R140

Le commit qui l'a introduit a 3 mois

@xavfernandez

Copy link
Copy Markdown
Contributor

ahah 😅
Bon OK pour ne pas réécrire l'historique git des 3 derniers mois 👍

@EwenKorr

EwenKorr commented Feb 6, 2025

Copy link
Copy Markdown
Contributor Author

Merci beaucoup pour tes relectures 🙏

@EwenKorr
EwenKorr added this pull request to the merge queue Feb 6, 2025
Merged via the queue into master with commit 25788c7 Feb 6, 2025
@EwenKorr
EwenKorr deleted the ewen/create-jobseeker-standalone branch February 6, 2025 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC ajouté Ajouté dans le changelog.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants