Skip to content

Commit

Permalink
Fix 5780 (#5991)
Browse files Browse the repository at this point in the history
* add crud methods for case-specific placements

* add placement destroy action

* final functionalities added: use Modal Components, create & new actions

* cleanup unused things

* write unit tests for added placement views

* run linter

* ensure placement_types are not hardcoded but still org-specific

* add back placement show action and placement decorators

* undo placement_types factory change

* fix-5780: add placement_policy_spec.rb

* undo config change

* fix failing tests for casa_case.show

* clean up placements, remove most added error handling and _placements partial table

* fix placement policy on certain actions

* add system specs for CRUD actions on placements

* fix failing tests

* update placement policies

* update spec/system/placements/index_spec.rb test

* flaky test fixes

* add policy scope for placements index action

* update placement policy scope

* please linter

* Update config/environments/test.rb

Co-authored-by: Jon Roberts <[email protected]>

* Update config/environments/test.rb

Co-authored-by: Jon Roberts <[email protected]>

* dont display placement info on casa case when org has no placement types yet

* run linter

---------

Co-authored-by: Jon Roberts <[email protected]>
  • Loading branch information
guswhitten and thejonroberts authored Sep 6, 2024
1 parent ac35c95 commit b682c08
Show file tree
Hide file tree
Showing 27 changed files with 575 additions and 28 deletions.
2 changes: 1 addition & 1 deletion app/assets/stylesheets/pages/casa_cases.scss
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,4 @@ body.casa_cases-show {
flex-direction: column;
gap: .2rem;
}
}
}
38 changes: 36 additions & 2 deletions app/controllers/placements_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,52 @@ class PlacementsController < ApplicationController
before_action :set_placement, only: %i[edit show generate update destroy]
before_action :require_organization!

rescue_from ActiveRecord::RecordNotFound, with: -> { head :not_found }
def index
@placements = policy_scope(@casa_case.placements).includes(:placement_type).order(placement_started_at: :desc)
end

def show
authorize @casa_case
authorize @placement
end

def new
@placement = Placement.new(casa_case: @casa_case)
authorize @placement
end

def edit
authorize @placement
end

def create
@placement = Placement.new(placement_params)
authorize @placement

if @placement.save
redirect_to casa_case_placements_path(@casa_case), notice: "Placement was successfully created."
else
render :new, status: :unprocessable_entity
end
end

def update
authorize @placement

if @placement.update(placement_params)
redirect_to casa_case_placements_path(@casa_case), notice: "Placement was successfully updated."
else
render :edit, status: :unprocessable_entity
end
end

def destroy
authorize @placement

if @placement.destroy
redirect_to casa_case_placements_path(@casa_case), notice: "Placement was successfully deleted."
else
render :edit, status: :unprocessable_entity
end
end

private
Expand All @@ -33,4 +60,11 @@ def set_casa_case
def set_placement
@placement = @casa_case.placements.find(params[:id])
end

def placement_params
params.require(:placement).permit(
:placement_started_at,
:placement_type_id
).merge({creator_id: current_user.id, casa_case_id: @casa_case.id})
end
end
1 change: 1 addition & 0 deletions app/models/casa_org.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class CasaOrg < ApplicationRecord
has_many :contact_topics
has_one_attached :logo
has_one_attached :court_report_template
has_many :placement_types, dependent: :destroy

def casa_admins
CasaAdmin.in_organization(self)
Expand Down
1 change: 1 addition & 0 deletions app/models/placement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Placement < ApplicationRecord
belongs_to :casa_case
belongs_to :placement_type
belongs_to :creator, class_name: "User"
has_one :casa_org, through: :casa_case

validates :placement_started_at, comparison: {
greater_than_or_equal_to: "1989-01-01".to_date,
Expand Down
3 changes: 3 additions & 0 deletions app/models/placement_type.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
class PlacementType < ApplicationRecord
belongs_to :casa_org

validates :name, presence: true
scope :for_organization, ->(org) { where(casa_org: org) }
scope :order_alphabetically, -> { order(:name) }
end

# == Schema Information
Expand Down
26 changes: 26 additions & 0 deletions app/policies/placement_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class PlacementPolicy < ApplicationPolicy
class Scope < ApplicationPolicy::Scope
def resolve
return scope.none unless @user&.casa_org

scope.joins(:casa_case).where(casa_cases: {casa_org: @user.casa_org})
end
end

def allowed_to_edit_casa_case?
casa_case_policy.edit?
end

alias_method :show?, :allowed_to_edit_casa_case?
alias_method :edit?, :allowed_to_edit_casa_case?
alias_method :update?, :allowed_to_edit_casa_case?
alias_method :new?, :allowed_to_edit_casa_case?
alias_method :create?, :allowed_to_edit_casa_case?
alias_method :destroy?, :admin_or_supervisor?

private

def casa_case_policy
CasaCasePolicy.new(user, record.casa_case)
end
end
29 changes: 17 additions & 12 deletions app/views/casa_cases/_placements.html.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<% placements = casa_case.placements %>
<label>Placements:</label>
<% if placements.empty? %>
No Placements
<% else %>
<ul>
<% placements.each do |pcd| %>
<p>
<%= link_to(pcd.decorate.placement_info, casa_case_placement_path(casa_case, pcd)) %>
</p>
<% end %>
</ul>
<% current_placement = casa_case.placements.order(placement_started_at: :desc).first %>

<% if current_placement %>
<h6>
<strong>Current Placement:</strong>
<%= current_placement.placement_type.name %>
</h6>

<p>Placed since: <%= current_placement.decorate.formatted_date %></p>
<p><%= link_to "See All Placements", casa_case_placements_path(casa_case), class: 'text-primary hover-underline' %></p>
<% elsif casa_case.casa_org.placement_types.present? %>
<h6>
<strong>Current Placement:</strong>
Unknown
</h6>

<p><%= link_to "See All Placements", casa_case_placements_path(casa_case), class: 'text-primary hover-underline' %></p>
<% end %>
18 changes: 18 additions & 0 deletions app/views/placements/_fields.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="input-style-1">
<%= form.label :placement_started_at, "Placement Started At" %>
<%= form.date_field :placement_started_at,
value: placement.placement_started_at&.to_date || Time.zone.now,
class: "form-control" %>
</div>
<div class="select-style-1">
<%= form.label :placement_type_id, "Placement Type" %>
<div class="select-position">
<%= form.collection_select(
:placement_type_id,
PlacementType.for_organization(current_organization).order_alphabetically,
:id, :name,
{include_hidden: false, include_blank: "-Select Placement Type-"},
{class: "form-control"}
) %>
</div>
</div>
29 changes: 29 additions & 0 deletions app/views/placements/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div class="card-style mb-30">
<div class="alert-box danger-alert">
<%= render "/shared/error_messages", resource: placement %>
</div>
<%= form_with(model: placement, url: [casa_case, placement], local: true,
data: { controller: "placement-form", nested_form_wrapper_selector_value: ".nested-form-wrapper" }) do |form| %>
<div class="row align-items-center">
<div class="col-md-6">
<h6><strong>Case Number:</strong> <%= link_to casa_case.case_number, casa_case %></h6>
</div>
<div class="col-md-6">
<div class="breadcrumb-wrapper">
<span class="top-page-actions ml-5">
<%= button_tag(type: "submit", class: "btn-sm main-btn primary-btn btn-hover") do %>
<% if placement.persisted? %>
<i class="lni lni-pencil-alt"></i> Update
<% else %>
<i class="lni lni-plus"></i> Create
<% end %>
<% end %>
</span>
</div>
</div>
</div>
<div class="row align-items-center">
<%= render 'placements/fields', placement: placement, form: form, casa_case: casa_case %>
</div>
<% end %>
</div>
11 changes: 11 additions & 0 deletions app/views/placements/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="title-wrapper pt-30">
<div class="row align-items-center">
<div class="col-md-6">
<div class="title mb-30">
<h1>Editing Placement</h1>
</div>
</div>
</div>
</div>

<%= render 'form', casa_case: @casa_case, placement: @placement %>
69 changes: 69 additions & 0 deletions app/views/placements/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<div class="title-wrapper pt-30">
<div class="row align-items-center">
<div class="col-md-6">
<div class="title mb-30">
<h1>Placement History for
<%= link_to "#{@casa_case.case_number}", casa_case_path(@casa_case) %>
</h1>
</div>
</div>
<div class="col-md-6">
<div class="breadcrumb-wrapper mb-30">
<%= link_to new_casa_case_placement_path(@casa_case), class: "main-btn btn-sm primary-btn btn-hover ml-3" do %>
<i class="lni lni-plus"></i>
New Placement
<% end %>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card-style mb-30">
<table class="table">
<thead>
<tr>
<th>Placement Type</th>
<th>Date</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @placements.each_with_index do |placement, idx| %>
<tr>
<td><%= placement.placement_type.name %></td>
<td>
<%= placement.decorate.formatted_date %>
-
<% if idx.zero? %>
Present
<% elsif @placements[idx - 1].placement_started_at %>
<%= @placements[idx - 1].decorate.formatted_date %>
<% end %>
</td>
<td><%= link_to edit_casa_case_placement_path(@casa_case, placement), class: "btn-sm main-btn primary-btn-outline btn-hover ms-auto" do %>
<i class="lni lni-pencil-alt"></i>
Edit
<% end %>
</td>
<td>
<%= render(Modal::OpenLinkComponent.new(target: placement.id, klass: "btn-sm main-btn danger-btn-outline btn-hover ms-auto")) do %>
<i class="lni lni-trash-can"></i>
Delete
<% end %>
</td>
</tr>
<%= render(Modal::GroupComponent.new(id: placement.id)) do |component| %>
<% component.with_header(text: "Delete Placement?", id: placement.id) %>
<% component.with_footer do %>
<%= link_to casa_case_placement_path(@casa_case, placement), method: :delete, class: "btn-sm main-btn danger-btn btn-hover ms-auto" do %>
<i class="lni lni-trash-can"></i>
Confirm
<% end %>
<% end %>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>
11 changes: 11 additions & 0 deletions app/views/placements/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="title-wrapper pt-30">
<div class="row align-items-center">
<div class="col-md-6">
<div class="title mb-30">
<h1>New Placement</h1>
</div>
</div>
</div>
</div>

<%= render 'form', casa_case: @casa_case, placement: @placement %>
2 changes: 1 addition & 1 deletion app/views/placements/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</div>
<div class="col-md-6">
<div class="breadcrumb-wrapper mb-30">
<%= link_to '#', class: "btn-sm main-btn primary-btn btn-hover" do %>
<%= link_to edit_casa_case_placement_path(@casa_case, @placement), class: "btn-sm main-btn primary-btn btn-hover" do %>
<i class="lni lni-pencil-alt mr-10"></i>
Edit
<% end %>
Expand Down
2 changes: 0 additions & 2 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# Settings specified here will take precedence over those in config/application.rb.
config.action_mailer.default_url_options = {host: "localhost", port: 3000} # for devise authentication
# While tests run files are not watched, reloading is not necessary.
config.enable_reloading = false
# Turn false under Spring and add config.action_view.cache_template_loading = true.
config.action_view.cache_template_loading = true

Expand All @@ -20,7 +19,6 @@
config.eager_load = ENV["CI"].present?
# cache classes on CI, but enable reloading for local work (bin/rspec)
config.enable_reloading = ENV["CI"].blank?

# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@

resources :court_dates, only: %i[create edit new show update destroy]

resources :placements, only: %i[create edit new show update destroy]
resources :placements

member do
patch :deactivate
Expand Down
10 changes: 10 additions & 0 deletions spec/factories/casa_orgs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,15 @@
trait :with_logo do
logo { Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "org_logo.jpeg")) }
end

trait :with_placement_types do
transient { placement_names { ["Reunification", "Adoption", "Foster Care", "Kinship"] } }

after(:create) do |org, evaluator|
evaluator.placement_names.each do |name|
org.placement_types.create!(name: name)
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/factories/placements.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FactoryBot.define do
factory :placement do
association :creator, factory: :user
casa_case
placement_type
placement_started_at { DateTime.now }
creator { association :user }
end
end
Loading

0 comments on commit b682c08

Please sign in to comment.