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/helpers/user_helper.rb b/app/helpers/user_helper.rb
index 06fe2bc7d..bbcb0acae 100644
--- a/app/helpers/user_helper.rb
+++ b/app/helpers/user_helper.rb
@@ -56,4 +56,23 @@ module UserHelper
user.errors.add(attribute, message)
end
end
+
+ def display_pending_email_change_banner?(user)
+ user.unconfirmed_email.present? && user.email != user.unconfirmed_email
+ end
+
+ def pending_email_change_title_text(current_user, user)
+ if current_user == user
+ "You have requested to change your email address to #{user.unconfirmed_email}."
+ else
+ "There has been a request to change this user’s email address to #{user.unconfirmed_email}."
+ end
+ end
+
+ def pending_email_change_banner_text(current_user)
+ text = "A confirmation link has been sent to the new email address. The current email will continue to work until the change is confirmed."
+ text += " Deactivating this user will cancel the email change request." if current_user.support? || current_user.data_coordinator?
+
+ text
+ 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/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 7f42107f8..a43b03f82 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -11,6 +11,15 @@
<% end %>
<% end %>
+<% if display_pending_email_change_banner?(@user) %>
+ <%= govuk_notification_banner(title_text: "Important") do %>
+
+ <%= pending_email_change_title_text(current_user, @user) %>
+
+ <%= pending_email_change_banner_text(current_user) %>
+ <% 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/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..4d6f18b84 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"
@@ -42,6 +42,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_09_18_112702) 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"
@@ -410,6 +411,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|
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/helpers/user_helper_spec.rb b/spec/helpers/user_helper_spec.rb
index c88790aa0..eb0a672db 100644
--- a/spec/helpers/user_helper_spec.rb
+++ b/spec/helpers/user_helper_spec.rb
@@ -105,6 +105,32 @@ RSpec.describe UserHelper do
end
end
+ describe "display_pending_email_change_banner?" do
+ context "when the user doesn't have an unconfirmed email" do
+ let(:user) { FactoryBot.create(:user, :data_provider, unconfirmed_email: nil) }
+
+ it "does not display pending email change banner" do
+ expect(display_pending_email_change_banner?(user)).to be false
+ end
+ end
+
+ context "when the user has the same unconfirmed email as current email" do
+ let(:user) { FactoryBot.create(:user, :data_provider, unconfirmed_email: "updated_email@example.com", email: "updated_email@example.com") }
+
+ it "does not display pending email change banner" do
+ expect(display_pending_email_change_banner?(user)).to be false
+ end
+ end
+
+ context "when the user has a different unconfirmed email" do
+ let(:user) { FactoryBot.create(:user, :data_provider, unconfirmed_email: "updated_email@example.com", email: "old_email@example.com") }
+
+ it "displays pending email change banner" do
+ expect(display_pending_email_change_banner?(user)).to be true
+ end
+ end
+ end
+
describe "organisation_change_confirmation_warning" do
context "when user owns logs" do
before do
@@ -147,4 +173,39 @@ RSpec.describe UserHelper do
end
end
end
+
+ describe "pending_email_change_title_text" do
+ let(:user) { FactoryBot.create(:user, :data_provider, unconfirmed_email: "updated_email@example.com", email: "old_email@example.com") }
+ let(:current_user) { FactoryBot.create(:user, :support) }
+
+ context "when viewing own profile" do
+ it "returns the correct text" do
+ expect(pending_email_change_title_text(user, user)).to eq("You have requested to change your email address to updated_email@example.com.")
+ end
+ end
+
+ context "when viewing another user's profile" do
+ it "returns the correct text" do
+ expect(pending_email_change_title_text(current_user, user)).to eq("There has been a request to change this user’s email address to updated_email@example.com.")
+ end
+ end
+ end
+
+ describe "pending_email_change_banner_text" do
+ context "with provider user" do
+ let(:user) { FactoryBot.create(:user, :data_provider) }
+
+ it "returns the correct text" do
+ expect(pending_email_change_banner_text(user)).to eq("A confirmation link has been sent to the new email address. The current email will continue to work until the change is confirmed.")
+ end
+ end
+
+ context "with support user" do
+ let(:user) { FactoryBot.create(:user, :support) }
+
+ it "returns the correct text" do
+ expect(pending_email_change_banner_text(user)).to eq("A confirmation link has been sent to the new email address. The current email will continue to work until the change is confirmed. Deactivating this user will cancel the email change request.")
+ end
+ end
+ end
end
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" } }