Skip to content

Commit

Permalink
CLDC-3743: Allow coordinators to manage schemes for recently absorbed…
Browse files Browse the repository at this point in the history
… organisations (#2764)

* CLDC-3743: Allow coordinators to manage schemes for recently absorbed organisations

* Fix status calculation for locations

* Avoid errors with merged stock owners

* Adjust when to hide org field in scheme creation

* Don't show activation buttons for schemes at merged orgs

* Update hint message about created locations, and restrict location creation to relevant org statuses

* Remove extra whitespace

* Fix references to scheme organisation
  • Loading branch information
RachaelBooth authored Nov 26, 2024
1 parent 4d14d4b commit 0899ed4
Show file tree
Hide file tree
Showing 15 changed files with 160 additions and 41 deletions.
2 changes: 1 addition & 1 deletion app/controllers/organisations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def index
end

def schemes
organisation_schemes = Scheme.visible.where(owning_organisation: [@organisation] + @organisation.parent_organisations)
organisation_schemes = Scheme.visible.where(owning_organisation: [@organisation] + @organisation.parent_organisations + @organisation.absorbed_organisations.visible.merged_during_open_collection_period)

@pagy, @schemes = pagy(filter_manager.filtered_schemes(organisation_schemes, search_term, session_filters))
@searched = search_term.presence
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/schemes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ def create
validation_errors scheme_params

if @scheme.errors.empty? && @scheme.save
if @scheme.owning_organisation.merge_date.present?
deactivation = SchemeDeactivationPeriod.new(scheme: @scheme, deactivation_date: @scheme.owning_organisation.merge_date)
deactivation.save!(validate: false)
end
redirect_to scheme_primary_client_group_path(@scheme)
else
if @scheme.errors.any? { |error| error.attribute == :owning_organisation }
Expand Down
8 changes: 7 additions & 1 deletion app/helpers/filters_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,15 @@ def managing_organisation_filter_options(user, filter_type)
end

def show_scheme_managing_org_filter?(user)
return true if user.support?

org = user.organisation
stock_owners = org.stock_owners.count
recently_absorbed_with_stock = org.absorbed_organisations.visible.merged_during_open_collection_period.where(holds_own_stock: true).count

relevant_orgs_count = stock_owners + recently_absorbed_with_stock + (org.holds_own_stock? ? 1 : 0)

user.support? || org.stock_owners.count > 1 || (org.holds_own_stock? && org.stock_owners.count.positive?)
relevant_orgs_count > 1
end

def logs_for_both_needstypes_present?(organisation)
Expand Down
20 changes: 14 additions & 6 deletions app/helpers/schemes_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ def delete_scheme_link(scheme)
end

def owning_organisation_options(current_user)
all_orgs = Organisation.visible.map { |org| OpenStruct.new(id: org.id, name: org.name) }
user_org = [OpenStruct.new(id: current_user.organisation_id, name: current_user.organisation.name)]
stock_owners = current_user.organisation.stock_owners.visible.map { |org| OpenStruct.new(id: org.id, name: org.name) }
merged_organisations = current_user.organisation.absorbed_organisations.visible.merged_during_open_collection_period.map { |org| OpenStruct.new(id: org.id, name: org.name) }
current_user.support? ? all_orgs : user_org + stock_owners + merged_organisations
if current_user.support?
Organisation.visible.map { |org| OpenStruct.new(id: org.id, name: org.name) }
else
user_org = [current_user.organisation]
stock_owners = current_user.organisation.stock_owners.visible.filter { |org| org.status == :active || (org.status == :merged && org.merge_date >= FormHandler.instance.start_date_of_earliest_open_for_editing_collection_period) }
merged_organisations = current_user.organisation.absorbed_organisations.visible.merged_during_open_collection_period
(user_org + stock_owners + merged_organisations).map { |org| OpenStruct.new(id: org.id, name: org.name) }
end
end

def null_option
Expand Down Expand Up @@ -81,7 +84,12 @@ def scheme_status_hint(scheme)
when :deactivating_soon
"This scheme deactivates on #{scheme.last_deactivation_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Reactivate the scheme to add locations active after this date."
when :deactivated
"This scheme deactivated on #{scheme.last_deactivation_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Reactivate the scheme to add locations active after this date."
case scheme.owning_organisation.status
when :active
"This scheme deactivated on #{scheme.last_deactivation_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Reactivate the scheme to add locations active after this date."
when :merged
"This scheme has been deactivated due to #{scheme.owning_organisation.name} merging into #{scheme.owning_organisation.absorbing_organisation.name} on #{scheme.owning_organisation.merge_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Use the after merge organisation for schemes and locations active after this date."
end
end
end

Expand Down
8 changes: 4 additions & 4 deletions app/models/location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ class Location < ApplicationRecord
}

scope :deactivated, lambda { |date = Time.zone.now|
deactivated_by_organisation
deactivated_by_organisation(date)
.or(deactivated_directly(date))
.or(deactivated_by_scheme(date))
}

scope :deactivated_by_organisation, lambda {
merge(Organisation.filter_by_inactive)
scope :deactivated_by_organisation, lambda { |date = Time.zone.now|
merge(Organisation.filter_by_inactive.or(Organisation.where("merge_date <= ?", date)))
}

scope :deactivated_by_scheme, lambda { |date = Time.zone.now|
Expand Down Expand Up @@ -206,7 +206,7 @@ def status
def status_at(date)
return :deleted if discarded_at.present?
return :incomplete unless confirmed
return :deactivated if scheme.owning_organisation.status_at(date) == :deactivated ||
return :deactivated if scheme.owning_organisation.status_at(date) == :deactivated || scheme.owning_organisation.status_at(date) == :merged ||
open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date || scheme.status_at(date) == :deactivated
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date || scheme.status_at(date) == :deactivating_soon
return :activating_soon if startdate.present? && date < startdate
Expand Down
8 changes: 4 additions & 4 deletions app/models/scheme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class Scheme < ApplicationRecord
.or(deactivated_directly)
}

scope :deactivated_by_organisation, lambda {
merge(Organisation.filter_by_inactive)
scope :deactivated_by_organisation, lambda { |date = Time.zone.now|
merge(Organisation.filter_by_inactive.or(Organisation.where("merge_date <= ?", date)))
}

scope :deactivated_directly, lambda { |date = Time.zone.now|
Expand Down Expand Up @@ -96,7 +96,7 @@ class Scheme < ApplicationRecord
scope :active, lambda { |date = Time.zone.now|
where.not(id: joins(:scheme_deactivation_periods).reactivating_soon(date).pluck(:id))
.where.not(id: incomplete.pluck(:id))
.where.not(id: joins(:owning_organisation).deactivated_by_organisation.pluck(:id))
.where.not(id: joins(:owning_organisation).deactivated_by_organisation(date).pluck(:id))
.where.not(id: joins(:owning_organisation).joins(:scheme_deactivation_periods).deactivated_directly(date).pluck(:id))
.where.not(id: activating_soon(date).pluck(:id))
}
Expand Down Expand Up @@ -314,7 +314,7 @@ def status
def status_at(date)
return :deleted if discarded_at.present?
return :incomplete unless confirmed && locations.confirmed.any?
return :deactivated if owning_organisation.status_at(date) == :deactivated ||
return :deactivated if owning_organisation.status_at(date) == :deactivated || owning_organisation.status_at(date) == :merged ||
(open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date)
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date
return :reactivating_soon if last_deactivation_before(date)&.reactivation_date.present? && date < last_deactivation_before(date).reactivation_date
Expand Down
15 changes: 9 additions & 6 deletions app/policies/location_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ def create?
if location == Location
user.data_coordinator?
else
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

def update?
return true if user.support?

user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end

def delete_confirmation?
Expand Down Expand Up @@ -62,7 +62,7 @@ def delete?
define_method method_name do
return true if user.support?

user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

Expand All @@ -73,7 +73,7 @@ def delete?
define_method method_name do
return true if user.support?

scheme_owned_by_user_org_or_stock_owner
scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

Expand All @@ -83,8 +83,11 @@ def scheme
location.scheme
end

def scheme_owned_by_user_org_or_stock_owner
scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
def scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
scheme_owned_by_user_org = scheme&.owning_organisation == user.organisation
scheme_owned_by_stock_owner = user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
scheme_owned_by_recently_absorbed_org = user.organisation.absorbed_organisations.visible.merged_during_open_collection_period.exists?(scheme&.owning_organisation_id)
scheme_owned_by_user_org || scheme_owned_by_stock_owner || scheme_owned_by_recently_absorbed_org
end

def has_any_logs_in_editable_collection_period
Expand Down
15 changes: 9 additions & 6 deletions app/policies/scheme_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def index?
if scheme == Scheme
true
else
scheme_owned_by_user_org_or_stock_owner
scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

Expand All @@ -27,7 +27,7 @@ def create?
def update?
return true if user.support?

user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end

def changes?
Expand All @@ -41,7 +41,7 @@ def changes?
define_method method_name do
return true if user.support?

scheme_owned_by_user_org_or_stock_owner
scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

Expand All @@ -61,7 +61,7 @@ def changes?
define_method method_name do
return true if user.support?

user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
end
end

Expand All @@ -78,8 +78,11 @@ def delete?

private

def scheme_owned_by_user_org_or_stock_owner
scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
def scheme_owned_by_user_org_or_stock_owner_or_recently_absorbed_org
scheme_owned_by_user_org = scheme&.owning_organisation == user.organisation
scheme_owned_by_stock_owner = user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
scheme_owned_by_recently_absorbed_org = user.organisation.absorbed_organisations.visible.merged_during_open_collection_period.exists?(scheme&.owning_organisation_id)
scheme_owned_by_user_org || scheme_owned_by_stock_owner || scheme_owned_by_recently_absorbed_org
end

def has_any_logs_in_editable_collection_period
Expand Down
15 changes: 7 additions & 8 deletions app/views/locations/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,13 @@
<% end %>
<% end %>

<% if status_hint_message = scheme_status_hint(@scheme) %>
<div class="govuk-hint">
<%= status_hint_message %>
</div>
<br>
<% end %>

<% if LocationPolicy.new(current_user, @scheme.locations.new).create? %>
<% if LocationPolicy.new(current_user, @scheme.locations.new).create? && [:active, :merged].include?(@scheme.owning_organisation.status) %>
<% if status_hint_message = scheme_status_hint(@scheme) %>
<div class="govuk-hint">
<%= status_hint_message %>
</div>
<br>
<% end %>
<%= govuk_button_to "Add a location", scheme_locations_path(@scheme), method: "post" %>
<% end %>
<br>
Expand Down
2 changes: 1 addition & 1 deletion app/views/locations/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
</div>
</div>

<% if @location.scheme.owning_organisation.active? && LocationPolicy.new(current_user, @location).deactivate? %>
<% if @location.scheme.owning_organisation.status == :active && LocationPolicy.new(current_user, @location).deactivate? %>
<%= toggle_location_link(@location) %>
<% end %>

Expand Down
6 changes: 4 additions & 2 deletions app/views/schemes/details.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@
:description,
legend: { text: "Is this scheme registered under the Care Standards Act 2000?", size: "m" } %>

<% if current_user.data_coordinator? && current_user.organisation.stock_owners.count.zero? && !current_user.organisation.has_recent_absorbed_organisations? %>
<% scheme_owning_organisation_options = owning_organisation_options(current_user) %>

<% if scheme_owning_organisation_options.count == 1 %>
<%= f.hidden_field :owning_organisation_id, value: current_user.organisation.id %>
<% else %>
<%= f.govuk_collection_select :owning_organisation_id,
owning_organisation_options(current_user),
scheme_owning_organisation_options,
:id,
:name,
label: { text: "Which organisation owns the housing stock for this scheme?", size: "m" },
Expand Down
2 changes: 1 addition & 1 deletion app/views/schemes/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
</div>
</div>

<% if @scheme.owning_organisation.active? && SchemePolicy.new(current_user, @scheme).deactivate? %>
<% if @scheme.owning_organisation.status == :active && SchemePolicy.new(current_user, @scheme).deactivate? %>
<%= toggle_scheme_link(@scheme) %>
<% end %>

Expand Down
5 changes: 5 additions & 0 deletions spec/models/location_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,11 @@
expect(location.status).to eq(:deactivated)
end

it "returns deactivated if the owning organisation has been merged" do
location.scheme.owning_organisation.merge_date = 2.days.ago
expect(location.status).to eq(:deactivated)
end

it "returns deactivated if deactivation_date is in the past" do
FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.yesterday, location:)
location.save!
Expand Down
5 changes: 5 additions & 0 deletions spec/models/scheme_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@
expect(scheme.status).to eq(:deactivated)
end

it "returns deactivated if the owning organisation has been merged" do
scheme.owning_organisation.merge_date = 2.days.ago
expect(scheme.status).to eq(:deactivated)
end

it "returns deactivated if deactivation_date is in the past" do
FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.yesterday, scheme:)
scheme.reload
Expand Down
Loading

0 comments on commit 0899ed4

Please sign in to comment.