Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 45 additions & 0 deletions app/helpers/record_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,51 @@ def deduplicate_subjects(subjects)
subjects.map { |subject| subject['value'].uniq(&:downcase) }.uniq { |values| values.map(&:downcase) }
end

# Formats availability information for display.
# Expects:
# - status: a string indicating availability status
# - location: an array with three elements: [library name, location name, call number]
# - other_availability: a boolean string indicating if there is availability at other locations
def availability(status, location, other_availability)
blurb = case status.downcase
# `available` is a common status used in Alma/Primo VE for items that are not checked out and should be
# on the shelf
when 'available'
"#{icon('check')} Available in #{location(location)}"
# `check_holdings`: unclear when (or if) this is used. Bento handled this so we did too assuming it was
# meaningful
when 'check_holdings'
"#{icon('question')} May be available in #{location(location)}"
# 'unavailable' is used for items that are checked out, missing, or otherwise not on the shelf
when 'unavailable'
"#{icon('times')} Not currently available in #{location(location)}"
# Unclear if there are other statuses we should handle here. For now we log and display a generic message.
else
Rails.logger.error("Unhandled availability status: #{status.inspect}")
"#{icon('question')} Uncertain availability in #{location(location)} #{status}"
end

blurb += ' and other locations.' if other_availability.present?

# We are generating HTML in this helper, so we need to mark it as safe or it will be escaped in the view.
blurb.html_safe
end

# Fontawesome helper. Currently only takes the icon name and assumes solid sharp style.
# Could be extended later to default to these styles but allow overrides if appropriate.
# Also defaults to aria-hidden true, which is probably what we want for icons used
# purely for decoration. If an icon is used in a more meaningful way, we may want to extend this helper
# to allow passing in additional aria attributes.
def icon(fa)
"<i class='fa-sharp fa-solid fa-#{fa}' aria-hidden='true''></i>"
end

# Formats location information for availability display.
# Expects an array with three elements: [library name, location name, call number]
def location(loc)
"<strong>#{loc[:name]}</strong> #{loc[:collection]} (#{loc[:call_number]})"
end

private

def render_kind_value(list)
Expand Down
8 changes: 7 additions & 1 deletion app/models/normalize_primo_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,18 @@ def publisher
@record['pnx']['addata']['pub'].first
end

# Current logic in this method should likely move to `holdings` field
def location
return unless @record['delivery']
return unless @record['delivery']['bestlocation']

loc = @record['delivery']['bestlocation']
["#{loc['mainLocation']} #{loc['subLocation']}", loc['callNumber']]

{
name: loc['mainLocation'],
collection: loc['subLocation'],
call_number: loc['callNumber']
}
end

def subjects
Expand Down
3 changes: 3 additions & 0 deletions app/views/search/_result_primo.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
<%= link_to link['kind'].titleize, link['url'], class: 'button' %>
<% end %>
<% end %>
<% if result[:availability].present? %>
<span class="availability"><%= availability(result[:availability], result[:location], result[:other_availability]) %></span>
<% end %>
</div>
</div>
</li>
24 changes: 24 additions & 0 deletions test/helpers/record_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,28 @@ class RecordHelperTest < ActionView::TestCase
subjects = []
assert_nil deduplicate_subjects(subjects)
end

test 'availability helper handles known statuses correctly' do
location = {
name: 'Main Library',
collection: 'First Floor',
call_number: 'QA76.73.R83 2023'
}

available_blurb = availability('available', location, false)
assert_includes available_blurb, 'Available in'
assert_includes available_blurb, location(location)

check_holdings_blurb = availability('check_holdings', location, false)
assert_includes check_holdings_blurb, 'May be available in'
assert_includes check_holdings_blurb, location(location)

unavailable_blurb = availability('unavailable', location, false)
assert_includes unavailable_blurb, 'Not currently available in'
assert_includes unavailable_blurb, location(location)

unknown_blurb = availability('unknown_status', location, false)
assert_includes unknown_blurb, 'Uncertain availability in'
assert_includes unknown_blurb, location(location)
end
end
2 changes: 1 addition & 1 deletion test/models/normalize_primo_record_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def cdi_record

test 'returns best location with call number' do
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
expected_location = ['Hayden Library Stacks', 'QA76.73.R83 2023']
expected_location = { name: 'Hayden Library', collection: 'Stacks', call_number: 'QA76.73.R83 2023' }
assert_equal expected_location, normalized[:location]
end

Expand Down