Skip to content

Commit

Permalink
Merge branch 'dev' into LTD_5653_DESNZ_multiple_licence_conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
Tllew authored Dec 2, 2024
2 parents 7815274 + 53887ec commit d5d5833
Show file tree
Hide file tree
Showing 18 changed files with 734 additions and 281 deletions.
15 changes: 6 additions & 9 deletions caseworker/core/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,12 @@ def is_super_user(request):

@rules.predicate
def check_user_is_not_logged_in_caseworker(request, user):
caseworker = get_logged_in_caseworker(request)
caseworker_user_id = caseworker["id"]
if not user:
return True
return user.get("user", {}).get("id") != caseworker_user_id
caseworker = get_logged_in_caseworker(request)
caseworker_user_id = caseworker["id"]
is_actioned_user_not_current_user = user.get("user", {}).get("id") != caseworker_user_id
return is_actioned_user_not_current_user


rules.add_rule("can_user_allocate_case", is_case_caseworker_operable)
Expand Down Expand Up @@ -221,9 +222,5 @@ def check_user_is_not_logged_in_caseworker(request, user):
"can_licence_status_be_changed", is_user_licencing_unit_senior_manager & is_case_finalised_and_licence_editable
)
rules.add_rule("can_user_manage_organisation", is_user_manage_organisations_role & is_organisation_active)
rules.add_rule("can_caseworker_edit_role", is_super_user | is_user_in_admin_team) # noqa
rules.add_rule("can_caseworker_edit_team", is_super_user | is_user_in_admin_team) # noqa
rules.add_rule(
"can_caseworker_deactivate",
(is_super_user | is_user_in_admin_team) & check_user_is_not_logged_in_caseworker, # noqa
)
rules.add_rule("can_caseworker_deactivate", (is_super_user) & check_user_is_not_logged_in_caseworker) # noqa
rules.add_rule("can_caseworker_edit_user", (is_super_user)) # noqa
1 change: 0 additions & 1 deletion caseworker/queues/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def get_queues(
option.data_attribute = queue_team.get("id")

options.append(option)

return options
else:
return data
Expand Down
6 changes: 6 additions & 0 deletions caseworker/teams/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ def get_teams(request, converted_to_options=False):
return data.json()["teams"]


def get_all_teams(request):
response = client.get(request, "/teams/")
response.raise_for_status()
return response.json()["teams"]


def get_users_team_queues(request, user, convert_to_options=True):
data = client.get(request, f"/users/{user}/team-queues/")
if convert_to_options:
Expand Down
1 change: 0 additions & 1 deletion caseworker/templates/core/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
{% block back_link %}
<a href="{{ back_link_url }}" id="back-link" class="govuk-back-link">{{ back_link_text|default:"Back" }}</a>
{% endblock %}

{% block two_thirds %}
{% include "core/includes/form.html" %}
{% endblock %}
23 changes: 13 additions & 10 deletions caseworker/templates/users/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{% block back_link %}
<a href="{% url 'users:users' %}" id="back-link" class="govuk-back-link">
{% lcs 'users.UserProfile.BACK_LINK' %}
back
</a>
{% endblock %}

Expand Down Expand Up @@ -67,10 +67,13 @@ <h1 class="govuk-heading-l">
{{ data.user.email }}
</dd>
<dd class="govuk-summary-list__actions">
<a id="link-edit-email" href="{% url 'users:edit' data.user.id %}#email" class="govuk-link govuk-link--no-visited-state">
{% lcs 'users.UserProfile.SummaryList.CHANGE' %}
<span class="govuk-visually-hidden">{% lcs 'users.UserProfile.SummaryList.EMAIL' %}</span>
</a>
{% test_rule 'can_caseworker_edit_user' request as show_edit_email %}
{% if show_edit_email %}
<a id="link-edit-email" href="{% url 'users:edit' data.user.id %}#email" class="govuk-link govuk-link--no-visited-state">
{% lcs 'users.UserProfile.SummaryList.CHANGE' %}
<span class="govuk-visually-hidden">{% lcs 'users.UserProfile.SummaryList.EMAIL' %}</span>
</a>
{% endif %}
</dd>
</div>
<div class="govuk-summary-list__row">
Expand All @@ -81,9 +84,9 @@ <h1 class="govuk-heading-l">
<a href="{% url 'teams:team' data.user.team.id %}" id="user-team-name" class="govuk-link govuk-link--no-visited-state">{{ data.user.team.name }}</a>
</dd>
<dd class="govuk-summary-list__actions">
{% test_rule 'can_caseworker_edit_team' request as show_edit_team %}
{% test_rule 'can_caseworker_edit_user' request as show_edit_team %}
{% if show_edit_team %}
<a id="link-edit-team" href="{% url 'users:edit' data.user.id %}#team" class="govuk-link govuk-link--no-visited-state">
<a id="link-edit-team" href="{% url 'users:edit' data.user.id %}" class="govuk-link govuk-link--no-visited-state">
{% lcs 'users.UserProfile.SummaryList.CHANGE' %}
<span class="govuk-visually-hidden">{% lcs 'users.UserProfile.SummaryList.TEAM' %}</span>
</a>
Expand All @@ -98,9 +101,9 @@ <h1 class="govuk-heading-l">
{{ data.user.role.name }}
</dd>
<dd class="govuk-summary-list__actions">
{% test_rule 'can_caseworker_edit_role' request as show_edit_role %}
{% test_rule 'can_caseworker_edit_user' request as show_edit_role %}
{% if show_edit_role %}
<a id="link-edit-role" href="{% url 'users:edit' data.user.id %}#role" class="govuk-link govuk-link--no-visited-state">
<a id="link-edit-role" href="{% url 'users:edit' data.user.id %}" class="govuk-link govuk-link--no-visited-state">
{% lcs 'users.UserProfile.SummaryList.CHANGE' %}
<span class="govuk-visually-hidden">{% lcs 'users.UserProfile.SummaryList.ROLE' %}</span>
</a>
Expand All @@ -115,7 +118,7 @@ <h1 class="govuk-heading-l">
{{ data.user.default_queue.name }}
</dd>
<dd class="govuk-summary-list__actions">
<a id="link-edit-default-queue" href="{% url 'users:edit' data.user.id %}#default_queue" class="govuk-link govuk-link--no-visited-state">
<a id="link-edit-default-queue" href="{% url 'users:edit' data.user.id %}" class="govuk-link govuk-link--no-visited-state">
{% lcs 'users.UserProfile.SummaryList.CHANGE' %}
<span class="govuk-visually-hidden">{% lcs 'users.UserProfile.SummaryList.DEFAULT_QUEUE' %}</span>
</a>
Expand Down
42 changes: 1 addition & 41 deletions caseworker/users/forms/users.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from django.urls import reverse_lazy

from lite_content.lite_internal_frontend.users import AddUserForm, EditUserForm
from lite_content.lite_internal_frontend.users import AddUserForm
from lite_forms.components import Form, Select, TextInput, BackLink
from lite_forms.helpers import conditional
from caseworker.queues.services import get_queues
from caseworker.teams.services import get_teams
from caseworker.users.services import get_roles
Expand Down Expand Up @@ -35,42 +34,3 @@ def add_user_form(request):
back_link=BackLink(AddUserForm.BACK_LINK, reverse_lazy("users:users")),
javascript_imports={"/javascripts/filter-default-queue-list.js"},
)


def edit_user_form(request, user, can_edit_role: bool, can_edit_team: bool):
return Form(
title=EditUserForm.TITLE.format(user["first_name"], user["last_name"]),
questions=[
TextInput(title=EditUserForm.Email.TITLE, description=EditUserForm.Email.DESCRIPTION, name="email"),
conditional(
can_edit_team,
Select(
title=EditUserForm.Team.TITLE,
description=EditUserForm.Team.DESCRIPTION,
name="team",
options=get_teams(request, True),
),
),
conditional(
can_edit_role,
Select(
title=EditUserForm.Role.TITLE,
description=EditUserForm.Role.DESCRIPTION,
name="role",
options=get_roles(request, True),
),
),
Select(
title=EditUserForm.DefaultQueue.TITLE,
description=EditUserForm.DefaultQueue.DESCRIPTION,
name="default_queue",
options=get_queues(request, include_system=True, convert_to_options=True),
),
],
back_link=BackLink(
EditUserForm.BACK_LINK.format(user["first_name"], user["last_name"]),
reverse_lazy("users:user", kwargs={"pk": user["id"]}),
),
default_button_name=EditUserForm.SUBMIT_BUTTON,
javascript_imports={"/javascripts/filter-default-queue-list.js"},
)
91 changes: 91 additions & 0 deletions caseworker/users/manage/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from django import forms

from core.common.forms import BaseForm
from core.forms.widgets import FilterSelect
from crispy_forms_gds.choices import Choice
from caseworker.users.services import get_gov_user_list


class BaseCaseworkerUser(BaseForm):

email = forms.EmailField(
label="Email",
error_messages={
"required": "Enter an email address in the correct format, like [email protected]",
},
)

role = forms.ChoiceField(
label="Role",
widget=forms.Select(attrs={"id": "role"}),
)

team = forms.ChoiceField(label="Team", widget=forms.Select(attrs={"id": "team"}))

default_queue = forms.ChoiceField(
label="Default Queue",
widget=FilterSelect(
parent_select_name="team",
attrs={"id": "default_queue", "class": "govuk-select"},
),
)

def get_layout_fields(self):
return (
"email",
"role",
"team",
"default_queue",
)

def __init__(self, request, teams, roles, queues, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
self.fields["team"].choices = [Choice(t["id"], t["name"]) for t in teams]
self.fields["role"].choices = [Choice(r["id"], r["name"]) for r in roles]

get_team_id = lambda queue: queue["team"].get("id") if queue.get("team") else None

self.fields["default_queue"].choices = [
Choice(value=q["id"], label=q["name"], attrs={"data-attribute": get_team_id(q)}) for q in queues
]
self.fields["default_queue"].choices.insert(0, Choice(None, "Select"))


class EditCaseworkerQueue(BaseCaseworkerUser):
class Layout:
TITLE = "Edit"
SUBMIT_BUTTON_TEXT = "Save and return"

_editable_fields = ["email", "team", "role"]

def __init__(self, request, teams, roles, queues, *args, **kwargs):
super().__init__(request, teams, roles, queues, *args, **kwargs)

self._email_changed = False
for field in self._editable_fields:
self.fields[field].disabled = True
self.fields[field].required = False

def clean(self):
cleaned_data = super().clean()
for field in self._editable_fields:
del cleaned_data[field]
return cleaned_data


class EditCaseworker(BaseCaseworkerUser):
class Layout:
TITLE = "Edit"
SUBMIT_BUTTON_TEXT = "Save and return"

def __init__(self, request, teams, roles, queues, *args, **kwargs):
super().__init__(request, teams, roles, queues, *args, **kwargs)

def clean_email(self):
email = self.cleaned_data["email"] or self.initial["email"]
if email != self.initial["email"].lower():
gov_user_list = get_gov_user_list(self.request, {"email": email})
if gov_user_list["count"]:
raise forms.ValidationError("This email has already been registered")
return email
80 changes: 80 additions & 0 deletions caseworker/users/manage/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from requests.exceptions import HTTPError
from http import HTTPStatus
import rules

from django.http import Http404
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.views.generic import FormView

from core.decorators import expect_status
from core.auth.views import LoginRequiredMixin
from caseworker.queues.services import get_queues
from caseworker.teams.services import get_all_teams
from caseworker.users.services import get_all_roles, get_gov_user, update_gov_user
from .forms import EditCaseworkerQueue, EditCaseworker


class EditCaseworkerUserView(LoginRequiredMixin, SuccessMessageMixin, FormView):
form_class = EditCaseworkerQueue

template_name = "core/form.html"
success_message = "User updated successfully"

def dispatch(self, *args, **kwargs):
try:
self.user_id = kwargs["pk"]
self.user, _ = get_gov_user(self.request, self.user_id)
self.user = self.user["user"]
except HTTPError:
raise Http404()

return super().dispatch(*args, **kwargs)

def get_initial(self):
return {
"email": self.user["email"],
"role": self.user["role"]["id"],
"team": self.user["team"]["id"],
"default_queue": self.user["default_queue"]["id"],
}

def get_form_class(self):
if rules.test_rule("can_caseworker_edit_user", self.request):
return EditCaseworker
return EditCaseworkerQueue

def get_form_kwargs(self):
form_kwargs = super().get_form_kwargs()

form_kwargs["request"] = self.request
form_kwargs["teams"] = get_all_teams(self.request)
form_kwargs["roles"] = get_all_roles(self.request)
form_kwargs["queues"] = get_queues(self.request, include_system=True)

return form_kwargs

def form_valid(self, form):
data = form.cleaned_data
self.edit_user(data)
# If user is updating their own default_queue, update the local user instance
if str(self.user_id) == self.request.session["lite_api_user_id"]:
self.request.session["default_queue"] = data.get("default_queue")
return super().form_valid(form)

def get_success_url(self):
self.success_url = reverse_lazy("users:user", kwargs={"pk": self.user_id})
return self.success_url

@expect_status(
HTTPStatus.OK,
"Error editing user",
"Unexpected error editing user",
)
def edit_user(self, data):
return update_gov_user(self.request, self.user_id, data)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["back_link_url"] = self.get_success_url()
return context
19 changes: 19 additions & 0 deletions caseworker/users/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from urllib.parse import urlencode

from core import client
from core.helpers import convert_parameters_to_query_params
from lite_content.lite_internal_frontend.users import AssignUserPage
from lite_forms.components import Option

Expand Down Expand Up @@ -83,6 +84,18 @@ def put_gov_user(request, pk, json):
return data.json(), data.status_code


def update_gov_user(request, pk, json):
data = client.patch(request, f"/caseworker/gov_users/{pk}/update", json)
return data.json(), data.status_code


def get_gov_user_list(request, filters):
params = convert_parameters_to_query_params(filters)
response = client.get(request, f"/caseworker/gov_users/{params}")
response.raise_for_status()
return response.json()


# Roles and Permissions
def get_roles(request, convert_to_options=False):
data = client.get(request, "/gov-users/roles/")
Expand All @@ -98,6 +111,12 @@ def get_roles(request, convert_to_options=False):
return data.json(), data.status_code


def get_all_roles(request):
response = client.get(request, "/gov-users/roles/")
response.raise_for_status()
return response.json()["roles"]


def get_role(request, pk):
data = client.get(request, f"/gov-users/roles/{pk}")
return data.json(), data.status_code
Expand Down
3 changes: 2 additions & 1 deletion caseworker/users/urls.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from django.urls import path

from caseworker.users.views import users, roles
from caseworker.users.manage import views

app_name = "users"

urlpatterns = [
path("", users.UsersList.as_view(), name="users"),
path("<uuid:pk>/", users.ViewUser.as_view(), name="user"),
path("add", users.AddUser.as_view(), name="add"),
path("<uuid:pk>/edit/", users.EditUser.as_view(), name="edit"),
path("<uuid:pk>/edit/", views.EditCaseworkerUserView.as_view(), name="edit"),
path("<uuid:pk>/edit/<str:status>/", users.ChangeUserStatus.as_view(), name="change_status"),
path("profile/", users.ViewProfile.as_view(), name="profile"),
path("mentions/", users.UserCaseNoteMentions.as_view(), name="user_case_note_mentions"),
Expand Down
Loading

0 comments on commit d5d5833

Please sign in to comment.