|
|
|
class MergeRequest < ApplicationRecord
|
|
|
|
belongs_to :requesting_organisation, class_name: "Organisation"
|
|
|
|
has_many :merge_request_organisations
|
|
|
|
belongs_to :absorbing_organisation, class_name: "Organisation", optional: true
|
|
|
|
has_many :merging_organisations, through: :merge_request_organisations, source: :merging_organisation
|
|
|
|
belongs_to :requester, class_name: "User", optional: true
|
|
|
|
|
|
|
|
STATUS = {
|
|
|
|
merge_issues: "merge_issues",
|
|
|
|
incomplete: "incomplete",
|
|
|
|
ready_to_merge: "ready_to_merge",
|
|
|
|
processing: "processing",
|
|
|
|
request_merged: "request_merged",
|
|
|
|
deleted: "deleted",
|
|
|
|
}.freeze
|
|
|
|
enum status: STATUS
|
|
|
|
|
|
|
|
scope :not_merged, -> { where(request_merged: [false, nil]) }
|
|
|
|
scope :merged, -> { where(request_merged: true) }
|
|
|
|
scope :visible, lambda {
|
|
|
|
open_collection_period_start_date = FormHandler.instance.start_date_of_earliest_open_collection_period
|
|
|
|
merged.where("merge_requests.merge_date >= ?", open_collection_period_start_date).or(not_merged).where(discarded_at: nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
def absorbing_organisation_name
|
|
|
|
absorbing_organisation&.name || ""
|
|
|
|
end
|
|
|
|
|
|
|
|
def dpo_user
|
|
|
|
absorbing_organisation.data_protection_officers.filter_by_active.first
|
|
|
|
end
|
|
|
|
|
|
|
|
def discard!
|
|
|
|
update!(discarded_at: Time.zone.now)
|
|
|
|
end
|
|
|
|
|
|
|
|
def status
|
|
|
|
return STATUS[:deleted] if discarded_at.present?
|
|
|
|
return STATUS[:request_merged] if request_merged
|
|
|
|
return STATUS[:processing] if processing
|
|
|
|
return STATUS[:incomplete] unless required_questions_answered?
|
|
|
|
return STATUS[:ready_to_merge] if absorbing_organisation_signed_dsa?
|
|
|
|
|
|
|
|
STATUS[:merge_issues]
|
|
|
|
end
|
|
|
|
|
|
|
|
def required_questions_answered?
|
|
|
|
absorbing_organisation_id.present? &&
|
|
|
|
merge_date.present? &&
|
|
|
|
!existing_absorbing_organisation.nil? &&
|
|
|
|
merging_organisations.count.positive? &&
|
|
|
|
errors.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def absorbing_organisation_signed_dsa?
|
|
|
|
absorbing_organisation&.data_protection_confirmed?
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_visible_users_after_merge
|
|
|
|
return total_users if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
absorbing_organisation.users.visible.count + merging_organisations.sum { |org| org.users.visible.count }
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_users_label
|
|
|
|
"#{total_visible_users_after_merge} #{'user'.pluralize(total_visible_users_after_merge)}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def organisations_with_users
|
|
|
|
return [] unless absorbing_organisation.present? && merging_organisations.any?
|
|
|
|
|
|
|
|
([absorbing_organisation] + merging_organisations).select(&:has_visible_users?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def organisations_without_users
|
|
|
|
return [] unless absorbing_organisation.present? && merging_organisations.any?
|
|
|
|
|
|
|
|
([absorbing_organisation] + merging_organisations).reject(&:has_visible_users?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_visible_schemes_after_merge
|
|
|
|
return total_schemes if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
absorbing_organisation.owned_schemes.visible.count + merging_organisations.sum { |org| org.owned_schemes.visible.count }
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_schemes_label
|
|
|
|
"#{total_visible_schemes_after_merge} #{'scheme'.pluralize(total_visible_schemes_after_merge)}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def organisations_with_schemes
|
|
|
|
return [] unless absorbing_organisation.present? && merging_organisations.any?
|
|
|
|
|
|
|
|
([absorbing_organisation] + merging_organisations).select(&:has_visible_schemes?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def organisations_without_schemes
|
|
|
|
return [] unless absorbing_organisation.present? && merging_organisations.any?
|
|
|
|
|
|
|
|
([absorbing_organisation] + merging_organisations).reject(&:has_visible_schemes?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def existing_absorbing_organisation_label
|
|
|
|
return if existing_absorbing_organisation.nil?
|
|
|
|
|
|
|
|
existing_absorbing_organisation ? "Yes" : "No"
|
|
|
|
end
|
|
|
|
|
|
|
|
def filter_relationships(absorbing_relationships, merging_relationships, absorbing_organisation, merging_organisations)
|
|
|
|
unique_relationships = (absorbing_relationships + merging_relationships).uniq
|
|
|
|
unique_relationships.reject do |relationship|
|
|
|
|
merging_organisations.include?(relationship) || relationship == absorbing_organisation
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_stock_owners_after_merge
|
|
|
|
return total_stock_owners if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
absorbing_stock_owners = absorbing_organisation.stock_owners.visible
|
|
|
|
merging_stock_owners = merging_organisations.flat_map { |org| org.stock_owners.visible }
|
|
|
|
|
|
|
|
total_filtered_stock_owners = filter_relationships(absorbing_stock_owners, merging_stock_owners, absorbing_organisation, merging_organisations)
|
|
|
|
total_filtered_stock_owners.count
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_managing_agents_after_merge
|
|
|
|
return total_managing_agents if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
absorbing_managing_agents = absorbing_organisation.managing_agents.visible
|
|
|
|
merging_managing_agents = merging_organisations.flat_map { |org| org.managing_agents.visible }
|
|
|
|
|
|
|
|
total_filtered_managing_agents = filter_relationships(absorbing_managing_agents, merging_managing_agents, absorbing_organisation, merging_organisations)
|
|
|
|
total_filtered_managing_agents.count
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_stock_owners_managing_agents_label
|
|
|
|
stock_owners_count = total_stock_owners_after_merge
|
|
|
|
managing_agents_count = total_managing_agents_after_merge
|
|
|
|
|
|
|
|
"#{stock_owners_count} #{'stock owner'.pluralize(stock_owners_count)}\n#{managing_agents_count} #{'managing agent'.pluralize(managing_agents_count)}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_visible_sales_logs_after_merge
|
|
|
|
return total_sales_logs if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
(absorbing_organisation.sales_logs.visible.pluck(:id) + merging_organisations.map { |org| org.sales_logs.visible.pluck(:id) }.flatten).uniq.count
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_visible_lettings_logs_after_merge
|
|
|
|
return total_lettings_logs if status == STATUS[:request_merged] || status == STATUS[:processing]
|
|
|
|
|
|
|
|
(absorbing_organisation.lettings_logs.visible.pluck(:id) + merging_organisations.map { |org| org.lettings_logs.visible.pluck(:id) }.flatten).uniq.count
|
|
|
|
end
|
|
|
|
|
|
|
|
def total_logs_label
|
|
|
|
"#{total_visible_lettings_logs_after_merge} lettings logs<br>#{total_visible_sales_logs_after_merge} sales logs"
|
|
|
|
end
|
|
|
|
|
|
|
|
def start_merge!
|
|
|
|
update!(
|
|
|
|
processing: true,
|
|
|
|
last_failed_attempt: nil,
|
|
|
|
total_users: total_visible_users_after_merge,
|
|
|
|
total_schemes: total_visible_schemes_after_merge,
|
|
|
|
total_stock_owners: total_stock_owners_after_merge,
|
|
|
|
total_managing_agents: total_managing_agents_after_merge,
|
|
|
|
total_lettings_logs: total_visible_lettings_logs_after_merge,
|
|
|
|
total_sales_logs: total_visible_sales_logs_after_merge,
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_back_to_ready_to_merge!
|
|
|
|
update!(
|
|
|
|
last_failed_attempt: Time.zone.now,
|
|
|
|
processing: false,
|
|
|
|
total_users: nil,
|
|
|
|
total_schemes: nil,
|
|
|
|
total_stock_owners: nil,
|
|
|
|
total_managing_agents: nil,
|
|
|
|
total_lettings_logs: nil,
|
|
|
|
total_sales_logs: nil,
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|