lib/banktools-se/ocr.rb in banktools-se-1.0.0 vs lib/banktools-se/ocr.rb in banktools-se-2.0.0

- old
+ new

@@ -3,10 +3,12 @@ module BankTools module SE class OCR class InvalidOCR < StandardError; end class OverlongOCR < InvalidOCR; end + class BadPadding < InvalidOCR; end + class BadLengthDigit < InvalidOCR; end class BadChecksum < InvalidOCR; end class MustBeNumeric < InvalidOCR; end MIN_LENGTH = 2 MAX_LENGTH = 25 @@ -32,17 +34,30 @@ number_with_ocr end def self.to_number(number, opts = {}) number = number.to_s - strip_length_digit = opts.fetch(:length_digit, false) + should_have_length_digit = opts.fetch(:length_digit, false) strip_padding = opts.fetch(:pad, "").to_s raise MustBeNumeric unless number.match(/\A\d+\z/) raise BadChecksum unless Utils.valid_luhn?(number) + if should_have_length_digit + length_digit = number[-2] + last_digit_of_actual_length = number.length.to_s[-1] + raise BadLengthDigit if length_digit != last_digit_of_actual_length + end + digits_to_chop = 1 # Checksum. - digits_to_chop += 1 if strip_length_digit + digits_to_chop += 1 if should_have_length_digit + + if strip_padding.length > 0 + expected_padding_end = -digits_to_chop - 1 + expected_padding_start = expected_padding_end - strip_padding.length + 1 + raise BadPadding if number[expected_padding_start..expected_padding_end] != strip_padding + end + digits_to_chop += strip_padding.length number[0...-digits_to_chop] end end