Skip to content
Merged
2 changes: 1 addition & 1 deletion app/controllers/forms/page_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def save
current_context.clear_submission_details if is_first_page?

validation_context = @step.autocomplete_selection_question? ? :skip_none_of_the_above_question_validation : nil
if current_context.save_step(@step, context: validation_context)
if current_context.save_step(@step, context: validation_context, locale:)
# Redirect before logging when the question has multiple pages so that we don't send multiple form started
# metrics to CloudWatch if this is the first question.
return redirect_to selection_none_of_the_above_page if redirect_to_none_of_the_above_page?
Expand Down
7 changes: 6 additions & 1 deletion app/lib/csv_generator.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "csv"

class CsvGenerator
def self.generate_submission(all_steps:, submission_reference:, timestamp:, is_s3_submission:)
def self.generate_submission(all_steps:, submission_reference:, timestamp:, is_s3_submission:, language:)
headers = [I18n.t("submission_csv.reference"), I18n.t("submission_csv.submitted_at")]
values = [submission_reference, timestamp.iso8601]
all_steps.map do |step|
Expand All @@ -10,6 +10,11 @@ def self.generate_submission(all_steps:, submission_reference:, timestamp:, is_s
values.push(*answer_parts.values)
end

if language.present?
headers.push(I18n.t("submission_csv.language"))
values.push(language)
end

CSV.generate do |csv|
csv << headers
csv << values
Expand Down
7 changes: 4 additions & 3 deletions app/lib/flow/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ def initialize(form:, store:)

delegate :support_details, to: :form
delegate :find_or_create, :previous_step, :next_page_slug, :next_step, :can_visit?, :completed_steps, :all_steps, to: :journey
delegate :clear_stored_answer, :clear, :form_submitted?, :answers, to: :answer_store
delegate :clear_stored_answer, :clear, :form_submitted?, :answers, :locales_used, to: :answer_store
delegate :save_submission_details, :get_submission_reference, :requested_email_confirmation?, :clear_submission_details, to: :confirmation_details_store

def save_step(step, context: nil)
def save_step(step, locale: :en, context: nil)
return false unless step.valid?(context)

step.save_to_store(@answer_store)
answer_store.add_locale(locale)
step.save_to_store(answer_store)
end

private
Expand Down
7 changes: 6 additions & 1 deletion app/lib/json_submission_generator.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
class JsonSubmissionGenerator
def self.generate_submission(form:, all_steps:, submission_reference:, timestamp:, is_s3_submission:)
def self.generate_submission(form:, all_steps:, submission_reference:, timestamp:, is_s3_submission:, language:)
submission = {
"$schema" => "#{Settings.forms_product_page.base_url}/json-submissions/v1/schema",
form_name: form.name,
submission_reference:,
submitted_at: timestamp.getutc.iso8601(3),
answers: all_steps.flat_map { |step| step.show_answer_in_json(is_s3_submission) },
}

if language.present?
submission[:language] = language
end

JSON.pretty_generate(submission)
end
end
13 changes: 13 additions & 0 deletions app/lib/store/session_answer_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ class SessionAnswerStore
include Store::Access

ANSWERS_KEY = :answers
LOCALES_KEY = :locales

def initialize(store, form_id)
@store = store
@form_key = form_id.to_s
@store[ANSWERS_KEY] ||= {}
@store[LOCALES_KEY] ||= {}
end

def save_step(step, answer)
Expand All @@ -25,6 +27,7 @@ def clear_stored_answer(step)

def clear
@store[ANSWERS_KEY][@form_key] = nil
@store[LOCALES_KEY][@form_key] = nil
end

def form_submitted?
Expand All @@ -34,5 +37,15 @@ def form_submitted?
def answers
@store[ANSWERS_KEY][@form_key]
end

def add_locale(locale)
@store[LOCALES_KEY][@form_key] ||= []
@store[LOCALES_KEY][@form_key] |= [locale.to_s]
end

def locales_used
locales = @store.dig(LOCALES_KEY, @form_key) || []
locales.map(&:to_sym) || []
end
end
end
1 change: 1 addition & 0 deletions app/mailers/aws_ses_form_submission_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def submission_email(answer_content_html:, answer_content_plain_text:, submissio
@subject = email_subject
@csv_filename = csv_filename
@json_filename = json_filename
@welsh_submission = submission.submission_locale.to_sym == :cy

files.each do |name, file|
attachments[name] = {
Expand Down
8 changes: 8 additions & 0 deletions app/services/aws_ses_submission_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def generate_csv_submission
submission_reference: @submission.reference,
timestamp: @submission.submission_time,
is_s3_submission: false,
language:,
)
end

Expand All @@ -62,6 +63,7 @@ def generate_json_submission
submission_reference: @submission.reference,
timestamp: @submission.submission_time,
is_s3_submission: false,
language:,
)
end

Expand Down Expand Up @@ -101,4 +103,10 @@ def generate_csv_filename
def generate_json_filename
SubmissionFilenameGenerator.json_filename(form_name: @form.name, submission_reference: @submission.reference)
end

def language
return nil unless @form.multilingual?

@submission.submission_locale
end
end
8 changes: 8 additions & 0 deletions app/services/form_submission_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ def submit
submission_reference
end

def submission_locale
return :cy if current_context.locales_used.present? && current_context.locales_used.include?(:cy)

:en
end

private

attr_accessor :current_context, :form, :email_confirmation_input, :mode, :timestamp, :submission_reference, :localised_form
Expand Down Expand Up @@ -77,6 +83,7 @@ def deliver_submission_via_s3
timestamp: timestamp,
submission_reference: submission_reference,
is_preview: mode.preview?,
submission_locale:,
)

s3_submission_service.submit
Expand All @@ -89,6 +96,7 @@ def deliver_submission_via_email
answers: current_context.answers,
mode: mode,
form_document: form.document_json,
submission_locale:,
)

SendSubmissionJob.perform_later(submission) do |job|
Expand Down
12 changes: 11 additions & 1 deletion app/services/s3_submission_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ def initialize(journey:,
form:,
timestamp:,
submission_reference:,
is_preview:)
is_preview:,
submission_locale:)
@journey = journey
@form = form
@timestamp = timestamp
@submission_reference = submission_reference
@is_preview = is_preview
@file_upload_bucket_name = Settings.aws.file_upload_s3_bucket_name
@submission_locale = submission_locale
end

def submit
Expand Down Expand Up @@ -44,6 +46,7 @@ def generate_csv_submission
submission_reference: @submission_reference,
timestamp: @timestamp,
is_s3_submission: true,
language:,
)
end

Expand All @@ -54,6 +57,7 @@ def generate_json_submission
submission_reference: @submission_reference,
timestamp: @timestamp,
is_s3_submission: true,
language:,
)
end

Expand Down Expand Up @@ -121,4 +125,10 @@ def generate_key(filename)
formatted_timestamp = @timestamp.utc.strftime("%Y%m%dT%H%M%SZ")
"#{folder}/#{@form.id}/#{formatted_timestamp}_#{@submission_reference}/#{filename}"
end

def language
return nil unless @form.multilingual?

@submission_locale
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
<p>
<%= I18n.t("mailer.submission.time", time: @submission.submission_time.strftime("%l:%M%P").strip, date: @submission.submission_time.strftime("%-d %B %Y") ) %>
</p>
<p>
<% if @welsh_submission %>
<%= I18n.t("mailer.submission.welsh_submission") %>
<% end %>
</p>
<p>
<%= I18n.t("mailer.submission.reference", submission_reference: @submission.reference) %>
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

<%= I18n.t("mailer.submission.time", time: @submission.submission_time.strftime("%l:%M%P").strip, date: @submission.submission_time.strftime("%-d %B %Y") ) %>

<% if @welsh_submission %>
<%= I18n.t("mailer.submission.welsh_submission") %>
<% end %>

<%= I18n.t("mailer.submission.reference", submission_reference: @submission.reference) %>

<% if @submission.payment_url.present? %>
Expand Down
2 changes: 2 additions & 0 deletions config/locales/cy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ cy:
subject_preview: 'TEST FORM SUBMISSION: %{form_name} - reference: %{reference}'
time: 'Submitted at: %{time} on %{date}'
title: 'Form name: “%{form_name}”'
welsh_submission: At least one of the questions was answered in Welsh
submission_confirmation:
default_support_contact_details: The form’s contact details for support will appear here once they’ve been added.
default_what_happens_next: The form’s information about what happens next will appear here once it has been added.
Expand Down Expand Up @@ -601,6 +602,7 @@ cy:
question/selection:
divider: neu
submission_csv:
language: Language
reference: Reference
repeatable_answer_header: "%{header} - Answer %{index}"
submitted_at: Submitted at
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ en:
subject_preview: 'TEST FORM SUBMISSION: %{form_name} - reference: %{reference}'
time: 'Submitted at: %{time} on %{date}'
title: 'Form name: “%{form_name}”'
welsh_submission: At least one of the questions was answered in Welsh
submission_confirmation:
default_support_contact_details: The form’s contact details for support will appear here once they’ve been added.
default_what_happens_next: The form’s information about what happens next will appear here once it has been added.
Expand Down Expand Up @@ -601,6 +602,7 @@ en:
question/selection:
divider: or
submission_csv:
language: Language
reference: Reference
repeatable_answer_header: "%{header} - Answer %{index}"
submitted_at: Submitted at
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSubmissionLocaleToSubmission < ActiveRecord::Migration[8.1]
def change
add_column :submissions, :submission_locale, :string, null: false, default: "en", comment: "The language the form was submitted in ISO 2 letter format. Normally either 'en' or 'cy'"
end
end
3 changes: 2 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions spec/factories/submissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
mode { is_preview ? "preview-live" : "live" }
form_document { build :v2_form_document }
delivery_status { :pending }
submission_locale { :en }

transient do
is_preview { false }
Expand Down
16 changes: 9 additions & 7 deletions spec/lib/csv_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
end

describe "#generate_submission" do
subject(:csv) { described_class.generate_submission(all_steps:, submission_reference:, timestamp:, is_s3_submission:) }
subject(:csv) { described_class.generate_submission(all_steps:, submission_reference:, timestamp:, is_s3_submission:, language: :en) }

context "when the submission is being sent by email" do
let(:is_s3_submission) { false }
Expand All @@ -32,8 +32,8 @@
it "generates the submission CSV" do
expect(CSV.parse(csv)).to eq(
[
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"],
[submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt"],
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"],
[submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt", "en"],
],
)
end
Expand All @@ -44,8 +44,8 @@
it "generates a CSV including blank column for unanswered optional question" do
expect(CSV.parse(csv)).to eq(
[
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"],
[submission_reference, "2022-09-14T08:00:00+01:00", "", name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt"],
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"],
[submission_reference, "2022-09-14T08:00:00+01:00", "", name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt", "en"],
],
)
end
Expand All @@ -67,6 +67,7 @@
"What is your name? - First name - Answer 2",
"What is your name? - Last name - Answer 2",
"Upload a file",
"Language",
],
[
submission_reference,
Expand All @@ -77,6 +78,7 @@
name_question_repeated.first_name,
name_question_repeated.last_name,
"test_#{submission_reference}.txt",
"en",
],
],
)
Expand All @@ -90,8 +92,8 @@
it "generates a CSV without including the submission reference in the filename for the file upload question" do
expect(CSV.parse(csv)).to eq(
[
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"],
[submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, file_question.original_filename],
["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"],
[submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, file_question.original_filename, "en"],
],
)
end
Expand Down
Loading