From 5f93c340b088c96d039eb7070ef5ed74df848575 Mon Sep 17 00:00:00 2001
From: jesse-b-wilcore <246108663+jesse-b-wilcore@users.noreply.github.com>
Date: Wed, 15 Jul 2026 18:04:39 +0000
Subject: [PATCH] Adding reimbursement status badge
---
app/decorators/case_contact_decorator.rb | 15 +++++--
.../case_contacts/_case_contact.html.erb | 11 +++++
.../decorators/case_contact_decorator_spec.rb | 40 ++++++++++++++++++-
spec/system/case_contacts/index_spec.rb | 38 ++++++++++++++++++
4 files changed, 98 insertions(+), 6 deletions(-)
diff --git a/app/decorators/case_contact_decorator.rb b/app/decorators/case_contact_decorator.rb
index 3b40bd22f0..0f1f6c915f 100644
--- a/app/decorators/case_contact_decorator.rb
+++ b/app/decorators/case_contact_decorator.rb
@@ -23,8 +23,16 @@ def miles_traveled
object.miles_driven.zero? ? nil : "#{object.miles_driven} miles driven"
end
- def reimbursement
- object.want_driving_reimbursement ? "Reimbursement" : nil
+ # Text for the reimbursement status badge shown on the case contact card so
+ # volunteers can see at a glance whether their reimbursement is still pending
+ # or has been completed, without having to ask their supervisor.
+ def reimbursement_status_text
+ object.reimbursement_complete? ? "Reimbursement Complete" : "Reimbursement Pending"
+ end
+
+ # Bootstrap badge color for the reimbursement status.
+ def reimbursement_status_badge_type
+ object.reimbursement_complete? ? :success : :warning
end
def contact_made
@@ -40,8 +48,7 @@ def subheading
I18n.l(object.occurred_at, format: :full, default: nil),
duration_minutes,
contact_made,
- miles_traveled,
- reimbursement
+ miles_traveled
].compact.join(" | ")
end
diff --git a/app/views/case_contacts/_case_contact.html.erb b/app/views/case_contacts/_case_contact.html.erb
index fbabde64af..152b4db64a 100644
--- a/app/views/case_contacts/_case_contact.html.erb
+++ b/app/views/case_contacts/_case_contact.html.erb
@@ -13,6 +13,17 @@
<% if !contact.active? %>
Draft
<% end %>
+ <% if contact.want_driving_reimbursement? %>
+ <% decorated_contact = contact.decorate %>
+
+ <%= render BadgeComponent.new(
+ text: decorated_contact.reimbursement_status_text,
+ type: decorated_contact.reimbursement_status_badge_type,
+ rounded: true,
+ margin: false
+ ) %>
+
+ <% end %>
<%= link_to("undelete", restore_case_contact_path(contact.id), method: :post, data: { turbo: false },
class: "btn btn-info") if policy(contact).restore? && contact.deleted? %>
diff --git a/spec/decorators/case_contact_decorator_spec.rb b/spec/decorators/case_contact_decorator_spec.rb
index 9ee95352bf..de070d7ac3 100644
--- a/spec/decorators/case_contact_decorator_spec.rb
+++ b/spec/decorators/case_contact_decorator_spec.rb
@@ -155,7 +155,7 @@
case_contact.contact_types = [contact_type]
expect(case_contact.decorate.subheading).to eq(
- "December 1, 2020 | 1 hour 39 minutes | No Contact Made | 100 miles driven | Reimbursement"
+ "December 1, 2020 | 1 hour 39 minutes | No Contact Made | 100 miles driven"
)
end
end
@@ -166,9 +166,45 @@
case_contact.contact_types = [contact_type]
expect(case_contact.decorate.subheading).to eq(
- "December 1, 2020 | 1 hour 39 minutes | 100 miles driven | Reimbursement"
+ "December 1, 2020 | 1 hour 39 minutes | 100 miles driven"
)
end
end
end
+
+ describe "#reimbursement_status_text" do
+ context "when the reimbursement has not been completed" do
+ let(:case_contact) { build(:case_contact, reimbursement_complete: false) }
+
+ it "returns pending text" do
+ expect(case_contact.decorate.reimbursement_status_text).to eq("Reimbursement Pending")
+ end
+ end
+
+ context "when the reimbursement has been completed" do
+ let(:case_contact) { build(:case_contact, reimbursement_complete: true) }
+
+ it "returns complete text" do
+ expect(case_contact.decorate.reimbursement_status_text).to eq("Reimbursement Complete")
+ end
+ end
+ end
+
+ describe "#reimbursement_status_badge_type" do
+ context "when the reimbursement has not been completed" do
+ let(:case_contact) { build(:case_contact, reimbursement_complete: false) }
+
+ it "returns the warning badge type" do
+ expect(case_contact.decorate.reimbursement_status_badge_type).to eq(:warning)
+ end
+ end
+
+ context "when the reimbursement has been completed" do
+ let(:case_contact) { build(:case_contact, reimbursement_complete: true) }
+
+ it "returns the success badge type" do
+ expect(case_contact.decorate.reimbursement_status_badge_type).to eq(:success)
+ end
+ end
+ end
end
diff --git a/spec/system/case_contacts/index_spec.rb b/spec/system/case_contacts/index_spec.rb
index a0ab7e5f1c..f15f380b74 100644
--- a/spec/system/case_contacts/index_spec.rb
+++ b/spec/system/case_contacts/index_spec.rb
@@ -61,6 +61,44 @@
end
end
+ describe "reimbursement status" do
+ it "shows a pending badge when the reimbursement has not been completed" do
+ create(:case_contact, :wants_reimbursement, creator: volunteer, casa_case: casa_case,
+ occurred_at: 2.days.ago, reimbursement_complete: false)
+
+ subject
+
+ within(".full-card", match: :first) do
+ expect(page).to have_text("Reimbursement Pending")
+ expect(page).to have_no_text("Reimbursement Complete")
+ end
+ end
+
+ it "shows a complete badge when the reimbursement has been completed" do
+ create(:case_contact, :wants_reimbursement, creator: volunteer, casa_case: casa_case,
+ occurred_at: 2.days.ago, reimbursement_complete: true)
+
+ subject
+
+ within(".full-card", match: :first) do
+ expect(page).to have_text("Reimbursement Complete")
+ expect(page).to have_no_text("Reimbursement Pending")
+ end
+ end
+
+ it "shows no reimbursement badge when reimbursement was not requested" do
+ create(:case_contact, creator: volunteer, casa_case: casa_case, occurred_at: 2.days.ago,
+ want_driving_reimbursement: false)
+
+ subject
+
+ within(".full-card", match: :first) do
+ expect(page).to have_no_text("Reimbursement Pending")
+ expect(page).to have_no_text("Reimbursement Complete")
+ end
+ end
+ end
+
describe "automated filtering case contacts" do
describe "by date of contact" do
it "only shows the contacts with the correct date", :js do