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

pulibrary / bibdata / 929a1b49-3757-46f6-b188-4af515cd83e4

12 Mar 2025 06:28PM UTC coverage: 89.757% (-2.4%) from 92.185%
929a1b49-3757-46f6-b188-4af515cd83e4

push

circleci

christinach
Add new facet fields that will be used for the subject browse table and the facet search
Helps with vocabulary work https://github.com/pulibrary/orangelight/pull/3386

rbgenr_genre_facet
aat_genre_facet
lcgft_genre_facet
homoit_genre_facet
homoit_subject_facet
local_subject_facet

3365 of 3749 relevant lines covered (89.76%)

265.68 hits per line

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

92.38
/marc_to_solr/lib/process_holdings_helpers.rb
1
class ProcessHoldingsHelpers
1✔
2
  attr_reader :record
1✔
3

4
  def initialize(record:)
1✔
5
    @record = record
30✔
6
  end
7

8
  def holding_id(field_852)
1✔
9
    if field_852['8'] && alma?(field_852)
220✔
10
      holding_id = field_852['8']
220✔
11
    elsif field_852['0'] && scsb?(field_852)
×
12
      holding_id = field_852['0']
×
13
    end
14
  end
15

16
  def alma?(field_852)
1✔
17
    alma_code_start_22?(field_852['8'])
514✔
18
  end
19

20
  def scsb?(field_852)
1✔
21
    scsb_doc?(record['001'].value) && field_852['0']
248✔
22
  end
23

24
  def group_866_867_868_on_holding_perm_id(holding_perm_id, field_852)
1✔
25
    if scsb?(field_852)
58✔
26
      record.fields('866'..'868').select { |f| f['0'] == holding_perm_id }
×
27
    else
28
      record.fields('866'..'868').select { |f| f['8'] == holding_perm_id }
67✔
29
    end
30
  end
31

32
  def items_by_852(field_852)
1✔
33
    holding_id = holding_id(field_852)
58✔
34
    items = record.fields('876').select { |f| f['0'] == holding_id }
583✔
35
    items.map { |item| item unless private_scsb_item?(item, field_852) }.compact
176✔
36
  end
37

38
  def private_scsb_item?(field_876, field_852)
1✔
39
    field_876['x'] == 'Private' && scsb?(field_852)
118✔
40
  end
41

42
  # Select 852 fields from an Alma or SCSB record
43
  # returns an array of MARC 852 (full holdings) fields
44
  def fields_852_alma_or_scsb
1✔
45
    record.fields('852').select do |f|
30✔
46
      alma_code_start_22?(f['8']) || (scsb_doc?(record['001'].value) && f['0'])
63✔
47
    end
48
  end
49

50
  # Build the current location code from 876$y and 876$z
51
  def current_location_code(field_876)
1✔
52
    "#{field_876['y']}$#{field_876['z']}" if field_876['y'] && field_876['z']
292✔
53
  end
54

55
  # Build the permanent location code from 852$b and 852$c
56
  # Do not append the 852c if it is a SCSB - we save the SCSB locations as scsbnypl and scsbcul
57
  def permanent_location_code(field_852)
1✔
58
    if alma?(field_852)
294✔
59
      "#{field_852['b']}$#{field_852['c']}"
294✔
60
    else
61
      field_852['b']
×
62
    end
63
  end
64

65
  # Select 876 fields (items) with permanent location. 876 location is equal to the 852 permanent location.
66
  def select_permanent_location_876(group_876_fields, field_852)
1✔
67
    return group_876_fields if /^scsb/.match?(field_852['b'])
52✔
68

69
    group_876_fields.select do |field_876|
52✔
70
      !in_temporary_location(field_876, field_852)
118✔
71
    end
72
  end
73

74
  # Select 876 fields (items) with current location. 876 location is NOT equal to the 852 permanent location.
75
  def select_temporary_location_876(group_876_fields, field_852)
1✔
76
    return [] if /^scsb/.match?(field_852['b'])
52✔
77

78
    group_876_fields.select do |field_876|
52✔
79
      in_temporary_location(field_876, field_852)
118✔
80
    end
81
  end
82

83
  def in_temporary_location(field_876, field_852)
1✔
84
    # temporary location is any item whose 876 and 852 do not match
85
    current_location_code(field_876) != permanent_location_code(field_852)
236✔
86
  end
87

88
  def build_call_number(field_852)
1✔
89
    # rubocop:disable Rails/CompactBlank
90
    call_number = [field_852['h'], field_852['i'], field_852['k'], field_852['j']].reject(&:blank?)
144✔
91
    # rubocop:enable Rails/CompactBlank
92
    call_number.present? ? call_number.join(' ').strip : []
144✔
93
  end
94

95
  def includes_only_private_scsb_items?(field_852)
1✔
96
    return false unless scsb?(field_852)
72✔
97

98
    items_by_852(field_852).empty?
×
99
  end
100

101
  # Builds the holding, without any item-specific information
102
  # @returns [Hash]
103
  def build_holding(field_852, field_876 = nil, permanent:)
1✔
104
    holding = {}
72✔
105
    if permanent
72✔
106
      holding['location_code'] = permanent_location_code(field_852)
58✔
107
      holding['location'] = Traject::TranslationMap.new('locations', default: '__passthrough__')[holding['location_code']]
58✔
108
      holding['library'] = Traject::TranslationMap.new('location_display', default: '__passthrough__')[holding['location_code']]
58✔
109
    else
110
      holding['location_code'] = current_location_code(field_876)
14✔
111
      holding['current_location'] = Traject::TranslationMap.new('locations', default: '__passthrough__')[holding['location_code']]
14✔
112
      holding['current_library'] = Traject::TranslationMap.new('location_display', default: '__passthrough__')[holding['location_code']]
14✔
113
    end
114

115
    holding['call_number'] = build_call_number(field_852)
72✔
116
    holding['call_number_browse'] = build_call_number(field_852)
72✔
117
    # Updates current holding key; values are from 852
118
    if field_852['k']
72✔
119
      holding['sub_location'] = []
40✔
120
      holding['sub_location'] << field_852['k']
40✔
121
    end
122
    if field_852['l']
72✔
123
      holding['shelving_title'] = []
×
124
      holding['shelving_title'] << field_852['l']
×
125
    end
126
    if field_852['z']
72✔
127
      holding['location_note'] = []
3✔
128
      holding['location_note'] << field_852['z']
3✔
129
    end
130
    holding
72✔
131
  end
132

133
  # Build the items array in all_holdings hash
134
  def holding_items(value:, all_holdings:, item:)
1✔
135
    if all_holdings[value].present?
118✔
136
      all_holdings[value]['items'] ||= []
104✔
137
      all_holdings[value]['items'] << item
104✔
138
    end
139
    all_holdings
118✔
140
  end
141

142
  def build_item(field_852:, field_876:)
1✔
143
    is_scsb = scsb?(field_852)
118✔
144
    item = {}
118✔
145
    item[:holding_id] = field_876['0'] if field_876['0']
118✔
146
    item[:description] = field_876['3'] if field_876['3']
118✔
147
    item[:id] = field_876['a'] if field_876['a']
118✔
148
    item[:status_at_load] = field_876['j'] if field_876['j']
118✔
149
    item[:barcode] = field_876['p'] if field_876['p']
118✔
150
    item[:copy_number] = field_876['t'] if field_876['t']
118✔
151
    item[:use_statement] = field_876['h'] if field_876['h'] && is_scsb
118✔
152
    item[:storage_location] = field_876['l'] if field_876['l'] && is_scsb
118✔
153
    if field_876['x']
118✔
154
      if is_scsb
2✔
155
        item[:cgd] = field_876['x']
×
156
      else
157
        item[:process_type] = field_876['x']
2✔
158
      end
159
    end
160
    item[:collection_code] = field_876['z'] if field_876['z'] && is_scsb
118✔
161
    item
118✔
162
  end
163

164
  def process_866_867_868_fields(fields:, all_holdings:, holding_id:)
1✔
165
    fields.each do |field|
52✔
166
      all_holdings[holding_id]['location_has'] ||= []
7✔
167
      all_holdings[holding_id]['supplements'] ||= []
7✔
168
      all_holdings[holding_id]['indexes'] ||= []
7✔
169
      all_holdings[holding_id]['location_has'] << parse_textual_holdings(field, '866')
7✔
170
      all_holdings[holding_id]['supplements'] << parse_textual_holdings(field, '867')
7✔
171
      all_holdings[holding_id]['indexes'] << parse_textual_holdings(field, '868')
7✔
172
    end
173
    all_holdings
52✔
174
  end
175

176
  def parse_textual_holdings(field, field_tag)
1✔
177
    textual_holdings = []
21✔
178
    textual_holdings << field['a'] if field.tag == field_tag && field['a']
21✔
179
    textual_holdings << field['z'] if field.tag == field_tag && field['z']
21✔
180
    textual_holdings.join(' ') if textual_holdings.present?
21✔
181
  end
182
end
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