From 3aa6830f43fe45f7d90b6791882a9bc0031403b5 Mon Sep 17 00:00:00 2001 From: Christopher Pettinga Date: Tue, 25 Feb 2025 15:11:09 +0000 Subject: [PATCH 1/5] working on link --- .../apply_for_a_licence/tasklist/__init__.py | 22 +++ .../tasklist/base_classes.py | 52 +++++ .../apply_for_a_licence/tasklist/sub_tasks.py | 185 ++++++++++++++++++ .../apply_for_a_licence/tasklist/tasks.py | 62 ++++++ .../dashboard/dashboard.html | 2 +- .../form_steps/check_your_answers.html | 16 +- .../apply_for_a_licence/tasklist.html | 49 +++++ django_app/apply_for_a_licence/urls.py | 9 +- django_app/apply_for_a_licence/utils.py | 14 +- .../views/views_documents.py | 4 +- .../views/views_existing_licence.py | 10 +- .../views/views_grounds_purpose.py | 2 +- .../views/views_individual.py | 13 +- .../views/views_recipients.py | 6 +- .../views/views_services.py | 3 +- .../apply_for_a_licence/views/views_start.py | 24 +-- .../views/views_tasklist.py | 50 +++++ .../views/views_yourself.py | 2 +- django_app/core/forms/base_forms.py | 9 +- .../core/templates/core/base_form_step.html | 2 +- django_app/core/views/base_views.py | 8 +- 21 files changed, 491 insertions(+), 53 deletions(-) create mode 100644 django_app/apply_for_a_licence/tasklist/__init__.py create mode 100644 django_app/apply_for_a_licence/tasklist/base_classes.py create mode 100644 django_app/apply_for_a_licence/tasklist/sub_tasks.py create mode 100644 django_app/apply_for_a_licence/tasklist/tasks.py create mode 100644 django_app/apply_for_a_licence/templates/apply_for_a_licence/tasklist.html create mode 100644 django_app/apply_for_a_licence/views/views_tasklist.py diff --git a/django_app/apply_for_a_licence/tasklist/__init__.py b/django_app/apply_for_a_licence/tasklist/__init__.py new file mode 100644 index 00000000..6e2ee361 --- /dev/null +++ b/django_app/apply_for_a_licence/tasklist/__init__.py @@ -0,0 +1,22 @@ +from .tasks import ( + AboutTheServicesTask, + AboutYouTask, + RecipientsTask, + ReviewAndSubmitTask, + WhoTheLicenceCoversTask, +) + + +class Tasklist: + def __init__(self, licence): + self.licence = licence + + def get_tasks(self): + tasks = [AboutYouTask(licence=self.licence)] + if self.licence.who_do_you_want_the_licence_to_cover != "myself": + tasks.append(WhoTheLicenceCoversTask(licence=self.licence)) + + tasks.append(AboutTheServicesTask(licence=self.licence)) + tasks.append(RecipientsTask(licence=self.licence)) + tasks.append(ReviewAndSubmitTask(licence=self.licence)) + return tasks diff --git a/django_app/apply_for_a_licence/tasklist/base_classes.py b/django_app/apply_for_a_licence/tasklist/base_classes.py new file mode 100644 index 00000000..a220cb82 --- /dev/null +++ b/django_app/apply_for_a_licence/tasklist/base_classes.py @@ -0,0 +1,52 @@ +from typing import Literal + + +class BaseTask: + name: str = "" + + def __init__(self, licence, *args, **kwargs): + self.licence = licence + super().__init__(*args, **kwargs) + + @property + def id(self) -> str: + return self.name.lower().replace(" ", "-") + + def get_sub_tasks(self): + raise NotImplementedError() + + def can_start_sub_task(self) -> bool: + return True + + +class BaseSubTask: + name: str = "" + help_text: str = "" + status: Literal["cannot_start", "not_started", "in_progress", "complete"] = "cannot_start" + url: str = "" + tag_colour: str = "blue" + + def __init__(self, licence, *args, **kwargs): + self.licence = licence + super().__init__(*args, **kwargs) + + @property + def id(self) -> str: + return self.name.lower().replace(" ", "-") + + @property + def should_show_tag(self) -> bool: + return self.status == "not_started" + + @property + def can_start(self) -> bool: + return self.status in ["not_started", "in_progress", "complete"] + + def get_human_readable_status(self) -> str: + status_mapping = { + "cannot_start": "Cannot start yet", + "not_started": "Not yet started", + "in_progress": "In progress", + "complete": "Complete", + } + return status_mapping[self.status] diff --git a/django_app/apply_for_a_licence/tasklist/sub_tasks.py b/django_app/apply_for_a_licence/tasklist/sub_tasks.py new file mode 100644 index 00000000..127f9d63 --- /dev/null +++ b/django_app/apply_for_a_licence/tasklist/sub_tasks.py @@ -0,0 +1,185 @@ +import uuid + +from apply_for_a_licence import choices +from apply_for_a_licence.models import Individual +from apply_for_a_licence.tasklist.base_classes import BaseSubTask +from django.urls import reverse, reverse_lazy + + +class YourDetailsSubTask(BaseSubTask): + name = "Your details" + + @property + def help_text(self): + if self.licence.who_do_you_want_the_licence_to_cover == "myself": + return "Your name and address, details of anyone else you want to add" + else: + return "" + + @property + def url(self): + if self.licence.who_do_you_want_the_licence_to_cover == "myself": + try: + applicant_individual = self.licence.individuals.filter(is_applicant=True).get() + return reverse("add_yourself", kwargs={"yourself_uuid": applicant_individual.pk}) + except Individual.DoesNotExist: + return reverse("add_yourself", kwargs={"yourself_uuid": uuid.uuid4()}) + else: + return reverse("are_you_third_party") + + @property + def status(self): + status = "not_started" + if self.licence.applicant_full_name: + status = "complete" + + return status + + +class DetailsOfTheEntityYouWantToCoverSubTask(BaseSubTask): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.is_business = ( + self.licence.who_do_you_want_the_licence_to_cover == choices.WhoDoYouWantTheLicenceToCoverChoices.business + ) + + @property + def name(self) -> str: + if self.is_business: + return "Details of the business you want to cover" + else: + return "Details of the individual you want to cover" + + @property + def help_text(self): + if self.is_business: + return "Name and address of business" + else: + return "Name, address, business they work for" + + @property + def url(self): + if self.is_business: + if self.licence.organisations.filter(type_of_relationship=choices.TypeOfRelationshipChoices.business).exists(): + return reverse("business_added") + else: + return reverse("is_the_business_registered_with_companies_house", kwargs={"business_uuid": str(uuid.uuid4())}) + else: + if self.licence.individuals.filter(is_applicant=False).exists(): + return reverse("individual_added") + else: + return reverse("add_an_individual", kwargs={"individual_uuid": str(uuid.uuid4())}) + + @property + def status(self): + status = "not_started" + + if self.is_business: + if self.licence.organisations.filter(type_of_relationship=choices.TypeOfRelationshipChoices.business).exists(): + status = "complete" + else: + if self.licence.individuals.filter(is_applicant=False).exists(): + status = "complete" + + return status + + +class PreviousLicensesHeldSubTask(BaseSubTask): + name = "Previous licences" + help_text = "Any previous licence numbers" + url = reverse_lazy("previous_licence") + + @property + def status(self): + status = "cannot_start_yet" + if self.licence.held_existing_licence: + status = "complete" + entity_details_subtask = DetailsOfTheEntityYouWantToCoverSubTask(self.licence) + if entity_details_subtask.status == "complete": + status = "not_started" + + return status + + +class ServicesYouWantToProvideSubTask(BaseSubTask): + name = "The services you want to provide" + help_text = "Description of your services" + url = reverse_lazy("type_of_service") + + @property + def status(self): + status = "not_started" + if self.licence.type_of_service: + status = "complete" + + return status + + +class PurposeForProvidingServicesSubTask(BaseSubTask): + name = "Your purpose for providing the services" + help_text = "Licensing grounds or alignment with sanctions regulations" + + @property + def status(self): + status = "cannot_start" + if self.licence.type_of_service: + status = "not_started" + if self.licence.purpose_of_provision: + status = "complete" + + return status + + @property + def url(self): + if self.licence.type_of_service == choices.TypeOfServicesChoices.professional_and_business: + return reverse("licensing_grounds") + else: + return reverse("purpose_of_provision") + + +class UploadDocumentsSubTask(BaseSubTask): + name = "Upload documents" + help_text = "Attach files to support your application" + url = reverse_lazy("upload_documents") + + @property + def status(self): + status = "not_started" + if self.licence.documents.exists(): + status = "complete" + + return status + + +class RecipientContactDetailsSubTask(BaseSubTask): + name = "Recipient contact details" + + @property + def status(self): + status = "not_started" + if self.licence.recipients.exists(): + status = "complete" + + return status + + @property + def url(self) -> str: + if self.licence.recipients.exists(): + return reverse("recipient_added") + else: + return reverse("where_is_the_recipient_located", kwargs={"recipient_uuid": uuid.uuid4()}) + + +class CheckYourAnswersSubTask(BaseSubTask): + name = "Check your answers before you submit your application" + url = reverse_lazy("check_your_answers") + + @property + def status(self): + status = "cannot_start" + if self.licence.recipients.exists(): + status = "not_started" + if self.licence.status == "submitted": + status = "complete" + + return status diff --git a/django_app/apply_for_a_licence/tasklist/tasks.py b/django_app/apply_for_a_licence/tasklist/tasks.py new file mode 100644 index 00000000..fe45f9b7 --- /dev/null +++ b/django_app/apply_for_a_licence/tasklist/tasks.py @@ -0,0 +1,62 @@ +from apply_for_a_licence.tasklist.base_classes import BaseTask +from apply_for_a_licence.tasklist.sub_tasks import ( + CheckYourAnswersSubTask, + DetailsOfTheEntityYouWantToCoverSubTask, + PreviousLicensesHeldSubTask, + PurposeForProvidingServicesSubTask, + RecipientContactDetailsSubTask, + ServicesYouWantToProvideSubTask, + UploadDocumentsSubTask, + YourDetailsSubTask, +) + + +class AboutYouTask(BaseTask): + name = "About you" + + def get_sub_tasks(self): + sub_tasks = [YourDetailsSubTask(licence=self.licence)] + if self.licence.who_do_you_want_the_licence_to_cover == "myself": + sub_tasks.append(PreviousLicensesHeldSubTask(licence=self.licence)) + return sub_tasks + + +class WhoTheLicenceCoversTask(BaseTask): + name = "Who the licence covers" + + def get_sub_tasks(self): + sub_tasks = [ + DetailsOfTheEntityYouWantToCoverSubTask(licence=self.licence), + PreviousLicensesHeldSubTask(licence=self.licence), + ] + return sub_tasks + + +class AboutTheServicesTask(BaseTask): + name = "About the services" + + def get_sub_tasks(self): + sub_tasks = [ + ServicesYouWantToProvideSubTask(licence=self.licence), + PurposeForProvidingServicesSubTask(licence=self.licence), + UploadDocumentsSubTask(licence=self.licence), + ] + return sub_tasks + + +class RecipientsTask(BaseTask): + name = "Recipients of the services" + + def get_sub_tasks(self): + sub_tasks = [ + RecipientContactDetailsSubTask(licence=self.licence), + ] + return sub_tasks + + +class ReviewAndSubmitTask(BaseTask): + name = "Review and submit" + + def get_sub_tasks(self): + sub_tasks = [CheckYourAnswersSubTask(licence=self.licence)] + return sub_tasks diff --git a/django_app/apply_for_a_licence/templates/apply_for_a_licence/dashboard/dashboard.html b/django_app/apply_for_a_licence/templates/apply_for_a_licence/dashboard/dashboard.html index f094d0df..6485e56d 100644 --- a/django_app/apply_for_a_licence/templates/apply_for_a_licence/dashboard/dashboard.html +++ b/django_app/apply_for_a_licence/templates/apply_for_a_licence/dashboard/dashboard.html @@ -51,7 +51,7 @@

Your applications

Continue + href="{% url 'triage' licence_pk=application.pk %}">Continue