Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifier les informations personnelles: utilisation de la clef primaire du candidat au lieu de celle de la candidature #2560

Merged
merged 1 commit into from May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion itou/templates/apply/includes/job_seeker_info.html
Expand Up @@ -63,7 +63,7 @@
{% endif %}
</ul>
<p>
<a href="{% if can_edit_personal_information %}{% url 'dashboard:edit_job_seeker_info' job_application_id=job_application.pk %}?back_url={{ request.get_full_path|urlencode }}{% endif %}"
<a href="{% if can_edit_personal_information %}{% url 'dashboard:edit_job_seeker_info' job_seeker_pk=job_application.job_seeker_id %}?back_url={{ request.get_full_path|urlencode }}&from_application={{ job_application.pk }}{% endif %}"
class="btn btn-outline-primary{% if with_matomo_event %} matomo-event{% endif %}{% if not can_edit_personal_information %} disabled{% endif %}"
{% if with_matomo_event %}data-matomo-category="salaries" data-matomo-action="clic" data-matomo-option="modfifier-les-informations-personnelles"{% endif %}
aria-label="Modifier les informations personnelles de {{ job_application.job_seeker.get_full_name|mask_unless:can_view_personal_information }}">
Expand Down
6 changes: 2 additions & 4 deletions itou/templates/dashboard/edit_job_seeker_info.html
Expand Up @@ -2,13 +2,11 @@
{% load bootstrap4 %}
{% load static %}

{% block title %}
Informations personnelles de {{ job_application.job_seeker.get_full_name|title }} {{ block.super }}
{% endblock %}
{% block title %}Informations personnelles de {{ job_seeker.get_full_name|title }} {{ block.super }}{% endblock %}

{% block content %}
<h1 class="h1-hero-c1">
Informations personnelles de <span class="text-muted">{{ job_application.job_seeker.get_full_name|title }}</span>
Informations personnelles de <span class="text-muted">{{ job_seeker.get_full_name|title }}</span>
</h1>

<div class="alert alert-warning">
Expand Down
18 changes: 16 additions & 2 deletions itou/www/approvals_views/tests/test_detail.py
@@ -1,4 +1,5 @@
from dateutil.relativedelta import relativedelta
from django.test import override_settings
from django.urls import reverse
from django.utils import timezone
from freezegun import freeze_time
Expand Down Expand Up @@ -274,18 +275,20 @@ def test_prolongation_button(self, client):
response = client.get(url)
assertNotContains(response, reverse("approvals:declare_prolongation", kwargs={"approval_id": approval.id}))

@override_settings(TALLY_URL="https://tally.so")
def test_edit_user_info_button(self, client):
approval = ApprovalFactory(with_jobapplication=True)
job_application = approval.jobapplication_set.get()
siae_member = job_application.to_siae.members.first()
client.force_login(siae_member)
url = reverse("approvals:detail", kwargs={"pk": approval.pk})

user_info_edit_url = reverse(
"dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk}
"dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id}
)
user_info_edit_url = f"{user_info_edit_url}?back_url={url}&from_application={job_application.pk}"
user_info_not_allowed = "Vous ne pouvez pas modifier ses informations"

url = reverse("approvals:detail", kwargs={"pk": approval.pk})
response = client.get(url)
assertNotContains(response, user_info_edit_url)
assertContains(response, user_info_not_allowed)
Expand All @@ -295,3 +298,14 @@ def test_edit_user_info_button(self, client):
response = client.get(url)
assertContains(response, user_info_edit_url)
assertNotContains(response, user_info_not_allowed)

# Check that the edit user link correctly displays the Tally link (thanks to from_application= parameter)
response = client.get(user_info_edit_url)
assertContains(
response,
(
f'<a href="https://tally.so/r/wzxQlg?jobapplication={job_application.pk}" target="_blank" '
f'rel="noopener">Demander la correction du numéro de sécurité sociale</a>'
),
html=True,
)
5 changes: 1 addition & 4 deletions itou/www/approvals_views/views.py
Expand Up @@ -70,14 +70,11 @@ class ApprovalDetailView(ApprovalBaseViewMixin, DetailView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["can_view_personal_information"] = True # SIAE members have access to personal info
context["can_edit_personal_information"] = self.request.user.can_edit_personal_information(self.object.user)
context["approval_can_be_suspended_by_siae"] = self.object.can_be_suspended_by_siae(self.siae)
context["hire_by_other_siae"] = not self.object.user.last_hire_was_made_by_siae(self.siae)
context["approval_can_be_prolonged_by_siae"] = self.object.can_be_prolonged_by_siae(self.siae)
job_application = self.get_job_application(self.object)
# For now, the view edit_job_seeker_info needs a job application to be able to edit personal information
context["can_edit_personal_information"] = job_application and self.request.user.can_edit_personal_information(
self.object.user
)
context["job_application"] = job_application
context["matomo_custom_title"] = "Profil salarié"
if job_application:
Expand Down
31 changes: 22 additions & 9 deletions itou/www/dashboard/tests.py
Expand Up @@ -840,8 +840,8 @@ def test_edit_by_siae_with_nir(self):
self.client.force_login(user)

back_url = reverse("apply:details_for_siae", kwargs={"job_application_id": job_application.id})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = f"{url}?back_url={back_url}"
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
url = f"{url}?back_url={back_url}&from_application={job_application.pk}"

response = self.client.get(url)
self.assertContains(
Expand Down Expand Up @@ -904,7 +904,7 @@ def test_edit_by_siae_with_lack_of_nir_reason(self):
self.client.force_login(user)

back_url = reverse("apply:details_for_siae", kwargs={"job_application_id": job_application.id})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
url = f"{url}?back_url={back_url}"

response = self.client.get(url)
Expand Down Expand Up @@ -949,7 +949,7 @@ def test_edit_by_siae_without_nir_information(self):
self.client.force_login(user)

back_url = reverse("apply:details_for_siae", kwargs={"job_application_id": job_application.id})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
url = f"{url}?back_url={back_url}"

response = self.client.get(url)
Expand Down Expand Up @@ -1022,6 +1022,19 @@ def test_edit_by_prescriber(self):
job_application.job_seeker.created_by = user
job_application.job_seeker.save()

self.client.force_login(user)
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
response = self.client.get(url)
assert response.status_code == 200

def test_edit_by_prescriber_with_job_application_URL(self):
job_application = JobApplicationFactory(sent_by_authorized_prescriber_organisation=True)
user = job_application.sender

# Ensure that the job seeker is not autonomous (i.e. he did not register by himself).
job_application.job_seeker.created_by = user
job_application.job_seeker.save()

self.client.force_login(user)
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
response = self.client.get(url)
Expand All @@ -1041,7 +1054,7 @@ def test_edit_by_prescriber_of_organization(self):
user=other_prescriber, organization=job_application.sender_prescriber_organization
)
self.client.force_login(other_prescriber)
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
response = self.client.get(url)
assert response.status_code == 200

Expand All @@ -1051,7 +1064,7 @@ def test_edit_autonomous_not_allowed(self):
user = job_application.sender
self.client.force_login(user)

url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})

response = self.client.get(url)
assert response.status_code == 403
Expand All @@ -1063,7 +1076,7 @@ def test_edit_not_allowed(self):
# Lambda prescriber not member of the sender organization
prescriber = PrescriberFactory()
self.client.force_login(prescriber)
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})

response = self.client.get(url)
assert response.status_code == 403
Expand All @@ -1080,7 +1093,7 @@ def test_edit_email_when_unconfirmed(self):
self.client.force_login(user)

back_url = reverse("apply:details_for_siae", kwargs={"job_application_id": job_application.id})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
url = f"{url}?back_url={back_url}"

response = self.client.get(url)
Expand Down Expand Up @@ -1130,7 +1143,7 @@ def test_edit_email_when_confirmed(self):
self.client.force_login(user)

back_url = reverse("apply:details_for_siae", kwargs={"job_application_id": job_application.id})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_application_id": job_application.pk})
url = reverse("dashboard:edit_job_seeker_info", kwargs={"job_seeker_pk": job_application.job_seeker_id})
url = f"{url}?back_url={back_url}"

response = self.client.get(url)
Expand Down
1 change: 1 addition & 0 deletions itou/www/dashboard/urls.py
Expand Up @@ -13,6 +13,7 @@
path("edit_user_info", views.edit_user_info, name="edit_user_info"),
path("edit_user_notifications", views.edit_user_notifications, name="edit_user_notifications"),
path("edit_job_seeker_info/<uuid:job_application_id>", views.edit_job_seeker_info, name="edit_job_seeker_info"),
path("edit_job_seeker_info/<int:job_seeker_pk>", views.edit_job_seeker_info, name="edit_job_seeker_info"),
path("switch_siae", views.switch_siae, name="switch_siae"),
path(
"switch_prescriber_organization", views.switch_prescriber_organization, name="switch_prescriber_organization"
Expand Down
27 changes: 20 additions & 7 deletions itou/www/dashboard/views.py
Expand Up @@ -27,7 +27,8 @@
from itou.siae_evaluations.constants import CAMPAIGN_VIEWABLE_DURATION
from itou.siae_evaluations.models import EvaluatedSiae, EvaluationCampaign
from itou.siaes.models import Siae, SiaeFinancialAnnex
from itou.users.enums import IdentityProvider
from itou.users.enums import IdentityProvider, UserKind
from itou.users.models import User
from itou.utils import constants as global_constants
from itou.utils.perms.institution import get_current_institution_or_404
from itou.utils.perms.prescriber import get_current_org_or_404
Expand Down Expand Up @@ -247,18 +248,30 @@ def edit_user_info(request, template_name="dashboard/edit_user_info.html"):


@login_required
def edit_job_seeker_info(request, job_application_id, template_name="dashboard/edit_job_seeker_info.html"):
job_application = get_object_or_404(JobApplication.objects.select_related("job_seeker"), pk=job_application_id)
if not request.user.can_edit_personal_information(job_application.job_seeker):
def edit_job_seeker_info(
request, job_application_id=None, job_seeker_pk=None, template_name="dashboard/edit_job_seeker_info.html"
):
if job_application_id:
# TODO(xafer): remove support for this url pattern in a week
job_application = get_object_or_404(JobApplication.objects.select_related("job_seeker"), pk=job_application_id)
job_seeker = job_application.job_seeker
tally_form_query = f"jobapplication={job_application.pk}"
elif job_seeker_pk:
job_seeker = get_object_or_404(User.objects.filter(kind=UserKind.JOB_SEEKER), pk=job_seeker_pk)
from_application_uuid = request.GET.get("from_application")
tally_form_query = from_application_uuid and f"jobapplication={from_application_uuid}"
else:
raise RuntimeError("We need either job_application_id or job_seeker_pk here")
if not request.user.can_edit_personal_information(job_seeker):
raise PermissionDenied

dashboard_url = reverse_lazy("dashboard:index")
back_url = get_safe_url(request, "back_url", fallback_url=dashboard_url)
form = EditJobSeekerInfoForm(
instance=job_application.job_seeker,
instance=job_seeker,
editor=request.user,
data=request.POST or None,
tally_form_query=f"jobapplication={job_application.pk}",
tally_form_query=tally_form_query,
)

if request.method == "POST" and form.is_valid():
Expand All @@ -268,7 +281,7 @@ def edit_job_seeker_info(request, job_application_id, template_name="dashboard/e

context = {
"form": form,
"job_application": job_application,
"job_seeker": job_seeker,
"prev_url": back_url,
"matomo_custom_title": "Informations personnelles du candidat",
}
Expand Down