diff --git a/django_app/apply_for_a_licence/choices.py b/django_app/apply_for_a_licence/choices.py
index 702ba292..92688dbb 100644
--- a/django_app/apply_for_a_licence/choices.py
+++ b/django_app/apply_for_a_licence/choices.py
@@ -12,10 +12,10 @@
class BaseChoices(models.TextChoices):
@classmethod
def active_choices(cls):
- return [choice for choice in cls.choices if choice[0] not in cls.deactive_choices()]
+ return [choice for choice in cls.choices if choice[0] not in cls.inactive_choices()]
@classmethod
- def deactive_choices(cls):
+ def inactive_choices(cls):
pass
@@ -79,7 +79,7 @@ class ProfessionalOrBusinessServicesChoices(models.TextChoices):
class LicensingGroundsChoices(BaseChoices):
@classmethod
- def deactive_choices(cls) -> List[str]:
+ def inactive_choices(cls) -> List[str]:
return ["parent_or_subsidiary_company"]
civil_society = (
diff --git a/django_app/feedback/choices.py b/django_app/feedback/choices.py
index 4e32fbc3..00c17f68 100644
--- a/django_app/feedback/choices.py
+++ b/django_app/feedback/choices.py
@@ -1,3 +1,6 @@
+from typing import List
+
+from apply_for_a_licence.choices import BaseChoices
from django.db import models
@@ -9,7 +12,11 @@ class RatingChoices(models.IntegerChoices):
VERY_SATISFIED = 5, "Very satisfied"
-class DidYouExperienceAnyIssues(models.TextChoices):
+class DidYouExperienceAnyIssues(BaseChoices):
+ @classmethod
+ def inactive_choices(cls) -> List[str]:
+ return ["no"]
+
NO = "no", "I did not experience any issues"
NOT_FOUND = "not_found", "I did not find what I was looking for"
DIFFICULT = "difficult", "I found it difficult to navigate"
diff --git a/django_app/feedback/forms.py b/django_app/feedback/forms.py
index b863a185..6774b730 100644
--- a/django_app/feedback/forms.py
+++ b/django_app/feedback/forms.py
@@ -13,7 +13,7 @@ class FeedbackForm(BaseModelForm):
submit_button_text = "Submit"
did_you_experience_any_issues = forms.MultipleChoiceField(
- choices=DidYouExperienceAnyIssues.choices,
+ choices=DidYouExperienceAnyIssues.active_choices(),
widget=forms.CheckboxSelectMultiple,
label="Did you experience any of the following issues?",
required=False,
@@ -21,7 +21,7 @@ class FeedbackForm(BaseModelForm):
class Meta:
model = FeedbackItem
- fields = ("rating", "did_you_experience_any_issues", "how_we_could_improve_the_service")
+ fields = ("rating", "did_you_experience_any_issues", "how_we_could_improve_the_service", "user_name", "user_email")
labels = {
"how_we_could_improve_the_service": "How could we improve the service?",
"rating": "Overall, how satisfied did you feel with using this service?",
@@ -61,5 +61,11 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
),
css_class="optional_question",
),
+ Fieldset(
+ HTMLTemplate("feedback/participate_in_user_research.html"),
+ Field.text("user_name", label_size=Size.SMALL),
+ Field.text("user_email", label_size=Size.SMALL),
+ css_class="optional_question",
+ ),
HTMLTemplate("feedback/feedback_disclaimer.html"),
)
diff --git a/django_app/feedback/migrations/0003_feedbackitem_user_email_feedbackitem_user_name_and_more.py b/django_app/feedback/migrations/0003_feedbackitem_user_email_feedbackitem_user_name_and_more.py
new file mode 100644
index 00000000..a310d084
--- /dev/null
+++ b/django_app/feedback/migrations/0003_feedbackitem_user_email_feedbackitem_user_name_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 4.2.16 on 2024-12-19 09:43
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("feedback", "0002_feedbackitem_url_historicalfeedbackitem_url"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="feedbackitem",
+ name="user_email",
+ field=models.EmailField(blank=True, max_length=254, null=True),
+ ),
+ migrations.AddField(
+ model_name="feedbackitem",
+ name="user_name",
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ migrations.AddField(
+ model_name="historicalfeedbackitem",
+ name="user_email",
+ field=models.EmailField(blank=True, max_length=254, null=True),
+ ),
+ migrations.AddField(
+ model_name="historicalfeedbackitem",
+ name="user_name",
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ ]
diff --git a/django_app/feedback/models.py b/django_app/feedback/models.py
index ca7ba917..9b44b55e 100644
--- a/django_app/feedback/models.py
+++ b/django_app/feedback/models.py
@@ -12,6 +12,8 @@ class FeedbackItem(BaseModel):
)
how_we_could_improve_the_service = models.TextField(null=True, blank=True)
url = models.URLField(null=True, blank=True)
+ user_name = models.CharField(max_length=255, null=True, blank=True)
+ user_email = models.EmailField(null=True, blank=True)
def get_did_you_experience_any_issues_display(self) -> str:
display_list = []
diff --git a/django_app/feedback/static/feedback/javascript/feedback.js b/django_app/feedback/static/feedback/javascript/feedback.js
index 79d59c89..77ab79f7 100644
--- a/django_app/feedback/static/feedback/javascript/feedback.js
+++ b/django_app/feedback/static/feedback/javascript/feedback.js
@@ -14,4 +14,6 @@ $(window).bind("pageshow", function(event) {
$('.optional_question').hide()
}
})
+
+ $("input[name='rating']:checked").trigger("change")
});
diff --git a/django_app/feedback/templates/feedback/crispy_fields/feedback_stars.html b/django_app/feedback/templates/feedback/crispy_fields/feedback_stars.html
deleted file mode 100644
index b11f4afb..00000000
--- a/django_app/feedback/templates/feedback/crispy_fields/feedback_stars.html
+++ /dev/null
@@ -1,45 +0,0 @@
-{% load crispy_forms_field crispy_forms_gds %}
-
-
-
-
diff --git a/django_app/feedback/templates/feedback/participate_in_user_research.html b/django_app/feedback/templates/feedback/participate_in_user_research.html
new file mode 100644
index 00000000..ea841291
--- /dev/null
+++ b/django_app/feedback/templates/feedback/participate_in_user_research.html
@@ -0,0 +1,2 @@
+Participating in further research
+We're always improving our services and would like your help to make this one better. If you're happy for us to contact you about participating in further research, please leave your name and email address.
diff --git a/django_app/view_a_licence/templates/view_a_licence/view_all_feedback.html b/django_app/view_a_licence/templates/view_a_licence/view_all_feedback.html
new file mode 100644
index 00000000..cb0abcfe
--- /dev/null
+++ b/django_app/view_a_licence/templates/view_a_licence/view_all_feedback.html
@@ -0,0 +1,73 @@
+{% extends "core/base.html" %}
+{% block cookie_banner %}{% endblock cookie_banner %}
+{% block title %}View Feedback for apply sanctioned services licence{% endblock title %}
+{% block back_button %}{% endblock back_button %}
+{% block column_content %}
+
+
+ View feedback on the apply for a sanctioned services licence service
+
+
+
+
+
+
+
+
+ Feedback
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for feedback_item in object_list %}
+
+ {{ feedback_item.id }} |
+ {{ feedback_item.created_at }} |
+ {{ feedback_item.modified_at }} |
+ {{ feedback_item.get_rating_display}} |
+ {{ feedback_item.get_did_you_experience_any_issues_display | linebreaksbr }} |
+ {{ feedback_item.how_we_could_improve_the_service }} |
+ {{ feedback_item.url }} |
+ {% if feedback_item.user_name or feedback_item.user_email %}Yes{% else %}No{% endif %} |
+
+ {% endfor %}
+
+
+{% endblock column_content %}
+
+{% block extra_js %}
+ {{ block.super }}
+
+{% endblock extra_js %}
diff --git a/django_app/view_a_licence/templates/view_a_licence/view_feedback.html b/django_app/view_a_licence/templates/view_a_licence/view_feedback.html
index d1b935e3..b1fa0c62 100644
--- a/django_app/view_a_licence/templates/view_a_licence/view_feedback.html
+++ b/django_app/view_a_licence/templates/view_a_licence/view_feedback.html
@@ -1,74 +1,39 @@
{% extends "core/base.html" %}
-{% block cookie_banner %}{% endblock cookie_banner %}
-{% block title %}View Feedback for apply sanctioned services licence{% endblock title %}
-{% block back_button %}{% endblock back_button %}
-{% block column_content %}
-
-
- View feedback on the apply for a sanctioned services licence service
-
-
-
-
-
-
-
-
- Feedback
-
-
-
-
-
-
-
-
-
-
+{% block title %}View individual feedback{% endblock title %}
-
-
-
- {% for feedback_item in object_list %}
-
- {{ feedback_item.id }} |
- {{ feedback_item.created_at }} |
- {{ feedback_item.modified_at }} |
- {{ feedback_item.get_rating_display}} |
- {{ feedback_item.get_did_you_experience_any_issues_display | linebreaksbr }} |
- {{ feedback_item.how_we_could_improve_the_service }} |
- {{ feedback_item.url }} |
-
- {% endfor %}
-
-
+{% block column_content %}
+
+ Feedback item - {{ feedback.id }}
+
+
+
+ {{ feedback.created_at }} |
+
+
+
+ {{ feedback.get_rating_display}} |
+
+
+
+ {{ feedback.get_did_you_experience_any_issues_display | linebreaksbr }} |
+
+
+
+ {{ feedback.how_we_could_improve_the_service }} |
+
+
+
+ {{ feedback.url }} |
+
+
+
+ {{ feedback.user_name }} |
+
+
+
+ {{ feedback.user_email }} |
+
+
+
{% endblock column_content %}
-
-{% block extra_js %}
- {{ block.super }}
-
-{% endblock extra_js %}
diff --git a/django_app/view_a_licence/urls.py b/django_app/view_a_licence/urls.py
index 8880a2ce..d1f60126 100644
--- a/django_app/view_a_licence/urls.py
+++ b/django_app/view_a_licence/urls.py
@@ -9,5 +9,6 @@
path("view-all-applications", views.ApplicationListView.as_view(), name="application_list"),
path("view-application//", views.ViewALicenceApplicationView.as_view(), name="view_application"),
path("manage-users/", views.ManageUsersView.as_view(), name="manage_users"),
- path("view-feedback/", views.ViewFeedbackView.as_view(), name="view_feedback"),
+ path("view-all-feedback/", views.ViewAllFeedbackView.as_view(), name="view_all_feedback"),
+ path("view-feedback/", views.ViewFeedbackView.as_view(), name="view_feedback"),
]
diff --git a/django_app/view_a_licence/views.py b/django_app/view_a_licence/views.py
index 64b0bec7..d144ba1f 100644
--- a/django_app/view_a_licence/views.py
+++ b/django_app/view_a_licence/views.py
@@ -21,6 +21,7 @@
logger = logging.getLogger(__name__)
+
# ALL VIEWS HERE MUST BE DECORATED WITH AT LEAST LoginRequiredMixin
@@ -109,10 +110,10 @@ def get_context_data(self, **kwargs: object) -> dict[str, Any]:
@method_decorator(require_view_a_licence(), name="dispatch")
-class ViewFeedbackView(LoginRequiredMixin, ActiveUserRequiredMixin, ListView):
+class ViewAllFeedbackView(LoginRequiredMixin, ActiveUserRequiredMixin, ListView):
context_object_name = "feedback"
model = FeedbackItem
- template_name = "view_a_licence/view_feedback.html"
+ template_name = "view_a_licence/view_all_feedback.html"
def get_queryset(self) -> "QuerySet[FeedbackItem]":
queryset = super().get_queryset()
@@ -121,3 +122,10 @@ def get_queryset(self) -> "QuerySet[FeedbackItem]":
if date_max := self.request.GET.get("date_max"):
queryset = queryset.filter(created_at__date__lte=date_max)
return queryset
+
+
+@method_decorator(require_view_a_licence(), name="dispatch")
+class ViewFeedbackView(LoginRequiredMixin, ActiveUserRequiredMixin, DetailView):
+ model = FeedbackItem
+ template_name = "view_a_licence/view_feedback.html"
+ context_object_name = "feedback"
diff --git a/tests/test_unit/test_feedback/test_views.py b/tests/test_unit/test_feedback/test_views.py
index 5f9a8059..e548cd29 100644
--- a/tests/test_unit/test_feedback/test_views.py
+++ b/tests/test_unit/test_feedback/test_views.py
@@ -48,3 +48,18 @@ def test_adding_url_to_feedback(self, al_client):
)
feedback_object = FeedbackItem.objects.get()
assert feedback_object.url == "https://example.com"
+
+ def test_adding_user_name_email_to_feedback(self, al_client):
+ al_client.post(
+ reverse("feedback:collect_full_feedback") + "?url=https://example.com",
+ data={
+ "rating": 1,
+ "how_we_could_improve_the_service": "try harder",
+ "did_you_experience_any_issues": ["not_found", "lacks_features"],
+ "user_name": "Sally",
+ "user_email": "sally@example.com",
+ },
+ )
+ feedback_object = FeedbackItem.objects.get()
+ assert feedback_object.user_name == "Sally"
+ assert feedback_object.user_email == "sally@example.com"
diff --git a/tests/test_unit/test_view_a_licence/test_views/test_view_feedback_view.py b/tests/test_unit/test_view_a_licence/test_views/test_view_feedback_view.py
index 9be2706a..1626b3e0 100644
--- a/tests/test_unit/test_view_a_licence/test_views/test_view_feedback_view.py
+++ b/tests/test_unit/test_view_a_licence/test_views/test_view_feedback_view.py
@@ -8,7 +8,7 @@
class TestViewFeedbackView:
def test_get_queryset(self, vl_client_logged_in):
FeedbackFactory.create_batch(3)
- response = vl_client_logged_in.get(reverse("view_a_licence:view_feedback"))
+ response = vl_client_logged_in.get(reverse("view_a_licence:view_all_feedback"))
objects = response.context["object_list"]
assert objects.count() == 3
@@ -24,7 +24,7 @@ def test_get_queryset_with_get_parameters(self, vl_client_logged_in):
# date_max query parameter
query_params = {"date_max": datetime.datetime.now().date() - datetime.timedelta(days=1)}
- response = vl_client_logged_in.get(reverse("view_a_licence:view_feedback"), data=query_params)
+ response = vl_client_logged_in.get(reverse("view_a_licence:view_all_feedback"), data=query_params)
objects = response.context["object_list"]
assert objects.count() == 2
object_ids = list(objects.values_list("id", flat=True))
@@ -35,7 +35,7 @@ def test_get_queryset_with_get_parameters(self, vl_client_logged_in):
# date_min query parameter
query_params = {"date_min": datetime.datetime.now().date() - datetime.timedelta(days=5)}
- response = vl_client_logged_in.get(reverse("view_a_licence:view_feedback"), data=query_params)
+ response = vl_client_logged_in.get(reverse("view_a_licence:view_all_feedback"), data=query_params)
objects = response.context["object_list"]
assert objects.count() == 2
object_ids = list(objects.values_list("id", flat=True))
@@ -50,7 +50,7 @@ def test_get_queryset_with_get_parameters(self, vl_client_logged_in):
"date_min": datetime.datetime.now().date() - datetime.timedelta(days=6),
}
- response = vl_client_logged_in.get(reverse("view_a_licence:view_feedback"), data=query_params)
+ response = vl_client_logged_in.get(reverse("view_a_licence:view_all_feedback"), data=query_params)
objects = response.context["object_list"]
assert objects.count() == 1
object_ids = list(objects.values_list("id", flat=True))