From b88801c9aed9b7d2d2b57fcb5b969cc5ed2b7206 Mon Sep 17 00:00:00 2001 From: Manny Dinssa <44172848+Dinssa@users.noreply.github.com> Date: Thu, 6 Mar 2025 09:32:20 +0000 Subject: [PATCH] Add group logic --- app/controllers/organisations_controller.rb | 8 ++++- app/helpers/organisations_helper.rb | 33 +++++++++++++++++-- app/models/organisation.rb | 23 ++++++++++++- app/views/organisations/edit.html.erb | 4 +-- app/views/organisations/new.html.erb | 4 +-- config/locales/en.yml | 4 +++ ...add_new_question_fields_to_organisation.rb | 1 + db/schema.rb | 1 + 8 files changed, 70 insertions(+), 8 deletions(-) diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index 8c073d1af..d2154a824 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -90,6 +90,7 @@ class OrganisationsController < ApplicationController def create selected_rent_periods = rent_period_params[:rent_periods].compact_blank @organisation = Organisation.new(org_params) + @organisation.group = org_params[:group_member] ? helpers.assign_group_number(@organisation.id, org_params[:group_member_id]) : nil if @organisation.save OrganisationRentPeriod.transaction do selected_rent_periods.each { |period| OrganisationRentPeriod.create!(organisation: @organisation, rent_period: period) } @@ -127,6 +128,7 @@ class OrganisationsController < ApplicationController def update if (current_user.data_coordinator? && org_params[:active].nil?) || current_user.support? + @organisation.group = org_params[:group_member] ? helpers.assign_group_number(@organisation.id, org_params[:group_member_id]) : nil if @organisation.update(org_params) case org_params[:active] when "false" @@ -341,7 +343,7 @@ private end def org_params - params.require(:organisation).permit(:name, :address_line1, :address_line2, :postcode, :phone, :holds_own_stock, :provider_type, :housing_registration_no, :active, :profit_status, :group_member, :group) + params.require(:organisation).permit(:name, :address_line1, :address_line2, :postcode, :phone, :holds_own_stock, :provider_type, :housing_registration_no, :active, :profit_status, :group_member, :group_member_id) end def rent_period_params @@ -385,4 +387,8 @@ private end end end + + def next_available_group_number + Organisation.maximum(:group).to_i + 1 + end end diff --git a/app/helpers/organisations_helper.rb b/app/helpers/organisations_helper.rb index 2a011af64..c1cc08420 100644 --- a/app/helpers/organisations_helper.rb +++ b/app/helpers/organisations_helper.rb @@ -21,7 +21,7 @@ module OrganisationsHelper ] if organisation.group_member - attributes << { name: "Group number", value: organisation.group, editable: current_user.support? } + attributes << { name: "Group number", value: "GROUP#{organisation.group}", editable: current_user.support? } end attributes << { name: "For profit", value: organisation.display_profit_status, editable: current_user.support? } @@ -80,10 +80,24 @@ module OrganisationsHelper def group_organisation_options null_option = [OpenStruct.new(id: "", name: "Select an option", group: nil)] - organisations = Organisation.visible.map { |org| OpenStruct.new(id: org.id, name: org.name, group: org.group) } + organisations = Organisation.visible.map { |org| OpenStruct.new(id: org.id, name: group_organisation_options_name(org)) } null_option + organisations end + def group_organisation_options_name(org) + "#{org.name}#{group_organisation_options_group_text(org)}" + end + + def group_organisation_options_group_text(org) + return "" unless org.oldest_group_member + + " (GROUP#{org.oldest_group_member&.group})" + end + + def group_organisation_options_group(org) + org.oldest_group_member&.group || next_available_group_number + end + def profit_status_options(provider_type = nil) null_option = [OpenStruct.new(id: "", name: "Select an option")] profit_statuses = Organisation::PROFIT_STATUS.map do |key, _value| @@ -99,4 +113,19 @@ module OrganisationsHelper null_option + profit_statuses end + + def assign_group_number(current_org_id, selected_org_id) + selected_org = Organisation.find_by(id: selected_org_id) + if selected_org&.group.present? + selected_org.group + else + next_group_number = next_available_group_number + selected_org.update!(group_member: true, group_member_id: current_org_id, group: next_group_number) if selected_org + next_group_number + end + end + + def next_available_group_number + Organisation.maximum(:group).to_i + 1 + end end diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 5d292cb13..9acea5138 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -69,6 +69,9 @@ class Organisation < ApplicationRecord validates :name, presence: { message: I18n.t("validations.organisation.name_missing") } validates :name, uniqueness: { case_sensitive: false, message: I18n.t("validations.organisation.name_not_unique") } validates :provider_type, presence: { message: I18n.t("validations.organisation.provider_type_missing") } + validates :group_member_id, presence: { message: I18n.t("validations.organisation.group_missing") }, if: :group_member? + + validate :validate_profit_status def self.find_by_id_on_multiple_fields(id) return if id.nil? @@ -144,7 +147,7 @@ class Organisation < ApplicationRecord DISPLAY_PROVIDER_TYPE[provider_type.to_sym] end - DISPLAY_PROFIT_STATUS = { "non_profit": "Non-profit", "profit": "Profit", "local_authority": "Local Authority" }.freeze + DISPLAY_PROFIT_STATUS = { "non_profit": "Non-profit", "profit": "Profit", "local_authority": "Local authority" }.freeze def display_profit_status DISPLAY_PROFIT_STATUS.fetch(profit_status&.to_sym, "") @@ -217,4 +220,22 @@ class Organisation < ApplicationRecord def has_visible_schemes? owned_schemes.visible.count.positive? end + + def oldest_group_member + return nil if group.blank? + + Organisation.visible.where(group:).order(:created_at).first + end + +private + + def validate_profit_status + if provider_type == "LA" && profit_status != "local_authority" + errors.add(:profit_status, I18n.t("validations.organisation.profit_status.must_be_LA")) + end + + if provider_type == "PRP" && profit_status == "local_authority" + errors.add(:profit_status, I18n.t("validations.organisation.profit_status.must_not_be_LA")) + end + end end diff --git a/app/views/organisations/edit.html.erb b/app/views/organisations/edit.html.erb index 34bec62e9..c6649a30a 100644 --- a/app/views/organisations/edit.html.erb +++ b/app/views/organisations/edit.html.erb @@ -41,12 +41,12 @@ "data-controller": "conditional-question", "data-action": "click->conditional-question#displayConditional", "data-info": { conditional_questions: { group: [true] }, type: "organisation" }.to_json do %> - <%= f.govuk_collection_select :group, + <%= f.govuk_collection_select :group_member_id, group_organisation_options, :id, :name, label: { text: "Search for an organisation that is part of the same group as this organisation", size: "m" }, - options: { disabled: [""], selected: @organisation.group || "" }, + options: { disabled: [""], selected: @organisation.oldest_group_member&.id || "" }, "data-controller": %w[accessible-autocomplete conditional-filter] %> <% end %> <%= f.govuk_radio_button :group_member, false, label: { text: "No" } %> diff --git a/app/views/organisations/new.html.erb b/app/views/organisations/new.html.erb index b338d23bd..d5aa33164 100644 --- a/app/views/organisations/new.html.erb +++ b/app/views/organisations/new.html.erb @@ -65,12 +65,12 @@ "data-controller": "conditional-question", "data-action": "click->conditional-question#displayConditional", "data-info": { conditional_questions: { group: [true] }, type: "organisation" }.to_json do %> - <%= f.govuk_collection_select :group, + <%= f.govuk_collection_select :group_member_id, group_organisation_options, :id, :name, label: { text: "Search for an organisation that is part of the same group as this organisation", size: "m" }, - options: { disabled: [""], selected: @organisation.group || "" }, + options: { disabled: [""], selected: @organisation.oldest_group_member&.id || "" }, "data-controller": %w[accessible-autocomplete conditional-filter] %> <% end %> <%= f.govuk_radio_button :group_member, false, label: { text: "No" } %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 6ca3ea322..bbee236be 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -218,6 +218,10 @@ en: name_missing: "Enter the name of the organisation." name_not_unique: "An organisation with this name already exists. Use the organisation that already exists or add a location or other identifier to the name. For example: Organisation name (City)." provider_type_missing: "Select the organisation type." + group_missing: "Select a group member." + profit_status: + must_be_LA: "This organisation is a local authority, it's profit status must also be local authority." + must_not_be_LA: "This organisation is a private registered provider, it's profit status cannot be local authority." stock_owner: blank: "You must choose a stock owner." already_added: "You have already added this stock owner." diff --git a/db/migrate/20250227085622_add_new_question_fields_to_organisation.rb b/db/migrate/20250227085622_add_new_question_fields_to_organisation.rb index 08b3ff2bf..dad16dc76 100644 --- a/db/migrate/20250227085622_add_new_question_fields_to_organisation.rb +++ b/db/migrate/20250227085622_add_new_question_fields_to_organisation.rb @@ -2,6 +2,7 @@ class AddNewQuestionFieldsToOrganisation < ActiveRecord::Migration[7.2] def change add_column :organisations, :profit_status, :integer add_column :organisations, :group_member, :boolean + add_column :organisations, :group_member_id, :integer add_column :organisations, :group, :integer end end diff --git a/db/schema.rb b/db/schema.rb index f00ffb5d4..1840a3263 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -550,6 +550,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_02_27_085622) do t.datetime "schemes_deduplicated_at" t.integer "profit_status" t.boolean "group_member" + t.integer "group_member_id" t.integer "group" t.index ["absorbing_organisation_id"], name: "index_organisations_on_absorbing_organisation_id" t.index ["name"], name: "index_organisations_on_name", unique: true