diff --git a/app/controllers/collection_resources_controller.rb b/app/controllers/collection_resources_controller.rb new file mode 100644 index 000000000..dc7225832 --- /dev/null +++ b/app/controllers/collection_resources_controller.rb @@ -0,0 +1,12 @@ +class CollectionResourcesController < ApplicationController + include CollectionResourcesHelper + + before_action :authenticate_user! + + 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) + end +end diff --git a/app/controllers/start_controller.rb b/app/controllers/start_controller.rb index 0c54013b2..62bb3add7 100644 --- a/app/controllers/start_controller.rb +++ b/app/controllers/start_controller.rb @@ -1,7 +1,10 @@ class StartController < ApplicationController include CollectionTimeHelper + include CollectionResourcesHelper 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) if current_user @homepage_presenter = HomepagePresenter.new(current_user) render "home/index" diff --git a/app/helpers/collection_resources_helper.rb b/app/helpers/collection_resources_helper.rb index 2c4389c38..70b4f0edf 100644 --- a/app/helpers/collection_resources_helper.rb +++ b/app/helpers/collection_resources_helper.rb @@ -54,4 +54,24 @@ module CollectionResourcesHelper def short_underscored_year_range_format(year) "#{year % 100}_#{(year + 1) % 100}" end + + def document_list_component_items(resources) + resources.map do |resource| + { + name: "Download the #{resource.display_name}", + href: send(resource.download_path), + metadata: file_type_size_and_pages(resource.download_filename), + } + end + end + + def document_list_edit_component_items(resources) + resources.map do |resource| + { + name: resource.download_filename, + href: send(resource.download_path), + metadata: file_type_size_and_pages(resource.download_filename), + } + end + end end diff --git a/app/models/collection_resource.rb b/app/models/collection_resource.rb new file mode 100644 index 000000000..8e9740484 --- /dev/null +++ b/app/models/collection_resource.rb @@ -0,0 +1,5 @@ +class CollectionResource + include ActiveModel::Model + + attr_accessor :display_name, :short_display_name, :year, :log_type, :download_filename, :download_path +end diff --git a/app/services/mandatory_collection_resources_service.rb b/app/services/mandatory_collection_resources_service.rb new file mode 100644 index 000000000..199a81ca3 --- /dev/null +++ b/app/services/mandatory_collection_resources_service.rb @@ -0,0 +1,60 @@ +class MandatoryCollectionResourcesService + MANDATORY_RESOURCES = %w[paper_form bulk_upload_template bulk_upload_specification].freeze + + def self.generate_resources(log_type, collection_years) + mandatory_resources_per_year = {} + collection_years.map do |year| + mandatory_resources_per_year[year] = resources_per_year(year, log_type) + end + mandatory_resources_per_year + end + + def self.resources_per_year(year, log_type) + MANDATORY_RESOURCES.map do |resource| + CollectionResource.new( + display_name: display_name(resource, year, log_type), + short_display_name: resource.humanize, + year:, + log_type:, + download_filename: download_filename(resource, year, log_type), + download_path: download_path(resource, year, log_type), + ) + end + end + + def self.display_name(resource, year, log_type) + year_range = "#{year} to #{year + 1}" + case resource + when "paper_form" + "#{log_type} log for tenants (#{year_range})" + when "bulk_upload_template" + "#{log_type} bulk upload template (#{year_range})" + when "bulk_upload_specification" + "#{log_type} bulk upload specification (#{year_range})" + end + end + + def self.download_path(resource, year, log_type) + year_range = "#{year % 100}_#{(year + 1) % 100}" + case resource + when "paper_form" + "download_#{year_range}_#{log_type}_form_path" + when "bulk_upload_template" + "download_#{year_range}_#{log_type}_bulk_upload_template_path" + when "bulk_upload_specification" + "download_#{year_range}_#{log_type}_bulk_upload_specification_path" + end + end + + def self.download_filename(resource, year, log_type) + year_range = "#{year}_#{(year + 1) % 100}" + case resource + when "paper_form" + "#{year_range}_#{log_type}_paper_form.pdf" + when "bulk_upload_template" + "bulk-upload-#{log_type}-template-#{year_range.dasherize}.xlsx" + when "bulk_upload_specification" + "bulk-upload-#{log_type}-specification-#{year_range.dasherize}.xlsx" + 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 new file mode 100644 index 000000000..272a82272 --- /dev/null +++ b/app/views/collection_resources/_collection_resource_summary_list.erb @@ -0,0 +1,14 @@ +<%= govuk_summary_list do |summary_list| %> + <% mandatory_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: "/", + ) %> + <% end %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/collection_resources/index.html.erb b/app/views/collection_resources/index.html.erb new file mode 100644 index 000000000..7ce6d5eb6 --- /dev/null +++ b/app/views/collection_resources/index.html.erb @@ -0,0 +1,23 @@ +<% title = "Collection resources" %> +<% content_for :title, title %> +<% content_for :before_content do %> + <%= govuk_back_link(href: :back) %> +<% end %> + +

<%= title %>

+ +<% @mandatory_lettings_collection_resources_per_year.each do |year, mandatory_resources| %> +

+ Lettings <%= text_year_range_format(year) %> +

+ <%= render partial: "collection_resource_summary_list", locals: { mandatory_resources: } %> +
+<% end %> + +<% @mandatory_sales_collection_resources_per_year.each do |year, mandatory_resources| %> +

+ Sales <%= text_year_range_format(year) %> +

+ <%= render partial: "collection_resource_summary_list", locals: { mandatory_resources: } %> +
+<% end %> diff --git a/app/views/layouts/_collection_resources.html.erb b/app/views/layouts/_collection_resources.html.erb index c49dfe00a..59718d65f 100644 --- a/app/views/layouts/_collection_resources.html.erb +++ b/app/views/layouts/_collection_resources.html.erb @@ -5,56 +5,22 @@ <% else %>

Collection resources

<% end %> -<% collection_resource_years.each do |collection_start_year| %> +<% displayed_collection_resource_years.each do |collection_start_year| %>

Use the <%= collection_start_year %> to <%= collection_start_year + 1 %> forms for lettings that start and sales that complete between 1 April <%= collection_start_year %> and 31 March <%= collection_start_year + 1 %>.

<% end %>
<%= govuk_tabs(title: "Collection resources", classes: %w[app-tab__small-headers]) do |c| %> - <% collection_resource_years.each do |collection_start_year| %> - <% c.with_tab(label: "Lettings #{year_range_format(collection_start_year)}") do %> - <%= render DocumentListComponent.new( - items: [ - { - name: "Download the lettings log for tenants (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_lettings_form_path"), - metadata: file_type_size_and_pages("#{underscored_file_year_format(collection_start_year)}_lettings_paper_form.pdf", number_of_pages: 8), - }, - { - name: "Download the lettings bulk upload template (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_lettings_bulk_upload_template_path"), - metadata: file_type_size_and_pages("bulk-upload-lettings-template-#{dasherised_file_year_format(collection_start_year)}.xlsx"), - }, - { - name: "Download the lettings bulk upload specification (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_lettings_bulk_upload_specification_path"), - metadata: file_type_size_and_pages("bulk-upload-lettings-specification-#{dasherised_file_year_format(collection_start_year)}.xlsx"), - }, - ], - label: "Lettings #{text_year_range_format(collection_start_year)}", - ) %> + <% @mandatory_lettings_collection_resources_per_year.each do |year, resources| %> + <% c.with_tab(label: "Lettings #{year_range_format(year)}") do %> + <%= render DocumentListComponent.new(items: document_list_component_items(resources), label: "Lettings #{text_year_range_format(year)}") %> <% end %> - <% c.with_tab(label: "Sales #{year_range_format(collection_start_year)}") do %> - <%= render DocumentListComponent.new( - items: [ - { - name: "Download the sales log for buyers (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_sales_form_path"), - metadata: file_type_size_and_pages("#{underscored_file_year_format(collection_start_year)}_sales_paper_form.pdf", number_of_pages: 8), - }, - { - name: "Download the sales bulk upload template (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_sales_bulk_upload_template_path"), - metadata: file_type_size_and_pages("bulk-upload-sales-template-#{dasherised_file_year_format(collection_start_year)}.xlsx"), - }, - { - name: "Download the sales bulk upload specification (#{text_year_range_format(collection_start_year)})", - href: send("download_#{short_underscored_year_range_format(collection_start_year)}_sales_bulk_upload_specification_path"), - metadata: file_type_size_and_pages("bulk-upload-sales-specification-#{dasherised_file_year_format(collection_start_year)}.xlsx"), - }, - ], - label: "Sales #{text_year_range_format(collection_start_year)}", - ) %> + <% end %> + <% @mandatory_sales_collection_resources_per_year.each do |year, resources| %> + <% c.with_tab(label: "Sales #{year_range_format(year)}") do %> + <%= render DocumentListComponent.new(items: document_list_component_items(resources), label: "Sales #{text_year_range_format(year)}") %> <% end %> <% end %> <% end %>
+ +<%= govuk_button_link_to "Manage collection resources", collection_resources_path, secondary: true, class: "govuk-!-margin-bottom-2" if current_user.support? %> diff --git a/config/routes.rb b/config/routes.rb index ed6f47bbd..1a5f69ad5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,26 +40,31 @@ Rails.application.routes.draw do get "/service-moved", to: "maintenance#service_moved" get "/service-unavailable", to: "maintenance#service_unavailable" - get "/download-23-24-lettings-form", to: "start#download_23_24_lettings_form" - get "/download-23-24-lettings-bulk-upload-template", to: "start#download_23_24_lettings_bulk_upload_template" get "/download-23-24-lettings-bulk-upload-legacy-template", to: "start#download_23_24_lettings_bulk_upload_legacy_template" - get "/download-23-24-lettings-bulk-upload-specification", to: "start#download_23_24_lettings_bulk_upload_specification" - - get "/download-23-24-sales-form", to: "start#download_23_24_sales_form" - get "/download-23-24-sales-bulk-upload-template", to: "start#download_23_24_sales_bulk_upload_template" get "/download-23-24-sales-bulk-upload-legacy-template", to: "start#download_23_24_sales_bulk_upload_legacy_template" - get "/download-23-24-sales-bulk-upload-specification", to: "start#download_23_24_sales_bulk_upload_specification" - get "/download-24-25-lettings-form", to: "start#download_24_25_lettings_form" - get "/download-24-25-lettings-bulk-upload-template", to: "start#download_24_25_lettings_bulk_upload_template" - get "/download-24-25-lettings-bulk-upload-specification", to: "start#download_24_25_lettings_bulk_upload_specification" + FormHandler.instance.years_of_available_lettings_forms.each do |year| + short_underscored_year = "#{year % 100}_#{(year + 1) % 100}" + short_dasherized_year = short_underscored_year.dasherize + + get "/download-#{short_dasherized_year}-lettings-form", to: "start#download_#{short_underscored_year}_lettings_form" + get "/download-#{short_dasherized_year}-lettings-bulk-upload-template", to: "start#download_#{short_underscored_year}_lettings_bulk_upload_template" + get "/download-#{short_dasherized_year}-lettings-bulk-upload-specification", to: "start#download_#{short_underscored_year}_lettings_bulk_upload_specification" + end + + FormHandler.instance.years_of_available_sales_forms.each do |year| + short_underscored_year = "#{year % 100}_#{(year + 1) % 100}" + short_dasherized_year = short_underscored_year.dasherize - get "/download-24-25-sales-form", to: "start#download_24_25_sales_form" - get "/download-24-25-sales-bulk-upload-template", to: "start#download_24_25_sales_bulk_upload_template" - get "/download-24-25-sales-bulk-upload-specification", to: "start#download_24_25_sales_bulk_upload_specification" + get "/download-#{short_dasherized_year}-sales-form", to: "start#download_#{short_underscored_year}_sales_form" + get "/download-#{short_dasherized_year}-sales-bulk-upload-template", to: "start#download_#{short_underscored_year}_sales_bulk_upload_template" + get "/download-#{short_dasherized_year}-sales-bulk-upload-specification", to: "start#download_#{short_underscored_year}_sales_bulk_upload_specification" + end get "clear-filters", to: "sessions#clear_filters" + get "collection-resources", to: "collection_resources#index" + resource :account, only: %i[show edit], controller: "users" do get "edit/password", to: "users#edit_password" end diff --git a/spec/requests/collection_resources_controller_spec.rb b/spec/requests/collection_resources_controller_spec.rb new file mode 100644 index 000000000..d5b0a72a5 --- /dev/null +++ b/spec/requests/collection_resources_controller_spec.rb @@ -0,0 +1,86 @@ +require "rails_helper" + +RSpec.describe CollectionResourcesController, type: :request do + let(:page) { Capybara::Node::Simple.new(response.body) } + + describe "GET #index" do + context "when user is not signed in" do + it "redirects to the sign in page" do + get collection_resources_path + expect(response).to redirect_to(new_user_session_path) + end + end + + context "when user is signed in as a data coordinator" do + let(:user) { create(:user, :data_coordinator) } + + before do + sign_in user + end + + it "returns page not found" do + get collection_resources_path + expect(response).to have_http_status(:not_found) + end + end + + context "when user is signed in as a data provider" do + let(:user) { create(:user, :data_provider) } + + before do + sign_in user + end + + it "returns page not found" do + get collection_resources_path + expect(response).to have_http_status(:not_found) + end + end + + context "when user is signed in as a support user" do + let(:user) { create(:user, :support) } + + before do + allow(Time.zone).to receive(:today).and_return(Time.zone.local(2025, 1, 8)) + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get collection_resources_path + end + + it "displays collection resources" do + expect(page).to have_content("Lettings 2024 to 2025") + expect(page).to have_content("Lettings 2025 to 2026") + expect(page).to have_content("Sales 2024 to 2025") + expect(page).to have_content("Sales 2025 to 2026") + end + + it "displays mandatory filed" do + expect(page).to have_content("Paper form") + expect(page).to have_content("Bulk upload template") + expect(page).to have_content("Bulk upload specification") + end + + context "when files are on S3" do + it "displays file names with download links" do + expect(page).to have_link("2024_25_lettings_paper_form.pdf", href: download_24_25_lettings_form_path) + expect(page).to have_link("bulk-upload-lettings-template-2024-25.xlsx", href: download_24_25_lettings_bulk_upload_template_path) + expect(page).to have_link("bulk-upload-lettings-specification-2024-25.xlsx", href: download_24_25_lettings_bulk_upload_specification_path) + expect(page).to have_link("2024_25_sales_paper_form.pdf", href: download_24_25_sales_form_path) + expect(page).to have_link("bulk-upload-sales-template-2024-25.xlsx", href: download_24_25_sales_bulk_upload_template_path) + expect(page).to have_link("bulk-upload-sales-specification-2024-25.xlsx", href: download_24_25_sales_bulk_upload_specification_path) + + expect(page).to have_link("2025_26_lettings_paper_form.pdf", href: download_25_26_lettings_form_path) + expect(page).to have_link("bulk-upload-lettings-template-2025-26.xlsx", href: download_25_26_lettings_bulk_upload_template_path) + expect(page).to have_link("bulk-upload-lettings-specification-2025-26.xlsx", href: download_25_26_lettings_bulk_upload_specification_path) + expect(page).to have_link("2025_26_sales_paper_form.pdf", href: download_25_26_sales_form_path) + expect(page).to have_link("bulk-upload-sales-template-2025-26.xlsx", href: download_25_26_sales_bulk_upload_template_path) + expect(page).to have_link("bulk-upload-sales-specification-2025-26.xlsx", href: download_25_26_sales_bulk_upload_specification_path) + end + + it "displays change links" do + expect(page).to have_selector(:link_or_button, "Change", count: 12) + end + end + end + end +end diff --git a/spec/requests/start_controller_spec.rb b/spec/requests/start_controller_spec.rb index f7503f2bd..40f52f59c 100644 --- a/spec/requests/start_controller_spec.rb +++ b/spec/requests/start_controller_spec.rb @@ -367,6 +367,24 @@ RSpec.describe StartController, type: :request do get root_path expect(page).to have_content("About this service") end + + context "with support user" do + let(:user) { create(:user, :support) } + + it "displays link to edit collection resources" do + get root_path + + expect(page).to have_link("Manage collection resources", href: collection_resources_path) + end + end + + context "with data coordinator" do + it "does not display the link to edit collection resources" do + get root_path + + expect(page).not_to have_link("Manage collection resources", href: collection_resources_path) + end + end end end