diff --git a/app/models/form_document/exit_page.rb b/app/models/form_document/exit_page.rb new file mode 100644 index 0000000000..7628bcde74 --- /dev/null +++ b/app/models/form_document/exit_page.rb @@ -0,0 +1,16 @@ +class FormDocument::ExitPage + include ActiveModel::API + include ActiveModel::Attributes + + attribute :id, :integer + attribute :created_at, :datetime + attribute :updated_at, :datetime + attribute :question_page_id, :string + attribute :heading, :string + attribute :markdown, :string + + def initialize(attributes = {}) + attributes.slice!(*self.class.attribute_names) + super + end +end diff --git a/app/models/form_document/step.rb b/app/models/form_document/step.rb index 5bdc6fe53c..cceca4351a 100644 --- a/app/models/form_document/step.rb +++ b/app/models/form_document/step.rb @@ -2,7 +2,7 @@ class FormDocument::Step include ActiveModel::API include ActiveModel::Attributes - attr_reader :routing_conditions + attr_reader :routing_conditions, :exit_pages attribute :id, :string attribute :data, DataStructType.new @@ -14,6 +14,7 @@ class FormDocument::Step def initialize(attributes = {}) @routing_conditions = attributes.fetch("routing_conditions", []).map { |condition| FormDocument::Condition.new(**condition) } + @exit_pages = attributes.fetch("exit_pages", []).map { |exit_page| FormDocument::ExitPage.new(**exit_page) } attributes.slice!(*self.class.attribute_names) super end diff --git a/app/services/step_summary_card_service.rb b/app/services/step_summary_card_service.rb index 4cc9a1ed51..5d4daf0732 100644 --- a/app/services/step_summary_card_service.rb +++ b/app/services/step_summary_card_service.rb @@ -225,9 +225,13 @@ def print_unconditional_route(condition) def print_routes(conditions) answer_value_groups = answer_value_groups(conditions) - answer_value_groups.map { |goto_page_id, condition_group| - if goto_page_id.nil? + answer_value_groups.map { |group| + condition_group = group[:conditions] + + if group[:group_type] == :skip_to_end caption = content_tag(:p, I18n.t("page_conditions.go_to_the_end"), class: "govuk-body-s") + elsif group[:group_type] == :exit_page + caption = content_tag(:p, I18n.t("page_conditions.go_to_exit_page", exit_page_index: group[:exit_page_index], exit_page_heading: group[:exit_page].heading), class: "govuk-body-s") else goto_question = @steps.find { |page| page.id == condition_group.first.goto_page_id } goto_page_question_text = ActionController::Base.helpers.sanitize(goto_question.question_text) @@ -288,12 +292,50 @@ def html_list_item(item) end def answer_value_groups(conditions) - answer_order = @step.answer_settings.selection_options.map(&:value) || [] + answer_order = @step.answer_settings&.selection_options&.map(&:value) || [] + + ordered_conditions = conditions.to_a + .in_order_of(:answer_value, answer_order, filter: false) + + groups = [] + + goto_page_groups = ordered_conditions.select { |condition| condition.goto_page_id.present? }.group_by(&:goto_page_id) + goto_page_groups.each_value do |grouped_conditions| + groups << { + group_type: :goto_page, + conditions: grouped_conditions, + } + end + + skip_to_end_conditions = ordered_conditions.select(&:skip_to_end) + + if skip_to_end_conditions.any? + groups << { + group_type: :skip_to_end, + conditions: skip_to_end_conditions, + } + end + + exit_page_groups = ordered_conditions.select { |condition| condition.exit_page_id.present? } + .group_by(&:exit_page_id) + .values + .sort_by { |grouped_conditions| grouped_conditions.first.exit_page_id } + + exit_page_groups.each do |grouped_conditions| + exit_page = @step.exit_pages.detect { it.id == grouped_conditions.first.exit_page_id } + + groups << { + group_type: :exit_page, + exit_page_index: exit_page_position_calc(exit_page), + conditions: grouped_conditions, + exit_page:, + } + end + + groups + end - conditions.group_by(&:goto_page_id).map { |goto_page_id, condition_group| - goto_page_position = @steps.find_index { |page| page.id == goto_page_id } + 1 unless goto_page_id.nil? - sorted_condition_group = condition_group.in_order_of(:answer_value, answer_order, filter: false) - [goto_page_position, sorted_condition_group] - }.sort_by { |goto_page_position, _| goto_page_position || Float::INFINITY } + def exit_page_position_calc(exit_page) + @step.exit_pages.find_index(exit_page) + 1 end end diff --git a/config/locales/en.yml b/config/locales/en.yml index f7fb145373..6a1983b235 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1686,6 +1686,7 @@ en: exit_page_label: An ‘exit page’ to leave the form go_to_page: 'Go to %{goto_page_question_number}, ‘%{goto_page_question_text}’ if the answer is:' go_to_the_end: 'Go to the end of the form if the answer is:' + go_to_exit_page: 'Go to exit page %{exit_page_index}, ‘%{exit_page_heading}’ if the answer is:' none_of_the_above: None of the above route: Route route2: