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

pulibrary / bibdata / 2b274cd3-5d04-438b-ba47-a8d5eeac0c16

11 Aug 2025 04:31PM UTC coverage: 87.857% (-4.3%) from 92.158%
2b274cd3-5d04-438b-ba47-a8d5eeac0c16

Pull #2830

circleci

sandbergja
[#2746] Begin indexing access restriction notes

Advances #2746
Pull Request #2830: [#2746] Begin indexing access restriction notes

3350 of 3813 relevant lines covered (87.86%)

668.76 hits per line

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

74.29
/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
39✔
6
  end
7

8
  def holding_id(field_852)
1✔
9
    if field_852['8'] && alma?(field_852)
6✔
10
      holding_id = field_852['8']
6✔
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'])
12✔
18
  end
19

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

24
  def group_866_867_868_on_holding_perm_id(holding_perm_id, field_852)
1✔
25
    if scsb?(field_852)
2✔
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 }
2✔
29
    end
30
  end
31

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

38
  def private_scsb_item?(field_876, field_852)
1✔
39
    field_876['x'] == 'Private' && scsb?(field_852)
2✔
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|
39✔
46
      alma_code_start_22?(f['8']) || (scsb_doc?(record['001'].value) && f['0'])
2✔
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']
4✔
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)
6✔
59
      "#{field_852['b']}$#{field_852['c']}"
6✔
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'])
2✔
68

69
    group_876_fields.select do |field_876|
2✔
70
      !in_temporary_location(field_876, field_852)
2✔
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'])
2✔
77

78
    group_876_fields.select do |field_876|
2✔
79
      in_temporary_location(field_876, field_852)
2✔
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)
4✔
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?)
4✔
91
    # rubocop:enable Rails/CompactBlank
92
    call_number.present? ? call_number.join(' ').strip : []
4✔
93
  end
94

95
  def includes_only_private_scsb_items?(field_852)
1✔
96
    return false unless scsb?(field_852)
2✔
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 = {}
2✔
105
    if permanent
2✔
106
      holding['location_code'] = permanent_location_code(field_852)
2✔
107
      holding['location'] = Traject::TranslationMap.new('locations', default: '__passthrough__')[holding['location_code']]
2✔
108
      holding['library'] = Traject::TranslationMap.new('location_display', default: '__passthrough__')[holding['location_code']]
2✔
109
    else
110
      holding['location_code'] = current_location_code(field_876)
×
111
      holding['current_location'] = Traject::TranslationMap.new('locations', default: '__passthrough__')[holding['location_code']]
×
112
      holding['current_library'] = Traject::TranslationMap.new('location_display', default: '__passthrough__')[holding['location_code']]
×
113
    end
114

115
    holding['call_number'] = build_call_number(field_852)
2✔
116
    holding['call_number_browse'] = build_call_number(field_852)
2✔
117
    # Updates current holding key; values are from 852
118
    if field_852['k']
2✔
119
      holding['sub_location'] = []
×
120
      holding['sub_location'] << field_852['k']
×
121
    end
122
    if field_852['l']
2✔
123
      holding['shelving_title'] = []
×
124
      holding['shelving_title'] << field_852['l']
×
125
    end
126
    if field_852['z']
2✔
127
      holding['location_note'] = []
×
128
      holding['location_note'] << field_852['z']
×
129
    end
130
    holding
2✔
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?
2✔
136
      all_holdings[value]['items'] ||= []
2✔
137
      all_holdings[value]['items'] << item
2✔
138
    end
139
    all_holdings
2✔
140
  end
141

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

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

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