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

pulibrary / bibdata / 373ad6ff-fad2-405a-ab26-3d30fb5ceecf

24 Dec 2024 08:24PM UTC coverage: 91.938% (+0.08%) from 91.859%
373ad6ff-fad2-405a-ab26-3d30fb5ceecf

Pull #2563

circleci

maxkadel
Put attaching xml files in their own batch
Pull Request #2563: I2321 Shift SCSB full index tasks into separate background jobs

152 of 156 new or added lines in 10 files covered. (97.44%)

65 existing lines in 17 files now uncovered.

3478 of 3783 relevant lines covered (91.94%)

366.14 hits per line

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

98.1
/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
164✔
6
  end
7

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

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

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

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

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

38
  def private_scsb_item?(field_876, field_852)
1✔
39
    field_876['x'] == 'Private' && scsb?(field_852)
1,053✔
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|
164✔
46
      alma_code_start_22?(f['8']) || scsb_doc?(record['001'].value) && f['0']
387✔
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']
2,676✔
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)
1,530✔
59
      "#{field_852['b']}$#{field_852['c']}"
1,317✔
60
    else
61
      field_852['b']
213✔
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'])
337✔
68
    group_876_fields.select do |field_876|
124✔
69
      !in_temporary_location(field_876, field_852)
584✔
70
    end
71
  end
72

73
  # Select 876 fields (items) with current location. 876 location is NOT equal to the 852 permanent location.
74
  def select_temporary_location_876(group_876_fields, field_852)
1✔
75
    return [] if /^scsb/.match?(field_852['b'])
337✔
76
    group_876_fields.select do |field_876|
124✔
77
      in_temporary_location(field_876, field_852)
584✔
78
    end
79
  end
80

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

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

93
  def includes_only_private_scsb_items?(field_852)
1✔
94
    return false unless scsb?(field_852)
741✔
95

96
    items_by_852(field_852).empty?
216✔
97
  end
98

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

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

131
  # Build the items array in all_holdings hash
132
  def holding_items(value:, all_holdings:, item:)
1✔
133
    if all_holdings[value].present?
817✔
134
      all_holdings[value]["items"] ||= []
453✔
135
      all_holdings[value]["items"] << item
453✔
136
    end
137
    all_holdings
817✔
138
  end
139

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

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

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