class BerkeleyLibrary::Alma::BibNumber

{RecordId} subclass representing a Millennium bib number.

Attributes

check_str[R]

@return [String] the check digit of the bib number, as a string

digit_str[R]

@return [String] the numeric part of the bib number, excluding check digit, as a string

Public Class Methods

new(bib_number) click to toggle source

Initializes a new {BibNumber} from the specified string. Note that a bib number may start with an upper-case B, but it will be converted to lower case.

@param [String] bib_number The bib number, with or without check digit @raise [ArgumentError] if the specified string is not an 8- or 9-digit bib number,

or if a 9-digit bib number has an incorrect check digit
# File lib/berkeley_library/alma/bib_number.rb, line 27
def initialize(bib_number)
  @digit_str, @check_str = split_bib(bib_number)
end

Public Instance Methods

full_bib() click to toggle source

Returns the full bib number, including the correct check digit, as a string.

@return [String] the bib number, as a string

# File lib/berkeley_library/alma/bib_number.rb, line 37
def full_bib
  "b#{digit_str}#{check_str}"
end
sru_query_value() click to toggle source

Returns the SRU query value for this MMS ID.

Note that currently only UC Berkeley bib numbers (encoded ‘UCB-bXXXXXXXXX`) are supported.

@return [String] the SRU query value

# File lib/berkeley_library/alma/bib_number.rb, line 54
def sru_query_value
  "alma.local_field_996=#{full_bib}"
end
to_s() click to toggle source

Returns the full bib number, including the correct check digit, as a string.

@return [String] the bib number, as a string

# File lib/berkeley_library/alma/bib_number.rb, line 44
def to_s
  full_bib
end

Private Instance Methods

calculate_check_digit(digits) click to toggle source
# File lib/berkeley_library/alma/bib_number.rb, line 80
def calculate_check_digit(digits)
  raise ArgumentError, "Not an 8-digit array : #{digits.inspect}" unless digits.is_a?(Array) && digits.size == 8

  # From: http://liwong.blogspot.com/2018/04/recipe-computing-millennium-checkdigit.html
  mod = digits.reverse.each_with_index.inject(0) { |sum, (v, i)| sum + (v * (i + 2)) } % 11
  mod == 10 ? 'x' : mod.to_s
end
ensure_check_digit(digit_str, check_str_orig) click to toggle source
# File lib/berkeley_library/alma/bib_number.rb, line 72
def ensure_check_digit(digit_str, check_str_orig)
  digits = digit_str.chars.map(&:to_i)
  check_digit = calculate_check_digit(digits)
  return check_digit if [nil, check_digit, 'a'].include?(check_str_orig)

  raise ArgumentError, "#{digit_str}#{check_str_orig} check digit invalid: expected #{check_digit}, got #{check_str_orig}"
end
split_bib(bib_number) click to toggle source

Private methods

# File lib/berkeley_library/alma/bib_number.rb, line 63
def split_bib(bib_number)
  raise ArgumentError, "Not a Millennium bib number: #{bib_number.inspect}" unless (md = MILLENNIUM_RECORD_RE.match(bib_number.to_s))

  digit_str, check_str_orig = %i[digits check].map { |part| md[part] }
  check_str = ensure_check_digit(digit_str, check_str_orig)

  [digit_str, check_str]
end