Skip to content

Commit

Permalink
Merge branch 'main' into EL-1756-new-field-in-completed-user-journeys
Browse files Browse the repository at this point in the history
  • Loading branch information
MazOneTwoOne authored Oct 10, 2024
2 parents 4c6e0aa + 70e5664 commit 4484414
Show file tree
Hide file tree
Showing 23 changed files with 413 additions and 43 deletions.
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.sass.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ $govuk-new-typography-scale: true;
@import "summary-lists";
@import "feedback";
@import "button-group-custom";
@import "early-result-banner";

// NOTE: suggestions input component not yet part of GOV.UK frontend
// https://github.com/alphagov/govuk-frontend/pull/2453
Expand Down
9 changes: 9 additions & 0 deletions app/assets/stylesheets/early-result-banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.panel-blue {
background: govuk-colour("blue");
padding: 30px;
border: none;
}

.white_text {
color: white !important;
}
2 changes: 1 addition & 1 deletion app/assets/stylesheets/results.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ tr.solid-bottom-border {
}

// make the confirmation panel a neutral colour
.panel-blue {
.panel-blue-white-text {
background: govuk-colour("blue");

// All text on the blue background should be white for accessibility and legibility purposes.
Expand Down
81 changes: 54 additions & 27 deletions app/controllers/change_answers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,22 @@ def update
# Note that this merge! has the side effect of altering the session data in the '@check' variable
# that was loaded by our base class which looks quite awkward
session_data.merge!(@form.attributes_for_export_to_session)
next_step = Steps::Helper.next_step_for(session_data, step)
if @check.consistent?
if Steps::Helper.last_step_in_group?(session_data, step)
# if we have a 'check stops' block, it may have been removed even if we're consistent
# e.g. going from employed to unemployed
# but only check this if we have financial information in the check
if Steps::Logic.check_stops_at_gross_income?(session_data) && !Steps::Logic.non_means_tested?(session_data)
last_step_with_data = Steps::Helper.last_step_with_valid_data(session_data)
completed_steps = Steps::Helper.completed_steps_for(session_data, last_step_with_data)
cfe_result = CfeService.result(session_data, completed_steps)

if cfe_result.ineligible_gross_income?
# no change - go back to check answers
save_and_redirect_to_check_answers
else
# eligibility changed - remove 'ineligible' block and show notification
session_data.delete IneligibleGrossIncomeForm::SELECTION
flash[:notice] = I18n.t("service.change_eligibility")
redirect_to_next_question
end
else
save_and_redirect_to_check_answers
end
if FeatureFlags.enabled?(:ee_banner, session_data)
next_step = step_with_inconsistent_data
# we need to check for aggregated_means so we know when to show the ":how_to_aggregate" screen when in a change loop
if next_step && step != :aggregated_means
redirect_to helpers.check_step_path_from_step(next_step, assessment_code)
elsif Steps::Helper.last_step_in_group?(session_data, step)
save_and_redirect_to_check_answers
else
# this is the mini-loop - it isn't the last step in the section, we have
# valid data from a previous selection but we choose to take the user
# through the whole section again.
next_step = Steps::Helper.next_step_for(session_data, step)
redirect_to helpers.check_step_path_from_step(next_step, assessment_code)
end
# this branch is neccessary to surface the ":how_to_aggregate" screen when changing answers
elsif step == :aggregated_means
redirect_to helpers.check_step_path_from_step(next_step, assessment_code)
else
redirect_to_next_question
legacy_early_eligibility_change_answers
end
else
track_validation_error
Expand All @@ -63,6 +48,48 @@ def redirect_to_next_question
redirect_to helpers.check_step_path_from_step(next_check_answer_step, assessment_code)
end

def step_with_inconsistent_data
Steps::Helper.remaining_steps_for(session_data, step)
.drop_while { |thestep|
Flow::Handler.model_from_session(thestep, session_data).valid?
}.first
end

def legacy_early_eligibility_change_answers
next_step = Steps::Helper.next_step_for(session_data, step)
if @check.consistent? # check will always be consistent at change answers for the new ee_banner flow
if Steps::Helper.last_step_in_group?(session_data, step)
# if we have a 'check stops' block, it may have been removed even if we're consistent
# e.g. going from employed to unemployed
# but only check this if we have financial information in the check
if Steps::Logic.check_stops_at_gross_income?(session_data) && !Steps::Logic.non_means_tested?(session_data)
last_step_with_data = Steps::Helper.last_step_with_valid_data(session_data)
completed_steps = Steps::Helper.completed_steps_for(session_data, last_step_with_data)
cfe_result = CfeService.result(session_data, completed_steps)

if cfe_result.ineligible_gross_income?
# no change - go back to check answers
save_and_redirect_to_check_answers
else
# eligibility changed - remove 'ineligible' block and show notification
session_data.delete IneligibleGrossIncomeForm::SELECTION
flash[:notice] = I18n.t("service.change_eligibility")
redirect_to_next_question
end
else
save_and_redirect_to_check_answers
end
else
redirect_to helpers.check_step_path_from_step(next_step, assessment_code)
end
# this branch is neccessary to surface the ":how_to_aggregate" screen when changing answers
elsif step == :aggregated_means
redirect_to helpers.check_step_path_from_step(next_step, assessment_code)
else
redirect_to_next_question
end
end

# While we're in a 'change answers loop', we want to be working with a temporary copy of the answers
# stored in a section of the session called 'pending'.
def session_data
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/checks_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class ChecksController < ApplicationController
before_action :redirect_to_primary_host, only: :new
before_action :clear_early_result, only: :check_answers

def new
new_assessment_code = SecureRandom.uuid
Expand Down Expand Up @@ -32,6 +33,11 @@ def assessment_code
params[:assessment_code]
end

def clear_early_result
# not all checks have an early result e.g. passported clients, U18 etc
session_data["early_result"]&.clear
end

def specify_feedback_widget
@feedback = action_name == "end_of_journey" ? :satisfaction : :freetext
end
Expand Down
16 changes: 15 additions & 1 deletion app/controllers/forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ def update
if @form.valid?
track_choices(@form)
session_data.merge!(@form.attributes_for_export_to_session)
next_step = calculate_next_step(session_data, step)
next_step = if FeatureFlags.enabled?(:ee_banner, session_data)
Steps::Helper.next_step_for(session_data, step)
else
calculate_next_step(session_data, step)
end
calculate_early_result if FeatureFlags.enabled?(:ee_banner, session_data)
if next_step
redirect_to helpers.step_path_from_step(next_step, assessment_code)
else
Expand All @@ -31,4 +36,13 @@ def calculate_next_step(session_data, step)
Steps::Helper.next_step_for(session_data, step)
end
end

def calculate_early_result
if last_tag_in_group?(:gross_income)
cfe_result = CfeService.result(session_data, Steps::Helper.completed_steps_for(session_data, step))
session_data["early_result"] = { "result" => cfe_result.gross_income_result,
"gross_income_excess" => cfe_result.gross_income_excess }
# add analytics tracking here? completed user journeys
end
end
end
16 changes: 16 additions & 0 deletions app/controllers/results_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,28 @@ def create
redirect_to result_path(assessment_code:)
end

def early_result_redirect
@previous_step = params[:step].to_sym
session_data["api_response"] = CfeService.call(session_data, Steps::Helper.completed_steps_for(session_data, @previous_step))
set_early_result_type
redirect_to result_path(assessment_code:)
end

def show
# ee_banner @early_eligibility_selection can be removed when FF is removed
@early_result_type = session_data.dig("early_result", "type")
@early_eligibility_selection = session_data.fetch("early_eligibility_selection", nil)
@model = CalculationResult.new(session_data)
# we'll need to move this tracking point or do something with it
track_completed_journey(@model)
track_page_view(page: :view_results)
@journey_continues_on_another_page = @check.controlled? && @model.decision == "eligible"
@feedback = @journey_continues_on_another_page ? :freetext : :satisfaction
end

def download
# ee_banner @early_eligibility_selection can be removed when FF is removed
@early_result_type = session_data.dig("early_result", "type")
@early_eligibility_selection = session_data.fetch("early_eligibility_selection", nil)
track_page_view(page: :download_results)
@model = CalculationResult.new(session_data)
Expand Down Expand Up @@ -43,6 +55,10 @@ def load_check
@check = Check.new(session_data)
end

def set_early_result_type
session_data["early_result"]["type"] = "gross_income"
end

def track_completed_journey(calculation_result)
if signed_in? && current_provider.present?
JourneyLoggerService.call(assessment_id, calculation_result, @check, current_provider.first_office_code, cookies)
Expand Down
14 changes: 9 additions & 5 deletions app/models/cfe_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ def initialize(api_response)
@api_response = api_response.deep_symbolize_keys
end

def ineligible_gross_income?
api_response.dig(:result_summary, :gross_income, :proceeding_types).first[:result] == "ineligible"
end

def decision
@decision ||= begin
# In some circumstances CFE can return other results, such as 'partially_eligible'.
Expand All @@ -22,9 +18,17 @@ def decision
end
end

def ineligible_gross_income?
gross_income_result == "ineligible"
end

def gross_income_result
api_response.dig(:result_summary, :gross_income, :proceeding_types, 0, :result)
end

def gross_income_excess
total_gross_income = api_response.dig(:result_summary, :gross_income, :total_gross_income)
upper_threshold = api_response.dig(:result_summary, :gross_income, :proceeding_types).first[:upper_threshold]
upper_threshold = api_response.dig(:result_summary, :gross_income, :proceeding_types, 0, :upper_threshold)
total_gross_income - upper_threshold
end

Expand Down
8 changes: 8 additions & 0 deletions app/models/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,12 @@ def owns_property_with_mortgage_or_loan?
def owns_property_outright?
Steps::Logic.owns_property_outright?(session_data)
end

def early_ineligible_result?
session_data.dig("early_result", "result") == "ineligible"
end

def gross_income_excess
session_data.dig("early_result", "gross_income_excess")
end
end
18 changes: 18 additions & 0 deletions app/views/question_flow/_early_result_banner.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
- if FeatureFlags.enabled?(:ee_banner, @check.session_data) && @check.early_ineligible_result?
.govuk-panel.panel-blue.govuk-panel--confirmation class="govuk-!-text-align-left govuk-!-margin-bottom-9"
.govuk-panel__body
h2.govuk-heading-l.white_text
= t("question_flow.early_result.gross_income.title", cfe_result_number: as_money_string(@check.gross_income_excess))

p.govuk-body.white_text class="govuk-!-font-weight-bold"
- if @check.controlled?
= t("question_flow.early_result.gross_income.controlled.para_1")
- else
= t("question_flow.early_result.gross_income.certificated.para_1")

= link_to t("question_flow.early_result.gross_income.go_to_results"),
early_result_redirect_path(assessment_code: params[:assessment_code], step: @previous_step),
method: :post,
class: "govuk-button govuk-button--secondary govuk-!-margin-top-2",
role: "button",
id: "early-result-button"
1 change: 1 addition & 0 deletions app/views/question_flow/forms/_outgoings.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

= form_for(@form, url: request.path, method: :put) do |form|
= form.govuk_error_summary t("generic.error_summary_title")
= render partial: "question_flow/early_result_banner"
= render "shared/heading",
header_text: t("question_flow.#{i18n_key}.heading"),
post_header_text: t("question_flow.#{i18n_key}.caption"),
Expand Down
2 changes: 1 addition & 1 deletion app/views/question_flow/how_to_aggregate.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

.govuk-grid-column-full
= render "shared/heading"
.govuk-panel.panel-blue.govuk-panel--confirmation class="govuk-!-text-align-left govuk-!-margin-bottom-9"
.govuk-panel.panel-blue-white-text.govuk-panel--confirmation class="govuk-!-text-align-left govuk-!-margin-bottom-9"
.govuk-panel__body
h1.govuk-heading-l = t(".title")
p.govuk-body = t(".panel_text")
Expand Down
3 changes: 2 additions & 1 deletion app/views/results/_capital_table.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- if @early_eligibility_selection == "gross"
/ ee_banner @early_eligibility_selection can be removed when FF is removed
- if @early_eligibility_selection == "gross" || @early_result_type == "gross_income"
p class="govuk-body" = t(".not_assessed")
- else
- if @is_pdf == true
Expand Down
45 changes: 45 additions & 0 deletions app/views/results/_early_summary.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
- data = @model.summary_data(section)
- status = data.status.dasherize

- if @early_result_type == section.to_s
- total_calc = @model.send("total_calculated_#{section}")

. class="summary-box summary-box-#{@early_result_type == section.to_s ? status : "not-assessed"}"
p.govuk-body-l.summary-list-subheader class="govuk-!-margin-bottom-0" = t("results.show.section_summaries.heading.#{section}")
h3.govuk-heading-l class="govuk-!-margin-bottom-2 govuk-!-margin-top-0" = total_calc

- if @early_result_type != section.to_s
.govuk-tag
= t("results.show.section_summaries.not_assessed")
- elsif data.status == "ineligible"
.govuk-tag.govuk-tag--custom-red
= t("results.show.section_summaries.exceeds_upper_limit")
- elsif data.status == "contribution_required_and_overall_contribution_required"
.govuk-tag
= t("results.show.section_summaries.contribution_needed")

p.govuk-body class="govuk-!-margin-top-3"
- upper_snippet = "_no_upper_threshold" if data.no_upper_threshold
- lower_snippet = "_no_lower_threshold" if data.no_lower_threshold
ruby:
matter_type = if @model.domestic_abuse_applicant
t("results.show.section_summaries.matter_types.domestic_abuse_applicant")
elsif @model.immigration_or_asylum_type_upper_tribunal
t("results.show.section_summaries.matter_types.#{@model.immigration_or_asylum_type_upper_tribunal}")
else
t("results.show.section_summaries.matter_types.none")
end
- if @early_result_type != section.to_s
=> t("results.show.section_summaries.texts.not_assessed_desc")
- else
=> t("results.show.section_summaries.texts.#{section}.#{data.status}#{upper_snippet}#{lower_snippet}",
upper_threshold: data.upper_threshold,
lower_threshold: data.lower_threshold,
matter_type:,
capital_contribution: @model.capital_contribution,
income_contribution: @model.income_contribution)
- if links
= link_to t("results.show.section_summaries.see_calculation"),
"##{data[:section]}",
class: "summary-box-link",
"aria-label": t("results.show.section_summaries.see_calculation_aria_label.#{data[:section]}")
3 changes: 2 additions & 1 deletion app/views/results/_outgoings_table.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- if @early_eligibility_selection == "gross"
/ ee_banner @early_eligibility_selection can be removed when FF is removed
- if @early_eligibility_selection == "gross" || @early_result_type == "gross_income"
p class="govuk-body" = t(".not_assessed")
- else
= pdf_friendly_h2(t("results.show.client_outgoings"), "m", @is_pdf)
Expand Down
1 change: 1 addition & 0 deletions app/views/results/_summary.html.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
- data = @model.summary_data(section)
- status = data.status.dasherize
/ ee_banner: conditionals and reference to early_result can be removed when FF is removed
- early_result = data.ineligible_gross_income == "gross" && section != :gross_income

- unless early_result
Expand Down
16 changes: 11 additions & 5 deletions app/views/results/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@

.govuk-grid-column-full
= render "shared/heading"
.govuk-panel.panel-blue.govuk-panel--confirmation class="govuk-!-text-align-left govuk-!-margin-bottom-9"
.govuk-panel.panel-blue-white-text.govuk-panel--confirmation class="govuk-!-text-align-left govuk-!-margin-bottom-9"
.govuk-panel__body
= render "result_panel_content"

- if @model.any_calculations_performed?
h2.govuk-heading-m = t(".section_summaries.your_clients_key_eligibility_totals")
.summary-box-holder class="govuk-!-margin-bottom-5"
- %i[gross_income disposable_income capital].each
= render("summary", section: _1, links: true) if @model.calculated?(_1)
- if FeatureFlags.enabled?(:ee_banner, @check.session_data) && @early_result_type
h2.govuk-heading-m = t(".section_summaries.your_clients_key_eligibility_totals")
.summary-box-holder class="govuk-!-margin-bottom-5"
- %i[gross_income disposable_income capital].each
= render("early_summary", section: _1, links: true) if @model.calculated?(_1)
- else
h2.govuk-heading-m = t(".section_summaries.your_clients_key_eligibility_totals")
.summary-box-holder class="govuk-!-margin-bottom-5"
- %i[gross_income disposable_income capital].each
= render("summary", section: _1, links: true) if @model.calculated?(_1)

- if @journey_continues_on_another_page
h2.govuk-heading-m = t(".save_results")
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,7 @@ en:
para_1: We have enough information to tell you that your client will not qualify for legal aid.
certificated:
para_1: We have enough information to tell you that your client is not likely to qualify for legal aid.
go_to_results: Go to results page
para_2: "You can:"
help: Help with next steps
details_para_1: "You can:"
Expand Down
Loading

0 comments on commit 4484414

Please sign in to comment.