diff --git a/app/controllers/collection_resources_controller.rb b/app/controllers/collection_resources_controller.rb
index ed080c749..06988c88c 100644
--- a/app/controllers/collection_resources_controller.rb
+++ b/app/controllers/collection_resources_controller.rb
@@ -1,13 +1,15 @@
class CollectionResourcesController < ApplicationController
include CollectionResourcesHelper
- before_action :authenticate_user!, except: %i[download_mandatory_collection_resource]
+ before_action :authenticate_user!, except: %i[download_mandatory_collection_resource download_additional_collection_resource]
def index
render_not_found unless current_user.support?
@mandatory_lettings_collection_resources_per_year = MandatoryCollectionResourcesService.generate_resources("lettings", editable_collection_resource_years)
@mandatory_sales_collection_resources_per_year = MandatoryCollectionResourcesService.generate_resources("sales", editable_collection_resource_years)
+ @additional_lettings_collection_resources_per_year = CollectionResource.visible.where(log_type: "lettings", mandatory: false).group_by(&:year)
+ @additional_sales_collection_resources_per_year = CollectionResource.visible.where(log_type: "sales", mandatory: false).group_by(&:year)
end
def download_mandatory_collection_resource
@@ -23,8 +25,17 @@ class CollectionResourcesController < ApplicationController
download_resource(resource.download_filename)
end
- def edit
- return render_not_found unless current_user.support?
+ def download_additional_collection_resource
+ resource = CollectionResource.find_by(id: params[:collection_resource_id])
+
+ return render_not_found unless resource
+ return render_not_found unless resource_for_year_can_be_downloaded?(resource.year)
+
+ download_resource(resource.download_filename)
+ end
+
+ def edit_mandatory_collection_resource
+ return render_not_authorized unless current_user.support?
year = params[:year].to_i
resource_type = params[:resource_type]
@@ -39,8 +50,19 @@ class CollectionResourcesController < ApplicationController
render "collection_resources/edit"
end
- def update
- return render_not_found unless current_user.support?
+ def edit_additional_collection_resource
+ return render_not_authorized unless current_user.support?
+
+ @collection_resource = CollectionResource.find_by(id: params[:collection_resource_id])
+
+ return render_not_found unless @collection_resource
+ return render_not_found unless resource_for_year_can_be_updated?(@collection_resource.year)
+
+ render "collection_resources/edit"
+ end
+
+ def update_mandatory_collection_resource
+ return render_not_authorized unless current_user.support?
year = resource_params[:year].to_i
resource_type = resource_params[:resource_type]
@@ -52,7 +74,8 @@ class CollectionResourcesController < ApplicationController
@collection_resource = MandatoryCollectionResourcesService.generate_resource(log_type, year, resource_type)
render_not_found unless @collection_resource
- validate_file(file)
+ @collection_resource.file = file
+ @collection_resource.validate_attached_file
return render "collection_resources/edit" if @collection_resource.errors.any?
@@ -68,8 +91,38 @@ class CollectionResourcesController < ApplicationController
redirect_to collection_resources_path
end
+ def update_additional_collection_resource
+ return render_not_authorized unless current_user.support?
+
+ @collection_resource = CollectionResource.find_by(id: params[:collection_resource_id])
+
+ return render_not_found unless @collection_resource
+ return render_not_found unless resource_for_year_can_be_updated?(@collection_resource.year)
+
+ @collection_resource.file = resource_params[:file]
+ @collection_resource.validate_attached_file
+ @collection_resource.validate_short_display_name
+ return render "collection_resources/edit" if @collection_resource.errors.any?
+
+ @collection_resource.short_display_name = resource_params[:short_display_name]
+ @collection_resource.download_filename = @collection_resource.file&.original_filename
+ @collection_resource.display_name = "#{@collection_resource.log_type} #{@collection_resource.short_display_name} (#{text_year_range_format(@collection_resource.year)})"
+ if @collection_resource.save
+ begin
+ CollectionResourcesService.new.upload_collection_resource(@collection_resource.download_filename, @collection_resource.file)
+ flash[:notice] = "The #{@collection_resource.log_type} #{text_year_range_format(@collection_resource.year)} #{@collection_resource.short_display_name.downcase} has been updated."
+ redirect_to collection_resources_path
+ rescue StandardError
+ @collection_resource.errors.add(:file, :error_uploading)
+ render "collection_resources/edit"
+ end
+ else
+ render "collection_resources/edit"
+ end
+ end
+
def confirm_mandatory_collection_resources_release
- return render_not_found unless current_user.support?
+ return render_not_authorized unless current_user.support?
@year = params[:year].to_i
@@ -79,7 +132,7 @@ class CollectionResourcesController < ApplicationController
end
def release_mandatory_collection_resources
- return render_not_found unless current_user.support?
+ return render_not_authorized unless current_user.support?
year = params[:year].to_i
@@ -91,10 +144,73 @@ class CollectionResourcesController < ApplicationController
redirect_to collection_resources_path
end
+ def new
+ return render_not_authorized unless current_user.support?
+
+ year = params[:year].to_i
+ log_type = params[:log_type]
+
+ return render_not_found unless editable_collection_resource_years.include?(year)
+
+ @collection_resource = CollectionResource.new(year:, log_type:)
+ end
+
+ def create
+ return render_not_authorized unless current_user.support? && editable_collection_resource_years.include?(resource_params[:year].to_i)
+
+ @collection_resource = CollectionResource.new(resource_params)
+ @collection_resource.download_filename ||= @collection_resource.file&.original_filename
+ @collection_resource.display_name = "#{@collection_resource.log_type} #{@collection_resource.short_display_name} (#{text_year_range_format(@collection_resource.year)})"
+
+ @collection_resource.validate_attached_file
+ @collection_resource.validate_short_display_name
+ return render "collection_resources/new" if @collection_resource.errors.any?
+
+ if @collection_resource.save
+ begin
+ CollectionResourcesService.new.upload_collection_resource(@collection_resource.download_filename, @collection_resource.file)
+ flash[:notice] = if displayed_collection_resource_years.include?(@collection_resource.year)
+ "The #{@collection_resource.log_type} #{text_year_range_format(@collection_resource.year)} #{@collection_resource.short_display_name} is now available to users."
+ else
+ "The #{@collection_resource.log_type} #{text_year_range_format(@collection_resource.year)} #{@collection_resource.short_display_name} has been uploaded."
+ end
+ redirect_to collection_resources_path
+ rescue StandardError
+ @collection_resource.errors.add(:file, :error_uploading)
+ render "collection_resources/new"
+ end
+ else
+ render "collection_resources/new"
+ end
+ end
+
+ def delete_confirmation
+ return render_not_authorized unless current_user.support?
+
+ @collection_resource = CollectionResource.find_by(id: params[:collection_resource_id])
+
+ return render_not_found unless @collection_resource
+
+ render "collection_resources/delete_confirmation"
+ end
+
+ def delete
+ return render_not_authorized unless current_user.support?
+
+ @collection_resource = CollectionResource.find_by(id: params[:collection_resource_id])
+
+ return render_not_found unless @collection_resource
+
+ @collection_resource.discard!
+
+ flash[:notice] = "The #{@collection_resource.log_type} #{text_year_range_format(@collection_resource.year)} #{@collection_resource.short_display_name.downcase} has been deleted."
+ redirect_to collection_resources_path
+ end
+
private
def resource_params
- params.require(:collection_resource).permit(:year, :log_type, :resource_type, :file)
+ params.require(:collection_resource).permit(:year, :log_type, :resource_type, :file, :mandatory, :short_display_name)
end
def download_resource(filename)
@@ -113,23 +229,4 @@ private
def resource_for_year_can_be_updated?(year)
editable_collection_resource_years.include?(year)
end
-
- def validate_file(file)
- return @collection_resource.errors.add(:file, :blank) unless file
- return @collection_resource.errors.add(:file, :above_100_mb) if file.size > 100.megabytes
-
- argv = %W[file --brief --mime-type -- #{file.path}]
- output = `#{argv.shelljoin}`
-
- case @collection_resource.resource_type
- when "paper_form"
- unless output.match?(/application\/pdf/)
- @collection_resource.errors.add(:file, :must_be_pdf)
- end
- when "bulk_upload_template", "bulk_upload_specification"
- unless output.match?(/application\/vnd\.ms-excel|application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet/)
- @collection_resource.errors.add(:file, :must_be_xlsx, resource: @collection_resource.short_display_name.downcase)
- end
- end
- end
end
diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb
index 0194946d4..cc3c731d5 100644
--- a/app/controllers/lettings_logs_controller.rb
+++ b/app/controllers/lettings_logs_controller.rb
@@ -65,7 +65,7 @@ class LettingsLogsController < LogsController
elsif @log.collection_closed_for_editing?
redirect_to review_lettings_log_path(@log)
else
- render("logs/edit", locals: { current_user: })
+ render("logs/edit", locals: { current_user:, bulk_upload_filter_applied: session_filters["bulk_upload_id"].present? })
end
end
diff --git a/app/controllers/sales_logs_controller.rb b/app/controllers/sales_logs_controller.rb
index d1bbe3bc2..af9879896 100644
--- a/app/controllers/sales_logs_controller.rb
+++ b/app/controllers/sales_logs_controller.rb
@@ -39,7 +39,7 @@ class SalesLogsController < LogsController
if @log.collection_closed_for_editing?
redirect_to review_sales_log_path(@log, sales_log: true)
else
- render "logs/edit", locals: { current_user: }
+ render "logs/edit", locals: { current_user:, bulk_upload_filter_applied: session_filters["bulk_upload_id"].present? }
end
end
diff --git a/app/controllers/start_controller.rb b/app/controllers/start_controller.rb
index 5bd49df3f..d6df81c39 100644
--- a/app/controllers/start_controller.rb
+++ b/app/controllers/start_controller.rb
@@ -4,6 +4,8 @@ class StartController < ApplicationController
def index
@mandatory_lettings_collection_resources_per_year = MandatoryCollectionResourcesService.generate_resources("lettings", displayed_collection_resource_years)
@mandatory_sales_collection_resources_per_year = MandatoryCollectionResourcesService.generate_resources("sales", displayed_collection_resource_years)
+ @additional_lettings_collection_resources_per_year = CollectionResource.visible.where(log_type: "lettings", mandatory: false, year: displayed_collection_resource_years).group_by(&:year)
+ @additional_sales_collection_resources_per_year = CollectionResource.visible.where(log_type: "sales", mandatory: false, year: displayed_collection_resource_years).group_by(&:year)
if current_user
@homepage_presenter = HomepagePresenter.new(current_user)
render "home/index"
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index b7c323ca1..f27bfc2b3 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -257,13 +257,7 @@ private
def user_params
if @user == current_user
- if current_user.data_coordinator?
- params.require(:user).permit(:email, :phone, :phone_extension, :name, :password, :password_confirmation, :role, :is_dpo, :is_key_contact, :initial_confirmation_sent)
- elsif current_user.support?
- params.require(:user).permit(:email, :phone, :phone_extension, :name, :password, :password_confirmation, :role, :is_dpo, :is_key_contact, :initial_confirmation_sent, :organisation_id)
- else
- params.require(:user).permit(:email, :phone, :phone_extension, :name, :password, :password_confirmation, :initial_confirmation_sent)
- end
+ current_user_params
elsif current_user.data_coordinator?
params.require(:user).permit(:email, :phone, :phone_extension, :name, :role, :is_dpo, :is_key_contact, :active, :initial_confirmation_sent)
elsif current_user.support?
@@ -271,6 +265,15 @@ private
end
end
+ def current_user_params
+ base_params = %i[email phone phone_extension name password password_confirmation initial_confirmation_sent]
+ return params.require(:user).permit(*(base_params + %i[role is_dpo is_key_contact])) if current_user.data_coordinator?
+ return params.require(:user).permit(*(base_params + %i[role is_dpo is_key_contact organisation_id])) if current_user.support?
+ return params.require(:user).permit(*(base_params + [:role])) if Rails.env.staging? && current_user.in_staging_role_update_email_allowlist?
+
+ params.require(:user).permit(*base_params)
+ end
+
def user_params_without_org
user_params.except(:organisation_id)
end
diff --git a/app/frontend/styles/_bulk-uploads.scss b/app/frontend/styles/_bulk-uploads.scss
index eceae6565..65213ee82 100644
--- a/app/frontend/styles/_bulk-uploads.scss
+++ b/app/frontend/styles/_bulk-uploads.scss
@@ -12,6 +12,11 @@
border-bottom: 1px solid #b1b4b6;
}
+.no-bottom-border,
+.no-bottom-border > tbody > tr:last-of-type td {
+ border-bottom: none;
+}
+
.text-normal-break {
white-space: normal;
word-break: break-all;
diff --git a/app/frontend/styles/_document-list.scss b/app/frontend/styles/_document-list.scss
index e8cef0625..a1f812551 100644
--- a/app/frontend/styles/_document-list.scss
+++ b/app/frontend/styles/_document-list.scss
@@ -1,5 +1,4 @@
.app-document-list {
- margin-top: govuk-spacing(3);
margin-bottom: govuk-spacing(6);
}
diff --git a/app/helpers/collection_resources_helper.rb b/app/helpers/collection_resources_helper.rb
index 9deb13887..1a5887744 100644
--- a/app/helpers/collection_resources_helper.rb
+++ b/app/helpers/collection_resources_helper.rb
@@ -49,7 +49,7 @@ module CollectionResourcesHelper
def document_list_component_items(resources)
resources.map do |resource|
{
- name: "Download the #{resource.display_name}",
+ name: "Download the #{resource.display_name.downcase}",
href: resource.download_path,
metadata: file_type_size_and_pages(resource.download_filename),
}
diff --git a/app/helpers/log_actions_helper.rb b/app/helpers/log_actions_helper.rb
index 8a018445e..3f2737cdd 100644
--- a/app/helpers/log_actions_helper.rb
+++ b/app/helpers/log_actions_helper.rb
@@ -2,8 +2,8 @@ module LogActionsHelper
include GovukLinkHelper
include GovukVisuallyHiddenHelper
- def edit_actions_for_log(log)
- back = back_button_for(log)
+ def edit_actions_for_log(log, bulk_upload_filter_applied)
+ back = back_button_for(log, bulk_upload_filter_applied)
delete = delete_button_for_log(log)
return if back.nil? && delete.nil?
@@ -15,9 +15,9 @@ module LogActionsHelper
private
- def back_button_for(log)
+ def back_button_for(log, bulk_upload_filter_applied)
if log.completed?
- if log.creation_method_bulk_upload? && log.bulk_upload.present?
+ if log.creation_method_bulk_upload? && log.bulk_upload.present? && bulk_upload_filter_applied
if log.lettings?
govuk_button_link_to "Back to uploaded logs", resume_bulk_upload_lettings_result_path(log.bulk_upload)
else
diff --git a/app/models/collection_resource.rb b/app/models/collection_resource.rb
index 81665ccf6..fc5808cec 100644
--- a/app/models/collection_resource.rb
+++ b/app/models/collection_resource.rb
@@ -1,9 +1,45 @@
class CollectionResource < ApplicationRecord
include Rails.application.routes.url_helpers
+ has_paper_trail
attr_accessor :file
+ scope :visible, -> { where(discarded_at: nil) }
+ validates :short_display_name, presence: true
+
def download_path
- download_mandatory_collection_resource_path(log_type:, year:, resource_type:)
+ if mandatory
+ download_mandatory_collection_resource_path(log_type:, year:, resource_type:)
+ else
+ collection_resource_download_path(self)
+ end
+ end
+
+ def validate_attached_file
+ return errors.add(:file, :blank) unless file
+ return errors.add(:file, :above_100_mb) if file.size > 100.megabytes
+
+ argv = %W[file --brief --mime-type -- #{file.path}]
+ output = `#{argv.shelljoin}`
+
+ case resource_type
+ when "paper_form"
+ unless output.match?(/application\/pdf/)
+ errors.add(:file, :must_be_pdf)
+ end
+ when "bulk_upload_template", "bulk_upload_specification"
+ unless output.match?(/application\/vnd\.ms-excel|application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet/)
+ errors.add(:file, :must_be_xlsx, resource: short_display_name.downcase)
+ end
+ end
+ end
+
+ def validate_short_display_name
+ errors.add(:short_display_name, :blank) if short_display_name.blank?
+ end
+
+ def discard!
+ CollectionResourcesService.new.delete_collection_resource(download_filename)
+ update!(discarded_at: Time.zone.now)
end
end
diff --git a/app/models/form/sales/pages/buyer1_income.rb b/app/models/form/sales/pages/buyer1_income.rb
index 943296d2b..657cf8807 100644
--- a/app/models/form/sales/pages/buyer1_income.rb
+++ b/app/models/form/sales/pages/buyer1_income.rb
@@ -2,6 +2,7 @@ class Form::Sales::Pages::Buyer1Income < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_income"
+ @copy_key = "sales.income_benefits_and_savings.buyer_1_income"
end
def questions
diff --git a/app/models/form/sales/pages/buyer1_income_max_value_check.rb b/app/models/form/sales/pages/buyer1_income_max_value_check.rb
index b093baa2a..55599ff26 100644
--- a/app/models/form/sales/pages/buyer1_income_max_value_check.rb
+++ b/app/models/form/sales/pages/buyer1_income_max_value_check.rb
@@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer1IncomeMaxValueCheck < ::Form::Page
"income1_over_soft_max?" => true,
},
]
+ @copy_key = "sales.soft_validations.income1_value_check.max"
@title_text = {
- "translation" => "soft_validations.income.over_soft_max_for_la_buyer_1",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
diff --git a/app/models/form/sales/pages/buyer1_income_min_value_check.rb b/app/models/form/sales/pages/buyer1_income_min_value_check.rb
index 2feb4f887..9fc85bb76 100644
--- a/app/models/form/sales/pages/buyer1_income_min_value_check.rb
+++ b/app/models/form/sales/pages/buyer1_income_min_value_check.rb
@@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer1IncomeMinValueCheck < ::Form::Page
"income1_under_soft_min?" => true,
},
]
+ @copy_key = "sales.soft_validations.income1_value_check.min"
@title_text = {
- "translation" => "soft_validations.income.under_soft_min_for_economic_status.title_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
@@ -22,7 +23,7 @@ class Form::Sales::Pages::Buyer1IncomeMinValueCheck < ::Form::Page
],
}
@informative_text = {
- "translation" => "soft_validations.income.under_soft_min_for_economic_status.hint_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [],
}
end
diff --git a/app/models/form/sales/pages/buyer2_income.rb b/app/models/form/sales/pages/buyer2_income.rb
index f865418a7..fd35d52cc 100644
--- a/app/models/form/sales/pages/buyer2_income.rb
+++ b/app/models/form/sales/pages/buyer2_income.rb
@@ -2,6 +2,7 @@ class Form::Sales::Pages::Buyer2Income < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_income"
+ @copy_key = "sales.income_benefits_and_savings.buyer_2_income"
@depends_on = [{
"joint_purchase?" => true,
}]
diff --git a/app/models/form/sales/pages/buyer2_income_max_value_check.rb b/app/models/form/sales/pages/buyer2_income_max_value_check.rb
index 894da8799..deece885e 100644
--- a/app/models/form/sales/pages/buyer2_income_max_value_check.rb
+++ b/app/models/form/sales/pages/buyer2_income_max_value_check.rb
@@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer2IncomeMaxValueCheck < ::Form::Page
"income2_over_soft_max?" => true,
},
]
+ @copy_key = "sales.soft_validations.income2_value_check.max"
@title_text = {
- "translation" => "soft_validations.income.over_soft_max_for_la_buyer_2",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
diff --git a/app/models/form/sales/pages/buyer2_income_min_value_check.rb b/app/models/form/sales/pages/buyer2_income_min_value_check.rb
index adef17843..a7b68cd10 100644
--- a/app/models/form/sales/pages/buyer2_income_min_value_check.rb
+++ b/app/models/form/sales/pages/buyer2_income_min_value_check.rb
@@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer2IncomeMinValueCheck < ::Form::Page
"income2_under_soft_min?" => true,
},
]
+ @copy_key = "sales.soft_validations.income2_value_check.min"
@title_text = {
- "translation" => "soft_validations.income.under_soft_min_for_economic_status.title_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
@@ -22,7 +23,7 @@ class Form::Sales::Pages::Buyer2IncomeMinValueCheck < ::Form::Page
],
}
@informative_text = {
- "translation" => "soft_validations.income.under_soft_min_for_economic_status.hint_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [],
}
end
diff --git a/app/models/form/sales/pages/combined_income_max_value_check.rb b/app/models/form/sales/pages/combined_income_max_value_check.rb
index 82f2e4469..1cd1fd851 100644
--- a/app/models/form/sales/pages/combined_income_max_value_check.rb
+++ b/app/models/form/sales/pages/combined_income_max_value_check.rb
@@ -6,8 +6,9 @@ class Form::Sales::Pages::CombinedIncomeMaxValueCheck < ::Form::Page
"combined_income_over_soft_max?" => true,
},
]
+ @copy_key = "sales.soft_validations.combined_income_value_check"
@title_text = {
- "translation" => "soft_validations.income.over_soft_max_for_la_combined",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
diff --git a/app/models/form/sales/pages/deposit_value_check.rb b/app/models/form/sales/pages/deposit_value_check.rb
index cca25a43b..cbec4b031 100644
--- a/app/models/form/sales/pages/deposit_value_check.rb
+++ b/app/models/form/sales/pages/deposit_value_check.rb
@@ -1,12 +1,13 @@
class Form::Sales::Pages::DepositValueCheck < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection)
+ @copy_key = "sales.soft_validations.deposit_value_check.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@informative_text = {
- "translation" => "soft_validations.deposit.hint_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [],
}
@title_text = {
- "translation" => "soft_validations.deposit.title_text.#{joint_purchase ? 'two' : 'one'}",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
diff --git a/app/models/form/sales/pages/household_wheelchair_check.rb b/app/models/form/sales/pages/household_wheelchair_check.rb
index 72b78cc2b..8cd2821be 100644
--- a/app/models/form/sales/pages/household_wheelchair_check.rb
+++ b/app/models/form/sales/pages/household_wheelchair_check.rb
@@ -6,8 +6,8 @@ class Form::Sales::Pages::HouseholdWheelchairCheck < ::Form::Page
"wheelchair_when_not_disabled?" => true,
},
]
- @informative_text = {}
- @title_text = { "translation" => "soft_validations.wheelchair.title_text" }
+ @copy_key = "sales.soft_validations.wheel_value_check"
+ @title_text = { "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text" }
end
def questions
diff --git a/app/models/form/sales/pages/housing_benefits.rb b/app/models/form/sales/pages/housing_benefits.rb
index 90d721ad8..c40dff5f4 100644
--- a/app/models/form/sales/pages/housing_benefits.rb
+++ b/app/models/form/sales/pages/housing_benefits.rb
@@ -2,6 +2,7 @@ class Form::Sales::Pages::HousingBenefits < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection)
@joint_purchase = joint_purchase
+ @copy_key = "sales.income_benefits_and_savings.housing_benefits.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end
def questions
diff --git a/app/models/form/sales/pages/mortgage_value_check.rb b/app/models/form/sales/pages/mortgage_value_check.rb
index 949cea27f..bfab9a014 100644
--- a/app/models/form/sales/pages/mortgage_value_check.rb
+++ b/app/models/form/sales/pages/mortgage_value_check.rb
@@ -2,10 +2,10 @@ class Form::Sales::Pages::MortgageValueCheck < ::Form::Page
def initialize(id, hsh, subsection, person_index = nil)
super(id, hsh, subsection)
@depends_on = depends_on
- @informative_text = {}
@person_index = person_index
+ @copy_key = "sales.soft_validations.mortgage_value_check"
@title_text = {
- "translation" => "soft_validations.mortgage.title_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
@@ -15,7 +15,7 @@ class Form::Sales::Pages::MortgageValueCheck < ::Form::Page
],
}
@informative_text = {
- "translation" => "soft_validations.mortgage.hint_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [],
}
end
diff --git a/app/models/form/sales/pages/previous_ownership.rb b/app/models/form/sales/pages/previous_ownership.rb
index 50711baf7..ac7a17787 100644
--- a/app/models/form/sales/pages/previous_ownership.rb
+++ b/app/models/form/sales/pages/previous_ownership.rb
@@ -3,6 +3,7 @@ class Form::Sales::Pages::PreviousOwnership < ::Form::Page
super(id, hsh, subsection)
@joint_purchase = joint_purchase
@depends_on = [{ "joint_purchase?" => @joint_purchase }]
+ @copy_key = "sales.income_benefits_and_savings.prevown.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end
def questions
diff --git a/app/models/form/sales/pages/savings.rb b/app/models/form/sales/pages/savings.rb
index 7a13dbe34..64a2b1ecf 100644
--- a/app/models/form/sales/pages/savings.rb
+++ b/app/models/form/sales/pages/savings.rb
@@ -2,6 +2,7 @@ class Form::Sales::Pages::Savings < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection)
@joint_purchase = joint_purchase
+ @copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end
def questions
diff --git a/app/models/form/sales/pages/savings_value_check.rb b/app/models/form/sales/pages/savings_value_check.rb
index bcb95abc9..00be6decd 100644
--- a/app/models/form/sales/pages/savings_value_check.rb
+++ b/app/models/form/sales/pages/savings_value_check.rb
@@ -1,8 +1,9 @@
class Form::Sales::Pages::SavingsValueCheck < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection)
+ @copy_key = "sales.soft_validations.savings_value_check.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@title_text = {
- "translation" => "soft_validations.savings.title_text.#{joint_purchase ? 'two' : 'one'}",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [
{
"key" => "field_formatted_as_currency",
@@ -12,7 +13,7 @@ class Form::Sales::Pages::SavingsValueCheck < ::Form::Page
],
}
@informative_text = {
- "translation" => "soft_validations.savings.hint_text",
+ "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [],
}
@joint_purchase = joint_purchase
diff --git a/app/models/form/sales/questions/armed_forces.rb b/app/models/form/sales/questions/armed_forces.rb
index 0d655a733..7bd14d7b1 100644
--- a/app/models/form/sales/questions/armed_forces.rb
+++ b/app/models/form/sales/questions/armed_forces.rb
@@ -2,10 +2,7 @@ class Form::Sales::Questions::ArmedForces < ::Form::Question
def initialize(id, hsh, page)
super
@id = "hhregres"
- @check_answer_label = "Have any of the buyers ever served as a regular in the UK armed forces?"
- @header = "Have any of the buyers ever served as a regular in the UK armed forces?"
@type = "radio"
- @hint_text = "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Airforce or Army full time and does not include reserve forces"
@answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
diff --git a/app/models/form/sales/questions/armed_forces_spouse.rb b/app/models/form/sales/questions/armed_forces_spouse.rb
index 949b5d612..02be7c5e3 100644
--- a/app/models/form/sales/questions/armed_forces_spouse.rb
+++ b/app/models/form/sales/questions/armed_forces_spouse.rb
@@ -2,8 +2,6 @@ class Form::Sales::Questions::ArmedForcesSpouse < ::Form::Question
def initialize(id, hsh, page)
super
@id = "armedforcesspouse"
- @check_answer_label = "Are any of the buyers a spouse or civil partner of a UK armed forces regular who died in service within the last 2 years?"
- @header = "Are any of the buyers a spouse or civil partner of a UK armed forces regular who died in service within the last 2 years?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
diff --git a/app/models/form/sales/questions/buyer1_income.rb b/app/models/form/sales/questions/buyer1_income.rb
index 106f040f8..3f1159a8f 100644
--- a/app/models/form/sales/questions/buyer1_income.rb
+++ b/app/models/form/sales/questions/buyer1_income.rb
@@ -2,9 +2,7 @@ class Form::Sales::Questions::Buyer1Income < ::Form::Question
def initialize(id, hsh, page)
super
@id = "income1"
- @check_answer_label = "Buyer 1’s gross annual income"
- @header = "Buyer 1’s gross annual income"
- @hint_text = "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
+ @copy_key = "sales.income_benefits_and_savings.buyer_1_income.income1"
@type = "numeric"
@min = 0
@max = 999_999
diff --git a/app/models/form/sales/questions/buyer1_income_known.rb b/app/models/form/sales/questions/buyer1_income_known.rb
index b00b45475..46c1f4caa 100644
--- a/app/models/form/sales/questions/buyer1_income_known.rb
+++ b/app/models/form/sales/questions/buyer1_income_known.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer1IncomeKnown < ::Form::Question
def initialize(id, hsh, page)
super
@id = "income1nk"
- @check_answer_label = "Buyer 1’s gross annual income known?"
- @header = "Do you know buyer 1’s annual income?"
+ @copy_key = "sales.income_benefits_and_savings.buyer_1_income.income1nk"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@conditional_for = {
diff --git a/app/models/form/sales/questions/buyer1_income_value_check.rb b/app/models/form/sales/questions/buyer1_income_value_check.rb
index 63e3b6478..410bd53d5 100644
--- a/app/models/form/sales/questions/buyer1_income_value_check.rb
+++ b/app/models/form/sales/questions/buyer1_income_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer1IncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page)
@id = "income1_value_check"
- @check_answer_label = "Buyer 1 income confirmation"
- @header = "Are you sure this is correct?"
+ @copy_key = "sales.soft_validations.income1_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/buyer1_mortgage.rb b/app/models/form/sales/questions/buyer1_mortgage.rb
index eaa2a07fa..d2a94f6b5 100644
--- a/app/models/form/sales/questions/buyer1_mortgage.rb
+++ b/app/models/form/sales/questions/buyer1_mortgage.rb
@@ -2,8 +2,6 @@ class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question
def initialize(id, hsh, page)
super
@id = "inc1mort"
- @check_answer_label = "Buyer 1’s income used for mortgage application"
- @header = "Was buyer 1’s income used for a mortgage application?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 1
diff --git a/app/models/form/sales/questions/buyer2_income.rb b/app/models/form/sales/questions/buyer2_income.rb
index cff25b344..39777f870 100644
--- a/app/models/form/sales/questions/buyer2_income.rb
+++ b/app/models/form/sales/questions/buyer2_income.rb
@@ -2,10 +2,8 @@ class Form::Sales::Questions::Buyer2Income < ::Form::Question
def initialize(id, hsh, page)
super
@id = "income2"
- @check_answer_label = "Buyer 2’s gross annual income"
- @header = "Buyer 2’s gross annual income"
+ @copy_key = "sales.income_benefits_and_savings.buyer_2_income.income2"
@type = "numeric"
- @hint_text = "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
@min = 0
@max = 999_999
@step = 1
diff --git a/app/models/form/sales/questions/buyer2_income_known.rb b/app/models/form/sales/questions/buyer2_income_known.rb
index b3cc5f33a..0b125f2af 100644
--- a/app/models/form/sales/questions/buyer2_income_known.rb
+++ b/app/models/form/sales/questions/buyer2_income_known.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer2IncomeKnown < ::Form::Question
def initialize(id, hsh, page)
super
@id = "income2nk"
- @check_answer_label = "Buyer 2’s gross annual income known?"
- @header = "Do you know buyer 2’s annual income?"
+ @copy_key = "sales.income_benefits_and_savings.buyer_2_income.income2"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@conditional_for = {
diff --git a/app/models/form/sales/questions/buyer2_income_value_check.rb b/app/models/form/sales/questions/buyer2_income_value_check.rb
index 37b6cb380..6b0bab5c2 100644
--- a/app/models/form/sales/questions/buyer2_income_value_check.rb
+++ b/app/models/form/sales/questions/buyer2_income_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer2IncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page)
@id = "income2_value_check"
- @check_answer_label = "Buyer 2 income confirmation"
- @header = "Are you sure this is correct?"
+ @copy_key = "sales.soft_validations.income2_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/buyer2_mortgage.rb b/app/models/form/sales/questions/buyer2_mortgage.rb
index 42b8cda06..415d5b714 100644
--- a/app/models/form/sales/questions/buyer2_mortgage.rb
+++ b/app/models/form/sales/questions/buyer2_mortgage.rb
@@ -2,8 +2,6 @@ class Form::Sales::Questions::Buyer2Mortgage < ::Form::Question
def initialize(id, hsh, page)
super
@id = "inc2mort"
- @check_answer_label = "Buyer 2’s income used for mortgage application"
- @header = "Was buyer 2’s income used for a mortgage application?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2
diff --git a/app/models/form/sales/questions/buyer_still_serving.rb b/app/models/form/sales/questions/buyer_still_serving.rb
index 602a0804d..04c1c2307 100644
--- a/app/models/form/sales/questions/buyer_still_serving.rb
+++ b/app/models/form/sales/questions/buyer_still_serving.rb
@@ -2,8 +2,6 @@ class Form::Sales::Questions::BuyerStillServing < ::Form::Question
def initialize(id, hsh, page)
super
@id = "hhregresstill"
- @check_answer_label = "Are they still serving in the UK armed forces?"
- @header = "Is the buyer still serving in the UK armed forces?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
diff --git a/app/models/form/sales/questions/combined_income_value_check.rb b/app/models/form/sales/questions/combined_income_value_check.rb
index 47cafeaa2..c2688ffe5 100644
--- a/app/models/form/sales/questions/combined_income_value_check.rb
+++ b/app/models/form/sales/questions/combined_income_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::CombinedIncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page)
@id = "combined_income_value_check"
- @check_answer_label = "Combined income confirmation"
- @header = "Are you sure this is correct?"
+ @copy_key = "sales.soft_validations.combined_income_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/deposit_value_check.rb b/app/models/form/sales/questions/deposit_value_check.rb
index f3cd27e3a..f8d403d9c 100644
--- a/app/models/form/sales/questions/deposit_value_check.rb
+++ b/app/models/form/sales/questions/deposit_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::DepositValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "deposit_value_check"
- @check_answer_label = "Deposit confirmation"
- @header = "Are you sure that the deposit is this much higher than the buyer's savings?"
+ @copy_key = "sales.soft_validations.deposit_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/household_disability.rb b/app/models/form/sales/questions/household_disability.rb
index 43773dcf3..3dac19bb6 100644
--- a/app/models/form/sales/questions/household_disability.rb
+++ b/app/models/form/sales/questions/household_disability.rb
@@ -2,11 +2,8 @@ class Form::Sales::Questions::HouseholdDisability < ::Form::Question
def initialize(id, hsh, page)
super
@id = "disabled"
- @header = "Does anyone in the household consider themselves to have a disability?"
- @check_answer_label = "Does anyone in the household have a disability?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
- @hint_text = "This includes any long-term health condition that has an impact on the person's day-to-day life"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
diff --git a/app/models/form/sales/questions/household_wheelchair.rb b/app/models/form/sales/questions/household_wheelchair.rb
index 4b5316b29..4c46bd55d 100644
--- a/app/models/form/sales/questions/household_wheelchair.rb
+++ b/app/models/form/sales/questions/household_wheelchair.rb
@@ -2,10 +2,8 @@ class Form::Sales::Questions::HouseholdWheelchair < ::Form::Question
def initialize(id, hsh, page)
super
@id = "wheel"
- @header = "Does anyone in the household use a wheelchair?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
- @hint_text = "This can be inside or outside the home"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
diff --git a/app/models/form/sales/questions/household_wheelchair_check.rb b/app/models/form/sales/questions/household_wheelchair_check.rb
index 50498b099..a37e80203 100644
--- a/app/models/form/sales/questions/household_wheelchair_check.rb
+++ b/app/models/form/sales/questions/household_wheelchair_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::HouseholdWheelchairCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "wheel_value_check"
- @check_answer_label = "Does anyone in the household use a wheelchair?"
- @header = "You told us that someone in the household uses a wheelchair."
+ @copy_key = "sales.soft_validations.wheel_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/housing_benefits.rb b/app/models/form/sales/questions/housing_benefits.rb
index 70bc4ba2e..d7a670f2e 100644
--- a/app/models/form/sales/questions/housing_benefits.rb
+++ b/app/models/form/sales/questions/housing_benefits.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::HousingBenefits < ::Form::Question
def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page)
@id = "hb"
- @check_answer_label = "Housing-related benefits #{joint_purchase ? 'buyers' : 'buyer'} received before buying this property"
- @header = "#{joint_purchase ? 'Were the buyers' : 'Was the buyer'} receiving any of these housing-related benefits immediately before buying this property?"
+ @copy_key = "sales.income_benefits_and_savings.housing_benefits.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
diff --git a/app/models/form/sales/questions/mortgage_value_check.rb b/app/models/form/sales/questions/mortgage_value_check.rb
index 39079d40e..99307ab38 100644
--- a/app/models/form/sales/questions/mortgage_value_check.rb
+++ b/app/models/form/sales/questions/mortgage_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::MortgageValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "mortgage_value_check"
- @check_answer_label = "Mortgage confirmation"
- @header = "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?"
+ @copy_key = "sales.soft_validations.mortgage_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/prevown.rb b/app/models/form/sales/questions/prevown.rb
index f913f950b..ecd6c9071 100644
--- a/app/models/form/sales/questions/prevown.rb
+++ b/app/models/form/sales/questions/prevown.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Prevown < ::Form::Question
def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page)
@id = "prevown"
- @check_answer_label = I18n.t("check_answer_labels.prevown", count: joint_purchase ? 2 : 1)
- @header = I18n.t("questions.prevown", count: joint_purchase ? 2 : 1)
+ @copy_key = "sales.income_benefits_and_savings.prevown.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
diff --git a/app/models/form/sales/questions/prevshared.rb b/app/models/form/sales/questions/prevshared.rb
index 018f57faa..f4ced14b9 100644
--- a/app/models/form/sales/questions/prevshared.rb
+++ b/app/models/form/sales/questions/prevshared.rb
@@ -2,11 +2,8 @@ class Form::Sales::Questions::Prevshared < ::Form::Question
def initialize(id, hsh, page)
super
@id = "prevshared"
- @check_answer_label = "Previous property shared ownership?"
- @header = "Was the previous property under shared ownership?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
- @hint_text = "For any buyer"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
diff --git a/app/models/form/sales/questions/savings.rb b/app/models/form/sales/questions/savings.rb
index 82b8e0f87..bb1f939a5 100644
--- a/app/models/form/sales/questions/savings.rb
+++ b/app/models/form/sales/questions/savings.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::Savings < ::Form::Question
def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page)
@id = "savings"
- @check_answer_label = "#{joint_purchase ? 'Buyers’' : 'Buyer’s'} total savings before any deposit paid"
- @header = "Enter their total savings to the nearest £10"
+ @copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}.savings"
@type = "numeric"
@width = 5
@prefix = "£"
diff --git a/app/models/form/sales/questions/savings_nk.rb b/app/models/form/sales/questions/savings_nk.rb
index 931ba835a..3c7e115f4 100644
--- a/app/models/form/sales/questions/savings_nk.rb
+++ b/app/models/form/sales/questions/savings_nk.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::SavingsNk < ::Form::Question
def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page)
@id = "savingsnk"
- @check_answer_label = "#{joint_purchase ? 'Buyers’' : 'Buyer’s'} total savings known?"
- @header = "Do you know how much the #{joint_purchase ? 'buyers' : 'buyer'} had in savings before they paid any deposit for the property?"
+ @copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}.savingsnk"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@conditional_for = {
diff --git a/app/models/form/sales/questions/savings_value_check.rb b/app/models/form/sales/questions/savings_value_check.rb
index bcd16827a..f547969bf 100644
--- a/app/models/form/sales/questions/savings_value_check.rb
+++ b/app/models/form/sales/questions/savings_value_check.rb
@@ -2,8 +2,7 @@ class Form::Sales::Questions::SavingsValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "savings_value_check"
- @check_answer_label = "Savings confirmation"
- @header = "Are you sure the savings are higher than £100,000?"
+ @copy_key = "sales.soft_validations.savings_value_check"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
diff --git a/app/models/form/sales/questions/uprn.rb b/app/models/form/sales/questions/uprn.rb
index 75a41a0ec..94aaccb43 100644
--- a/app/models/form/sales/questions/uprn.rb
+++ b/app/models/form/sales/questions/uprn.rb
@@ -16,7 +16,7 @@ class Form::Sales::Questions::Uprn < ::Form::Question
end
def unanswered_error_message
- I18n.t("validations.property.uprn.invalid")
+ I18n.t("validations.sales.property_information.uprn.invalid")
end
def get_extra_check_answer_value(log)
diff --git a/app/models/form/sales/questions/uprn_known.rb b/app/models/form/sales/questions/uprn_known.rb
index 44ce03cad..fdd0c9e9a 100644
--- a/app/models/form/sales/questions/uprn_known.rb
+++ b/app/models/form/sales/questions/uprn_known.rb
@@ -31,7 +31,7 @@ class Form::Sales::Questions::UprnKnown < ::Form::Question
}.freeze
def unanswered_error_message
- I18n.t("validations.property.uprn_known.invalid")
+ I18n.t("validations.sales.property_information.uprn_known.invalid")
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 14, 2024 => 15 }.freeze
diff --git a/app/models/user.rb b/app/models/user.rb
index 0d3bc4846..75b5a366b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -212,7 +212,7 @@ class User < ApplicationRecord
end
def assignable_roles
- if Rails.env.staging? && Rails.application.credentials[:staging_role_update_email_allowlist].include?(email.split("@").last.downcase)
+ if Rails.env.staging? && in_staging_role_update_email_allowlist?
return ROLES
end
@@ -222,6 +222,10 @@ class User < ApplicationRecord
ROLES.except(:support)
end
+ def in_staging_role_update_email_allowlist?
+ Rails.application.credentials[:staging_role_update_email_allowlist].include?(email.split("@").last.downcase)
+ end
+
def logs_filters(specific_org: false)
if (support? && !specific_org) || organisation.has_managing_agents? || organisation.has_stock_owners?
%w[years status needstypes assigned_to user owning_organisation managing_organisation bulk_upload_id user_text_search owning_organisation_text_search managing_organisation_text_search]
diff --git a/app/models/validations/sales/household_validations.rb b/app/models/validations/sales/household_validations.rb
index e006374aa..fb1ea65c2 100644
--- a/app/models/validations/sales/household_validations.rb
+++ b/app/models/validations/sales/household_validations.rb
@@ -9,9 +9,9 @@ module Validations::Sales::HouseholdValidations
return unless record.form.start_date.year >= 2023
if record.buyers_will_live_in? && record.buyer_one_will_not_live_in_property? && record.buyer_two_will_not_live_in_property?
- record.errors.add :buylivein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup")
- record.errors.add :buy1livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
- record.errors.add :buy2livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
+ record.errors.add :buylivein, I18n.t("validations.sales.household.buylivein.buyers_will_live_in_property_values_inconsistent")
+ record.errors.add :buy1livein, I18n.t("validations.sales.household.buy1livein.buyers_will_live_in_property_values_inconsistent")
+ record.errors.add :buy2livein, I18n.t("validations.sales.household.buy2livein.buyers_will_live_in_property_values_inconsistent")
end
end
@@ -20,8 +20,8 @@ module Validations::Sales::HouseholdValidations
return unless record.discounted_ownership_sale? && record.prevten
if [3, 4, 5, 6, 7, 9, 0].include?(record.prevten)
- record.errors.add :prevten, I18n.t("validations.household.prevten.invalid_for_discounted_sale")
- record.errors.add :ownershipsch, I18n.t("validations.household.prevten.invalid_for_discounted_sale")
+ record.errors.add :prevten, I18n.t("validations.sales.household.prevten.prevten_invalid_for_discounted_sale")
+ record.errors.add :ownershipsch, I18n.t("validations.sales.household.ownershipsch.prevten_invalid_for_discounted_sale")
end
end
@@ -34,11 +34,11 @@ module Validations::Sales::HouseholdValidations
next unless age && relationship
if age < 16 && !relationship_is_child_other_or_refused?(relationship)
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_relat_sales", person_num:)
- record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_under_16_sales", person_num:)
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_under_16", person_num:)
+ record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_under_16", person_num:)
elsif age >= 20 && person_is_child?(relationship)
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_20")
- record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_over_20")
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_over_20")
+ record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_over_20")
end
end
end
@@ -58,16 +58,16 @@ module Validations::Sales::HouseholdValidations
child = person_is_child?(relationship)
if age_between_16_19 && !(student || economic_status_refused) && child
- record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.must_be_student")
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student")
- record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.16_19_not_student")
+ record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.student_16_19.must_be_student")
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.student_16_19.cannot_be_16_19.child_not_student")
+ record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.16_19_not_student")
end
next unless !age_between_16_19 && student && child
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.must_be_16_19")
- record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")
- record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.student_not_16_19")
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.student_16_19.must_be_16_19")
+ record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")
+ record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.student_not_16_19")
end
end
@@ -78,12 +78,12 @@ module Validations::Sales::HouseholdValidations
next unless age && economic_status
if age < 16 && !economic_status_is_child_other_or_refused?(economic_status) && !record.form.start_year_after_2024?
- record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_under_16", person_num:)
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_ecstat", person_num:)
+ record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.child_under_16", person_num:)
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_under_16_ecstat", person_num:)
end
if person_is_economic_child?(economic_status) && age > 16
- record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_over_16", person_num:)
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_16", person_num:)
+ record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.child_over_16", person_num:)
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_over_16", person_num:)
end
end
end
@@ -99,17 +99,17 @@ module Validations::Sales::HouseholdValidations
next unless person_age > buyer_1_age - 12 && person_is_child?(relationship)
- record.errors.add "age1", I18n.t("validations.household.age.child_12_years_younger")
- record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_12_years_younger")
- record.errors.add "relat#{person_num}", I18n.t("validations.household.age.child_12_years_younger")
+ record.errors.add "age1", I18n.t("validations.sales.household.age1.child_12_years_younger")
+ record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_12_years_younger")
+ record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_12_years_younger")
end
end
def validate_buyer_not_child(record)
return unless record.saledate && record.form.start_year_after_2024?
- record.errors.add "ecstat1", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "1") if person_is_economic_child?(record.ecstat1)
- record.errors.add "ecstat2", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "2") if person_is_economic_child?(record.ecstat2) && record.joint_purchase?
+ record.errors.add "ecstat1", I18n.t("validations.sales.household.ecstat1.buyer_cannot_be_child") if person_is_economic_child?(record.ecstat1)
+ record.errors.add "ecstat2", I18n.t("validations.sales.household.ecstat2.buyer_cannot_be_child") if person_is_economic_child?(record.ecstat2) && record.joint_purchase?
end
private
diff --git a/app/models/validations/sales/property_validations.rb b/app/models/validations/sales/property_validations.rb
index 50818c422..59d616c9a 100644
--- a/app/models/validations/sales/property_validations.rb
+++ b/app/models/validations/sales/property_validations.rb
@@ -4,10 +4,11 @@ module Validations::Sales::PropertyValidations
return unless record.ppostcode_full.present? && record.postcode_full.present?
if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full
- record.errors.add :postcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
- record.errors.add :ppostcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
- record.errors.add :ownershipsch, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
- record.errors.add :uprn, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
+ joint_purchase_id = record.joint_purchase? ? "joint_purchase" : "not_joint_purchase"
+ record.errors.add :postcode_full, I18n.t("validations.sales.property_information.postcode_full.postcode_must_match_previous.#{joint_purchase_id}")
+ record.errors.add :ppostcode_full, I18n.t("validations.sales.property_information.ppostcode_full.postcode_must_match_previous.#{joint_purchase_id}")
+ record.errors.add :ownershipsch, I18n.t("validations.sales.property_information.ownershipsch.postcode_must_match_previous.#{joint_purchase_id}")
+ record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.postcode_must_match_previous.#{joint_purchase_id}")
end
end
@@ -15,8 +16,8 @@ module Validations::Sales::PropertyValidations
return unless record.proptype.present? && record.beds.present?
if record.is_bedsit? && record.beds > 1
- record.errors.add :proptype, I18n.t("validations.property.proptype.bedsits_have_max_one_bedroom")
- record.errors.add :beds, I18n.t("validations.property.beds.bedsits_have_max_one_bedroom")
+ record.errors.add :proptype, I18n.t("validations.sales.property_information.proptype.bedsits_have_max_one_bedroom")
+ record.errors.add :beds, I18n.t("validations.sales.property_information.beds.bedsits_have_max_one_bedroom")
end
end
@@ -25,6 +26,6 @@ module Validations::Sales::PropertyValidations
return if record.uprn.match?(/^[0-9]{1,12}$/)
- record.errors.add :uprn, I18n.t("validations.property.uprn.invalid")
+ record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.invalid")
end
end
diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb
index 217b2c170..a2ae916c1 100644
--- a/app/models/validations/shared_validations.rb
+++ b/app/models/validations/shared_validations.rb
@@ -131,7 +131,11 @@ module Validations::SharedValidations
partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) }
if partner_numbers.count > 1
partner_numbers.each do |n|
- record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner")
+ if record.sales?
+ record.errors.add "relat#{n}", I18n.t("validations.sales.household.relat.one_partner")
+ else
+ record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner")
+ end
end
end
end
diff --git a/app/services/bulk_upload/lettings/year2023/csv_parser.rb b/app/services/bulk_upload/lettings/year2023/csv_parser.rb
index 64e27108f..96be2256d 100644
--- a/app/services/bulk_upload/lettings/year2023/csv_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/csv_parser.rb
@@ -109,9 +109,11 @@ private
def first_record_start_date
if with_headers?
- Date.new(row_parsers.first.field_9.to_i + 2000, row_parsers.first.field_8.to_i, row_parsers.first.field_7.to_i)
+ year = row_parsers.first.field_9.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_9.to_i + 2000 : row_parsers.first.field_9.to_i
+ Date.new(year, row_parsers.first.field_8.to_i, row_parsers.first.field_7.to_i)
else
- Date.new(rows.first[97].to_i + 2000, rows.first[96].to_i, rows.first[95].to_i)
+ year = rows.first[97].to_s.strip.length.between?(1, 2) ? rows.first[97].to_i + 2000 : rows.first[97].to_i
+ Date.new(year, rows.first[96].to_i, rows.first[95].to_i)
end
end
end
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index 8c435ad24..59cf7ea34 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -323,8 +323,8 @@ class BulkUpload::Lettings::Year2023::RowParser
category: :setup,
},
format: {
- with: /\A\d{2}\z/,
- message: I18n.t("validations.setup.startdate.year_not_two_digits"),
+ with: /\A(\d{2}|\d{4})\z/,
+ message: I18n.t("validations.setup.startdate.year_not_two_or_four_digits"),
category: :setup,
unless: -> { field_9.blank? },
},
@@ -618,14 +618,6 @@ private
end
end
- def start_date
- return if field_7.blank? || field_8.blank? || field_9.blank?
-
- Date.parse("20#{field_9.to_s.rjust(2, '0')}-#{field_8}-#{field_7}")
- rescue StandardError
- nil
- end
-
def validate_no_and_dont_know_disabled_needs_conjunction
if field_87 == 1 && field_88 == 1
errors.add(:field_87, I18n.t("validations.household.housingneeds.no_and_dont_know_disabled_needs_conjunction"))
@@ -736,9 +728,9 @@ private
end
def validate_relevant_collection_window
- return if start_date.blank? || bulk_upload.form.blank?
+ return if startdate.blank? || bulk_upload.form.blank?
- unless bulk_upload.form.valid_start_date_for_form?(start_date)
+ unless bulk_upload.form.valid_start_date_for_form?(startdate)
errors.add(:field_7, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
errors.add(:field_8, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
errors.add(:field_9, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
@@ -1388,7 +1380,8 @@ private
end
def startdate
- Date.new(field_9 + 2000, field_8, field_7) if field_9.present? && field_8.present? && field_7.present?
+ year = field_9.to_s.strip.length.between?(1, 2) ? field_9 + 2000 : field_9
+ Date.new(year, field_8, field_7) if field_9.present? && field_8.present? && field_7.present?
rescue Date::Error
Date.new
end
@@ -1584,13 +1577,15 @@ private
end
def mrcdate
- Date.new(field_38 + 2000, field_37, field_36) if field_38.present? && field_37.present? && field_36.present?
+ year = field_38.to_s.strip.length.between?(1, 2) ? field_38 + 2000 : field_38
+ Date.new(year, field_37, field_36) if field_38.present? && field_37.present? && field_36.present?
rescue Date::Error
Date.new
end
def voiddate
- Date.new(field_35 + 2000, field_34, field_33) if field_35.present? && field_34.present? && field_33.present?
+ year = field_35.to_s.strip.length.between?(1, 2) ? field_35 + 2000 : field_35
+ Date.new(year, field_34, field_33) if field_35.present? && field_34.present? && field_33.present?
rescue Date::Error
Date.new
end
diff --git a/app/services/bulk_upload/lettings/year2024/csv_parser.rb b/app/services/bulk_upload/lettings/year2024/csv_parser.rb
index d8d430755..22caeab02 100644
--- a/app/services/bulk_upload/lettings/year2024/csv_parser.rb
+++ b/app/services/bulk_upload/lettings/year2024/csv_parser.rb
@@ -112,9 +112,11 @@ private
def first_record_start_date
if with_headers?
- Date.new(row_parsers.first.field_10.to_i + 2000, row_parsers.first.field_9.to_i, row_parsers.first.field_8.to_i)
+ year = row_parsers.first.field_10.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_10.to_i + 2000 : row_parsers.first.field_10.to_i
+ Date.new(year, row_parsers.first.field_9.to_i, row_parsers.first.field_8.to_i)
else
- Date.new(rows.first[9].to_i + 2000, rows.first[8].to_i, rows.first[7].to_i)
+ year = rows.first[9].to_s.strip.length.between?(1, 2) ? rows.first[9].to_i + 2000 : rows.first[9].to_i
+ Date.new(year, rows.first[8].to_i, rows.first[7].to_i)
end
end
end
diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb
index a7eb96c61..312a5472a 100644
--- a/app/services/bulk_upload/lettings/year2024/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb
@@ -324,8 +324,8 @@ class BulkUpload::Lettings::Year2024::RowParser
category: :setup,
},
format: {
- with: /\A\d{2}\z/,
- message: I18n.t("validations.setup.startdate.year_not_two_digits"),
+ with: /\A(\d{2}|\d{4})\z/,
+ message: I18n.t("validations.setup.startdate.year_not_two_or_four_digits"),
category: :setup,
unless: -> { field_10.blank? },
},
@@ -686,14 +686,6 @@ private
end
end
- def start_date
- return if field_8.blank? || field_9.blank? || field_10.blank?
-
- Date.parse("20#{field_10.to_s.rjust(2, '0')}-#{field_9}-#{field_8}")
- rescue StandardError
- nil
- end
-
def validate_no_and_dont_know_disabled_needs_conjunction
if field_83 == 1 && field_84 == 1
errors.add(:field_83, I18n.t("validations.household.housingneeds.no_and_dont_know_disabled_needs_conjunction"))
@@ -790,9 +782,9 @@ private
end
def validate_relevant_collection_window
- return if start_date.blank? || bulk_upload.form.blank?
+ return if startdate.blank? || bulk_upload.form.blank?
- unless bulk_upload.form.valid_start_date_for_form?(start_date)
+ unless bulk_upload.form.valid_start_date_for_form?(startdate)
errors.add(:field_8, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
errors.add(:field_9, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
errors.add(:field_10, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup)
@@ -1394,7 +1386,8 @@ private
end
def startdate
- Date.new(field_10 + 2000, field_9, field_8) if field_10.present? && field_9.present? && field_8.present?
+ year = field_10.to_s.strip.length.between?(1, 2) ? field_10 + 2000 : field_10
+ Date.new(year, field_9, field_8) if field_10.present? && field_9.present? && field_8.present?
rescue Date::Error
Date.new
end
@@ -1599,13 +1592,15 @@ private
end
def mrcdate
- Date.new(field_35 + 2000, field_34, field_33) if field_35.present? && field_34.present? && field_33.present?
+ year = field_35.to_s.strip.length.between?(1, 2) ? field_35 + 2000 : field_35
+ Date.new(year, field_34, field_33) if field_35.present? && field_34.present? && field_33.present?
rescue Date::Error
Date.new
end
def voiddate
- Date.new(field_32 + 2000, field_31, field_30) if field_32.present? && field_31.present? && field_30.present?
+ year = field_32.to_s.strip.length.between?(1, 2) ? field_32 + 2000 : field_32
+ Date.new(year, field_31, field_30) if field_32.present? && field_31.present? && field_30.present?
rescue Date::Error
Date.new
end
diff --git a/app/services/bulk_upload/sales/year2023/csv_parser.rb b/app/services/bulk_upload/sales/year2023/csv_parser.rb
index ec7346f92..85d455d01 100644
--- a/app/services/bulk_upload/sales/year2023/csv_parser.rb
+++ b/app/services/bulk_upload/sales/year2023/csv_parser.rb
@@ -111,9 +111,11 @@ private
def first_record_start_date
if with_headers?
- Date.new(row_parsers.first.field_5.to_i + 2000, row_parsers.first.field_4.to_i, row_parsers.first.field_3.to_i)
+ year = row_parsers.first.field_5.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_5.to_i + 2000 : row_parsers.first.field_5.to_i
+ Date.new(year, row_parsers.first.field_4.to_i, row_parsers.first.field_3.to_i)
else
- Date.new(rows.first[3].to_i + 2000, rows.first[2].to_i, rows.first[1].to_i)
+ year = rows.first[3].to_s.strip.length.between?(1, 2) ? rows.first[3].to_i + 2000 : rows.first[3].to_i
+ Date.new(year, rows.first[2].to_i, rows.first[1].to_i)
end
end
end
diff --git a/app/services/bulk_upload/sales/year2023/row_parser.rb b/app/services/bulk_upload/sales/year2023/row_parser.rb
index 6a18512aa..d87c94dce 100644
--- a/app/services/bulk_upload/sales/year2023/row_parser.rb
+++ b/app/services/bulk_upload/sales/year2023/row_parser.rb
@@ -328,8 +328,8 @@ class BulkUpload::Sales::Year2023::RowParser
category: :setup,
},
format: {
- with: /\A\d{2}\z/,
- message: I18n.t("validations.setup.saledate.year_not_two_digits"),
+ with: /\A(\d{2}|\d{4})\z/,
+ message: I18n.t("validations.setup.saledate.year_not_two_or_four_digits"),
category: :setup,
if: proc { field_5.present? },
}, on: :after_log
@@ -954,19 +954,22 @@ private
end
def saledate
- Date.new(field_5 + 2000, field_4, field_3) if field_5.present? && field_4.present? && field_3.present?
+ year = field_5.to_s.strip.length.between?(1, 2) ? field_5 + 2000 : field_5
+ Date.new(year, field_4, field_3) if field_5.present? && field_4.present? && field_3.present?
rescue Date::Error
Date.new
end
def hodate
- Date.new(field_97 + 2000, field_96, field_95) if field_97.present? && field_96.present? && field_95.present?
+ year = field_97.to_s.strip.length.between?(1, 2) ? field_97 + 2000 : field_97
+ Date.new(year, field_96, field_95) if field_97.present? && field_96.present? && field_95.present?
rescue Date::Error
Date.new
end
def exdate
- Date.new(field_94 + 2000, field_93, field_92) if field_94.present? && field_93.present? && field_92.present?
+ year = field_94.to_s.strip.length.between?(1, 2) ? field_94 + 2000 : field_94
+ Date.new(year, field_93, field_92) if field_94.present? && field_93.present? && field_92.present?
rescue Date::Error
Date.new
end
diff --git a/app/services/bulk_upload/sales/year2024/csv_parser.rb b/app/services/bulk_upload/sales/year2024/csv_parser.rb
index 9ba99c19b..4a3cb7ac9 100644
--- a/app/services/bulk_upload/sales/year2024/csv_parser.rb
+++ b/app/services/bulk_upload/sales/year2024/csv_parser.rb
@@ -114,9 +114,11 @@ private
def first_record_start_date
if with_headers?
- Date.new(row_parsers.first.field_6.to_i + 2000, row_parsers.first.field_5.to_i, row_parsers.first.field_4.to_i)
+ year = row_parsers.first.field_6.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_6.to_i + 2000 : row_parsers.first.field_6.to_i
+ Date.new(year, row_parsers.first.field_5.to_i, row_parsers.first.field_4.to_i)
else
- Date.new(rows.first[5].to_i + 2000, rows.first[4].to_i, rows.first[3].to_i)
+ year = rows.first[5].to_s.strip.length.between?(1, 2) ? rows.first[5].to_i + 2000 : rows.first[5].to_i
+ Date.new(year, rows.first[4].to_i, rows.first[3].to_i)
end
end
end
diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb
index fbc99ba02..7b72eef5c 100644
--- a/app/services/bulk_upload/sales/year2024/row_parser.rb
+++ b/app/services/bulk_upload/sales/year2024/row_parser.rb
@@ -320,8 +320,8 @@ class BulkUpload::Sales::Year2024::RowParser
category: :setup,
},
format: {
- with: /\A\d{2}\z/,
- message: I18n.t("validations.setup.saledate.year_not_two_digits"),
+ with: /\A(\d{2}|\d{4})\z/,
+ message: I18n.t("validations.setup.saledate.year_not_two_or_four_digits"),
category: :setup,
if: proc { field_6.present? },
}, on: :after_log
@@ -994,19 +994,22 @@ private
end
def saledate
- Date.new(field_6 + 2000, field_5, field_4) if field_6.present? && field_5.present? && field_4.present?
+ year = field_6.to_s.strip.length.between?(1, 2) ? field_6 + 2000 : field_6
+ Date.new(year, field_5, field_4) if field_6.present? && field_5.present? && field_4.present?
rescue Date::Error
Date.new
end
def hodate
- Date.new(field_96 + 2000, field_95, field_94) if field_96.present? && field_95.present? && field_94.present?
+ year = field_96.to_s.strip.length.between?(1, 2) ? field_96 + 2000 : field_96
+ Date.new(year, field_95, field_94) if field_96.present? && field_95.present? && field_94.present?
rescue Date::Error
Date.new
end
def exdate
- Date.new(field_93 + 2000, field_92, field_91) if field_93.present? && field_92.present? && field_91.present?
+ year = field_93.to_s.strip.length.between?(1, 2) ? field_93 + 2000 : field_93
+ Date.new(year, field_92, field_91) if field_93.present? && field_92.present? && field_91.present?
rescue Date::Error
Date.new
end
@@ -1469,10 +1472,10 @@ private
def validate_buyer1_economic_status
if field_35 == 9
if field_31.present? && field_31.to_i >= 16
- errors.add(:field_35, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
- errors.add(:field_31, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
+ errors.add(:field_35, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
+ errors.add(:field_31, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
else
- errors.add(:field_35, I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "1"))
+ errors.add(:field_35, I18n.t("validations.sales.household.ecstat1.buyer_cannot_be_child"))
end
end
end
@@ -1482,10 +1485,10 @@ private
if field_42 == 9
if field_38.present? && field_38.to_i >= 16
- errors.add(:field_42, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
- errors.add(:field_38, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
+ errors.add(:field_42, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
+ errors.add(:field_38, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
else
- errors.add(:field_42, I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "2"))
+ errors.add(:field_42, I18n.t("validations.sales.household.ecstat2.buyer_cannot_be_child"))
end
end
end
diff --git a/app/services/collection_resources_service.rb b/app/services/collection_resources_service.rb
index 81ab08254..f6762116a 100644
--- a/app/services/collection_resources_service.rb
+++ b/app/services/collection_resources_service.rb
@@ -24,6 +24,11 @@ class CollectionResourcesService
end
def upload_collection_resource(filename, file)
- @storage_service.write_file(filename, file)
+ content_type = MiniMime.lookup_by_filename(filename)&.content_type
+ @storage_service.write_file(filename, file, content_type:)
+ end
+
+ def delete_collection_resource(filename)
+ @storage_service.delete_file(filename)
end
end
diff --git a/app/services/mandatory_collection_resources_service.rb b/app/services/mandatory_collection_resources_service.rb
index 8b34153e9..397e4b5d0 100644
--- a/app/services/mandatory_collection_resources_service.rb
+++ b/app/services/mandatory_collection_resources_service.rb
@@ -27,6 +27,7 @@ class MandatoryCollectionResourcesService
year:,
log_type:,
download_filename: download_filename(resource_type, year, log_type),
+ mandatory: true,
)
end
diff --git a/app/services/storage/local_disk_service.rb b/app/services/storage/local_disk_service.rb
index bb5825340..8e69e2516 100644
--- a/app/services/storage/local_disk_service.rb
+++ b/app/services/storage/local_disk_service.rb
@@ -19,7 +19,9 @@ module Storage
File.open(path, "r")
end
- def write_file(filename, data)
+ # rubocop:disable Lint/UnusedMethodArgument
+ def write_file(filename, data, content_type: nil)
+ # rubocop:enable Lint/UnusedMethodArgument
path = Rails.root.join("tmp/storage", filename)
FileUtils.mkdir_p(path.dirname)
@@ -43,5 +45,11 @@ module Storage
File.exist?(path)
end
+
+ def delete_file(filename)
+ path = Rails.root.join("tmp/storage", filename)
+
+ File.delete(path)
+ end
end
end
diff --git a/app/services/storage/s3_service.rb b/app/services/storage/s3_service.rb
index 88199c0a0..a6eef7d49 100644
--- a/app/services/storage/s3_service.rb
+++ b/app/services/storage/s3_service.rb
@@ -36,12 +36,21 @@ module Storage
.body.read
end
- def write_file(file_name, data)
- @client.put_object(
- body: data,
- bucket: @configuration.bucket_name,
- key: file_name,
- )
+ def write_file(file_name, data, content_type: nil)
+ if content_type.nil?
+ @client.put_object(
+ body: data,
+ bucket: @configuration.bucket_name,
+ key: file_name,
+ )
+ else
+ @client.put_object(
+ body: data,
+ bucket: @configuration.bucket_name,
+ key: file_name,
+ content_type:,
+ )
+ end
end
def get_file_metadata(file_name)
@@ -55,6 +64,10 @@ module Storage
false
end
+ def delete_file(file_name)
+ @client.delete_object(bucket: @configuration.bucket_name, key: file_name)
+ end
+
private
def create_configuration
diff --git a/app/services/storage/storage_service.rb b/app/services/storage/storage_service.rb
index afb3d4a58..37d4cc0fd 100644
--- a/app/services/storage/storage_service.rb
+++ b/app/services/storage/storage_service.rb
@@ -15,5 +15,13 @@ module Storage
def write_file(_file_name, _data)
raise NotImplementedError
end
+
+ def get_file(_file_name, _data)
+ raise NotImplementedError
+ end
+
+ def delete_file(_file_name, _data)
+ raise NotImplementedError
+ end
end
end
diff --git a/app/views/collection_resources/_collection_resource_summary_list.erb b/app/views/collection_resources/_collection_resource_summary_list.erb
index 8ef588fd5..581bb6303 100644
--- a/app/views/collection_resources/_collection_resource_summary_list.erb
+++ b/app/views/collection_resources/_collection_resource_summary_list.erb
@@ -23,10 +23,27 @@
<% end %>
<% end %>
<% end %>
+ <% additional_resources&.each do |resource| %>
+ <% summary_list.with_row do |row| %>
+ <% row.with_key { resource.short_display_name } %>
+ <% row.with_value do %>
+ <%= render DocumentListComponent.new(items: document_list_edit_component_items([resource]), label: "") %>
+ <% end %>
+ <% row.with_action(
+ text: "Change",
+ href: collection_resource_edit_path(resource),
+ ) %>
+ <% row.with_action(
+ text: "Delete",
+ href: collection_resource_delete_confirmation_path(resource),
+ classes: "app-!-colour-red"
+ ) %>
+ <% end %>
+ <% end %>
<% end %>
-
- <%= govuk_link_to "Add new #{mandatory_resources.first.log_type} #{text_year_range_format(mandatory_resources.first.year)} resource", href: "/" %>
+
+ <%= govuk_link_to "Add new #{mandatory_resources.first.log_type} #{text_year_range_format(mandatory_resources.first.year)} resource", href: new_collection_resource_path(year: mandatory_resources.first.year, log_type: mandatory_resources.first.log_type) %>
-
+
diff --git a/app/views/collection_resources/delete_confirmation.html.erb b/app/views/collection_resources/delete_confirmation.html.erb
new file mode 100644
index 000000000..9f861bc19
--- /dev/null
+++ b/app/views/collection_resources/delete_confirmation.html.erb
@@ -0,0 +1,31 @@
+<% content_for :before_content do %>
+ <% content_for :title, "Are you sure you want to delete the #{@collection_resource.short_display_name.downcase}?" %>
+ <%= govuk_back_link href: collection_resources_path %>
+<% end %>
+
+