Skip to content
40 changes: 38 additions & 2 deletions app/controllers/forms/welsh_translation_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,38 @@ def download
form_content_service = WelshCsvService.new(form_with_pages_and_conditions)

send_data form_content_service.as_csv,
type: "text/csv; charset=iso-8859-1",
disposition: "attachment; filename=#{form_content_service.filename}"
type: "text/csv; charset=utf-8",
filename: form_content_service.filename,
disposition: "attachment"
end

def show_upload
authorize current_form, :can_edit_form?
welsh_translation_upload_input = WelshTranslationUploadInput.new(form: current_form)
render :show_upload, locals: { current_form:, welsh_translation_upload_input: }
end

def upload
authorize current_form, :can_edit_form?

welsh_translation_upload_input = WelshTranslationUploadInput.new(**welsh_translation_upload_params)

data = welsh_translation_upload_input.read_file
unless data
return render :show_upload, status: :unprocessable_entity, locals: { current_form:, welsh_translation_upload_input: }
end

@welsh_translation_input = if FeatureService.new(group: current_form.group).enabled?(:multiple_branches)
WelshTranslationInput2.new(form: form_with_pages_and_exit_pages)
else
WelshTranslationInput.new(form: form_with_pages_and_conditions)
end

@welsh_translation_input.assign_from_spreadsheet(data).validate(:upload)
@table_presenter = Forms::TranslationTablePresenter.new

flash.now[:success] = t("banner.success.form.welsh_translation_uploaded")
render :new
end

private
Expand Down Expand Up @@ -122,5 +152,11 @@ def form_with_pages_and_conditions
def form_with_pages_and_exit_pages
Form.includes(pages: [:exit_pages]).find(current_form.id)
end

def welsh_translation_upload_params
params.fetch(:forms_welsh_translation_upload_input, ActionController::Parameters.new)
.permit(:file)
.merge(form: current_form)
end
end
end
12 changes: 12 additions & 0 deletions app/input_objects/forms/welsh_condition_translation_input.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Forms::WelshConditionTranslationInput < BaseInput
include ActionView::Helpers::FormTagHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :condition

Expand Down Expand Up @@ -39,6 +40,17 @@ def assign_condition_values
self
end

def assign_from_spreadsheet(data)
assign_condition_values

%i[exit_page_heading exit_page_markdown].each do |attr|
content_label = condition_label(condition.routing_page, attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

self
end

def form_field_id(attribute)
field_id(:forms_welsh_condition_translation_input, condition.id, :condition_translations, attribute)
end
Expand Down
12 changes: 12 additions & 0 deletions app/input_objects/forms/welsh_exit_page_translation_input.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Forms::WelshExitPageTranslationInput < BaseInput
include ActionView::Helpers::FormTagHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :exit_page, :position

Expand Down Expand Up @@ -41,6 +42,17 @@ def assign_exit_page_values
self
end

def assign_from_spreadsheet(data)
assign_exit_page_values

%i[heading markdown].each do |attr|
content_label = exit_page_label(exit_page.question_page, position, attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

self
end

def form_field_id(attribute)
field_id(:forms_welsh_exit_page_translation_input, exit_page.id, :exit_page_translations, attribute)
end
Expand Down
22 changes: 22 additions & 0 deletions app/input_objects/forms/welsh_page_translation_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Forms::WelshPageTranslationInput < BaseInput
include TextInputHelper
include ActionView::Helpers::FormTagHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :condition_translations, :selection_options_cy
attr_reader :page
Expand Down Expand Up @@ -82,6 +83,27 @@ def assign_page_values
self
end

def assign_from_spreadsheet(data)
# assign values from the form first, and override only those that are set in the spreadsheet
assign_page_values

%i[question_text hint_text page_heading guidance_markdown none_of_the_above_question].each do |attr|
content_label = page_label(page, attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

selection_options_cy&.each_with_index do |option, index|
content_label = selection_option_label(page, index)
option.name_cy = data[content_label] if data.key?(content_label) && data[content_label].present?
end

condition_translations.each do |condition_translation|
condition_translation.assign_from_spreadsheet(data)
end

self
end

def condition_translations_attributes=(attributes)
submitted_condition_ids = attributes.values.map { |attrs| attrs["id"] }.compact

Expand Down
22 changes: 22 additions & 0 deletions app/input_objects/forms/welsh_page_translation_input2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Forms::WelshPageTranslationInput2 < BaseInput
include TextInputHelper
include ActionView::Helpers::FormTagHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :exit_page_translations, :selection_options_cy
attr_reader :page
Expand Down Expand Up @@ -84,6 +85,27 @@ def assign_page_values
self
end

def assign_from_spreadsheet(data)
# assign values from the form first, and override only those that are set in the spreadsheet
assign_page_values

%i[question_text hint_text page_heading guidance_markdown none_of_the_above_question].each do |attr|
content_label = page_label(page, attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

selection_options_cy&.each_with_index do |option, index|
content_label = selection_option_label(page, index)
option.name_cy = data[content_label] if data.key?(content_label) && data[content_label].present?
end

exit_page_translations&.each do |exit_page_translation|
exit_page_translation.assign_from_spreadsheet(data)
end

self
end

def exit_page_translations_attributes=(attributes)
submitted_exit_page_ids = attributes.values.map { |attrs| attrs["id"] }.compact

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def assign_selection_option_values
self
end

def assign_selection_option_values_from_csv_values(csv_values)
return self unless selection_option

spreadsheet_id = page_content_id(page.id, "option_#{index}")
self.name_cy = csv_values[spreadsheet_id] if csv_values.key?(spreadsheet_id)
self
end

def as_selection_option
{ name: name_cy, value: selection_option.value }
end
Expand Down
35 changes: 34 additions & 1 deletion app/input_objects/forms/welsh_translation_input.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Forms::WelshTranslationInput < Forms::MarkCompleteInput
class Forms::WelshTranslationInput < BaseInput
include TextInputHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :form, :page_translations

Expand All @@ -16,6 +17,10 @@ class Forms::WelshTranslationInput < Forms::MarkCompleteInput
attribute :what_happens_next_markdown_cy
attribute :payment_url_cy

with_options except_on: :upload do
validates :mark_complete, presence: true
end

validates :name_cy, presence: true, if: -> { marked_complete? }
validates :name_cy, length: { maximum: 500 }, if: -> { name_cy.present? }

Expand Down Expand Up @@ -122,6 +127,34 @@ def assign_form_values
self
end

def assign_from_spreadsheet(data)
# assign values from the form first, and override only those that are set in the spreadsheet
assign_form_values

%i[name
privacy_policy_url
support_email
support_phone
support_url
support_url_text
declaration_markdown
what_happens_next_markdown
payment_url].each do |attr|
content_label = FORM_ATTRIBUTE_LABELS.fetch(attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

self.page_translations = form.pages.map do |page|
Forms::WelshPageTranslationInput.new(page:).assign_from_spreadsheet(data)
end

self
end

def marked_complete?
["true", true].include?(mark_complete)
end

def blanked?
all_fields_empty? && page_translations.all?(&:blanked?)
end
Expand Down
35 changes: 34 additions & 1 deletion app/input_objects/forms/welsh_translation_input2.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Forms::WelshTranslationInput2 < Forms::MarkCompleteInput
class Forms::WelshTranslationInput2 < BaseInput
include TextInputHelper
include ActiveModel::Attributes
include WelshTranslationContentLabels

attr_accessor :form, :page_translations

Expand All @@ -16,6 +17,10 @@ class Forms::WelshTranslationInput2 < Forms::MarkCompleteInput
attribute :what_happens_next_markdown_cy
attribute :payment_url_cy

with_options except_on: :upload do
validates :mark_complete, presence: true
end

validates :name_cy, presence: true, if: -> { marked_complete? }
validates :name_cy, length: { maximum: 500 }, if: -> { name_cy.present? }

Expand Down Expand Up @@ -122,6 +127,34 @@ def assign_form_values
self
end

def assign_from_spreadsheet(data)
# assign values from the form first, and override only those that are set in the spreadsheet
assign_form_values

%i[name
privacy_policy_url
support_email
support_phone
support_url
support_url_text
declaration_markdown
what_happens_next_markdown
payment_url].each do |attr|
content_label = FORM_ATTRIBUTE_LABELS.fetch(attr)
send(:"#{attr}_cy=", data[content_label]) if data.key?(content_label) && data[content_label].present?
end

self.page_translations = form.pages.map do |page|
Forms::WelshPageTranslationInput2.new(page:).assign_from_spreadsheet(data)
end

self
end

def marked_complete?
["true", true].include?(mark_complete)
end

def blanked?
all_fields_empty? && page_translations.all?(&:blanked?)
end
Expand Down
31 changes: 31 additions & 0 deletions app/input_objects/forms/welsh_translation_upload_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class Forms::WelshTranslationUploadInput < BaseInput
FILE_TYPES = %w[
text/csv
].freeze
MAX_SIZE_IN_MB = 10

attr_accessor :form, :file

validates :file, presence: true, file_content_type: { in: FILE_TYPES }
validate :validate_file_size

def read_file
return false if invalid?

WelshCsvImportService.new(file, form).read
rescue CSV::MalformedCSVError
errors.add(:file, :malformed)
false
rescue WelshCsvImportService::InvalidHeadersError
errors.add(:file, :invalid_headers)
false
end

private

def validate_file_size
if file.present? && file.size > MAX_SIZE_IN_MB.megabytes
errors.add(:file, :too_big)
end
end
end
51 changes: 51 additions & 0 deletions app/lib/welsh_translation_content_labels.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module WelshTranslationContentLabels
FORM_ATTRIBUTE_LABELS = {
name: "Form name",
declaration_markdown: "Declaration",
what_happens_next_markdown: "Information about what happens next",
payment_url: "GOV.UK Pay payment link",
privacy_policy_url: "Link to privacy information for this form",
support_email: "Contact details for support - email address",
support_phone: "Contact details for support - phone number and opening times",
support_url: "Contact details for support - online contact link",
support_url_text: "Contact details for support - online contact link text",
}.freeze

PAGE_ATTRIBUTE_LABELS = {
question_text: "question text",
hint_text: "hint text",
page_heading: "page heading",
guidance_markdown: "guidance text",
none_of_the_above_question: "question or label if 'None of the above' is selected",
}.freeze

CONDITION_ATTRIBUTE_LABELS = {
exit_page_heading: "exit page heading",
exit_page_markdown: "exit page content",
}.freeze

EXIT_PAGE_ATTRIBUTE_LABELS = {
heading: "heading",
markdown: "content",
}.freeze

def page_label(page, attribute)
"#{question_name(page)} - #{PAGE_ATTRIBUTE_LABELS.fetch(attribute)}"
end

def selection_option_label(page, option_index)
"#{question_name(page)} - option #{option_index + 1}"
end

def condition_label(page, attribute)
"#{question_name(page)} - #{CONDITION_ATTRIBUTE_LABELS.fetch(attribute)}"
end

def exit_page_label(page, exit_page_position, attribute)
"#{question_name(page)} - exit page #{exit_page_position} #{EXIT_PAGE_ATTRIBUTE_LABELS.fetch(attribute)}"
end

def question_name(page)
"Question #{page.position}"
end
end
Loading
Loading