Browse Source

Add an organisation question for the support user (#674)

* Add an organisation question for the support user (WIP)

Co-authored-by: baarkerlounger  <baarkerlounger@users.noreply.github.com>

* All the things are green

* Add user question

* Restrict shown answer options based on already answered questions

* Derive managing org

* Guard against missing DB connection

* Remove empty file

* Only select the fields we actually need

* All is redundant

* Fix spec description

* Fix comments

Co-authored-by: Kat <katrina@madetech.com>
Co-authored-by: baarkerlounger  <baarkerlounger@users.noreply.github.com>
pull/681/head
baarkerlounger 3 years ago committed by GitHub
parent
commit
07409aec61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      app/controllers/case_logs_controller.rb
  2. 2
      app/controllers/form_controller.rb
  3. 12
      app/models/case_log.rb
  4. 2
      app/models/derived_variables/case_log_variables.rb
  5. 3
      app/models/form.rb
  6. 4
      app/models/form/page.rb
  7. 24
      app/models/form/setup/pages/created_by.rb
  8. 24
      app/models/form/setup/pages/organisation.rb
  9. 39
      app/models/form/setup/questions/created_by_id.rb
  10. 39
      app/models/form/setup/questions/owning_organisation_id.rb
  11. 2
      app/models/form/setup/subsections/setup.rb
  12. 2
      app/models/validations/financial_validations.rb
  13. 2
      app/models/validations/household_validations.rb
  14. 4
      app/views/case_logs/_log_list.html.erb
  15. 0
      config/forms/setup/log_setup.json
  16. 65
      spec/models/form/setup/pages/created_by_spec.rb
  17. 65
      spec/models/form/setup/pages/organisation_spec.rb
  18. 90
      spec/models/form/setup/questions/created_by_id_spec.rb
  19. 91
      spec/models/form/setup/questions/owning_organisation_id_spec.rb
  20. 11
      spec/models/form/setup/subsections/setup_spec.rb
  21. 2
      spec/models/form_handler_spec.rb
  22. 19
      spec/requests/form_controller_spec.rb

13
app/controllers/case_logs_controller.rb

@ -27,11 +27,15 @@ class CaseLogsController < ApplicationController
end
def create
case_log = CaseLog.create(case_log_params)
case_log = CaseLog.new(case_log_params)
case_log.form.current_user = current_user
respond_to do |format|
format.html { redirect_to case_log }
format.html do
case_log.save!
redirect_to case_log
end
format.json do
if case_log.persisted?
if case_log.save
render json: case_log, status: :created
else
render json: { errors: case_log.errors.messages }, status: :unprocessable_entity
@ -58,6 +62,7 @@ class CaseLogsController < ApplicationController
format.html { edit }
format.json do
if @case_log
@case_log.form.current_user = current_user
render json: @case_log, status: :ok
else
render_not_found_json("Log", params[:id])
@ -104,7 +109,7 @@ private
end
def case_log_params
if current_user
if current_user && !current_user.support?
org_params.merge(api_case_log_params)
else
api_case_log_params

2
app/controllers/form_controller.rb

@ -25,6 +25,7 @@ class FormController < ApplicationController
if @case_log
current_url = request.env["PATH_INFO"]
subsection = @case_log.form.get_subsection(current_url.split("/")[-2])
@case_log.form.current_user = current_user
render "form/check_answers", locals: { subsection: }
else
render_not_found
@ -50,6 +51,7 @@ class FormController < ApplicationController
end
@subsection = @case_log.form.subsection_for_page(page)
@page = @case_log.form.get_page(page.id)
@case_log.form.current_user = current_user
if @page.routed_to?(@case_log) && @page.subsection.enabled?(@case_log)
render "form/page"
else

12
app/models/case_log.rb

@ -32,9 +32,9 @@ class CaseLog < ApplicationRecord
before_validation :set_derived_fields!
before_save :update_status!
belongs_to :owning_organisation, class_name: "Organisation"
belongs_to :managing_organisation, class_name: "Organisation"
belongs_to :created_by, class_name: "User"
belongs_to :owning_organisation, class_name: "Organisation", optional: true
belongs_to :managing_organisation, class_name: "Organisation", optional: true
belongs_to :created_by, class_name: "User", optional: true
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org).or(where(managing_organisation: org)) }
scope :filter_by_status, ->(status, _user = nil) { where status: }
@ -474,13 +474,16 @@ private
enabled_answer_options = enabled_question_ids.include?(question.id) ? enabled_questions.find { |q| q.id == question.id }.answer_options : {}
current_answer_option_valid = enabled_answer_options.present? ? enabled_answer_options.key?(public_send(question.id).to_s) : false
if !current_answer_option_valid && respond_to?(question.id.to_s)
Rails.logger.debug("Cleared #{question.id} value")
public_send("#{question.id}=", nil)
else
(question.answer_options.keys - enabled_answer_options.keys).map do |invalid_answer_option|
Rails.logger.debug("Cleared #{invalid_answer_option} value")
public_send("#{invalid_answer_option}=", nil) if respond_to?(invalid_answer_option)
end
end
else
Rails.logger.debug("Cleared #{question.id} value")
public_send("#{question.id}=", nil) unless enabled_question_ids.include?(question.id)
end
end
@ -496,6 +499,7 @@ private
condition_key = conditions.first[:key]
condition_value = conditions.first[:value]
if public_send("#{condition_key}_changed?") && condition_value == public_send(condition_key) && !public_send("#{dependent}_changed?")
Rails.logger.debug("Cleared derived #{dependent} value")
self[dependent] = nil
end
end
@ -585,7 +589,7 @@ private
end
def get_lettype
return unless renttype.present? && needstype.present? && owning_organisation[:provider_type].present?
return unless renttype.present? && needstype.present? && owning_organisation.present? && owning_organisation[:provider_type].present?
case RENT_TYPE_MAPPING_LABELS[renttype]
when "Social Rent"

2
app/models/derived_variables/case_log_variables.rb

@ -6,6 +6,8 @@ module DerivedVariables::CaseLogVariables
end
def set_derived_fields!
# TODO: Remove once we support parent/child relationships
self.managing_organisation_id ||= owning_organisation_id
# TODO: Remove once we support supported housing logs
self.needstype = 1 unless supported_housing_schemes_enabled?
if rsnvac.present?

3
app/models/form.rb

@ -2,6 +2,7 @@ class Form
attr_reader :form_definition, :sections, :subsections, :pages, :questions,
:start_date, :end_date, :type, :name, :setup_definition,
:setup_sections, :form_sections
attr_accessor :current_user
include Form::Setup
@ -115,7 +116,7 @@ class Form
end
def invalidated_pages(case_log)
pages.reject { |p| p.routed_to?(case_log) }
pages.select { |p| p.invalidated?(case_log) }
end
def invalidated_questions(case_log)

4
app/models/form/page.rb

@ -31,6 +31,10 @@ class Form::Page
end
end
def invalidated?(case_log)
!routed_to?(case_log)
end
private
def conditional_question_ids

24
app/models/form/setup/pages/created_by.rb

@ -0,0 +1,24 @@
class Form::Setup::Pages::CreatedBy < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "created_by"
@header = ""
@description = ""
@questions = questions
@subsection = subsection
end
def questions
[
Form::Setup::Questions::CreatedById.new(nil, nil, self),
]
end
def routed_to?(_case_log)
!!form.current_user&.support?
end
def invalidated?(_case_log)
false
end
end

24
app/models/form/setup/pages/organisation.rb

@ -0,0 +1,24 @@
class Form::Setup::Pages::Organisation < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "organisation"
@header = ""
@description = ""
@questions = questions
@subsection = subsection
end
def questions
[
Form::Setup::Questions::OwningOrganisationId.new(nil, nil, self),
]
end
def routed_to?(_case_log)
!!form.current_user&.support?
end
def invalidated?(_case_log)
false
end
end

39
app/models/form/setup/questions/created_by_id.rb

@ -0,0 +1,39 @@
class Form::Setup::Questions::CreatedById < ::Form::Question
def initialize(id, hsh, page)
super
@id = "created_by_id"
@check_answer_label = "User"
@header = "Which user are you creating this log for?"
@hint_text = ""
@type = "select"
@page = page
@answer_options = answer_options_values
end
def answer_options_values
answer_opts = { "" => "Select an option" }
return answer_opts unless ActiveRecord::Base.connected?
User.select(:id, :name).each_with_object(answer_opts) do |user, hsh|
hsh[user.id] = user.name
hsh
end
end
def displayed_answer_options(case_log)
return answer_options unless case_log.owning_organisation
user_ids = case_log.owning_organisation.users.pluck(:id) + [""]
answer_options.select { |k, _v| user_ids.include?(k) }
end
def label_from_value(value)
return unless value
answer_options[value]
end
def hidden_in_check_answers
!form.current_user.support?
end
end

39
app/models/form/setup/questions/owning_organisation_id.rb

@ -0,0 +1,39 @@
class Form::Setup::Questions::OwningOrganisationId < ::Form::Question
def initialize(id, hsh, page)
super
@id = "owning_organisation_id"
@check_answer_label = "Owning organisation"
@header = "Which organisation is the owning organisation for this log?"
@hint_text = ""
@type = "select"
@page = page
@answer_options = answer_options_values
end
def answer_options_values
answer_opts = { "" => "Select an option" }
return answer_opts unless ActiveRecord::Base.connected?
Organisation.select(:id, :name).each_with_object(answer_opts) do |organisation, hsh|
hsh[organisation.id] = organisation.name
hsh
end
end
def displayed_answer_options(case_log)
return answer_options unless case_log.created_by
ids = ["", case_log.created_by.organisation.id]
answer_options.select { |k, _v| ids.include?(k) }
end
def label_from_value(value)
return unless value
answer_options[value]
end
def hidden_in_check_answers
!form.current_user.support?
end
end

2
app/models/form/setup/subsections/setup.rb

@ -9,6 +9,8 @@ class Form::Subsections::Setup < ::Form::Subsection
def pages
[
Form::Setup::Pages::Organisation.new(nil, nil, self),
Form::Setup::Pages::CreatedBy.new(nil, nil, self),
Form::Setup::Pages::NeedsType.new(nil, nil, self),
Form::Setup::Pages::Renewal.new(nil, nil, self),
Form::Setup::Pages::TenancyStartDate.new(nil, nil, self),

2
app/models/validations/financial_validations.rb

@ -141,6 +141,8 @@ private
NEEDSTYPE_VALUES = { 2 => :supported_housing, 1 => :general_needs }.freeze
def validate_charges(record)
return unless record.owning_organisation
provider_type = record.owning_organisation.provider_type_before_type_cast
%i[scharge pscharge supcharg].each do |charge|
maximum = CHARGE_MAXIMUMS.dig(charge, PROVIDER_TYPE[provider_type], NEEDSTYPE_VALUES[record.needstype])

2
app/models/validations/household_validations.rb

@ -110,6 +110,8 @@ module Validations::HouseholdValidations
end
def validate_referral(record)
return unless record.owning_organisation
if record.is_internal_transfer? && record.owning_organisation.provider_type == "PRP" && record.is_prevten_la_general_needs?
record.errors.add :prevten, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.household.prevten.la_general_needs.internal_transfer")
record.errors.add :referral, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.household.referral.la_general_needs.internal_transfer")

4
app/views/case_logs/_log_list.html.erb

@ -58,8 +58,8 @@
<%= status_tag(log.status) %>
<% end %>
<% if current_user.support? %>
<% row.cell(text: log.owning_organisation.name) %>
<% row.cell(text: log.managing_organisation.name) %>
<% row.cell(text: log.owning_organisation&.name) %>
<% row.cell(text: log.managing_organisation&.name) %>
<% end %>
<% end %>
<% end %>

0
config/forms/setup/log_setup.json

65
spec/models/form/setup/pages/created_by_spec.rb

@ -0,0 +1,65 @@
require "rails_helper"
RSpec.describe Form::Setup::Pages::CreatedBy, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
let(:case_log) { instance_double(CaseLog) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[created_by_id])
end
it "has the correct id" do
expect(page.id).to eq("created_by")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has the correct description" do
expect(page.description).to eq("")
end
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
context "when the current user is a support user" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown" do
expect(page.routed_to?(case_log)).to be true
end
end
context "when the current user is not a support user" do
let(:user) { FactoryBot.build(:user) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown" do
expect(page.routed_to?(case_log)).to be false
end
end
end

65
spec/models/form/setup/pages/organisation_spec.rb

@ -0,0 +1,65 @@
require "rails_helper"
RSpec.describe Form::Setup::Pages::Organisation, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
let(:case_log) { instance_double(CaseLog) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[owning_organisation_id])
end
it "has the correct id" do
expect(page.id).to eq("organisation")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has the correct description" do
expect(page.description).to eq("")
end
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
context "when the current user is a support user" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown" do
expect(page.routed_to?(case_log)).to be true
end
end
context "when the current user is not a support user" do
let(:user) { FactoryBot.build(:user) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown" do
expect(page.routed_to?(case_log)).to be false
end
end
end

90
spec/models/form/setup/questions/created_by_id_spec.rb

@ -0,0 +1,90 @@
require "rails_helper"
RSpec.describe Form::Setup::Questions::CreatedById, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
let!(:user_1) { FactoryBot.create(:user, name: "first user") }
let!(:user_2) { FactoryBot.create(:user, name: "second user") }
let(:expected_answer_options) do
{
"" => "Select an option",
user_1.id => user_1.name,
user_2.id => user_2.name,
}
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("created_by_id")
end
it "has the correct header" do
expect(question.header).to eq("Which user are you creating this log for?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("User")
end
it "has the correct type" do
expect(question.type).to eq("select")
end
it "has the correct hint_text" do
expect(question.hint_text).to eq("")
end
it "has the correct answer options" do
expect(question.answer_options).to eq(expected_answer_options)
end
context "when the current user is support" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown in check answers" do
expect(question.hidden_in_check_answers).to be false
end
end
context "when the current user is not support" do
let(:user) { FactoryBot.build(:user) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown in check answers" do
expect(question.hidden_in_check_answers).to be true
end
end
context "when the owning organisation is already set" do
let(:case_log) { FactoryBot.create(:case_log, owning_organisation: user_2.organisation) }
let(:expected_answer_options) do
{
"" => "Select an option",
user_2.id => user_2.name,
}
end
it "only displays users that belong to that organisation" do
expect(question.displayed_answer_options(case_log)).to eq(expected_answer_options)
end
end
end

91
spec/models/form/setup/questions/owning_organisation_id_spec.rb

@ -0,0 +1,91 @@
require "rails_helper"
RSpec.describe Form::Setup::Questions::OwningOrganisationId, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
let!(:organisation_1) { FactoryBot.create(:organisation, name: "first test org") }
let!(:organisation_2) { FactoryBot.create(:organisation, name: "second test org") }
let(:expected_answer_options) do
{
"" => "Select an option",
organisation_1.id => organisation_1.name,
organisation_2.id => organisation_2.name,
}
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("owning_organisation_id")
end
it "has the correct header" do
expect(question.header).to eq("Which organisation is the owning organisation for this log?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Owning organisation")
end
it "has the correct type" do
expect(question.type).to eq("select")
end
it "has the correct hint_text" do
expect(question.hint_text).to eq("")
end
it "has the correct answer options" do
expect(question.answer_options).to eq(expected_answer_options)
end
context "when the current user is support" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown in check answers" do
expect(question.hidden_in_check_answers).to be false
end
end
context "when the current user is not support" do
let(:user) { FactoryBot.build(:user) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown in check answers" do
expect(question.hidden_in_check_answers).to be true
end
end
context "when the user is already set" do
let(:user) { FactoryBot.create(:user, organisation: organisation_2) }
let(:case_log) { FactoryBot.create(:case_log, created_by: user) }
let(:expected_answer_options) do
{
"" => "Select an option",
organisation_2.id => organisation_2.name,
}
end
it "only displays users that belong to that organisation" do
expect(question.displayed_answer_options(case_log)).to eq(expected_answer_options)
end
end
end

11
spec/models/form/setup/subsections/setup_spec.rb

@ -12,7 +12,16 @@ RSpec.describe Form::Setup::Subsections::Setup, type: :model do
end
it "has correct pages" do
expect(setup.pages.map(&:id)).to eq(%w[needs_type renewal tenancy_start_date rent_type tenant_code property_reference])
expect(setup.pages.map(&:id)).to eq(
%w[organisation
created_by
needs_type
renewal
tenancy_start_date
rent_type
tenant_code
property_reference],
)
end
it "has the correct id" do

2
spec/models/form_handler_spec.rb

@ -17,7 +17,7 @@ RSpec.describe FormHandler do
form_handler = described_class.instance
form = form_handler.get_form(test_form_name)
expect(form).to be_a(Form)
expect(form.pages.count).to eq(40)
expect(form.pages.count).to eq(42)
end
end

19
spec/requests/form_controller_spec.rb

@ -70,6 +70,7 @@ RSpec.describe FormController, type: :request do
context "when a user is signed in" do
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
end
@ -141,6 +142,24 @@ RSpec.describe FormController, type: :request do
expect(response.body).to match("Review lettings log")
end
end
context "when viewing a user dependent page" do
context "when the dependency is met" do
let(:user) { FactoryBot.create(:user, :support) }
it "routes to the page" do
get "/logs/#{case_log.id}/organisation"
expect(response).to have_http_status(:ok)
end
end
context "when the dependency is not met" do
it "redirects to the tasklist page" do
get "/logs/#{case_log.id}/organisation"
expect(response).to redirect_to("/logs/#{case_log.id}")
end
end
end
end
describe "Submit Form" do

Loading…
Cancel
Save