Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4241 change agency type to enum #4931

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2566e16
Update agency_type to be an enum
Benjamin-Couey Jan 10, 2025
4e156a2
Created new I18n config file to translate agency_type codes to descri…
Benjamin-Couey Jan 16, 2025
b8a4d61
Applied translation of agency_type code to descriptive strings in views
Benjamin-Couey Jan 16, 2025
7c9d8a8
Applied translation of agency_type code in partner info report
Benjamin-Couey Jan 16, 2025
9521d48
Updated existing tests to refer to enum
Benjamin-Couey Jan 16, 2025
f840bb0
Updated Partner.agency_info to refer to new enum instead of AGENCY_TY…
Benjamin-Couey Jan 16, 2025
de2d69f
Removed unecessary brackets
Benjamin-Couey Jan 16, 2025
c5e260d
Added comment warning people away from using AGENCY_TYPES
Benjamin-Couey Jan 16, 2025
6c1625c
Created migration to update existing agency_type values to enum values
Benjamin-Couey Jan 17, 2025
c62835c
Changes made by linter
Benjamin-Couey Jan 17, 2025
93feb8f
Merge branch 'main' into 4241-change-agency-type-to-enum
Benjamin-Couey Jan 17, 2025
ec45472
Cleaned up formatting, removed puts statements, ran through linter
Benjamin-Couey Jan 18, 2025
21a8cd3
Reformatted :agency_type so each entry is on one line
Benjamin-Couey Jan 21, 2025
f32237d
Fixed test using and expecting enum values
Benjamin-Couey Jan 21, 2025
74073cb
Changed calculation of agency_type symbols to more performant impleme…
Benjamin-Couey Jan 21, 2025
a516804
Changes made by linter
Benjamin-Couey Jan 21, 2025
1f4bd43
Removed old cleanup of partner agency types and associated mapping fr…
Benjamin-Couey Jan 21, 2025
596e79c
Updated mapping in migration to handle agency_type values previously …
Benjamin-Couey Jan 21, 2025
2987a2a
Merge branch 'main' into 4241-change-agency-type-to-enum
Benjamin-Couey Jan 21, 2025
b5606af
Fixed using wrong function to symbolize strings
Benjamin-Couey Jan 22, 2025
2e5a0a1
Updated agency_info to translate agency_types for now
Benjamin-Couey Jan 22, 2025
9fc8950
Fixed views not comparing agency_type to enum keys
Benjamin-Couey Jan 23, 2025
723d43d
Merge branch 'main' into 4241-change-agency-type-to-enum
Benjamin-Couey Jan 23, 2025
761195b
Merge branch 'main' into 4241-change-agency-type-to-enum
Benjamin-Couey Jan 31, 2025
4ac097d
Added agency_types_for_selection function to provide sorted agency ty…
Benjamin-Couey Feb 3, 2025
01a9ebf
Merge branch 'main' into 4241-change-agency-type-to-enum
Benjamin-Couey Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/models/partner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ class Partner < ApplicationRecord
where(status: status.to_sym)
}

# This constant mapping is preserved as it is a dependency of
# 20241122201255_cleanup_partner_agency_types.rb. In all other cases, one should
# refer to Partners::Profile.agency_types for a list of profile agency_types,
# and use I18n.t scope: :partners_profile to convert from an agency_type code
# to a descriptive string.
AGENCY_TYPES = {
"CAREER" => "Career technical training",
"ABUSE" => "Child abuse resource center",
Expand Down Expand Up @@ -241,13 +246,14 @@ def agency_info

return {} if profile.blank?

symbolic_agency_type = profile.agency_type&.to_sym
@agency_info = {
address: [profile.address1, profile.address2].select(&:present?).join(', '),
city: profile.city,
state: profile.state,
zip_code: profile.zip_code,
website: profile.website,
agency_type: (profile.agency_type == AGENCY_TYPES["OTHER"]) ? "#{AGENCY_TYPES["OTHER"]}: #{profile.other_agency_type}" : profile.agency_type
agency_type: (symbolic_agency_type == :other) ? "#{Partners::Profile.agency_types[:other]}: #{profile.other_agency_type}" : profile.agency_type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming the values here are for display? Then I'd suggest

agency_type: (symbolic_agency_type == :other) ? "Other: #{profile.other_agency_type}" : profile.agency_type

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually - would we want to do i18n.translate for these values? As far as I can tell this is only used in the CSV export, so we should have readable strings here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had originally left profile.agency_type because @cielf had a recollection that the type codes were used in the CSV and some of the full descriptive strings seemed quite long for a CSV column..

Below are some screenshots of the CSV under different conditions. Which looks best?

CSV with full descriptive strings

PartnerCSVExportFullStrings

CSV with full descriptive strings (agency type column fully expanded)

PartnerCSVExportFullStringsWideColumn

CSV with untranslated type codes

PartnerCSVExportCodes

CSV with untranslated type codes, including `other_agency_type` for `:other`

PartnerCSVExportCodesOtherType

}
end

Expand Down
11 changes: 11 additions & 0 deletions app/models/partners/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ class Profile < Base
accepts_nested_attributes_for :served_areas, allow_destroy: true

has_many_attached :documents
enum :agency_type, other: "OTHER", career: "CAREER", abuse: "ABUSE", bnb: "BNB",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be reformatted so each value is on a single line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change in the recent commits.

church: "CHURCH", college: "COLLEGE", cdc: "CDC", health: "HEALTH",
outreach: "OUTREACH", legal: "LEGAL", crisis: "CRISIS", disab: "DISAB",
district: "DISTRICT", domv: "DOMV", ece: "ECE", child: "CHILD",
edu: "EDU", family: "FAMILY", food: "FOOD", foster: "FOSTER", govt: "GOVT",
headstart: "HEADSTART", homevisit: "HOMEVISIT", homeless: "HOMELESS",
hosp: "HOSP", infpan: "INFPAN", lib: "LIB", mhealth: "MHEALTH", military: "MILITARY",
police: "POLICE", preg: "PREG", presch: "PRESCH", ref: "REF", es: "ES",
hs: "HS", ms: "MS", senior: "SENIOR", tribal: "TRIBAL", treat: "TREAT",
twoycollege: "2YCOLLEGE", wic: "WIC"

validate :check_social_media, on: :edit

validate :client_share_is_0_or_100
Expand Down
2 changes: 1 addition & 1 deletion app/services/reports/partner_info_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def report

entries = { 'Number of Partner Agencies' => partner_agencies }
partner_agency_counts.each do |agency, count|
entries["Agency Type: #{agency || 'Unknown'}"] = count
entries["Agency Type: #{(I18n.t agency, scope: [:partners_profile]) || 'Unknown'}"] = count
end
entries['Zip Codes Served'] = partner_zipcodes_serviced
@report = { name: 'Partner Agencies and Service Area', entries: entries }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
</div>
<div class="card-body">
<%= form.input :name, label: "Agency Name", class: "form-control", wrapper: :input_group %>
<%= profile_form.input :agency_type, collection: Partner::AGENCY_TYPES.values, label: "Agency Type", class: "form-control", wrapper: :input_group %>
<%= profile_form.input :agency_type,
# Symbolize keys, because simple_form will only do a I18n lookup for
# symbols
collection: Partners::Profile.agency_types.symbolize_keys.keys,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a bit more performant to do Partners::Profile.agency_types.keys.map(&:symbolize), but I may be nitpicking here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change in the recent commits. For my own edification, why was my implementation less performant?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beacuse you go through the list of values twice, once to symbolize every key and then again to collect the keys from the entries. Like I said, it's a nitpick. :)

label: "Agency Type",
class: "form-control",
wrapper: :input_group %>
<%= profile_form.input :other_agency_type, label: "Other Agency Type", class: "form-control", wrapper: :input_group %>
<div class="form-group row">
<label class="control-label col-md-3">501(c)(3) IRS Determination Letter or other Proof of Agency Status</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<dd><%= profile.partner.name %></dd>

<dt>Agency Type</dt>
<dd><%= profile.agency_type %></dd>
<dd><%= t profile.agency_type, scope: :partners_profile %></dd>

<% if profile.agency_type == "Other" %>
<dt>Other Agency Type</dt>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@

<%= f.fields_for :profile, profile do |pf| %>
<div class="form-group">
<%= pf.input :agency_type, collection: Partner::AGENCY_TYPES.values, label: "Agency Type", class: "form-control", wrapper: :input_group %>
<%= pf.input :agency_type,
# Symbolize keys, because simple_form will only do a I18n lookup for
# symbols
collection: Partners::Profile.agency_types.symbolize_keys.keys,
label: "Agency Type",
class: "form-control",
wrapper: :input_group %>
</div>

<div class="form-group">
Expand Down
2 changes: 1 addition & 1 deletion app/views/profiles/_show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<%# The field for inputting the name registers it as partner.name, %>
<%# not partner_profile.name, so this pulls from partner.name %>
<p>Name: <%= @partner.name %></p>
<p>Agency Type: <%= partner_profile.agency_type %>
<p>Agency Type: <%= t partner_profile.agency_type, scope: :partners_profile %>
<% if partner_profile.agency_type == "Other" && partner_profile.other_agency_type %>
(<%= partner_profile.other_agency_type %>)
<% end %>
Expand Down
52 changes: 52 additions & 0 deletions config/locales/partners_profile.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
agency_type_map: &agency_type_map
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functional issue: "Other" is appearing at the top of the list of types when selecting. It should be at the bottom. Everything else should be in alphabetical order (by the full text) (though I note it isn't in staging --so the alpha thing could be a separate issue)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cielf alright this should be addressed in the most recent commit. Below is a screenshot demonstrating the new behavior.

Partner facing edit page with dropdown open

PartnerFacingEditPageDropdownAlphabetized

other: "Other"
career: "Career technical training"
abuse: "Child abuse resource center"
bnb: "Basic Needs Bank"
church: "Church outreach ministry"
college: "College and Universities"
cdc: "Community development corporation"
health: "Community health program or clinic"
outreach: "Community outreach services"
legal: "Correctional Facilities / Jail / Prison / Legal System"
crisis: "Crisis/Disaster services"
disab: "Developmental disabilities program"
district: "School District"
domv: "Domestic violence shelter"
ece: "Early Childhood Education/Childcare"
child: "Early childhood services"
edu: "Education program"
family: "Family resource center"
food: "Food bank/pantry"
foster: "Foster Program"
govt: "Government Agency/Affiliate"
headstart: "Head Start/Early Head Start"
homevisit: "Home visits"
homeless: "Homeless resource center"
hosp: "Hospital"
infpan: "Infant/Child Pantry/Closet"
lib: "Library"
mhealth: "Mental Health"
military: "Military Bases/Veteran Services"
police: "Police Station"
preg: "Pregnancy resource center"
presch: "Preschool"
ref: "Refugee resource center"
es: "School - Elementary School"
hs: "School - High School"
ms: "School - Middle School"
senior: "Senior Center"
tribal: "Tribal/Native-Based Organization"
treat: "Treatment clinic"
twoycollege: "Two-Year College"
wic: "Women, Infants and Children"

en:
partners_profile:
*agency_type_map

simple_form:
options:
profile:
agency_type:
*agency_type_map
77 changes: 77 additions & 0 deletions db/migrate/20250116180121_convert_partner_agency_types_to_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
class ConvertPartnerAgencyTypesToEnum < ActiveRecord::Migration[7.2]

def up
# A mapping from the lowercase full descriptive strings previously stored in
# agency_type to the newly enumerated values
string_to_value_mapping = {
"other" => "OTHER",
"career technical training" => "CAREER",
"child abuse resource center" => "ABUSE",
"basic needs bank" => "BNB",
"church outreach ministry" => "CHURCH",
"college and universities" => "COLLEGE",
"community development corporation" => "CDC",
"community health program or clinic" => "HEALTH",
"community outreach services" => "OUTREACH",
"correctional facilities / jail / prison / legal system" => "LEGAL",
"crisis/disaster services" => "CRISIS",
"developmental disabilities program" => "DISAB",
"school district" => "DISTRICT",
"domestic violence shelter" => "DOMV",
"early childhood education/childcare" => "ECE",
"early childhood services" => "CHILD",
"education program" => "EDU",
"family resource center" => "FAMILY",
"food bank/pantry" => "FOOD",
"foster program" => "FOSTER",
"government agency/affiliate" => "GOVT",
"head start/early head start" => "HEADSTART",
"home visits" => "HOMEVISIT",
"homeless resource center" => "HOMELESS",
"hospital" => "HOSP",
"infant/child pantry/closet" => "INFPAN",
"library" => "LIB",
"mental health" => "MHEALTH",
"military bases/veteran services" => "MILITARY",
"police station" => "POLICE",
"pregnancy resource center" => "PREG",
"preschool" => "PRESCH",
"refugee resource center" => "REF",
"school - elementary school" => "ES",
"school - high school" => "HS",
"school - middle school" => "MS",
"senior center" => "SENIOR",
"tribal/native-based organization" => "TRIBAL",
"treatment clinic" => "TREAT",
"two-year college" => "2YCOLLEGE",
"women, infants and children" => "WIC"
}

# Some agency types have trailing spaces -- need to get rid of them first
update 'UPDATE partner_profiles SET agency_type = TRIM(agency_type);'

profiles = Partners::Profile.all()
profiles.each do |profile|
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
profiles = Partners::Profile.all()
profiles.each do |profile|
Partners::Profile.all.each do |profile|

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change in the recent commits.

# Read the agency_type without casting so values not part of the enum aren't
# read as nil
current_agency_type = profile.read_attribute_before_type_cast(:agency_type)
puts profile.id
puts current_agency_type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these puts statements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change in the recent commits.

if !current_agency_type.nil?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !current_agency_type.nil?
if current_agency_type.present?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change in the recent commits.

# If a profile has a descriptive string (ignoring case) as an agency type
# update it to the associated value code.
if( string_to_value_mapping.key?( current_agency_type.downcase ) )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if( string_to_value_mapping.key?( current_agency_type.downcase ) )
if string_to_value_mapping.key?(current_agency_type.downcase)

(similarly below - not sure why lint didn't pick this up)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, for some reason the linter missed this file entirely. It only made corrections when I specified this file explicitly. Regardless, ran this through the inter in the recent commits.

profile.agency_type = string_to_value_mapping[ current_agency_type.downcase ]
# If a profile has a value code (ignoring case) as an agency type, uppercase it.
elsif( string_to_value_mapping.value?( current_agency_type.upcase ) )
profile.agency_type = current_agency_type.upcase
end
profile.save!
end
end
end

def down
# Irreversible data migration
end
end
2 changes: 1 addition & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2024_12_20_020009) do
ActiveRecord::Schema[7.2].define(version: 2025_01_16_180121) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down
4 changes: 2 additions & 2 deletions spec/models/partner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
let(:agency_state) { "ND" }
let(:agency_zipcode) { "09980-7010" }
let(:agency_website) { "bosco.example" }
let(:agency_type) { Partner::AGENCY_TYPES["OTHER"] }
let(:agency_type) { Partners::Profile.agency_types[:other] }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let(:agency_type) { Partners::Profile.agency_types[:other] }
let(:agency_type) { :other }

Copy link
Contributor Author

@Benjamin-Couey Benjamin-Couey Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change, and also fixed the test improperly expecting the enum value (OTHER). Might need to update this again depending on what we choose for the CSV export.

let(:other_agency_type) { "Another Agency Name" }
let(:notes) { "Some notes" }
let(:providing_diapers) { {value: "N", index: 13} }
Expand Down Expand Up @@ -335,7 +335,7 @@
agency_state,
agency_zipcode,
agency_website,
"#{Partner::AGENCY_TYPES["OTHER"]}: #{other_agency_type}",
"#{Partners::Profile.agency_types[:other]}: #{other_agency_type}",
contact_name,
contact_phone,
contact_email,
Expand Down
6 changes: 3 additions & 3 deletions spec/services/reports/partner_info_report_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@
context "with partners available" do
let!(:p1) do
create(:partner, :uninvited, organization: organization, name: 'Partner 1') do |p|
p.profile.update!(zips_served: '90210-1234', agency_type: Partner::AGENCY_TYPES['CAREER'])
p.profile.update!(zips_served: '90210-1234', agency_type: Partners::Profile.agency_types[:career])
end
end
let!(:p2) do
create(:partner, :uninvited, organization: organization, name: 'Partner 2') do |p|
p.profile.update!(zips_served: '12345', agency_type: Partner::AGENCY_TYPES['CAREER'])
p.profile.update!(zips_served: '12345', agency_type: Partners::Profile.agency_types[:career])
end
end
let!(:p3) do
create(:partner, :uninvited, organization: organization, name: 'Partner 3') do |p|
p.profile.update!(zips_served: '09876-3564', agency_type: Partner::AGENCY_TYPES['EDU'])
p.profile.update!(zips_served: '09876-3564', agency_type: Partners::Profile.agency_types[:edu])
end
end

Expand Down
Loading