• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / orangelight / 72cc2230-18d1-4824-869b-816c40318205

23 Oct 2025 12:57PM UTC coverage: 95.288% (-0.002%) from 95.29%
72cc2230-18d1-4824-869b-816c40318205

Pull #5257

circleci

sandbergja
Remove trivial method format_email
Pull Request #5257: Remove trivial method format_email

6087 of 6388 relevant lines covered (95.29%)

1513.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.25
/app/helpers/requests/application_helper.rb
1
# frozen_string_literal: true
2
# rubocop:disable Metrics/ModuleLength
3
module Requests
3✔
4
  module ApplicationHelper
3✔
5
    def format_label(key)
3✔
6
      label = key.to_s
×
7
      human_label = label.tr('_', ' ')
×
8
      formatted = human_label.split.map(&:capitalize).join(' ')
×
9
      formatted
×
10
    end
11

12
    def error_key_format(key)
3✔
13
      keys_to_ignore = ['items']
×
14
      format_label(key) unless keys_to_ignore.include? key.to_s
×
15
    end
16

17
    # array of error_keys
18
    def guest_user_error?(error_keys)
3✔
19
      user_errors = [:email, :user_name, :barcode]
×
20
      error_keys.any? { |item| user_errors.include? item }
×
21
    end
22

23
    def show_pick_up_service_options(requestable, mfhd_id)
3✔
24
      if requestable.on_shelf?
142✔
25
        display_on_shelf(requestable, mfhd_id)
70✔
26
      else
27
        display_requestable_list(requestable)
71✔
28
      end
29
    end
30

31
    def show_service_options(requestable, _mfhd_id)
3✔
32
      if requestable.no_services?
2✔
33
        content_tag(:div, "#{requestable.title} #{enum_copy_display(requestable.item)} #{sanitize(I18n.t('requests.no_services.brief_msg'))}", class: 'visually-hidden') +
×
34
          content_tag(:div, sanitize(I18n.t("requests.no_services.brief_msg")), class: 'service-item', aria: { hidden: true })
35
      elsif requestable.charged? && !requestable.aeon? && !requestable.ask_me?
2✔
36
        render partial: 'checked_out_options', locals: { requestable: }
1✔
37
      else
38
        display_requestable_list(requestable)
1✔
39
      end
40
    end
41

42
    def hidden_service_options(requestable, fill_in: false)
3✔
43
      return hidden_service_options_fill_in(requestable) if fill_in
131✔
44
      hidden = output_request_input(requestable)
120✔
45
      return hidden if hidden.present?
120✔
46

47
      if requestable.services.include? 'recap'
49✔
48
        recap_print_only_input requestable
40✔
49
      else
50
        request_input(requestable.services.first)
9✔
51
      end
52
    end
53

54
    def output_request_input(requestable)
3✔
55
      output = ""
120✔
56
      ['annex', 'pres', 'ppl', 'lewis', 'paging', 'on_order', 'on_shelf'].each do |type|
120✔
57
        next unless requestable.services.include?(type)
786✔
58
        output = request_input(type)
71✔
59
        break
71✔
60
      end
61
      output
120✔
62
    end
63

64
    # only requestable services that support "user-supplied volume info"
65
    def hidden_service_options_fill_in(requestable)
3✔
66
      if requestable.annex?
11✔
67
        request_input('annex')
2✔
68
      elsif requestable.services.include? 'recap_no_items'
9✔
69
        request_input('recap_no_items')
1✔
70
      else
71
        request_input('paging')
8✔
72
      end
73
    end
74

75
    def recap_print_only_input(requestable)
3✔
76
      content_tag(:fieldset, class: 'recap--print', id: "recap_group_#{requestable.preferred_request_id}") do
40✔
77
        concat hidden_field_tag "requestable[][type]", "", value: 'recap'
40✔
78
      end
79
    end
80

81
    # rubocop:disable Style/NumericPredicate
82
    def enum_copy_display(item)
3✔
83
      return "" if item.blank?
526✔
84
      [item.description, item.copy_value].join(" ").strip
524✔
85
    end
86
    # rubocop:enable Style/NumericPredicate
87

88
    def request_input(type)
3✔
89
      hidden_field_tag "requestable[][type]", "", value: type
97✔
90
    end
91

92
    def gfa_lookup(lib_code)
3✔
93
      if lib_code == "firestone"
6✔
94
        "PA"
×
95
      else
96
        lib = Requests::BibdataService.delivery_locations.select { |_key, hash| hash["library"]["code"] == lib_code }
144✔
97
        lib.keys.first.to_s
6✔
98
      end
99
    end
100

101
    def pick_up_classlist(requestable, collapse)
3✔
102
      class_list = "collapse request--print"
150✔
103
      class_list += " show" if !requestable.digitize? && !collapse
150✔
104
      class_list
150✔
105
    end
106

107
    # move this to requestable object
108
    # Default pick-ups should be available
109
    def pick_up_choices(requestable, default_pick_ups, collapse = false)
3✔
110
      content_tag(:div, id: "fields-print__#{requestable.preferred_request_id}", class: pick_up_classlist(requestable, collapse)) do
139✔
111
        preferred_request_content_tag(requestable, requestable.pick_up_locations || default_pick_ups)
139✔
112
      end
113
    end
114

115
    # :reek:NilCheck
116
    def preferred_request_content_tag(requestable, default_pick_ups)
3✔
117
      (show_pick_up_service_options(requestable, nil) || "".html_safe) +
145✔
118
        content_tag(:div, id: "fields-print__#{requestable.preferred_request_id}_card", class: "card card-body bg-light") do
119
          locs = pick_up_locations(requestable, default_pick_ups)
144✔
120

121
          name = 'requestable[][pick_up]'
144✔
122
          id = "requestable__pick_up_#{requestable.preferred_request_id}"
144✔
123
          if locs.size > 1
144✔
124
            prompt_text = custom_pickup_prompt(requestable, locs) || I18n.t("requests.default.pick_up_placeholder")
64✔
125
            selected_value = find_selected_pickup_value(requestable, locs)
64✔
126
            # For ReCAP items, select the empty prompt instead of any actual option
127
            selected_value = '' if requestable.recap? && selected_value.nil?
64✔
128
            options = [[prompt_text, '', { disabled: true, selected: false }]] + locs.map { |loc| [loc[:label], { 'pick_up' => loc[:gfa_pickup], 'pick_up_location_code' => loc[:pick_up_location_code] }.to_json] }
563✔
129
            select_tag name.to_s, options_for_select(options, selected_value), id: id
64✔
130
          else
131

132
            single_pickup(requestable.charged?, name, id, locs[0])
80✔
133
          end
134
        end
135
    end
136

137
    # rubocop:disable Rails/OutputSafety
138
    def hidden_fields_mfhd(mfhd)
3✔
139
      hidden = ""
75✔
140
      return hidden if mfhd.nil?
75✔
141
      hidden += hidden_field_tag "mfhd[][call_number]", "", value: (mfhd['call_number']).to_s unless mfhd["call_number"].nil?
74✔
142
      hidden += hidden_field_tag "mfhd[][location]", "", value: (mfhd['location']).to_s unless mfhd["location"].nil?
74✔
143
      hidden += hidden_field_tag "mfhd[][library]", "", value: (mfhd['library']).to_s
74✔
144
      hidden.html_safe
74✔
145
    end
146
    # rubocop:enable Rails/OutputSafety
147

148
    def hidden_fields_item(requestable)
3✔
149
      request_id = requestable.preferred_request_id
531✔
150
      hidden = hidden_field_tag "requestable[][bibid]", "", value: requestable.bib[:id].to_s, id: "requestable_bibid_#{request_id}"
531✔
151
      hidden += hidden_field_tag "requestable[][mfhd]", "", value: requestable.holding.mfhd_id, id: "requestable_mfhd_#{request_id}"
531✔
152
      hidden += hidden_field_tag "requestable[][call_number]", "", value: requestable.holding.holding_data['call_number'].to_s, id: "requestable_call_number_#{request_id}" unless requestable.holding.holding_data["call_number"].nil?
531✔
153
      hidden += hidden_field_tag "requestable[][location_code]", "", value: requestable.item_location_code.to_s, id: "requestable_location_#{request_id}"
531✔
154
      hidden += if requestable.item?
531✔
155
                  hidden_fields_for_item(item: requestable.item, preferred_request_id: requestable.preferred_request_id)
518✔
156
                else
157
                  hidden_field_tag("requestable[][item_id]", "", value: requestable.preferred_request_id, id: "requestable_item_id_#{requestable.preferred_request_id}")
13✔
158
                end
159
      hidden += hidden_fields_for_scsb(item: requestable.item) if requestable.partner_holding?
531✔
160
      hidden
531✔
161
    end
162

163
    def isbn_string(array_of_isbns)
3✔
164
      array_of_isbns.join(',')
1✔
165
    end
166

167
    def suppress_login?(request)
3✔
168
      request.only_aeon?
79✔
169
    end
170

171
    def item_checkbox(requestable, single_item_form)
3✔
172
      disabled = !requestable.will_submit_via_form?
512✔
173
      check_box_tag "requestable[][selected]", true, check_box_selected?(disabled, single_item_form), class: 'request--select', disabled:, aria: { labelledby: "title enum_#{requestable.preferred_request_id}" }, id: "requestable_selected_#{requestable.preferred_request_id}"
512✔
174
    end
175

176
    ## If any requestable items have a temp location assume everything at the holding is in a temp loc?
177
    def current_location_label(holding_location_label, requestable_list)
3✔
178
      first_location = requestable_list.first.location
147✔
179
      location_label = first_location.short_label.blank? ? "" : "- #{first_location.short_label}"
147✔
180
      label = if requestable_list.first.temp_loc_other_than_resource_sharing?
147✔
181
                "#{first_location.library_label}#{location_label}"
4✔
182
              else
183
                holding_location_label
143✔
184
              end
185
      "#{label} #{requestable_list.first.call_number}"
147✔
186
    end
187

188
    def check_box_selected?(disabled, single_item_form)
3✔
189
      if single_item_form
512✔
190
        !disabled
40✔
191
      else
192
        false
472✔
193
      end
194
    end
195

196
    def submit_button_disabled?(requestable_list)
3✔
197
      # temporary chane issue 438 guest can no longer check out materials
198
      return true if @user.blank? || @user.guest
54✔
199
      return unsubmittable? requestable_list unless requestable_list.size == 1
52✔
200
      # temporary changes issue 438 do not disable the button for circulating items
201
      # requestable_list.first.services.empty? || requestable_list.first.on_reserve? || (requestable_list.first.services.include? 'on_shelf') || requestable_list.first.ask_me?
202
      requestable_list.first.services.empty? || requestable_list.first.on_reserve?
43✔
203
    end
204

205
    def unsubmittable?(requestable_list)
3✔
206
      !requestable_list.any? { |requestable| (requestable.services | submitable_services).present? }
18✔
207
    end
208

209
    def submitable_services
3✔
210
      ['on_shelf', 'in_process', 'on_order', 'annex', 'recap', 'recap_edd', 'paging', 'recap_no_items', 'ppl', 'lewis']
9✔
211
    end
212

213
    def submit_message(requestable_list)
3✔
214
      single_item = "Request this Item"
50✔
215
      multi_item = "Request Selected Items"
50✔
216
      no_item = "No Items Available"
50✔
217
      return multi_item unless requestable_list.size == 1
50✔
218
      if requestable_list.first.services.empty?
41✔
219
        no_item
×
220
      elsif requestable_list.first.annex?
41✔
221
        # Annex items have the potential to display the
222
        # use the fill-in form, where a user could potentially
223
        # request multiple volumes.  For that reason, we show
224
        # the plural form "Request Selected Items" in this case
225
        multi_item
3✔
226
      else
227
        single_item
38✔
228
      end
229
    end
230

231
    # only show the table sort if there are enough items
232
    # to make it worthwhile
233
    def show_tablesorter(requestable_list)
3✔
234
      return "tablesorter" if table_sorter_present?(requestable_list)
74✔
235
      ""
65✔
236
    end
237

238
    def table_sorter_present?(requestable_list)
3✔
239
      requestable_list.size > 5
107✔
240
    end
241

242
    def display_label
3✔
243
      {
×
244
        author: "Author/Artist",
245
        title: "Title",
246
        date: "Published/Created",
247
        id: "Bibliographic ID",
248
        mfhd: "Holding ID (mfhd)"
249
      }.with_indifferent_access
250
    end
251

252
    def display_status(requestable)
3✔
253
      content_tag(:span, requestable.item['status']) unless requestable.item.nil?
×
254
    end
255

256
    def system_status_label(requestable)
3✔
257
      return "" if requestable.item.blank?
×
258
      content_tag(:div, requestable.item[:status], class: 'system-status')
×
259
    end
260

261
    def display_urls(requestable)
3✔
262
      content_tag :ol do
×
263
        requestable.urls.each do |key, value|
×
264
          unless key == 'iiif_manifest_paths'
×
265
            value.reverse!
×
266
            concat content_tag(:li, link_to(value.join(": "), key), class: 'link')
×
267
          end
268
        end
269
      end
270
    end
271

272
    def self.recap_annex_available_pick_ups(requestable, default_pick_ups)
3✔
273
      locations = requestable.pick_up_locations || default_pick_ups
65✔
274
      pick_ups = locations.select { |loc| Requests::Location.valid_recap_annex_pickup?(loc) }
762✔
275
      pick_ups << default_pick_ups[0] if pick_ups.empty?
65✔
276
      pick_ups
65✔
277
    end
278

279
    private
3✔
280

281
      def custom_pickup_prompt(requestable, locs)
3✔
282
        # For ReCAP items, return nil to use default prompt
283
        return nil if requestable.recap?
71✔
284

285
        holding_library = normalize_holding_library(requestable)
24✔
286
        return nil if holding_library.blank?
24✔
287

288
        find_prompt_for_holding_library(holding_library, locs)
24✔
289
      end
290

291
      # :reek:UtilityFunction
292
      def normalize_holding_library(requestable)
3✔
293
        requestable.holding_library&.downcase
41✔
294
      end
295

296
      def find_prompt_for_holding_library(holding_library, locs)
3✔
297
        # Check for special engineering library cases first
298
        engineering_prompt = engineering_library_prompt(holding_library, locs)
24✔
299
        return engineering_prompt if engineering_prompt
24✔
300

301
        # Find matching library by code and suggest it in the prompt
302
        suggested_location = find_matching_location_label(holding_library, locs)
20✔
303
        return unless suggested_location
20✔
304
        I18n.t('requests.pick_up_suggested.holding_library', holding_library: suggested_location)
4✔
305
        # "Select a Delivery Location (Recommended: #{suggested_location})"
306
      end
307

308
      def find_matching_location_label(holding_library, locs)
3✔
309
        matching_loc = find_matching_location_by_code(holding_library, locs)
20✔
310
        matching_loc&.dig(:label)
20✔
311
      end
312

313
      # :reek:UtilityFunction
314
      def find_matching_location_by_code(holding_library, locs)
3✔
315
        locs.find do |loc|
35✔
316
          # Extract library code and compare with holding library
317
          location = Requests::Location.new(loc)
173✔
318
          location.library_code&.downcase == holding_library
173✔
319
        end
320
      end
321

322
      # :reek:UtilityFunction
323
      def engineering_library_prompt(holding_library, locs)
3✔
324
        # Special case: lewis, plasma should default to Engineering Library
325
        if ['lewis', 'plasma'].include?(holding_library)
24✔
326
          engineering_loc = locs.find { |loc| loc[:label] == "Engineering Library" }
16✔
327
          return I18n.t('requests.pick_up_suggested.engineering_holding_library', engineering_holding_library: engineering_loc[:label]) if engineering_loc
5✔
328
        end
329
        nil
20✔
330
      end
331

332
      def find_selected_pickup_value(requestable, locs)
3✔
333
        return nil if should_skip_form_preselection?(requestable)
64✔
334

335
        holding_library = normalize_holding_library(requestable)
17✔
336
        return nil if holding_library.blank?
17✔
337

338
        find_form_preselected_location_json(holding_library, locs)
17✔
339
      end
340

341
      # :reek:UtilityFunction
342
      def should_skip_form_preselection?(requestable)
3✔
343
        requestable.recap?
64✔
344
      end
345

346
      def find_form_preselected_location_json(holding_library, locs)
3✔
347
        selected_location = find_engineering_location(holding_library, locs) ||
17✔
348
                            find_matching_location_by_code(holding_library, locs)
349
        return nil unless selected_location
17✔
350

351
        location_to_json(selected_location)
3✔
352
      end
353

354
      # :reek:UtilityFunction
355
      def find_engineering_location(holding_library, locs)
3✔
356
        return nil unless ['lewis', 'plasma'].include?(holding_library)
17✔
357
        locs.find { |loc| Requests::Location.new(loc).engineering_library? }
6✔
358
      end
359

360
      # :reek:UtilityFunction
361
      def location_to_json(location)
3✔
362
        { 'pick_up' => location[:gfa_pickup], 'pick_up_location_code' => location[:pick_up_location_code] }.to_json
3✔
363
      end
364

365
      def display_requestable_list(requestable)
3✔
366
        return if requestable.no_services?
142✔
367
        content_tag(:ul, class: "service-list") do
140✔
368
          if requestable.ill_eligible?
140✔
369
            concat content_tag(:li, sanitize(I18n.t("requests.ill.brief_msg")), class: "service-item")
1✔
370
          else
371
            # there are no instances where more than one actual service is available to an item, so we are going to take the first service that is not edd
372
            filtered_services = if requestable.services.size == 1 && requestable.services.first.include?("edd")
139✔
373
                                  requestable.services
×
374
                                else
375
                                  requestable.services.reject { |service_name| service_name.include?("edd") }
402✔
376
                                end
377
            brief_msg = I18n.t("requests.#{filtered_services.first}.brief_msg")
139✔
378
            concat content_tag(:li, sanitize(brief_msg), class: "service-item")
139✔
379
          end
380
        end
381
      end
382

383
      def display_on_shelf(requestable, _mfhd_id)
3✔
384
        content_tag(:div) do
70✔
385
          display_requestable_list(requestable)
70✔
386
        end
387
      end
388

389
      def pick_up_locations(requestable, default_pick_ups)
3✔
390
        # we don't want to change the ill_eligible rules
391
        return ill_eligible_pick_up_location(default_pick_ups) if requestable.ill_eligible?
146✔
392
        return Requests::ApplicationHelper.recap_annex_available_pick_ups(requestable, default_pick_ups) if requestable.recap? || requestable.annex?
144✔
393
        return default_pick_ups if requestable.location&.standard_circ_location?
82✔
394
        if requestable.delivery_location_label.present?
79✔
395
          [{ label: requestable.delivery_location_label, gfa_pickup: requestable.delivery_location_code, pick_up_location_code: requestable.pick_up_location_code, staff_only: false }]
72✔
396
        else
397
          [{ label: requestable.location.library_label, gfa_pickup: gfa_lookup(requestable.location.library_code), staff_only: false }]
7✔
398
        end
399
      end
400

401
      # :reek:UtilityFunction
402
      def ill_eligible_pick_up_location(default_pick_ups)
3✔
403
        # currently for resource sharing items through Illiad we use firestone Library with gfa_pickup of PA
404
        location = default_pick_ups.find { |location| location[:gfa_pickup] == "PA" }
7✔
405
        [location].compact
2✔
406
      end
407

408
      def hidden_fields_for_item(item:, preferred_request_id:)
3✔
409
        hidden = hidden_field_tag("requestable[][item_id]", "", value: preferred_request_id.to_s, id: "requestable_item_id_#{preferred_request_id}")
518✔
410
        hidden += hidden_field_tag("requestable[][barcode]", "", value: item['barcode'].to_s, id: "requestable_barcode_#{preferred_request_id}") unless item["barcode"].nil?
518✔
411
        hidden += hidden_field_tag("requestable[][enum]", "", value: item.enum_value.to_s, id: "requestable_enum_#{preferred_request_id}") if item.enum_value.present?
518✔
412
        hidden += hidden_field_tag("requestable[][copy_number]", "", value: item.copy_number.to_s, id: "requestable_copy_number_#{preferred_request_id}")
518✔
413
        hidden + hidden_field_tag("requestable[][status]", "", value: item['status'].to_s, id: "requestable_status_#{preferred_request_id}")
518✔
414
      end
415

416
      def hidden_fields_for_scsb(item:)
3✔
417
        hidden = hidden_field_tag("requestable[][cgd]", "", value: item['cgd'].to_s, id: "requestable_cgd_#{item['id']}")
6✔
418
        hidden += hidden_field_tag("requestable[][cc]", "", value: item['collection_code'].to_s, id: "requestable_collection_code_#{item['id']}")
6✔
419
        hidden + hidden_field_tag("requestable[][use_statement]", "", value: item['use_statement'].to_s, id: "requestable_use_statement_#{item['id']}")
6✔
420
      end
421

422
      def single_pickup(is_charged, name, id, location)
3✔
423
        style = if is_charged
80✔
424
                  'margin-top:10px;'
×
425
                else
426
                  ''
80✔
427
                end
428
        hidden = hidden_field_tag name.to_s, "", value: { 'pick_up' => location[:gfa_pickup], 'pick_up_location_code' => location[:pick_up_location_code] }.to_json, class: 'single-pick-up-hidden', id: id
80✔
429
        label = label_tag id, "Pick-up location: #{location[:label]}", class: 'single-pick-up', style: style.to_s
80✔
430
        hidden + label
80✔
431
      end
432

433
      def aeon_base
3✔
434
        Requests.config[:aeon_base]
×
435
      end
436
  end
437
end
438
# rubocop:enable Metrics/ModuleLength
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc