-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2260 from uktrade/LTD-5706-approve-session-wizard
[LTD-5706] convert advice form and views into structured folders.
- Loading branch information
Showing
32 changed files
with
1,072 additions
and
945 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
from django import forms | ||
|
||
from core.common.forms import BaseForm | ||
from crispy_forms_gds.helper import FormHelper | ||
from crispy_forms_gds.layout import Layout, Submit | ||
from crispy_forms_gds.choices import Choice | ||
|
||
from core.forms.layouts import ( | ||
ConditionalCheckboxes, | ||
ConditionalCheckboxesQuestion, | ||
RadioTextArea, | ||
) | ||
|
||
|
||
class SelectAdviceForm(forms.Form): | ||
CHOICES = [("approve_all", "Approve all"), ("refuse_all", "Refuse all")] | ||
|
||
recommendation = forms.ChoiceField( | ||
choices=CHOICES, | ||
widget=forms.RadioSelect, | ||
label="", | ||
error_messages={"required": "Select if you approve all or refuse all"}, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.helper = FormHelper() | ||
self.helper.add_input(Submit("submit", "Continue")) | ||
|
||
|
||
class PicklistAdviceForm(forms.Form): | ||
def _picklist_to_choices(self, picklist_data): | ||
reasons_choices = [] | ||
reasons_text = {"other": ""} | ||
|
||
for result in picklist_data["results"]: | ||
key = "_".join(result.get("name").lower().split()) | ||
choice = Choice(key, result.get("name")) | ||
if result == picklist_data["results"][-1]: | ||
choice = Choice(key, result.get("name"), divider="or") | ||
reasons_choices.append(choice) | ||
reasons_text[key] = result.get("text") | ||
reasons_choices.append(Choice("other", "Other")) | ||
return reasons_choices, reasons_text | ||
|
||
|
||
class MoveCaseForwardForm(forms.Form): | ||
def __init__(self, move_case_button_label="Move case forward", *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.helper = FormHelper() | ||
self.helper.layout = Layout(Submit("submit", move_case_button_label, css_id="move-case-forward-button")) | ||
|
||
|
||
class RecommendAnApprovalForm(PicklistAdviceForm, BaseForm): | ||
class Layout: | ||
TITLE = "Recommend an approval" | ||
|
||
approval_reasons = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": 7, "class": "govuk-!-margin-top-4"}), | ||
label="", | ||
error_messages={"required": "Enter a reason for approving"}, | ||
) | ||
approval_radios = forms.ChoiceField( | ||
label="What is your reason for approving?", | ||
required=False, | ||
widget=forms.RadioSelect, | ||
choices=(), | ||
) | ||
add_licence_conditions = forms.BooleanField( | ||
label="Add licence conditions, instructions to exporter or footnotes (optional)", | ||
required=False, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
approval_reason = kwargs.pop("approval_reason") | ||
# this follows the same pattern as denial_reasons. | ||
approval_choices, approval_text = self._picklist_to_choices(approval_reason) | ||
self.approval_text = approval_text | ||
super().__init__(*args, **kwargs) | ||
|
||
self.fields["approval_radios"].choices = approval_choices | ||
|
||
def get_layout_fields(self): | ||
return ( | ||
RadioTextArea("approval_radios", "approval_reasons", self.approval_text), | ||
"add_licence_conditions", | ||
) | ||
|
||
|
||
class LicenceConditionsForm(PicklistAdviceForm, BaseForm): | ||
class Layout: | ||
TITLE = "Add licence conditions, instructions to exporter or footnotes (optional)" | ||
|
||
proviso = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": 7, "class": "govuk-!-margin-top-4"}), | ||
label="", | ||
required=False, | ||
) | ||
|
||
approval_radios = forms.ChoiceField( | ||
label="What is your reason for approving?", | ||
required=False, | ||
widget=forms.RadioSelect, | ||
choices=(), | ||
) | ||
proviso_checkboxes = forms.MultipleChoiceField( | ||
label="Add a licence condition (optional)", | ||
required=False, | ||
widget=forms.CheckboxSelectMultiple, | ||
choices=(), | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
# only return proviso (text) for selected radios, nothing else matters, join by 2 newlines | ||
return {"proviso": "\r\n\r\n".join([cleaned_data[selected] for selected in cleaned_data["proviso_checkboxes"]])} | ||
|
||
def __init__(self, *args, **kwargs): | ||
proviso = kwargs.pop("proviso") | ||
|
||
proviso_choices, proviso_text = self._picklist_to_choices(proviso) | ||
self.proviso_text = proviso_text | ||
|
||
self.conditional_checkbox_choices = ( | ||
ConditionalCheckboxesQuestion(choices.label, choices.value) for choices in proviso_choices | ||
) | ||
|
||
super().__init__(*args, **kwargs) | ||
|
||
self.fields["proviso_checkboxes"].choices = proviso_choices | ||
for choices in proviso_choices: | ||
self.fields[choices.value] = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": 3, "class": "govuk-!-margin-top-4"}), | ||
label="Description", | ||
required=False, | ||
initial=proviso_text[choices.value], | ||
) | ||
|
||
def get_layout_fields(self): | ||
|
||
return (ConditionalCheckboxes("proviso_checkboxes", *self.conditional_checkbox_choices),) | ||
|
||
|
||
class FootnotesApprovalAdviceForm(PicklistAdviceForm, BaseForm): | ||
class Layout: | ||
TITLE = "Instructions for the exporter (optional)" | ||
|
||
instructions_to_exporter = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": "3"}), | ||
label="Add any instructions for the exporter (optional)", | ||
help_text="These may be added to the licence cover letter, subject to review by the Licensing Unit.", | ||
required=False, | ||
) | ||
|
||
footnote_details_radios = forms.ChoiceField( | ||
label="Add a reporting footnote (optional)", | ||
required=False, | ||
widget=forms.RadioSelect, | ||
choices=(), | ||
) | ||
footnote_details = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": 3, "class": "govuk-!-margin-top-4"}), | ||
label="", | ||
required=False, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
footnote_details = kwargs.pop("footnote_details") | ||
footnote_details_choices, footnote_text = self._picklist_to_choices(footnote_details) | ||
self.footnote_text = footnote_text | ||
|
||
super().__init__(*args, **kwargs) | ||
|
||
self.fields["footnote_details_radios"].choices = footnote_details_choices | ||
|
||
def get_layout_fields(self): | ||
return ( | ||
"instructions_to_exporter", | ||
RadioTextArea("footnote_details_radios", "footnote_details", self.footnote_text), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from django import forms | ||
from django.utils.html import format_html | ||
|
||
from caseworker.advice.forms.approval import SelectAdviceForm | ||
from caseworker.advice.forms.forms import GiveApprovalAdviceForm | ||
from crispy_forms_gds.helper import FormHelper | ||
from crispy_forms_gds.layout import Layout, Submit | ||
|
||
from core.forms.layouts import ( | ||
RadioTextArea, | ||
) | ||
|
||
|
||
class ConsolidateSelectAdviceForm(SelectAdviceForm): | ||
DOCUMENT_TITLE = "Recommend and combine case recommendation case" | ||
CHOICES = [("approve", "Approve"), ("refuse", "Refuse")] | ||
recommendation = forms.ChoiceField( | ||
choices=CHOICES, | ||
widget=forms.RadioSelect, | ||
label="", | ||
error_messages={"required": "Select if you approve or refuse"}, | ||
) | ||
|
||
def __init__(self, team_name, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
recommendation_label = "What is the combined recommendation" | ||
if team_name: | ||
recommendation_label = f"{recommendation_label} for {team_name}" | ||
self.fields["recommendation"].label = f"{recommendation_label}?" | ||
|
||
|
||
class ConsolidateApprovalForm(GiveApprovalAdviceForm): | ||
"""Approval form minus some fields.""" | ||
|
||
def __init__(self, team_alias, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
self.helper = FormHelper() | ||
self.helper.layout = Layout( | ||
RadioTextArea("approval_radios", "approval_reasons", self.approval_text), | ||
RadioTextArea("proviso_radios", "proviso", self.proviso_text), | ||
Submit("submit", "Submit recommendation"), | ||
) | ||
|
||
|
||
class LUConsolidateRefusalForm(forms.Form): | ||
refusal_note = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": "7"}), | ||
label="Enter the refusal note as agreed in the refusal meeting", | ||
error_messages={"required": "Enter the refusal meeting note"}, | ||
) | ||
|
||
denial_reasons = forms.MultipleChoiceField( | ||
widget=forms.SelectMultiple(), | ||
label="What is the refusal criteria?", | ||
help_text=format_html( | ||
f'Select all <a class="govuk-link" ' | ||
f'href="https://questions-statements.parliament.uk/written-statements/detail/2021-12-08/hcws449" ' | ||
f'target="_blank">refusal criteria (opens in a new tab)</a> that apply' | ||
), | ||
error_messages={"required": "Select at least one refusal criteria"}, | ||
) | ||
|
||
def __init__(self, choices, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.fields["denial_reasons"].choices = choices | ||
self.helper = FormHelper() | ||
self.helper.layout = Layout("denial_reasons", "refusal_note", Submit("submit", "Submit recommendation")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from django import forms | ||
|
||
from crispy_forms_gds.helper import FormHelper | ||
from crispy_forms_gds.layout import Field, Layout | ||
|
||
from core.forms.layouts import ( | ||
ConditionalRadios, | ||
ConditionalRadiosQuestion, | ||
) | ||
from core.forms.utils import coerce_str_to_bool | ||
|
||
|
||
class CountersignAdviceForm(forms.Form): | ||
DOCUMENT_TITLE = "Review and countersign this case" | ||
approval_reasons = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": "10"}), | ||
label="Explain why you are agreeing with this recommendation", | ||
error_messages={"required": "Enter why you agree with the recommendation"}, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.helper = FormHelper() | ||
self.helper.form_tag = False | ||
self.helper.layout = Layout("approval_reasons") | ||
|
||
|
||
class CountersignDecisionAdviceForm(forms.Form): | ||
DECISION_CHOICES = [(True, "Yes"), (False, "No")] | ||
|
||
outcome_accepted = forms.TypedChoiceField( | ||
choices=DECISION_CHOICES, | ||
widget=forms.RadioSelect, | ||
coerce=coerce_str_to_bool, | ||
label="Do you agree with this recommendation?", | ||
error_messages={"required": "Select yes if you agree with the recommendation"}, | ||
) | ||
approval_reasons = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": "10"}), | ||
label="Explain your reasons", | ||
required=False, | ||
) | ||
rejected_reasons = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": "10"}), | ||
label="Message to the case officer (explaining why the case is being returned)", | ||
required=False, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.helper = FormHelper() | ||
self.helper.form_tag = False | ||
self.helper.layout = Layout( | ||
ConditionalRadios( | ||
"outcome_accepted", | ||
ConditionalRadiosQuestion("Yes", Field("approval_reasons")), | ||
ConditionalRadiosQuestion("No", Field("rejected_reasons")), | ||
), | ||
) | ||
|
||
def clean_approval_reasons(self): | ||
outcome_accepted = self.cleaned_data.get("outcome_accepted") | ||
approval_reasons = self.cleaned_data.get("approval_reasons") | ||
if outcome_accepted and not self.cleaned_data.get("approval_reasons"): | ||
self.add_error("approval_reasons", "Enter a reason for countersigning") | ||
|
||
return approval_reasons | ||
|
||
def clean_rejected_reasons(self): | ||
outcome_accepted = self.cleaned_data.get("outcome_accepted") | ||
rejected_reasons = self.cleaned_data.get("rejected_reasons") | ||
if outcome_accepted is False and not self.cleaned_data.get("rejected_reasons"): | ||
self.add_error("rejected_reasons", "Enter a message explaining why the case is being returned") | ||
|
||
return rejected_reasons |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from django import forms | ||
|
||
from crispy_forms_gds.helper import FormHelper | ||
from crispy_forms_gds.layout import Submit | ||
|
||
|
||
class DeleteAdviceForm(forms.Form): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.helper = FormHelper() | ||
self.helper.add_input(Submit("confirm", "Confirm")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from django import forms | ||
|
||
from core.common.forms import BaseForm | ||
|
||
|
||
class PicklistApprovalAdviceEditForm(BaseForm): | ||
class Layout: | ||
TITLE = "Add licence conditions, instructions to exporter or footnotes (optional)" | ||
|
||
proviso = forms.CharField( | ||
widget=forms.Textarea(attrs={"rows": 30, "class": "govuk-!-margin-top-4"}), | ||
label="", | ||
required=False, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
def get_layout_fields(self): | ||
return ("proviso",) |
Oops, something went wrong.