Skip to content

Commit

Permalink
feat(job-applications): use a wizard for the apply refuse form, sugge…
Browse files Browse the repository at this point in the history
…st candidate messages for each reason
  • Loading branch information
leo-naeka committed Apr 15, 2024
1 parent 52e86ed commit 2496e73
Show file tree
Hide file tree
Showing 23 changed files with 646 additions and 170 deletions.
2 changes: 1 addition & 1 deletion itou/job_applications/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class RefusalReason(models.TextChoices):
)
NO_POSITION = "no_position", "Pas de recrutement en cours"
DUPLICATE = "duplicate", "Candidature en doublon"
OTHER = "other", "Autre (détails dans le message ci-dessous)"
OTHER = "other", "Autre"

# Hidden reasons kept for history.
APPROVAL_EXPIRATION_TOO_CLOSE = (
Expand Down
2 changes: 1 addition & 1 deletion itou/job_applications/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class Migration(migrations.Migration):
),
("no_position", "Pas de recrutement en cours"),
("duplicate", "Candidature en doublon"),
("other", "Autre (détails dans le message ci-dessous)"),
("other", "Autre"),
("approval_expiration_too_close", "La date de fin du PASS IAE / agrément est trop proche"),
("unavailable", "Candidat indisponible ou non intéressé par le poste"),
(
Expand Down
17 changes: 7 additions & 10 deletions itou/job_applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ class JobApplicationWorkflow(xwf_models.Workflow):
JobApplicationState.CANCELLED,
]
CAN_BE_TRANSFERRED_STATES = CAN_BE_ACCEPTED_STATES
CAN_BE_REFUSED_STATES = [
JobApplicationState.NEW,
JobApplicationState.PROCESSING,
JobApplicationState.PRIOR_TO_HIRE,
JobApplicationState.POSTPONED,
]
CAN_ADD_PRIOR_ACTION_STATES = [
JobApplicationState.PROCESSING,
JobApplicationState.POSTPONED,
Expand All @@ -97,16 +103,7 @@ class JobApplicationWorkflow(xwf_models.Workflow):
(TRANSITION_ACCEPT, CAN_BE_ACCEPTED_STATES, JobApplicationState.ACCEPTED),
(TRANSITION_MOVE_TO_PRIOR_TO_HIRE, CAN_ADD_PRIOR_ACTION_STATES, JobApplicationState.PRIOR_TO_HIRE),
(TRANSITION_CANCEL_PRIOR_TO_HIRE, [JobApplicationState.PRIOR_TO_HIRE], JobApplicationState.PROCESSING),
(
TRANSITION_REFUSE,
[
JobApplicationState.NEW,
JobApplicationState.PROCESSING,
JobApplicationState.PRIOR_TO_HIRE,
JobApplicationState.POSTPONED,
],
JobApplicationState.REFUSED,
),
(TRANSITION_REFUSE, CAN_BE_REFUSED_STATES, JobApplicationState.REFUSED),
(TRANSITION_CANCEL, JobApplicationState.ACCEPTED, JobApplicationState.CANCELLED),
(
TRANSITION_RENDER_OBSOLETE,
Expand Down
2 changes: 1 addition & 1 deletion itou/templates/apply/includes/buttons/refuse.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load matomo %}
<a href="{% url 'apply:refuse' job_application_id=job_application.id %}" class="btn btn-lg btn-outline-white btn-block btn-ico" {% matomo_event "candidature" "clic" "refuse_application" %}>
<a href="{% url 'apply:refuse' job_application_id=job_application.id step='reason' %}" class="btn btn-lg btn-outline-white btn-block btn-ico" {% matomo_event "candidature" "clic" "refuse_application" %}>
<i class="ri-close-line font-weight-medium" aria-hidden="true"></i>
<span>Décliner</span>
</a>
174 changes: 122 additions & 52 deletions itou/templates/apply/process_refuse.html
Original file line number Diff line number Diff line change
@@ -1,72 +1,142 @@
{% extends "apply/process_base.html" %}
{% load django_bootstrap5 %}
{% load theme_inclusion %}
{% load buttons_form %}

{% block content_extend %}
<div class="c-form">
<h2>Renseigner le motif de refus de candidature.</h2>
<form method="post" class="js-prevent-multiple-submit">
{% block content_title %}
<div class="d-md-flex align-items-center mb-3">
<h1 class="mb-1 mb-md-0 me-3">
Refuser la candidature de <span class="text-muted">{{ job_application.job_seeker.get_full_name }}</span>
</h1>
</div>
{% endblock %}

{% csrf_token %}
{% block content %}
<section class="s-section">
<div class="s-section__container container">
<div class="row">
<div class="col-12 col-lg-8">
<div class="c-stepper mb-3 mb-lg-5">
<div class="progress progress--emploi">
<div class="progress-bar progress-bar-{{ wizard|stepper_progress }}" role="progressbar" aria-valuenow="{{ wizard|stepper_progress }}" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
<p>
{% if wizard.steps.current == "reason" %}
<strong>Étape {{ wizard.steps.step1 }}</strong>/{{ wizard.steps.count }} : Choix du motif de refus
{% elif wizard.steps.current == "job-seeker-answer" %}
<strong>Étape {{ wizard.steps.step1 }}</strong>/{{ wizard.steps.count }} : Message au candidat
{% elif wizard.steps.current == "prescriber-answer" %}
<strong>Étape {{ wizard.steps.step1 }}</strong>/{{ wizard.steps.count }} : Message au prescripteur
{% endif %}
</p>
</div>
<div class="c-form mb-3 mb-lg-5">
<form method="post" class="js-prevent-multiple-submit">
{% csrf_token %}
{{ wizard.management_form }}

{% bootstrap_form_errors form type="all" %}
{% if wizard.steps.current == "reason" %}
<h2 class="mb-3 mb-md-4">Choix du motif de refus</h2>
<p class="mb-3 mb-md-4">
{% if job_application.sender_kind == SenderKind.PRESCRIBER %}
Dans le cadre d’un parcours IAE, la transparence sur les motifs de refus est importante pour le candidat comme pour le prescripteur. Nous vous encourageons à répondre à chacune des parties.
{% else %}
Dans le cadre d’un parcours IAE, la transparence sur les motifs de refus est importante pour le candidat.
{% endif %}
</p>
{% elif wizard.steps.current == "job-seeker-answer" %}
<h2 class="mb-3 mb-md-4">Réponse au candidat</h2>
<p class="mb-3 mb-md-4">
{% if job_application.sender_kind == SenderKind.PRESCRIBER %}
Une copie de ce message sera adressée au prescripteur.
<br>
{% endif %}
Merci de bien vouloir adapter ce message en fonction de la situation.
</p>
<p class="mb-3 mb-md-4">
<strong>Raison du refus :</strong> {{ refusal_reason_label }}
</p>
{% elif wizard.steps.current == "prescriber-answer" %}
<h2 class="mb-3 mb-md-4">Réponse au prescripteur</h2>
<p class="mb-3 mb-md-4">
Vous pouvez partager un message au prescripteur uniquement, comme détailler ou évoquer d’autres motifs de refus.
</p>
<p class="mb-3 mb-md-4">
<strong>Raison du refus :</strong> {{ refusal_reason_label }}
</p>
{% endif %}

{# TODO: Fix incorrect rendering of form with radio buttons #}
{# https:/zostera/django-django_bootstrap5/issues/126 #}
<div class="form-group{% if form.refusal_reason.field.required %} form-group-required{% endif %} js-refusal-reasons">
{{ form.refusal_reason.label_tag }}
<ul class="list-unstyled">
{% for radio in form.refusal_reason %}
<li>
<label for="{{ radio.id_for_label }}">
{{ radio.tag }}
{% if radio.data.value == RefusalReason.PREVENT_OBJECTIVES %}
{{ radio.choice_label }}&nbsp;<i class="ri-information-line ri-xl text-button ms-1"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="L'embauche empêche l'atteinte des engagements contractuels avec les parties prenantes à la convention de financement mise en place par l'État."></i>
{% elif radio.data.value == RefusalReason.NO_POSITION %}
{{ radio.choice_label }}&nbsp;<i class="ri-information-line ri-xl text-button ms-1" data-bs-toggle="tooltip" data-bs-placement="right" title="Si vous choisissez ce motif, les fiches de postes associées seront dépubliées."></i>
{% if wizard.steps.current == "reason" %}
<fieldset class="js-refusal-reasons form-group{% if form.refusal_reason.field.required %} form-group-required{% endif %}">
{{ form.refusal_reason.label_tag }}
<ul class="list-unstyled">
{% for radio in form.refusal_reason %}
<li class="mb-2">
<div class="form-check">
<input id="{{ radio.id_for_label }}" class="form-check-input" name="{{ radio.data.name }}" type="radio" value="{{ radio.data.value }}" {% if radio.data.selected %}checked=""{% endif %} required>
<label for="{{ radio.id_for_label }}" class="form-check-label">
{% if radio.data.value == RefusalReason.PREVENT_OBJECTIVES %}
{{ radio.choice_label }}
<i class="ri-information-line ri-lg text-info ms-1"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="L'embauche empêche l'atteinte des engagements contractuels avec les parties prenantes à la convention de financement mise en place par l'État."></i>
{% elif radio.data.value == RefusalReason.NO_POSITION %}
{{ radio.choice_label }}
<i class="ri-information-line ri-lg text-info ms-1" data-bs-toggle="tooltip" data-bs-placement="right" title="Si vous choisissez ce motif, les fiches de postes associées seront dépubliées."></i>
{% elif radio.data.value == RefusalReason.OTHER %}
{{ radio.choice_label }}
{% if job_application.sender_kind == SenderKind.PRESCRIBER %}
(détails à fournir dans le message au prescripteur)
{% endif %}
{% else %}
{{ radio.choice_label }}
{% endif %}
</label>
</div>
</li>
{% endfor %}
</ul>
<div class="c-info refusal-reason-no-position-info mt-2 d-none">
<span class="c-info__summary">En choisissant ce motif, les fiches de postes associées seront dépubliées.</span>
</div>
</fieldset>
{% else %}
{% bootstrap_form wizard.form alert_error_type="non_fields" %}
{% endif %}

{% else %}
{{ radio.choice_label }}
{% endif %}
</label>
</li>
{% endfor %}
</ul>
<div class="c-info refusal-reason-no-position-info d-none">
<span class="c-info__summary">En choisissant ce motif, les fiches de postes associées seront dépubliées.</span>
{% url 'apply:details_for_company' job_application_id=job_application.id as reset_url %}
{% if wizard.steps.prev %}
{% itou_buttons_form reset_url=reset_url primary_label=wizard.steps.next|yesno:"Suivant,Confirmer le refus" secondary_url=wizard.steps.prev matomo_category="candidature" matomo_action="submit" matomo_event="refuse_application_submit" %}
{% else %}
{% itou_buttons_form reset_url=reset_url primary_label=wizard.steps.next|yesno:"Suivant,Confirmer le refus" matomo_category="candidature" matomo_action="submit" matomo_event="refuse_application_submit" %}
{% endif %}
</form>
</div>
</div>
</div>

{% if form.answer_to_prescriber %}
{% bootstrap_field form.answer_to_prescriber %}
{% endif %}

<hr>
<h2>Répondre au candidat</h2>

{% bootstrap_field form.answer %}

{% url 'apply:details_for_company' job_application_id=job_application.id as reset_url %}
{% itou_buttons_form primary_label="Confirmer le refus" reset_url=reset_url matomo_category="candidature" matomo_action="submit" matomo_event="refuse_application_submit" %}

</form>
</div>
</div>
</section>
{% endblock %}

{% block script %}
{{ block.super }}
<script nonce="{{ CSP_NONCE }}">
$(document).ready(function() {
$('input[name="refusal_reason"]').change(function() {
if (this.value === 'no_position') {
{% if wizard.steps.current == "reason" %}
<script nonce="{{ CSP_NONCE }}">
function manageWarningSection(value) {
if (value === 'no_position') {
$('.refusal-reason-no-position-info').removeClass('d-none');
} else {
$('.refusal-reason-no-position-info').addClass('d-none');
}
}
$(document).ready(function() {
manageWarningSection($('input[name="reason-refusal_reason"]:checked').val());
$('input[name="reason-refusal_reason"]').change(function() {
manageWarningSection(this.value);
});
});
});
</script>
</script>
{% endif %}
{% endblock %}
7 changes: 7 additions & 0 deletions itou/templates/apply/refusal_messages/did_not_come.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention et souhaitions vous retenir sur le poste. Malheureusement, nous avons tenté de vous joindre à plusieurs reprises sans succès par mail et par téléphone. Je vous invite à nous recontacter ou à renvoyer votre candidature avec vos coordonnées actualisées au cas où nous n’ayons pas clôturé notre recrutement.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention mais nous sommes au regret de vous informer que celle-ci n'a pas été retenue.

Comme convenu communément, vous étiez donc invité à vous rendre à votre entretien d’embauche dans nos locaux.

Malheureusement, vous n’êtes pas venu à ce RDV sans avertir de votre indisponibilité.

C’est pourquoi nous considérons que vous n’êtes pas disponible pour cet emploi.

Nous vous souhaitons une pleine réussite dans vos recherches futures.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat
11 changes: 11 additions & 0 deletions itou/templates/apply/refusal_messages/duplicate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention.

Nous avons déjà reçu votre candidature précédemment.

Nous sommes très sensibles à l'intérêt que vous portez à notre entreprise, et reviendrons vers vous prochainement si le besoin se confirme dans notre entreprise.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat
9 changes: 9 additions & 0 deletions itou/templates/apply/refusal_messages/hired_elsewhere.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention mais nous sommes au regret de vous informer que celle-ci n'a pas été retenue.

Malheureusement, vous nous indiquez être en poste et ne pas être disponible actuellement.

Nous sommes très sensibles à l'intérêt que vous avez porté à notre entreprise lors de votre dépôt de candidature et conservons vos coordonnées afin de vous recontacter au besoin.

Nous vous souhaitons une pleine réussite dans votre emploi.
15 changes: 15 additions & 0 deletions itou/templates/apply/refusal_messages/incompatible.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention.

Malheureusement, un des freins à l'emploi que vous mentionnez est incompatible avec le poste sur lequel vous avez postulé dans notre établissement.

Soyez assuré que cette décision ne met pas en cause vos qualités personnelles.

Nous sommes très sensibles à l'intérêt que vous portez à notre entreprise, et conservons vos coordonnées afin de vous recontacter au besoin.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat

Pour information, voici un moteur de recherche susceptible de vous intéresser : https://dora.fabrique.social.gouv.fr/
13 changes: 13 additions & 0 deletions itou/templates/apply/refusal_messages/lacking_skills.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention.

Malheureusement, vous n’avez pas les compétences requises pour le poste sur lequel vous avez postulé dans notre établissement.

Soyez assuré que cette décision ne met pas en cause vos qualités personnelles.

Nous sommes très sensibles à l'intérêt que vous portez à notre entreprise, et conservons vos coordonnées afin de vous recontacter au besoin.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat
11 changes: 11 additions & 0 deletions itou/templates/apply/refusal_messages/no_position.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Bonjour,

Nous avons étudié votre candidature avec la plus grande attention.

Malheureusement, nous n’avons pas de recrutement en cours actuellement.

Nous sommes très sensibles à l'intérêt que vous portez à notre entreprise, et conservons vos coordonnées afin de vous recontacter au besoin.

Pour information, voici le mode d’emploi pour envoyer d’autres candidatures à des employeurs :

https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/articles/16920193628177--Postuler-en-tant-que-candidat
Loading

0 comments on commit 2496e73

Please sign in to comment.