<% potential_errors, critical_errors = bulk_upload_errors.partition { |error| error.category == "soft_validation" } %>
-
Critical errors
-
These errors must be fixed to complete your logs.
- <%= govuk_table do |table| %>
- <%= table.with_head do |head| %>
- <% head.with_row do |row| %>
- <% row.with_cell(header: true, text: "Cell") %>
- <% row.with_cell(header: true, text: "Question") %>
- <% row.with_cell(header: true, text: "Error") %>
- <% row.with_cell(header: true, text: "Specification") %>
- <% end %>
- <%= table.with_body do |body| %>
- <% critical_errors.each do |error| %>
- <% body.with_row do |row| %>
- <% row.with_cell(text: error.cell) %>
- <% row.with_cell(text: question_for_field(error.field), html_attributes: { class: "govuk-!-width-one-half" }) %>
- <% row.with_cell(text: error.error.html_safe, html_attributes: { class: "govuk-!-font-weight-bold govuk-!-width-one-half" }) %>
- <% row.with_cell(text: error.field.humanize) %>
+ <% if critical_errors.any? %>
+
Critical errors
+
These errors must be fixed to complete your logs.
+ <%= govuk_table do |table| %>
+ <%= table.with_head do |head| %>
+ <% head.with_row do |row| %>
+ <% row.with_cell(header: true, text: "Cell") %>
+ <% row.with_cell(header: true, text: "Question") %>
+ <% row.with_cell(header: true, text: "Error") %>
+ <% row.with_cell(header: true, text: "Specification") %>
+ <% end %>
+
+ <%= table.with_body do |body| %>
+ <% critical_errors.each do |error| %>
+ <% body.with_row do |row| %>
+ <% row.with_cell(text: error.cell) %>
+ <% row.with_cell(text: question_for_field(error.field), html_attributes: { class: "govuk-!-width-one-half" }) %>
+ <% row.with_cell(text: error.error.html_safe, html_attributes: { class: "govuk-!-font-weight-bold govuk-!-width-one-half" }) %>
+ <% row.with_cell(text: error.field.humanize) %>
+ <% end %>
<% end %>
<% end %>
<% end %>
diff --git a/app/views/schemes/index.html.erb b/app/views/schemes/index.html.erb
index d0ae44072..edaed6212 100644
--- a/app/views/schemes/index.html.erb
+++ b/app/views/schemes/index.html.erb
@@ -6,7 +6,9 @@
<%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Supported housing schemes", sub: nil } : { main: "Supported housing schemes", sub: current_user.organisation.name } %>
<% if SchemePolicy.new(current_user, nil).create? %>
- <%= govuk_button_link_to "Create a new supported housing scheme", new_scheme_path, html: { method: :post } %>
+
+ <%= govuk_button_link_to "Create a new supported housing scheme", new_scheme_path, html: { method: :post } %>
+
<% end %>
<%= render partial: "schemes/scheme_filters" %>
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb
index 7da3deda1..4e5053563 100644
--- a/app/views/users/index.html.erb
+++ b/app/views/users/index.html.erb
@@ -6,7 +6,9 @@
<%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Users", sub: nil } : { main: "Users", sub: current_user.organisation.name } %>
<% if current_user.data_coordinator? || current_user.support? %>
- <%= govuk_button_link_to "Invite user", new_user_path, html: { method: :get } %>
+
+ <%= govuk_button_link_to "Invite user", new_user_path, html: { method: :get } %>
+
<% end %>
<%= render partial: "users/user_filters" %>
From e604d358b35502ea7be08ad38e2baeadbaf7ae11 Mon Sep 17 00:00:00 2001
From: Manny Dinssa <44172848+Dinssa@users.noreply.github.com>
Date: Mon, 23 Sep 2024 15:45:35 +0100
Subject: [PATCH 4/6] CLDC-3627 Problem displaying apostrophes in browser tab
title (#2643)
---
app/helpers/application_helper.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index bb119b29e..5a9203da8 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -2,6 +2,7 @@ module ApplicationHelper
include Pagy::Frontend
def browser_title(title, pagy, *resources)
+ title = sanitize(title)&.gsub("&", "&")
if resources.any? { |r| r.present? && r.errors.present? }
"Error: #{[title, t('service_name'), 'GOV.UK'].select(&:present?).join(' - ')}"
else
From 806424992579127dffdee614216ed79d6b9c3af2 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Mon, 23 Sep 2024 16:31:23 +0100
Subject: [PATCH 5/6] Add checked field to log_validations (#2657)
---
db/migrate/20240923145326_add_validation_checked_field.rb | 5 +++++
db/schema.rb | 3 ++-
2 files changed, 7 insertions(+), 1 deletion(-)
create mode 100644 db/migrate/20240923145326_add_validation_checked_field.rb
diff --git a/db/migrate/20240923145326_add_validation_checked_field.rb b/db/migrate/20240923145326_add_validation_checked_field.rb
new file mode 100644
index 000000000..899992974
--- /dev/null
+++ b/db/migrate/20240923145326_add_validation_checked_field.rb
@@ -0,0 +1,5 @@
+class AddValidationCheckedField < ActiveRecord::Migration[7.0]
+ def change
+ add_column :log_validations, :checked, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 80463eaad..cd7708957 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_09_18_112702) do
+ActiveRecord::Schema[7.0].define(version: 2024_09_23_145326) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -410,6 +410,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_09_18_112702) do
t.string "other_validated_models"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.boolean "checked"
end
create_table "logs_exports", force: :cascade do |t|
From d0ce0b87f2390079444a08dd09bd8aa6f81bc4ab Mon Sep 17 00:00:00 2001
From: Manny Dinssa <44172848+Dinssa@users.noreply.github.com>
Date: Tue, 24 Sep 2024 11:21:18 +0100
Subject: [PATCH 6/6] CLDC 3623 Support user bulk uploading (#2629)
---
.../create_log_actions_component.html.erb | 2 +-
.../bulk_upload_lettings_logs_controller.rb | 6 +--
.../bulk_upload_sales_logs_controller.rb | 6 +--
.../bulk_upload_lettings/checking_file.rb | 7 ++-
.../forms/bulk_upload_lettings/guidance.rb | 3 +-
.../forms/bulk_upload_lettings/needstype.rb | 5 +-
.../bulk_upload_lettings/prepare_your_file.rb | 8 +--
.../bulk_upload_lettings/upload_your_file.rb | 7 +--
app/models/forms/bulk_upload_lettings/year.rb | 9 +++-
.../forms/bulk_upload_sales/checking_file.rb | 7 ++-
.../forms/bulk_upload_sales/guidance.rb | 3 +-
.../bulk_upload_sales/prepare_your_file.rb | 7 ++-
.../bulk_upload_sales/upload_your_file.rb | 6 ++-
app/models/forms/bulk_upload_sales/year.rb | 9 +++-
.../lettings/year2024/row_parser.rb | 28 +++++++---
.../bulk_upload/sales/year2024/row_parser.rb | 28 +++++++---
.../forms/checking_file.html.erb | 1 +
.../forms/needstype.erb | 1 +
.../forms/prepare_your_file_2024.html.erb | 1 +
.../forms/upload_your_file.html.erb | 1 +
.../forms/year.html.erb | 1 +
.../show.html.erb | 2 +-
.../summary.html.erb | 2 +-
.../forms/checking_file.html.erb | 1 +
.../forms/prepare_your_file_2024.html.erb | 1 +
.../forms/upload_your_file.html.erb | 1 +
.../forms/year.html.erb | 1 +
.../bulk_upload_sales_results/show.html.erb | 2 +-
.../summary.html.erb | 2 +-
.../logs/_create_for_org_actions.html.erb | 10 ++--
...332_add_organisation_id_to_bulk_uploads.rb | 5 ++
db/schema.rb | 1 +
spec/factories/bulk_upload.rb | 1 +
spec/features/organisation_spec.rb | 8 +++
.../lettings/year2024/row_parser_spec.rb | 54 +++++++++++++++++++
.../sales/year2024/row_parser_spec.rb | 54 +++++++++++++++++++
36 files changed, 244 insertions(+), 47 deletions(-)
create mode 100644 db/migrate/20240905092332_add_organisation_id_to_bulk_uploads.rb
diff --git a/app/components/create_log_actions_component.html.erb b/app/components/create_log_actions_component.html.erb
index 1b6bd8aca..5a90587ed 100644
--- a/app/components/create_log_actions_component.html.erb
+++ b/app/components/create_log_actions_component.html.erb
@@ -3,7 +3,7 @@
<% if create_button_href.present? %>
<%= govuk_button_to create_button_copy, create_button_href, class: "govuk-!-margin-right-6" %>
<% end %>
- <% if upload_button_href.present? %>
+ <% if upload_button_href.present? && !user.support? %>
<%= govuk_button_link_to upload_button_copy, upload_button_href, secondary: true %>
<% end %>
diff --git a/app/controllers/bulk_upload_lettings_logs_controller.rb b/app/controllers/bulk_upload_lettings_logs_controller.rb
index 465bbc5f6..a8ad14f9e 100644
--- a/app/controllers/bulk_upload_lettings_logs_controller.rb
+++ b/app/controllers/bulk_upload_lettings_logs_controller.rb
@@ -4,9 +4,9 @@ class BulkUploadLettingsLogsController < ApplicationController
def start
if have_choice_of_year?
- redirect_to bulk_upload_lettings_log_path(id: "year")
+ redirect_to bulk_upload_lettings_log_path(id: "year", form: { organisation_id: params[:organisation_id] }.compact)
else
- redirect_to bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: current_year })
+ redirect_to bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: current_year, organisation_id: params[:organisation_id] }.compact)
end
end
@@ -60,6 +60,6 @@ private
end
def form_params
- params.fetch(:form, {}).permit(:year, :needstype, :file)
+ params.fetch(:form, {}).permit(:year, :needstype, :file, :organisation_id)
end
end
diff --git a/app/controllers/bulk_upload_sales_logs_controller.rb b/app/controllers/bulk_upload_sales_logs_controller.rb
index 56bd1d4de..2fd312d10 100644
--- a/app/controllers/bulk_upload_sales_logs_controller.rb
+++ b/app/controllers/bulk_upload_sales_logs_controller.rb
@@ -4,9 +4,9 @@ class BulkUploadSalesLogsController < ApplicationController
def start
if have_choice_of_year?
- redirect_to bulk_upload_sales_log_path(id: "year")
+ redirect_to bulk_upload_sales_log_path(id: "year", form: { organisation_id: params[:organisation_id] }.compact)
else
- redirect_to bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: current_year })
+ redirect_to bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: current_year, organisation_id: params[:organisation_id] }.compact)
end
end
@@ -58,6 +58,6 @@ private
end
def form_params
- params.fetch(:form, {}).permit(:year, :file)
+ params.fetch(:form, {}).permit(:year, :file, :organisation_id)
end
end
diff --git a/app/models/forms/bulk_upload_lettings/checking_file.rb b/app/models/forms/bulk_upload_lettings/checking_file.rb
index 8cd9ee696..3b43cb269 100644
--- a/app/models/forms/bulk_upload_lettings/checking_file.rb
+++ b/app/models/forms/bulk_upload_lettings/checking_file.rb
@@ -6,13 +6,18 @@ module Forms
include Rails.application.routes.url_helpers
attribute :year, :integer
+ attribute :organisation_id, :integer
def view_path
"bulk_upload_lettings_logs/forms/checking_file"
end
def back_path
- bulk_upload_lettings_log_path(id: "start")
+ if organisation_id.present?
+ lettings_logs_organisation_path(organisation_id)
+ else
+ bulk_upload_lettings_log_path(id: "start")
+ end
end
def year_combo
diff --git a/app/models/forms/bulk_upload_lettings/guidance.rb b/app/models/forms/bulk_upload_lettings/guidance.rb
index b6cf5bf74..24bc531f2 100644
--- a/app/models/forms/bulk_upload_lettings/guidance.rb
+++ b/app/models/forms/bulk_upload_lettings/guidance.rb
@@ -7,6 +7,7 @@ module Forms
attribute :year, :integer
attribute :referrer
+ attribute :organisation_id, :integer
def view_path
"bulk_upload_shared/guidance"
@@ -15,7 +16,7 @@ module Forms
def back_path
case referrer
when "prepare-your-file"
- bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: })
+ bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year:, organisation_id: }.compact)
when "home"
root_path
else
diff --git a/app/models/forms/bulk_upload_lettings/needstype.rb b/app/models/forms/bulk_upload_lettings/needstype.rb
index 0cadd647c..32ed0acf3 100644
--- a/app/models/forms/bulk_upload_lettings/needstype.rb
+++ b/app/models/forms/bulk_upload_lettings/needstype.rb
@@ -7,6 +7,7 @@ module Forms
attribute :needstype, :integer
attribute :year, :integer
+ attribute :organisation_id, :integer
validates :needstype, presence: true
@@ -19,11 +20,11 @@ module Forms
end
def back_path
- bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year:, needstype: })
+ bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year:, needstype:, organisation_id: }.compact)
end
def next_path
- bulk_upload_lettings_log_path(id: "upload-your-file", form: { year:, needstype: })
+ bulk_upload_lettings_log_path(id: "upload-your-file", form: { year:, needstype:, organisation_id: }.compact)
end
def year_combo
diff --git a/app/models/forms/bulk_upload_lettings/prepare_your_file.rb b/app/models/forms/bulk_upload_lettings/prepare_your_file.rb
index b5069d908..159436ce1 100644
--- a/app/models/forms/bulk_upload_lettings/prepare_your_file.rb
+++ b/app/models/forms/bulk_upload_lettings/prepare_your_file.rb
@@ -7,6 +7,7 @@ module Forms
attribute :year, :integer
attribute :needstype, :integer
+ attribute :organisation_id, :integer
def view_path
case year
@@ -19,15 +20,16 @@ module Forms
def back_path
if have_choice_of_year?
- Rails.application.routes.url_helpers.bulk_upload_lettings_log_path(id: "year", form: { year: })
+ Rails.application.routes.url_helpers.bulk_upload_lettings_log_path(id: "year", form: { year:, organisation_id: }.compact)
+ elsif organisation_id.present?
+ lettings_logs_organisation_path(organisation_id)
else
Rails.application.routes.url_helpers.lettings_logs_path
end
end
def next_path
- page_id = year == 2022 ? "needstype" : "upload-your-file"
- bulk_upload_lettings_log_path(id: page_id, form: { year:, needstype: })
+ bulk_upload_lettings_log_path(id: "upload-your-file", form: { year:, needstype:, organisation_id: }.compact)
end
def legacy_template_path
diff --git a/app/models/forms/bulk_upload_lettings/upload_your_file.rb b/app/models/forms/bulk_upload_lettings/upload_your_file.rb
index 9ccec7622..954c6e6e6 100644
--- a/app/models/forms/bulk_upload_lettings/upload_your_file.rb
+++ b/app/models/forms/bulk_upload_lettings/upload_your_file.rb
@@ -11,6 +11,7 @@ module Forms
attribute :needstype, :integer
attribute :file
attribute :current_user
+ attribute :organisation_id, :integer
validates :file, presence: true
validate :validate_file_is_csv
@@ -20,8 +21,7 @@ module Forms
end
def back_path
- page_id = year == 2022 ? "needstype" : "prepare-your-file"
- bulk_upload_lettings_log_path(id: page_id, form: { year:, needstype: })
+ bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year:, needstype:, organisation_id: }.compact)
end
def year_combo
@@ -29,7 +29,7 @@ module Forms
end
def next_path
- bulk_upload_lettings_log_path(id: "checking-file", form: { year: })
+ bulk_upload_lettings_log_path(id: "checking-file", form: { year:, organisation_id: }.compact)
end
def save!
@@ -39,6 +39,7 @@ module Forms
year:,
needstype:,
filename: file.original_filename,
+ organisation_id: (organisation_id if current_user.support?) || current_user.organisation_id,
)
storage_service.write_file(bulk_upload.identifier, File.read(file.path))
diff --git a/app/models/forms/bulk_upload_lettings/year.rb b/app/models/forms/bulk_upload_lettings/year.rb
index e199559fa..396b91a79 100644
--- a/app/models/forms/bulk_upload_lettings/year.rb
+++ b/app/models/forms/bulk_upload_lettings/year.rb
@@ -6,6 +6,7 @@ module Forms
include Rails.application.routes.url_helpers
attribute :year, :integer
+ attribute :organisation_id, :integer
validates :year, presence: true
@@ -20,11 +21,15 @@ module Forms
end
def back_path
- lettings_logs_path
+ if organisation_id.present?
+ lettings_logs_organisation_path(organisation_id)
+ else
+ lettings_logs_path
+ end
end
def next_path
- bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: })
+ bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year:, organisation_id: }.compact)
end
def save!
diff --git a/app/models/forms/bulk_upload_sales/checking_file.rb b/app/models/forms/bulk_upload_sales/checking_file.rb
index a37be3ccb..243d64070 100644
--- a/app/models/forms/bulk_upload_sales/checking_file.rb
+++ b/app/models/forms/bulk_upload_sales/checking_file.rb
@@ -6,13 +6,18 @@ module Forms
include Rails.application.routes.url_helpers
attribute :year, :integer
+ attribute :organisation_id, :integer
def view_path
"bulk_upload_sales_logs/forms/checking_file"
end
def back_path
- bulk_upload_sales_log_path(id: "start")
+ if organisation_id.present?
+ sales_logs_organisation_path(organisation_id)
+ else
+ bulk_upload_sales_log_path(id: "start")
+ end
end
def year_combo
diff --git a/app/models/forms/bulk_upload_sales/guidance.rb b/app/models/forms/bulk_upload_sales/guidance.rb
index 28ca6c3b5..ef792a3e4 100644
--- a/app/models/forms/bulk_upload_sales/guidance.rb
+++ b/app/models/forms/bulk_upload_sales/guidance.rb
@@ -7,6 +7,7 @@ module Forms
attribute :year, :integer
attribute :referrer
+ attribute :organisation_id, :integer
def view_path
"bulk_upload_shared/guidance"
@@ -15,7 +16,7 @@ module Forms
def back_path
case referrer
when "prepare-your-file"
- bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: })
+ bulk_upload_sales_log_path(id: "prepare-your-file", form: { year:, organisation_id: }.compact)
when "home"
root_path
else
diff --git a/app/models/forms/bulk_upload_sales/prepare_your_file.rb b/app/models/forms/bulk_upload_sales/prepare_your_file.rb
index 387f6239f..4bf0797a8 100644
--- a/app/models/forms/bulk_upload_sales/prepare_your_file.rb
+++ b/app/models/forms/bulk_upload_sales/prepare_your_file.rb
@@ -6,6 +6,7 @@ module Forms
include Rails.application.routes.url_helpers
attribute :year, :integer
+ attribute :organisation_id, :integer
def view_path
case year
@@ -18,14 +19,16 @@ module Forms
def back_path
if have_choice_of_year?
- Rails.application.routes.url_helpers.bulk_upload_sales_log_path(id: "year", form: { year: })
+ Rails.application.routes.url_helpers.bulk_upload_sales_log_path(id: "year", form: { year: }.compact)
+ elsif organisation_id.present?
+ sales_logs_organisation_path(organisation_id)
else
Rails.application.routes.url_helpers.sales_logs_path
end
end
def next_path
- bulk_upload_sales_log_path(id: "upload-your-file", form: { year: })
+ bulk_upload_sales_log_path(id: "upload-your-file", form: { year:, organisation_id: }.compact)
end
def legacy_template_path
diff --git a/app/models/forms/bulk_upload_sales/upload_your_file.rb b/app/models/forms/bulk_upload_sales/upload_your_file.rb
index de650c831..5a0114caf 100644
--- a/app/models/forms/bulk_upload_sales/upload_your_file.rb
+++ b/app/models/forms/bulk_upload_sales/upload_your_file.rb
@@ -10,6 +10,7 @@ module Forms
attribute :year, :integer
attribute :file
attribute :current_user
+ attribute :organisation_id, :integer
validates :file, presence: true
validate :validate_file_is_csv
@@ -19,7 +20,7 @@ module Forms
end
def back_path
- bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: })
+ bulk_upload_sales_log_path(id: "prepare-your-file", form: { year:, organisation_id: }.compact)
end
def year_combo
@@ -27,7 +28,7 @@ module Forms
end
def next_path
- bulk_upload_sales_log_path(id: "checking-file", form: { year: })
+ bulk_upload_sales_log_path(id: "checking-file", form: { year:, organisation_id: }.compact)
end
def save!
@@ -36,6 +37,7 @@ module Forms
log_type: BulkUpload.log_types[:sales],
year:,
filename: file.original_filename,
+ organisation_id: (organisation_id if current_user.support?) || current_user.organisation_id,
)
storage_service.write_file(bulk_upload.identifier, File.read(file.path))
diff --git a/app/models/forms/bulk_upload_sales/year.rb b/app/models/forms/bulk_upload_sales/year.rb
index 85959c4e5..1de8dec04 100644
--- a/app/models/forms/bulk_upload_sales/year.rb
+++ b/app/models/forms/bulk_upload_sales/year.rb
@@ -6,6 +6,7 @@ module Forms
include Rails.application.routes.url_helpers
attribute :year, :integer
+ attribute :organisation_id, :integer
validates :year, presence: true
@@ -20,11 +21,15 @@ module Forms
end
def back_path
- sales_logs_path
+ if organisation_id.present?
+ sales_logs_organisation_path(organisation_id)
+ else
+ sales_logs_path
+ end
end
def next_path
- bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: })
+ bulk_upload_sales_log_path(id: "prepare-your-file", form: { year:, organisation_id: }.compact)
end
def save!
diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb
index 8fc913055..dc0b2dca3 100644
--- a/app/services/bulk_upload/lettings/year2024/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb
@@ -432,6 +432,7 @@ class BulkUpload::Lettings::Year2024::RowParser
validate :validate_assigned_to_exists, on: :after_log
validate :validate_assigned_to_related, on: :after_log
+ validate :validate_assigned_to_when_support, on: :after_log
validate :validate_all_charges_given, on: :after_log, if: proc { is_carehome.zero? }
validate :validate_address_option_found, on: :after_log, unless: -> { supported_housing? }
@@ -582,6 +583,12 @@ private
end
end
+ def validate_assigned_to_when_support
+ if field_3.blank? && bulk_upload.user.support?
+ errors.add(:field_3, category: :setup, message: I18n.t("validations.not_answered", question: "what is the CORE username of the account this letting log should be assigned to?"))
+ end
+ end
+
def validate_assigned_to_related
return unless assigned_to
return if assigned_to.organisation == owning_organisation || assigned_to.organisation == managing_organisation
@@ -891,12 +898,17 @@ private
end
def validate_owning_org_permitted
- if owning_organisation && !bulk_upload.user.organisation.affiliated_stock_owners.include?(owning_organisation)
- block_log_creation!
+ return unless owning_organisation
+ return if bulk_upload_organisation.affiliated_stock_owners.include?(owning_organisation)
- if errors[:field_1].blank?
- errors.add(:field_1, "You do not have permission to add logs for this owning organisation", category: :setup)
- end
+ block_log_creation!
+
+ return if errors[:field_1].present?
+
+ if bulk_upload.user.support?
+ errors.add(:field_1, "This owning organisation is not affiliated with #{bulk_upload_organisation.name}", category: :setup)
+ else
+ errors.add(:field_1, "You do not have permission to add logs for this owning organisation", category: :setup)
end
end
@@ -1137,7 +1149,7 @@ private
attributes["renewal"] = renewal
attributes["scheme"] = scheme
attributes["location"] = location
- attributes["assigned_to"] = assigned_to || bulk_upload.user
+ attributes["assigned_to"] = assigned_to || (bulk_upload.user.support? ? nil : bulk_upload.user)
attributes["created_by"] = bulk_upload.user
attributes["needstype"] = field_4
attributes["rent_type"] = RENT_TYPE_BU_MAPPING[field_11]
@@ -1625,4 +1637,8 @@ private
def reason_is_other?
field_98 == 20
end
+
+ def bulk_upload_organisation
+ Organisation.find(bulk_upload.organisation_id)
+ 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 8be08d62f..0b7a70c27 100644
--- a/app/services/bulk_upload/sales/year2024/row_parser.rb
+++ b/app/services/bulk_upload/sales/year2024/row_parser.rb
@@ -462,6 +462,7 @@ class BulkUpload::Sales::Year2024::RowParser
validate :validate_assigned_to_exists, on: :after_log
validate :validate_assigned_to_related, on: :after_log
+ validate :validate_assigned_to_when_support, on: :after_log
validate :validate_managing_org_related, on: :after_log
validate :validate_relevant_collection_window, on: :after_log
validate :validate_incomplete_soft_validations, on: :after_log
@@ -925,7 +926,7 @@ private
attributes["owning_organisation"] = owning_organisation
attributes["managing_organisation"] = managing_organisation
- attributes["assigned_to"] = assigned_to || bulk_upload.user
+ attributes["assigned_to"] = assigned_to || (bulk_upload.user.support? ? nil : bulk_upload.user)
attributes["created_by"] = bulk_upload.user
attributes["hhregres"] = field_72
attributes["hhregresstill"] = field_73
@@ -1302,12 +1303,17 @@ private
end
def validate_owning_org_permitted
- if owning_organisation && !bulk_upload.user.organisation.affiliated_stock_owners.include?(owning_organisation)
- block_log_creation!
+ return unless owning_organisation
+ return if bulk_upload_organisation.affiliated_stock_owners.include?(owning_organisation)
- if errors[:field_1].blank?
- errors.add(:field_1, "You do not have permission to add logs for this owning organisation", category: :setup)
- end
+ block_log_creation!
+
+ return if errors[:field_1].present?
+
+ if bulk_upload.user.support?
+ errors.add(:field_1, "This owning organisation is not affiliated with #{bulk_upload_organisation.name}", category: :setup)
+ else
+ errors.add(:field_1, "You do not have permission to add logs for this owning organisation", category: :setup)
end
end
@@ -1319,6 +1325,12 @@ private
end
end
+ def validate_assigned_to_when_support
+ if field_3.blank? && bulk_upload.user.support?
+ errors.add(:field_3, category: :setup, message: I18n.t("validations.not_answered", question: "what is the CORE username of the account this sales log should be assigned to?"))
+ end
+ end
+
def validate_assigned_to_related
return unless assigned_to
return if assigned_to.organisation == owning_organisation || assigned_to.organisation == managing_organisation
@@ -1492,4 +1504,8 @@ private
def valid_nationality_options
%w[0] + GlobalConstants::COUNTRIES_ANSWER_OPTIONS.keys # 0 is "Prefers not to say"
end
+
+ def bulk_upload_organisation
+ Organisation.find(bulk_upload.organisation_id)
+ end
end
diff --git a/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb b/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb
index 7524072a5..2e6d4cd10 100644
--- a/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb
+++ b/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb
@@ -6,6 +6,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "prepare-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %>
Upload lettings logs in bulk (<%= @form.year_combo %>)
We’re checking the file
diff --git a/app/views/bulk_upload_lettings_logs/forms/needstype.erb b/app/views/bulk_upload_lettings_logs/forms/needstype.erb
index 6deec7e1d..644dd9f5f 100644
--- a/app/views/bulk_upload_lettings_logs/forms/needstype.erb
+++ b/app/views/bulk_upload_lettings_logs/forms/needstype.erb
@@ -7,6 +7,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "needstype"), method: :patch do |f| %>
<%= f.govuk_error_summary %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %>
<%= f.govuk_collection_radio_buttons :needstype,
@form.options,
diff --git a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb b/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb
index 45ce4b385..7657396f1 100644
--- a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb
+++ b/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb
@@ -6,6 +6,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "prepare-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %>
Upload lettings logs in bulk (<%= @form.year_combo %>)
Prepare your file
diff --git a/app/views/bulk_upload_lettings_logs/forms/upload_your_file.html.erb b/app/views/bulk_upload_lettings_logs/forms/upload_your_file.html.erb
index bbafc28b3..2814eb1ea 100644
--- a/app/views/bulk_upload_lettings_logs/forms/upload_your_file.html.erb
+++ b/app/views/bulk_upload_lettings_logs/forms/upload_your_file.html.erb
@@ -7,6 +7,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "upload-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
<%= f.hidden_field :needstype %>
+ <%= f.hidden_field :organisation_id %>
<%= f.govuk_error_summary %>
diff --git a/app/views/bulk_upload_lettings_logs/forms/year.html.erb b/app/views/bulk_upload_lettings_logs/forms/year.html.erb
index 8ba1c280f..4fef16dd7 100644
--- a/app/views/bulk_upload_lettings_logs/forms/year.html.erb
+++ b/app/views/bulk_upload_lettings_logs/forms/year.html.erb
@@ -4,6 +4,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "year"), method: :patch do |f| %>
<%= f.govuk_error_summary %>
+ <%= f.hidden_field :organisation_id %>
<%= f.govuk_collection_radio_buttons :year,
@form.options,
diff --git a/app/views/bulk_upload_lettings_results/show.html.erb b/app/views/bulk_upload_lettings_results/show.html.erb
index 30a6fd585..15c486b91 100644
--- a/app/views/bulk_upload_lettings_results/show.html.erb
+++ b/app/views/bulk_upload_lettings_results/show.html.erb
@@ -25,4 +25,4 @@
-<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path %>
+<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path(organisation_id: @bulk_upload.organisation_id) %>
diff --git a/app/views/bulk_upload_lettings_results/summary.html.erb b/app/views/bulk_upload_lettings_results/summary.html.erb
index b144793bf..8a59e8999 100644
--- a/app/views/bulk_upload_lettings_results/summary.html.erb
+++ b/app/views/bulk_upload_lettings_results/summary.html.erb
@@ -29,4 +29,4 @@
<% end %>
-<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path %>
+<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path(organisation_id: @bulk_upload.organisation_id) %>
diff --git a/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb b/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb
index c47a97d5e..8bcef5cad 100644
--- a/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb
+++ b/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb
@@ -6,6 +6,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "prepare-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %><%= f.hidden_field :organisation_id %>
Upload sales logs in bulk (<%= @form.year_combo %>)
We’re checking the file
diff --git a/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2024.html.erb b/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2024.html.erb
index 81c947e15..2a64de689 100644
--- a/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2024.html.erb
+++ b/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2024.html.erb
@@ -6,6 +6,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "prepare-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %>
Upload sales logs in bulk (<%= @form.year_combo %>)
Prepare your file
diff --git a/app/views/bulk_upload_sales_logs/forms/upload_your_file.html.erb b/app/views/bulk_upload_sales_logs/forms/upload_your_file.html.erb
index 36e7240dc..75350ae9e 100644
--- a/app/views/bulk_upload_sales_logs/forms/upload_your_file.html.erb
+++ b/app/views/bulk_upload_sales_logs/forms/upload_your_file.html.erb
@@ -6,6 +6,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "upload-your-file"), method: :patch do |f| %>
<%= f.hidden_field :year %>
+ <%= f.hidden_field :organisation_id %>
<%= f.govuk_error_summary %>
diff --git a/app/views/bulk_upload_sales_logs/forms/year.html.erb b/app/views/bulk_upload_sales_logs/forms/year.html.erb
index d8aa09172..2aaa7c0f8 100644
--- a/app/views/bulk_upload_sales_logs/forms/year.html.erb
+++ b/app/views/bulk_upload_sales_logs/forms/year.html.erb
@@ -4,6 +4,7 @@
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "year"), method: :patch do |f| %>
<%= f.govuk_error_summary %>
+ <%= f.hidden_field :organisation_id %>
<%= f.govuk_collection_radio_buttons :year,
@form.options,
diff --git a/app/views/bulk_upload_sales_results/show.html.erb b/app/views/bulk_upload_sales_results/show.html.erb
index 0d645db33..776fdfa2f 100644
--- a/app/views/bulk_upload_sales_results/show.html.erb
+++ b/app/views/bulk_upload_sales_results/show.html.erb
@@ -25,4 +25,4 @@
-<%= govuk_button_link_to "Upload your file again", start_bulk_upload_sales_logs_path %>
+<%= govuk_button_link_to "Upload your file again", start_bulk_upload_sales_logs_path(organisation_id: @bulk_upload.organisation_id) %>
diff --git a/app/views/bulk_upload_sales_results/summary.html.erb b/app/views/bulk_upload_sales_results/summary.html.erb
index 0fa51b9dc..0e423621d 100644
--- a/app/views/bulk_upload_sales_results/summary.html.erb
+++ b/app/views/bulk_upload_sales_results/summary.html.erb
@@ -29,4 +29,4 @@
<% end %>
-<%= govuk_button_link_to "Upload your file again", start_bulk_upload_sales_logs_path %>
+<%= govuk_button_link_to "Upload your file again", start_bulk_upload_sales_logs_path(organisation_id: @bulk_upload.organisation_id) %>
diff --git a/app/views/logs/_create_for_org_actions.html.erb b/app/views/logs/_create_for_org_actions.html.erb
index f6ed9ad82..0564e678a 100644
--- a/app/views/logs/_create_for_org_actions.html.erb
+++ b/app/views/logs/_create_for_org_actions.html.erb
@@ -1,10 +1,12 @@
<% if @organisation.data_protection_confirmed? %>
<% if current_page?(controller: 'organisations', action: 'lettings_logs') %>
- <%= govuk_button_to "Create a new lettings log for this organisation", lettings_logs_path(lettings_log: { owning_organisation_id: @organisation.id }, method: :post) %>
- <% end %>
+ <%= govuk_button_to "Create a new lettings log for this organisation", lettings_logs_path(lettings_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %>
+ <%= govuk_button_link_to "Upload lettings logs in bulk", bulk_upload_lettings_log_path(id: "start", organisation_id: @organisation.id), secondary: true %>
+<% end %>
<% if current_page?(controller: 'organisations', action: 'sales_logs') %>
- <%= govuk_button_to "Create a new sales log for this organisation", sales_logs_path(sales_log: { owning_organisation_id: @organisation.id }, method: :post) %>
- <% end %>
+ <%= govuk_button_to "Create a new sales log for this organisation", sales_logs_path(sales_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %>
+ <%= govuk_button_link_to "Upload sales logs in bulk", bulk_upload_sales_log_path(id: "start", organisation_id: @organisation.id), secondary: true %>
+<% end %>
<% end %>
diff --git a/db/migrate/20240905092332_add_organisation_id_to_bulk_uploads.rb b/db/migrate/20240905092332_add_organisation_id_to_bulk_uploads.rb
new file mode 100644
index 000000000..d9f4f16da
--- /dev/null
+++ b/db/migrate/20240905092332_add_organisation_id_to_bulk_uploads.rb
@@ -0,0 +1,5 @@
+class AddOrganisationIdToBulkUploads < ActiveRecord::Migration[7.0]
+ def change
+ add_column :bulk_uploads, :organisation_id, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cd7708957..4d6f18b84 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -42,6 +42,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_09_23_145326) do
t.text "choice"
t.integer "total_logs_count"
t.string "rent_type_fix_status", default: "not_applied"
+ t.integer "organisation_id"
t.integer "moved_user_id"
t.index ["identifier"], name: "index_bulk_uploads_on_identifier", unique: true
t.index ["user_id"], name: "index_bulk_uploads_on_user_id"
diff --git a/spec/factories/bulk_upload.rb b/spec/factories/bulk_upload.rb
index c848fb071..cefe95c2b 100644
--- a/spec/factories/bulk_upload.rb
+++ b/spec/factories/bulk_upload.rb
@@ -9,6 +9,7 @@ FactoryBot.define do
sequence(:filename) { |n| "bulk-upload-#{n}.csv" }
needstype { 1 }
rent_type_fix_status { BulkUpload.rent_type_fix_statuses.values.sample }
+ organisation_id { user.organisation_id }
trait(:sales) do
log_type { BulkUpload.log_types[:sales] }
diff --git a/spec/features/organisation_spec.rb b/spec/features/organisation_spec.rb
index 1867285eb..3d65cda87 100644
--- a/spec/features/organisation_spec.rb
+++ b/spec/features/organisation_spec.rb
@@ -139,6 +139,10 @@ RSpec.describe "User Features" do
expect(page).to have_button("Create a new lettings log for this organisation")
end
+ it "shows a upload lettings logs in bulk link" do
+ expect(page).to have_link("Upload lettings logs in bulk")
+ end
+
context "when creating a log for that organisation" do
it "pre-fills the value for owning organisation for that log" do
click_button("Create a new lettings log for this organisation")
@@ -230,6 +234,10 @@ RSpec.describe "User Features" do
expect(page).to have_button("Create a new sales log for this organisation")
end
+ it "shows a upload sales logs in bulk link" do
+ expect(page).to have_link("Upload sales logs in bulk")
+ end
+
context "when creating a log for that organisation" do
it "pre-fills the value for owning organisation for that log" do
click_button("Create a new sales log for this organisation")
diff --git a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
index 3faa0a699..68de5d22b 100644
--- a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
@@ -815,6 +815,23 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
end
end
+ context "when blank and bulk upload user is support" do
+ let(:bulk_upload) { create(:bulk_upload, :sales, user: create(:user, :support), year: 2024) }
+
+ let(:attributes) { setup_section_params.merge(bulk_upload:, field_3: nil) }
+
+ it "is not permitted" do
+ parser.valid?
+ expect(parser.errors[:field_3]).to be_present
+ expect(parser.errors[:field_3]).to include("You must answer what is the CORE username of the account this letting log should be assigned to?")
+ end
+
+ it "blocks log creation" do
+ parser.valid?
+ expect(parser).to be_block_log_creation
+ end
+ end
+
context "when user could not be found" do
let(:attributes) { { bulk_upload:, field_3: "idonotexist@example.com" } }
@@ -1439,6 +1456,43 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
expect(parser.errors[:field_10]).to include(/Enter a date when the owning and managing organisation was active/)
end
end
+
+ context "when user is an unaffiliated non-support user and bulk upload organisation is affiliated with the owning organisation" do
+ let(:affiliated_org) { create(:organisation, :with_old_visible_id) }
+ let(:unaffiliated_user) { create(:user, organisation: create(:organisation)) }
+ let(:attributes) { { bulk_upload:, field_1: affiliated_org.old_visible_id } }
+ let(:organisation_id) { unaffiliated_user.organisation_id }
+
+ before do
+ create(:organisation_relationship, parent_organisation: owning_org, child_organisation: affiliated_org)
+ bulk_upload.update!(organisation_id:, user: unaffiliated_user)
+ end
+
+ it "blocks log creation and adds an error to field_1" do
+ parser = described_class.new(attributes)
+ parser.valid?
+ expect(parser).to be_block_log_creation
+ expect(parser.errors[:field_1]).to include("You do not have permission to add logs for this owning organisation")
+ end
+ end
+
+ context "when user is an unaffiliated support user and bulk upload organisation is affiliated with the owning organisation" do
+ let(:affiliated_org) { create(:organisation, :with_old_visible_id) }
+ let(:unaffiliated_support_user) { create(:user, :support, organisation: create(:organisation)) }
+ let(:attributes) { { bulk_upload:, field_1: affiliated_org.old_visible_id } }
+ let(:organisation_id) { affiliated_org.id }
+
+ before do
+ create(:organisation_relationship, parent_organisation: owning_org, child_organisation: affiliated_org)
+ bulk_upload.update!(organisation_id:, user: unaffiliated_support_user)
+ end
+
+ it "does not block log creation and does not add an error to field_1" do
+ parser = described_class.new(attributes)
+ parser.valid?
+ expect(parser.errors[:field_1]).not_to include("You do not have permission to add logs for this owning organisation")
+ end
+ end
end
describe "#field_2" do # managing org
diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb
index e428f7792..ca8f29e92 100644
--- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb
+++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb
@@ -554,6 +554,43 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do
expect(parser.errors[:field_6]).to include(/Enter a date when the owning organisation was active/)
end
end
+
+ context "when user is an unaffiliated non-support user and bulk upload organisation is affiliated with the owning organisation" do
+ let(:affiliated_org) { create(:organisation, :with_old_visible_id) }
+ let(:unaffiliated_user) { create(:user, organisation: create(:organisation)) }
+ let(:attributes) { { bulk_upload:, field_1: affiliated_org.old_visible_id } }
+ let(:organisation_id) { unaffiliated_user.organisation_id }
+
+ before do
+ create(:organisation_relationship, parent_organisation: owning_org, child_organisation: affiliated_org)
+ bulk_upload.update!(organisation_id:, user: unaffiliated_user)
+ end
+
+ it "blocks log creation and adds an error to field_1" do
+ parser = described_class.new(attributes)
+ parser.valid?
+ expect(parser).to be_block_log_creation
+ expect(parser.errors[:field_1]).to include("You do not have permission to add logs for this owning organisation")
+ end
+ end
+
+ context "when user is an unaffiliated support user and bulk upload organisation is affiliated with the owning organisation" do
+ let(:affiliated_org) { create(:organisation, :with_old_visible_id) }
+ let(:unaffiliated_support_user) { create(:user, :support, organisation: create(:organisation)) }
+ let(:attributes) { { bulk_upload:, field_1: affiliated_org.old_visible_id } }
+ let(:organisation_id) { affiliated_org.id }
+
+ before do
+ create(:organisation_relationship, parent_organisation: owning_org, child_organisation: affiliated_org)
+ bulk_upload.update!(organisation_id:, user: unaffiliated_support_user)
+ end
+
+ it "does not block log creation and does not add an error to field_1" do
+ parser = described_class.new(attributes)
+ parser.valid?
+ expect(parser.errors[:field_1]).not_to include("You do not have permission to add logs for this owning organisation")
+ end
+ end
end
describe "#field_3" do # username for assigned_to
@@ -576,6 +613,23 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do
end
end
+ context "when blank and bulk upload user is support" do
+ let(:bulk_upload) { create(:bulk_upload, :sales, user: create(:user, :support), year: 2024) }
+
+ let(:attributes) { setup_section_params.merge(bulk_upload:, field_3: nil) }
+
+ it "is not permitted" do
+ parser.valid?
+ expect(parser.errors[:field_3]).to be_present
+ expect(parser.errors[:field_3]).to include("You must answer what is the CORE username of the account this sales log should be assigned to?")
+ end
+
+ it "blocks log creation" do
+ parser.valid?
+ expect(parser).to be_block_log_creation
+ end
+ end
+
context "when user could not be found" do
let(:attributes) { { bulk_upload:, field_3: "idonotexist@example.com" } }