From 686dc401169934e7a47a27ed7f54bf3e4b1ade95 Mon Sep 17 00:00:00 2001 From: Rachael Wright-Munn Date: Sun, 8 Nov 2020 13:40:46 -0500 Subject: [PATCH 1/2] Add court_report_status and court_report_submitted_at to track court reports --- app/decorators/casa_case_decorator.rb | 6 +- app/models/casa_case.rb | 42 ++++++++----- app/policies/casa_case_policy.rb | 1 + app/views/casa_cases/_form.html.erb | 5 +- app/views/casa_cases/show.html.erb | 6 +- ...3_add_court_report_status_to_casa_cases.rb | 6 ++ db/schema.rb | 4 +- spec/decorators/casa_case_decorator_spec.rb | 46 ++++++++++++++ spec/decorators/case_decorator_spec.rb | 22 ------- spec/factories/casa_case.rb | 1 + spec/models/casa_case_spec.rb | 60 ++++++++++++++++++- spec/requests/casa_cases_spec.rb | 8 +-- 12 files changed, 161 insertions(+), 46 deletions(-) create mode 100644 db/migrate/20201108142333_add_court_report_status_to_casa_cases.rb create mode 100644 spec/decorators/casa_case_decorator_spec.rb delete mode 100644 spec/decorators/case_decorator_spec.rb diff --git a/app/decorators/casa_case_decorator.rb b/app/decorators/casa_case_decorator.rb index fb73b7f2c4..287d99331c 100644 --- a/app/decorators/casa_case_decorator.rb +++ b/app/decorators/casa_case_decorator.rb @@ -14,7 +14,11 @@ def transition_aged_youth_only_icon end def court_report_submission - object.court_report_submitted ? "Submitted" : "Not Submitted" + object.court_report_status.humanize + end + + def court_report_submitted_date + object.court_report_submitted_at&.strftime('%B%e, %Y') end def case_contacts_ordered_by_occurred_at diff --git a/app/models/casa_case.rb b/app/models/casa_case.rb index f517f65e62..537e5e017a 100644 --- a/app/models/casa_case.rb +++ b/app/models/casa_case.rb @@ -23,6 +23,8 @@ class CasaCase < ApplicationRecord has_many :contact_types, through: :casa_case_contact_types, source: :contact_type accepts_nested_attributes_for :casa_case_contact_types + enum court_report_status: { not_submitted: 0, submitted: 1, in_review: 2, completed: 3 }, _prefix: :court_report + scope :ordered, -> { order(updated_at: :desc) } scope :actively_assigned_to, ->(volunteer) { joins(:case_assignments).where( @@ -62,6 +64,16 @@ class CasaCase < ApplicationRecord delegate :name, to: :hearing_type, prefix: true, allow_nil: true delegate :name, to: :judge, prefix: true, allow_nil: true + def court_report_status=(value) + super + if (court_report_not_submitted?) + self.court_report_submitted_at = nil + else + self.court_report_submitted_at ||= Time.current + end + court_report_status + end + def self.available_for_volunteer(volunteer) ids = connection.select_values(%{ SELECT casa_cases.id @@ -96,7 +108,7 @@ def clear_court_dates if court_date && court_date < Time.current update(court_date: nil, court_report_due_date: nil, - court_report_submitted: false) + court_report_status: :not_submitted) end end @@ -136,19 +148,21 @@ def parse_date(date_field_name, args) # # Table name: casa_cases # -# id :bigint not null, primary key -# active :boolean default(TRUE), not null -# birth_month_year_youth :datetime -# case_number :string not null -# court_date :datetime -# court_report_due_date :datetime -# court_report_submitted :boolean default(FALSE), not null -# transition_aged_youth :boolean default(FALSE), not null -# created_at :datetime not null -# updated_at :datetime not null -# casa_org_id :bigint not null -# hearing_type_id :bigint -# judge_id :bigint +# id :bigint not null, primary key +# active :boolean default(TRUE), not null +# birth_month_year_youth :datetime +# case_number :string not null +# court_date :datetime +# court_report_due_date :datetime +# court_report_status :integer default("not_submitted") +# court_report_submitted :boolean default(FALSE), not null +# court_report_submitted_at :datetime +# transition_aged_youth :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# casa_org_id :bigint not null +# hearing_type_id :bigint +# judge_id :bigint # # Indexes # diff --git a/app/policies/casa_case_policy.rb b/app/policies/casa_case_policy.rb index 725e61ffb8..15dac5e2db 100644 --- a/app/policies/casa_case_policy.rb +++ b/app/policies/casa_case_policy.rb @@ -65,6 +65,7 @@ def assign_volunteers? def permitted_attributes common_attrs = [ :court_report_submitted, + :court_report_status, casa_case_contact_types_attributes: [:contact_type_id] ] diff --git a/app/views/casa_cases/_form.html.erb b/app/views/casa_cases/_form.html.erb index f545567e2d..9cf0ee5981 100644 --- a/app/views/casa_cases/_form.html.erb +++ b/app/views/casa_cases/_form.html.erb @@ -104,9 +104,10 @@ <%= form.check_box :transition_aged_youth %> <% end %> +
- <%= form.label :court_report_submitted %> - <%= form.check_box :court_report_submitted %> + <%= form.label :court_report_status %> + <%= form.select :court_report_status, CasaCase.court_report_statuses.map { |status| [status.first.humanize, status.first] } %>
<% if Pundit.policy(current_user, casa_case).update_contact_types? %> diff --git a/app/views/casa_cases/show.html.erb b/app/views/casa_cases/show.html.erb index 6047fb152c..029cc4d0f2 100644 --- a/app/views/casa_cases/show.html.erb +++ b/app/views/casa_cases/show.html.erb @@ -45,9 +45,13 @@

-

Court Report Submission: <%= @casa_case.decorate.court_report_submission %> +
Court Report Status: <%= @casa_case.decorate.court_report_submission %>

+ <% if @casa_case.court_report_submitted_at %> +

Court Report Submitted Date: <%= @casa_case.decorate.court_report_submitted_date %>

+ <% end %> +
Assigned Volunteers:
<% policy_scope(assigned_volunteers(@casa_case)).each_with_index do |volunteer, index| %> diff --git a/db/migrate/20201108142333_add_court_report_status_to_casa_cases.rb b/db/migrate/20201108142333_add_court_report_status_to_casa_cases.rb new file mode 100644 index 0000000000..e7cf6f628a --- /dev/null +++ b/db/migrate/20201108142333_add_court_report_status_to_casa_cases.rb @@ -0,0 +1,6 @@ +class AddCourtReportStatusToCasaCases < ActiveRecord::Migration[6.0] + def change + add_column :casa_cases, :court_report_submitted_at, :datetime + add_column :casa_cases, :court_report_status, :integer, default: 0, not_null: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 3e968ea198..7c0642cc7f 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.define(version: 2020_10_25_162142) do +ActiveRecord::Schema.define(version: 2020_11_08_142333) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -70,6 +70,8 @@ t.bigint "hearing_type_id" t.boolean "active", default: true, null: false t.bigint "judge_id" + t.datetime "court_report_submitted_at" + t.integer "court_report_status", default: 0 t.index ["casa_org_id"], name: "index_casa_cases_on_casa_org_id" t.index ["case_number"], name: "index_casa_cases_on_case_number", unique: true t.index ["hearing_type_id"], name: "index_casa_cases_on_hearing_type_id" diff --git a/spec/decorators/casa_case_decorator_spec.rb b/spec/decorators/casa_case_decorator_spec.rb new file mode 100644 index 0000000000..79c839c05d --- /dev/null +++ b/spec/decorators/casa_case_decorator_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +RSpec.describe CasaCaseDecorator do + describe "#court_report_submission" do + subject { casa_case.decorate.court_report_submission } + let(:casa_case) { build(:casa_case, court_report_status: court_report_status) } + + context "when case_report_status is not_submitted" do + let(:court_report_status) { :not_submitted } + + it { is_expected.to eq('Not submitted') } + end + + context "when case_report_status is submitted" do + let(:court_report_status) { :submitted } + + it { is_expected.to eq('Submitted') } + end + + context "when case_report_status is in_review" do + let(:court_report_status) { :in_review } + + it { is_expected.to eq('In review') } + end + + context "when case_report_status is completed" do + let(:court_report_status) { :completed } + + it { is_expected.to eq('Completed') } + end + end + + describe "#court_report_submission" do + subject { casa_case.decorate.court_report_submitted_date } + let(:submitted_time) { Time.parse("Sun Nov 08 11:06:20 2020") } + let(:casa_case) { build(:casa_case, court_report_submitted_at: submitted_time) } + + it { is_expected.to eq 'November 8, 2020' } + + context 'when report is not submitted' do + let(:submitted_time) { nil } + + it { is_expected.to be_nil } + end + end +end diff --git a/spec/decorators/case_decorator_spec.rb b/spec/decorators/case_decorator_spec.rb deleted file mode 100644 index 23ad63c940..0000000000 --- a/spec/decorators/case_decorator_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require "rails_helper" - -RSpec.describe CasaCaseDecorator do - describe "#court_report_submission" do - context "when case_report_submitted is false" do - it "returns Not Submitted" do - casa_case = create(:casa_case) - - expect(casa_case.decorate.court_report_submission).to eq "Not Submitted" - end - end - - context "when duration_minutes is greater than 60" do - it "when court_report_submitted is true" do - casa_case = create(:casa_case) - casa_case.court_report_submitted = true - - expect(casa_case.decorate.court_report_submission).to eq "Submitted" - end - end - end -end diff --git a/spec/factories/casa_case.rb b/spec/factories/casa_case.rb index 53d0f82a68..bb253e7728 100644 --- a/spec/factories/casa_case.rb +++ b/spec/factories/casa_case.rb @@ -6,6 +6,7 @@ casa_org hearing_type judge + court_report_status { :not_submitted } trait :with_case_assignments do case_assignments { build_list(:case_assignment, 2) } diff --git a/spec/models/casa_case_spec.rb b/spec/models/casa_case_spec.rb index 1b48b65969..84a6f1c1a4 100644 --- a/spec/models/casa_case_spec.rb +++ b/spec/models/casa_case_spec.rb @@ -67,6 +67,64 @@ end end + describe '#court_report_status=' do + let(:casa_case) { build(:casa_case) } + subject { casa_case.court_report_status = court_report_status } + + let(:submitted_time) { Time.parse("Sun Nov 08 11:06:20 2020") } + let(:the_future) { submitted_time + 2.days } + before do + travel_to submitted_time + end + + after do + travel_back + end + + context 'when the case is already submitted' do + let(:casa_case) { build(:casa_case, court_report_status: :submitted, court_report_submitted_at: submitted_time) } + before do + travel_to the_future + end + + context 'when the status is completed' do + let(:court_report_status) { :completed } + + it 'completes the court report and does not update time' do + is_expected.to eq :completed + expect(casa_case.court_report_submitted_at).to eq(submitted_time) + end + end + + context 'when the status is not_submitted' do + let(:court_report_status) { :not_submitted } + + it 'clears submission date and value' do + is_expected.to eq :not_submitted + expect(casa_case.court_report_submitted_at).to be_nil + end + end + end + + context 'when status is submitted' do + let(:court_report_status) { :submitted } + + it 'tracks the court report submission' do + is_expected.to eq :submitted + expect(casa_case.court_report_submitted_at).to eq(submitted_time) + end + end + + context 'when the status is in review' do + let(:court_report_status) { :in_review } + + it 'tracks the court report submission' do + is_expected.to eq :in_review + expect(casa_case.court_report_submitted_at).to eq(submitted_time) + end + end + end + describe ".available_for_volunteer" do let(:casa_org) { create(:casa_org) } let!(:casa_case1) { create(:casa_case, :with_case_assignments, case_number: "foo", casa_org: casa_org) } @@ -127,7 +185,7 @@ end it "sets court report as unsubmitted" do - casa_case = create(:casa_case, court_date: "2020-09-13 02:11:58", court_report_submitted: true) + casa_case = create(:casa_case, court_date: "2020-09-13 02:11:58", court_report_status: :submitted) casa_case.clear_court_dates expect(casa_case.court_report_submitted).to be false diff --git a/spec/requests/casa_cases_spec.rb b/spec/requests/casa_cases_spec.rb index 6526a38f44..25224b657e 100644 --- a/spec/requests/casa_cases_spec.rb +++ b/spec/requests/casa_cases_spec.rb @@ -163,7 +163,7 @@ let(:new_attributes) { { case_number: "12345", - court_report_submitted: true, + court_report_status: :submitted, hearing_type_id: hearing_type.id, judge_id: judge.id } @@ -172,7 +172,7 @@ it "updates permitted fields" do patch casa_case_url(casa_case), params: {casa_case: new_attributes} casa_case.reload - expect(casa_case.court_report_submitted).to be true + expect(casa_case.submitted?).to be_truthy # Not permitted expect(casa_case.case_number).to eq "111" @@ -222,13 +222,13 @@ describe "PATCH /update" do context "with valid parameters" do - let(:new_attributes) { {case_number: "12345", court_report_submitted: true} } + let(:new_attributes) { {case_number: "12345", court_report_status: :completed} } it "updates fields (except case_number)" do patch casa_case_url(casa_case), params: {casa_case: new_attributes} casa_case.reload expect(casa_case.case_number).to eq "111" - expect(casa_case.court_report_submitted).to be true + expect(casa_case.completed?).to be true end it "redirects to the casa_case" do From c8230d630eb8112b772adb9d2a93f3ef6d9d1446 Mon Sep 17 00:00:00 2001 From: Rachael Wright-Munn Date: Sun, 8 Nov 2020 13:42:29 -0500 Subject: [PATCH 2/2] BackFill court_report_status and court_report_submitted_at using court_report_submitted --- ...8181154_backfill_court_report_submitted_at.rake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/tasks/deployment/20201108181154_backfill_court_report_submitted_at.rake diff --git a/lib/tasks/deployment/20201108181154_backfill_court_report_submitted_at.rake b/lib/tasks/deployment/20201108181154_backfill_court_report_submitted_at.rake new file mode 100644 index 0000000000..040e309a92 --- /dev/null +++ b/lib/tasks/deployment/20201108181154_backfill_court_report_submitted_at.rake @@ -0,0 +1,14 @@ +namespace :after_party do + desc 'Deployment task: Backfill court_report_submitted_at and court_report_status' + task backfill_court_report_submitted_at: :environment do + puts "Running deploy task 'backfill_court_report_submitted_at'" + + CasaCase.where(court_report_submitted: true).in_batches.update_all(court_report_status: :submitted, + court_report_submitted_at: Time.current) + + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord + .create version: AfterParty::TaskRecorder.new(__FILE__).timestamp + end +end