uk_account_validator 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6ed06611b9e4a497d4b1b7898d8a614b0d3c7a9
4
- data.tar.gz: 401c799d9db00473a5c16e301f56a63626adec98
3
+ metadata.gz: c637157bc170af3a8dfffc98dc8eb077c8399a53
4
+ data.tar.gz: 306471bc50f263137a9345d71bdbb01030dfedd9
5
5
  SHA512:
6
- metadata.gz: fba09039c2827ea271879a61846a53bbf479657f5eaeb6051da7b5dd538dc7d0d8c391451a9839722668a7e354ea7cd04b866e9e260055edc1188d902250263b
7
- data.tar.gz: 698615735fb54619616f4894404acc90155b46190f96ad20146273cbfdbb9eb18c69b970915745727f703df279511d52f35a40f35936fe9d2a5f8990ce3b0c15
6
+ metadata.gz: 5d4c22ba1364efd73e909e109f99875f281ec87dbbd90e27042cd50223f3a899e7efe803da9aeac4d7f4c634fdfb256413f51ee6f9255f47958ad0ff5f69cdc2
7
+ data.tar.gz: 8455a102924d27c735870f1fe061c6200105a8a766a6fe36bf14e761b0e78aad6dc8a4f64b1258a718174d41ee2ca3cb2b0e0d8287de0fdcfe957821584adad3
@@ -6,8 +6,7 @@ rvm:
6
6
  - 2.1.6
7
7
  - 2.2.1
8
8
 
9
- install:
10
- - bundle install --without development
9
+ bundler_args: --without development
11
10
 
12
11
  script:
13
12
  - bundle exec cucumber
@@ -1,3 +1,4 @@
1
+ require 'uk_account_validator/number_indices.rb'
1
2
  require 'uk_account_validator/validator.rb'
2
3
  require 'uk_account_validator/modulus_weight.rb'
3
4
  require 'uk_account_validator/modulus_weights_table.rb'
@@ -8,6 +9,19 @@ require 'uk_account_validator/validators/modulus10.rb'
8
9
  require 'uk_account_validator/validators/modulus11.rb'
9
10
  require 'uk_account_validator/validators/double_alternate.rb'
10
11
 
12
+ require 'uk_account_validator/exceptions/base_exception.rb'
13
+ require 'uk_account_validator/exceptions/exception_1.rb'
14
+ require 'uk_account_validator/exceptions/exception_2_9.rb'
15
+ require 'uk_account_validator/exceptions/exception_3.rb'
16
+ require 'uk_account_validator/exceptions/exception_4.rb'
17
+ require 'uk_account_validator/exceptions/exception_5.rb'
18
+ require 'uk_account_validator/exceptions/exception_6.rb'
19
+ require 'uk_account_validator/exceptions/exception_7.rb'
20
+ require 'uk_account_validator/exceptions/exception_8.rb'
21
+ require 'uk_account_validator/exceptions/exception_10.rb'
22
+ require 'uk_account_validator/exceptions/exception_12.rb'
23
+ require 'uk_account_validator/exceptions/exception_14.rb'
24
+
11
25
  module UkAccountValidator
12
26
  def self.modulus_weights_table
13
27
  @modulus_weights_table ||= read_modulus_weights_table
@@ -0,0 +1,65 @@
1
+ class BaseException
2
+ include NumberIndices
3
+
4
+ attr_reader :modulus_weight, :account_number, :sort_code, :check_number
5
+
6
+ def initialize(modulus_weight, account_number, sort_code, check_number)
7
+ @modulus_weight = modulus_weight
8
+ @account_number = account_number
9
+ @sort_code = sort_code
10
+ @check_number = check_number
11
+ end
12
+
13
+ def self.allow_any?
14
+ false
15
+ end
16
+
17
+ def override_test?
18
+ false
19
+ end
20
+
21
+ # Returns the new modulus weight after applying the exception.
22
+ def replace_weight(_test_digits)
23
+ return modulus_weight
24
+ end
25
+
26
+ # Returns the new total after any adjustments
27
+ def after_calculate_total(total, _test_digits)
28
+ return total
29
+ end
30
+
31
+ def apply_account_number_substitutions
32
+ return account_number
33
+ end
34
+
35
+ # Returns the new sort code after substitutions
36
+ def apply_sort_code_substitutions
37
+ return sort_code
38
+ end
39
+
40
+ # Useful functions
41
+
42
+ # Zero all weights
43
+ def zero_all
44
+ UkAccountValidator::ModulusWeight.new(
45
+ modulus_weight.sort_code_start,
46
+ modulus_weight.sort_code_end,
47
+ modulus_weight.modulus,
48
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49
+ modulus_weight.exception
50
+ )
51
+ end
52
+
53
+ # Zero weights for u to b
54
+ def zero_u_b
55
+ UkAccountValidator::ModulusWeight.new(
56
+ modulus_weight.sort_code_start,
57
+ modulus_weight.sort_code_end,
58
+ modulus_weight.modulus,
59
+ 0, 0, 0, 0, 0, 0, 0, 0,
60
+ modulus_weight.c, modulus_weight.d, modulus_weight.e,
61
+ modulus_weight.f, modulus_weight.g, modulus_weight.h,
62
+ modulus_weight.exception
63
+ )
64
+ end
65
+ end
@@ -0,0 +1,10 @@
1
+ # Perform the double alternate check except:
2
+ # Add 27 to the total (ie before you divide by 10)
3
+ # This effectively places a financial institution number (580149) before the
4
+ # sorting code and account number which is subject to the alternate doubling as
5
+ # well.
6
+ class Exception1 < BaseException
7
+ def after_calculate_total(total, _test_digits)
8
+ return total + 27
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ # For the exception 10 check, if ab = 09 or ab = 99 and g = 9, zeroise weighting
2
+ # positions u-b.
3
+ class Exception10 < BaseException
4
+ def self.allow_any?
5
+ true
6
+ end
7
+
8
+ def replace_weight(test_digits)
9
+ # if ab = 09 or 99 and g=9, zeroise weighting positions u-b.
10
+ a = test_digits[NUMBER_INDEX[:a]]
11
+ b = test_digits[NUMBER_INDEX[:b]]
12
+
13
+ return zero_u_b if (a == 0 && b == 9) ||
14
+ (a == 9 && b == 9 && test_digits[NUMBER_INDEX[:g]] == 9)
15
+
16
+ return modulus_weight
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ # These are for Nationwide Flex accounts. Where there is a 12 in the exception
2
+ # column for the first check for a sorting code and a 13 in the exception column
3
+ # for the second check for the same sorting code, if either check is successful
4
+ # the account number is deemed valid.
5
+ class Exception12 < BaseException
6
+ def self.allow_any?
7
+ true
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ # Perform the modulus 11 check as normal:
2
+ # * If the check passes (that is, there is no remainder), then the account
3
+ # number should be considered valid. Do not perform the second check.
4
+ # * If the first check fails, then the second check must be performed as
5
+ # specified below.
6
+ #
7
+ # Second check:
8
+ # * If the 8th digit of the account number (reading from left to right) is not
9
+ # 0, 1 or 9 then the account number fails the second check and is not a valid
10
+ # Coutts account number
11
+ # * If the 8th digit is 0, 1 or 9, then remove the digit from the account
12
+ # number and insert a 0 as the 1st digit for check purposes only
13
+ # * Perform the modulus 11 check on the modified account number using the same
14
+ # weightings as specified in the table (that is, 0 0 0 0 0 0 8 7 6 5 4 3 2 1):
15
+ # - If there is no remainder, then the account number should be considered
16
+ # valid
17
+ # - If there is a remainder, then the account number fails the second check
18
+ # and is not a valid Coutts account number
19
+ class Exception14 < BaseException
20
+ def self.allow_any?
21
+ true
22
+ end
23
+
24
+ def apply_account_number_substitutions
25
+ return account_number unless %w(0 1 9).include?(account_number[7])
26
+
27
+ account_number.slice!(7)
28
+ return '0' + account_number
29
+ end
30
+ end
@@ -0,0 +1,68 @@
1
+ # Only occurs for some standard modulus 11 checks, when there is a 2 in the
2
+ # exception column for the first check for a sorting code and a 9 in the
3
+ # exception column for the second check for the same sorting code. This is used
4
+ # specifically for Lloyds euro accounts.
5
+ #
6
+ # Perform the standard check, except:
7
+ # * If a <> 0 and g <> 9, substitute the weight specified in the modulus weight
8
+ # table with:
9
+ # u v w x y z a b c d e f g h
10
+ # 0 0 1 2 5 3 6 4 8 7 10 9 3 1
11
+ #
12
+ # * If a <> 0 and g = 9, substitute the weight specified in the modulus weight
13
+ # table with:
14
+ # u v w x y z a b c d e f g h
15
+ # 0 0 0 0 0 0 0 0 8 7 10 9 3 1
16
+ #
17
+ # If the first row with exception 2 passes the standard modulus 11 check, you do
18
+ # not need to carry out the second check (ie it is deemed to be a valid sterling
19
+ # account).
20
+ #
21
+ # All Lloyds euro accounts are held at sorting code 30-96-34, however customers
22
+ # may perceive that their euro account is held at the branch where sterling
23
+ # accounts are held and thus quote a sorting code other than 30-96-34. The
24
+ # combination of the "sterling" sorting code and "euro" account number will
25
+ # cause the first standard modulus 11 check to fail. In such cases, carry out
26
+ # the second modulus 11 check, substituting the sorting code with 309634 and the
27
+ # appropriate weighting. If this check passes it is deemed to be a valid euro
28
+ # account.
29
+
30
+ class Exception29 < BaseException
31
+ def self.allow_any?
32
+ true
33
+ end
34
+
35
+ def apply_sort_code_substitutions
36
+ return '309634' if check_number == 2
37
+
38
+ return sort_code
39
+ end
40
+
41
+ def replace_weight(test_digits)
42
+ return modulus_weight if test_digits[NUMBER_INDEX[:a]] == 0
43
+ return substitute_modulus_weight if check_number == 2
44
+
45
+ if test_digits[NUMBER_INDEX[:g]] != 9
46
+ return UkAccountValidator::ModulusWeight.new(
47
+ modulus_weight.sort_code_start,
48
+ modulus_weight.sort_code_end,
49
+ modulus_weight.modulus,
50
+ 0, 0, 1, 2, 5, 3, 6, 4, 8, 7, 10, 9, 3, 1,
51
+ modulus_weight.exception
52
+ )
53
+ else
54
+ return UkAccountValidator::ModulusWeight.new(
55
+ modulus_weight.sort_code_start,
56
+ modulus_weight.sort_code_end,
57
+ modulus_weight.modulus,
58
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 10, 9, 3, 1,
59
+ modulus_weight.exception
60
+ )
61
+ end
62
+ end
63
+
64
+ # Returns the modulus weight for 309634
65
+ def substitute_modulus_weight
66
+ UkAccountValidator.modulus_weights_table.find('309634').first
67
+ end
68
+ end
@@ -0,0 +1,10 @@
1
+ # If c=6 or c=9 the double alternate check does not need to be carried out
2
+ class Exception3 < BaseException
3
+ def replace_weight(test_digits)
4
+ c = test_digits[NUMBER_INDEX[:c]]
5
+
6
+ return zero_all if c == 6 || c == 9
7
+
8
+ return modulus_weight
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # Perform the standard modulus 11 check.
2
+ # After you have finished the check, ensure that the remainder is the same as
3
+ # the two-digit checkdigit;
4
+ # the checkdigit for exception 4 is gh from the original account number.
5
+ class Exception4 < BaseException
6
+ def override_test?
7
+ true
8
+ end
9
+
10
+ def test(modulus, total, test_digits, _test)
11
+ check_sum = [test_digits[NUMBER_INDEX[:g]], test_digits[NUMBER_INDEX[:h]]].join
12
+ check_sum = check_sum.to_i
13
+
14
+ total % modulus == check_sum
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ # Perform the first check (standard modulus check) except:
2
+ # * If the sorting code appears in SCSUBTAB.txt, substitute it for the
3
+ # "substitute with" column (for check purposes only).
4
+ # If the sorting code is not found, use the original sorting code.
5
+ #
6
+ # For the standard check with exception 5 the checkdigit is g from the original
7
+ # account number.
8
+ # * After dividing the result by 11:
9
+ # - if the remainder = 0 and g = 0 the account number is valid
10
+ # - if the remainder = 1 the account number is invalid
11
+ # - for all other remainders, take the remainder away from 11. If the number
12
+ # you get is the same as g then the account number is valid.
13
+ #
14
+ # Perform the second double alternate check, and for the double alternate check
15
+ # with exception 5 the checkdigit is h from the original account number, except:
16
+ # * After dividing the result by 10:
17
+ # - if the remainder = 0 and h = 0 the account number is valid
18
+ # - for all other remainders, take the remainder away from 10. If the number
19
+ # you get is the same as h then the account number is valid.
20
+ class Exception5 < BaseException
21
+ def apply_sort_code_substitutions
22
+ substitutions = UkAccountValidator.read_sort_code_substitution
23
+
24
+ return substitutions[sort_code] if substitutions.keys.include?(sort_code)
25
+
26
+ return sort_code
27
+ end
28
+
29
+ def override_test?
30
+ true
31
+ end
32
+
33
+ def test(modulus, total, test_digits, test)
34
+ if test == :double_alternate
35
+ check_digit = :h
36
+ else
37
+ check_digit = :g
38
+ end
39
+
40
+ check_sum = total % modulus
41
+ expected_sum = test_digits[NUMBER_INDEX[check_digit]].to_i
42
+
43
+ return false if check_sum == 1 && check_digit == :g
44
+ return true if check_sum == 0 && expected_sum == 0
45
+
46
+ return (modulus - check_sum) == expected_sum
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ # Indicates that these sorting codes may contain foreign currency accounts which
2
+ # cannot be checked.
3
+ # Perform the first and second checks, except:
4
+ # If a = 4, 5, 6, 7 or 8, and g and h are the same, the accounts are for a
5
+ # foreign currency and the checks cannot be used.
6
+ class Exception6 < BaseException
7
+ def replace_weight(test_digits)
8
+ a = test_digits[NUMBER_INDEX[:a]]
9
+ g = test_digits[NUMBER_INDEX[:g]]
10
+ h = test_digits[NUMBER_INDEX[:h]]
11
+
12
+ return zero_all if (a == 4 || a == 5 || a == 6 || a == 7 || a == 8) && g == h
13
+
14
+ return modulus_weight
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # Perform the check as specified, except if g = 9 zeroise weighting positions
2
+ # u-b.
3
+ class Exception7 < BaseException
4
+ def replace_weight(test_digits)
5
+ return modulus_weight unless test_digits[NUMBER_INDEX[:g]] == 9
6
+
7
+ return zero_u_b
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # Perform the check as specified, except substitute the sorting code with
2
+ # 090126, for check purposes only
3
+ class Exception8 < BaseException
4
+ def apply_sort_code_substitutions
5
+ return '090126'
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
1
  module UkAccountValidator
2
2
  class ModulusWeight
3
- attr_accessor :sort_code_start, :sort_code_end, :modulus, :u, :v, :w, :x,
3
+ attr_reader :sort_code_start, :sort_code_end, :modulus, :u, :v, :w, :x,
4
4
  :y, :z, :a, :b, :c, :d, :e, :f, :g, :h, :exception
5
5
 
6
6
  # the size of each column
@@ -11,7 +11,7 @@ module UkAccountValidator
11
11
  # See https://www.ruby-forum.com/topic/184294#805359
12
12
  data = definition_line.unpack("A#{COLUMN_SIZES.join('A')}")
13
13
 
14
- data.map! { |d| d.strip }
14
+ data.map!(&:strip)
15
15
 
16
16
  @sort_code_start, @sort_code_end, @modulus, @u, @v, @w, @x,
17
17
  @y, @z, @a, @b, @c, @d, @e, @f, @g, @h, @exception = data
@@ -0,0 +1,18 @@
1
+ module NumberIndices
2
+ NUMBER_INDEX = {
3
+ u: 0,
4
+ v: 1,
5
+ w: 2,
6
+ x: 3,
7
+ y: 4,
8
+ z: 5,
9
+ a: 6,
10
+ b: 7,
11
+ c: 8,
12
+ d: 9,
13
+ e: 10,
14
+ f: 11,
15
+ g: 12,
16
+ h: 13
17
+ }
18
+ end
@@ -11,7 +11,7 @@ module UkAccountValidator
11
11
  @modulus_weights ||= UkAccountValidator.modulus_weights_table.find(sort_code)
12
12
  end
13
13
 
14
- def validator(modulus)
14
+ def modulus_validator(modulus)
15
15
  case modulus
16
16
  when 'MOD10'
17
17
  Validators::Modulus10
@@ -26,35 +26,50 @@ module UkAccountValidator
26
26
 
27
27
  def valid?
28
28
  exceptions = modulus_weights.map(&:exception)
29
+ exception_class = self.exception_class(exceptions)
29
30
 
30
31
  results = modulus_weights.each_with_index.map do |modulus_weight, i|
31
- if i == 1 && exceptions.include?('2') && exceptions.include?('9')
32
- next Validator.new(account_number, '309634').valid?
33
- end
32
+ exception = exception_class.new(modulus_weight, account_number, sort_code, i + 1)
34
33
 
35
- validator(modulus_weight.modulus).new(account_number, sort_code, modulus_weight, exceptions).valid?
34
+ @account_number = exception.apply_account_number_substitutions
35
+
36
+ modulus_validator(modulus_weight.modulus).new(
37
+ account_number, sort_code, modulus_weight, exception
38
+ ).valid?
36
39
  end
37
40
 
38
- return results.any? if exceptions.include?('2') && exceptions.include?('9')
39
- return results.any? if exceptions.include?('10') && exceptions.include?('11')
40
- return results.any? if exceptions.include?('12') && exceptions.include?('13')
41
- return apply_exception_14 if !results.any? && exceptions.include?('14')
41
+ return results.any? if exception_class.allow_any?
42
42
 
43
43
  results.all?
44
44
  end
45
45
 
46
- # If the 8th digit of the account number (reading from left to right) is
47
- # not 0, 1 or 9 then the account number fails the second check and is not a
48
- # valid Coutts account number.
49
- # If the 8th digit is 0, 1 or 9, then remove the digit from the account
50
- # number and insert a 0 as the 1st digit for check purposes only
51
- def apply_exception_14
52
- return false unless %w(0 1 9).include?(account_number[7])
53
-
54
- account_number.slice!(7)
55
- exception_account_number = '0' + account_number
56
-
57
- return Validator.new(exception_account_number, sort_code).valid?
46
+ def exception_class(exception_strings)
47
+ case
48
+ when exception_strings.include?('1')
49
+ Exception1
50
+ when exception_strings.include?('2') && exception_strings.include?('9')
51
+ Exception29
52
+ when exception_strings.include?('3')
53
+ Exception3
54
+ when exception_strings.include?('4')
55
+ Exception4
56
+ when exception_strings.include?('5')
57
+ Exception5
58
+ when exception_strings.include?('6')
59
+ Exception6
60
+ when exception_strings.include?('7')
61
+ Exception7
62
+ when exception_strings.include?('8')
63
+ Exception8
64
+ when exception_strings.include?('10') && exception_strings.include?('11')
65
+ Exception10
66
+ when exception_strings.include?('12') && exception_strings.include?('13')
67
+ Exception12
68
+ when exception_strings.include?('14')
69
+ Exception14
70
+ else
71
+ BaseException
72
+ end
58
73
  end
59
74
  end
60
75
  end
@@ -1,154 +1,28 @@
1
1
  module UkAccountValidator
2
2
  module Validators
3
3
  class BaseValidator
4
- NUMBER_INDEX = {
5
- u: 0,
6
- v: 1,
7
- w: 2,
8
- x: 3,
9
- y: 4,
10
- z: 5,
11
- a: 6,
12
- b: 7,
13
- c: 8,
14
- d: 9,
15
- e: 10,
16
- f: 11,
17
- g: 12,
18
- h: 13
19
- }
4
+ include NumberIndices
20
5
 
21
- def initialize(account_number, sort_code, modulus_weight, exceptions)
6
+ attr_reader :account_number, :sort_code, :modulus_weight, :exception
7
+
8
+ def initialize(account_number, sort_code, modulus_weight, exception)
22
9
  @account_number = account_number
23
10
  @sort_code = sort_code
24
11
  @modulus_weight = modulus_weight
25
- @exceptions = exceptions
12
+ @exception = exception
26
13
 
27
- @sort_code = apply_exception_5_substitutions(sort_code) if @modulus_weight.exception == '5'
14
+ @sort_code = exception.apply_sort_code_substitutions
28
15
  end
29
16
 
30
17
  def applying_exceptions(test_digits)
31
- apply_exception_2_9(test_digits) if @exceptions.include?('2') && @exceptions.include?('9')
32
- apply_exception_3(test_digits) if @modulus_weight.exception == '3'
33
- apply_exception_6(test_digits) if @modulus_weight.exception == '6'
34
- apply_exception_7(test_digits) if @modulus_weight.exception == '7'
35
- apply_exception_8(test_digits) if @modulus_weight.exception == '8'
36
- apply_exception_10(test_digits) if @modulus_weight.exception == '10'
18
+ @modulus_weight = exception.replace_weight(test_digits)
37
19
 
38
20
  total = yield
39
21
 
40
- total += 27 if @modulus_weight.exception == '1'
22
+ total = exception.after_calculate_total(total, test_digits)
41
23
 
42
24
  total
43
25
  end
44
-
45
- def zero_all
46
- @modulus_weight = ModulusWeight.new(
47
- @modulus_weight.sort_code_start,
48
- @modulus_weight.sort_code_end,
49
- @modulus_weight.modulus,
50
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51
- @modulus_weight.exception
52
- )
53
- end
54
-
55
- def zero_u_b
56
- @modulus_weight = ModulusWeight.new(
57
- @modulus_weight.sort_code_start,
58
- @modulus_weight.sort_code_end,
59
- @modulus_weight.modulus,
60
- 0, 0, 0, 0, 0, 0, 0, 0,
61
- @modulus_weight.c, @modulus_weight.d, @modulus_weight.e,
62
- @modulus_weight.f, @modulus_weight.g, @modulus_weight.h,
63
- @modulus_weight.exception
64
- )
65
- end
66
-
67
- def apply_exception_2_9(test_digits)
68
- return if test_digits[NUMBER_INDEX[:a]] == 0
69
-
70
- if test_digits[NUMBER_INDEX[:g]] != 9
71
- @modulus_weight = ModulusWeight.new(
72
- @modulus_weight.sort_code_start,
73
- @modulus_weight.sort_code_end,
74
- @modulus_weight.modulus,
75
- 0, 0, 1, 2, 5, 3, 6, 4, 8, 7, 10, 9, 3, 1,
76
- @modulus_weight.exception
77
- )
78
- else
79
- @modulus_weight = ModulusWeight.new(
80
- @modulus_weight.sort_code_start,
81
- @modulus_weight.sort_code_end,
82
- @modulus_weight.modulus,
83
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 10, 9, 3, 1,
84
- @modulus_weight.exception
85
- )
86
- end
87
- end
88
-
89
- def apply_exception_3(test_digits)
90
- c = test_digits[NUMBER_INDEX[:c]]
91
- zero_all if c == 6 || c == 9
92
- end
93
-
94
- def apply_exception_4(total, test_digits)
95
- check_sum = [test_digits[NUMBER_INDEX[:g]], test_digits[NUMBER_INDEX[:h]]].join
96
- check_sum = check_sum.to_i
97
-
98
- total % modulus == check_sum
99
- end
100
-
101
- def apply_exception_5_substitutions(sort_code)
102
- substitutions = UkAccountValidator.read_sort_code_substitution
103
-
104
- if substitutions.keys.include?(sort_code)
105
- sort_code = substitutions[sort_code]
106
- end
107
-
108
- return sort_code
109
- end
110
-
111
- def apply_exception_5(total, test_digits, check_digit)
112
- check_sum = total % modulus
113
- expected_sum = test_digits[NUMBER_INDEX[check_digit]].to_i
114
-
115
- return false if check_sum == 1 && check_digit == :g
116
- return true if check_sum == 0 && expected_sum == 0
117
-
118
- return (modulus - check_sum) == expected_sum
119
- end
120
-
121
- # If a = 4, 5, 6, 7 or 8, and g and h are the same
122
- def apply_exception_6(test_digits)
123
- a = test_digits[NUMBER_INDEX[:a]]
124
- g = test_digits[NUMBER_INDEX[:g]]
125
- h = test_digits[NUMBER_INDEX[:h]]
126
-
127
- zero_all if (a == 4 || a == 5 || a == 6 || a == 7 || a == 8) && g == h
128
- end
129
-
130
- def apply_exception_7(test_digits)
131
- return unless test_digits[NUMBER_INDEX[:g]] == 9
132
-
133
- zero_u_b
134
- end
135
-
136
- def apply_exception_8(test_digits)
137
- test_string = '090126' + @account_number
138
-
139
- test_digits.replace(test_string.split(//).map(&:to_i))
140
- end
141
-
142
- def apply_exception_10(test_digits)
143
- # if ab = 09 or 99 and g=9, zeroise weighting positions u-b.
144
- a = test_digits[NUMBER_INDEX[:a]]
145
- b = test_digits[NUMBER_INDEX[:b]]
146
-
147
- return unless (a == 0 && b == 9) ||
148
- (a == 9 && b == 9 && test_digits[NUMBER_INDEX[:g]] == 9)
149
-
150
- zero_u_b
151
- end
152
26
  end
153
27
  end
154
28
  end
@@ -24,11 +24,8 @@ module UkAccountValidator
24
24
  weighted_test_digits.inject(:+)
25
25
  end
26
26
 
27
- case @modulus_weight.exception
28
- when '4'
29
- return apply_exception_4(total, test_digits)
30
- when '5'
31
- return apply_exception_5(total, test_digits, :h)
27
+ if exception.override_test?
28
+ return exception.test(modulus, total, test_digits, :double_alternate)
32
29
  end
33
30
 
34
31
  total % modulus == 0
@@ -7,7 +7,7 @@ module UkAccountValidator
7
7
  end
8
8
 
9
9
  def valid?
10
- test_string = @sort_code + @account_number
10
+ test_string = sort_code + account_number
11
11
 
12
12
  test_digits = test_string.split(//).map(&:to_i)
13
13
 
@@ -15,15 +15,12 @@ module UkAccountValidator
15
15
  NUMBER_INDEX.each_pair.reduce(0) do |t, pair|
16
16
  weight, index = pair
17
17
 
18
- t + @modulus_weight.send(weight) * test_digits[index]
18
+ t + modulus_weight.send(weight) * test_digits[index]
19
19
  end
20
20
  end
21
21
 
22
- case @modulus_weight.exception
23
- when '4'
24
- return apply_exception_4(total, test_digits)
25
- when '5'
26
- return apply_exception_5(total, test_digits, :g)
22
+ if exception.override_test?
23
+ return exception.test(modulus, total, test_digits, :standard_modulus)
27
24
  end
28
25
 
29
26
  total % modulus == 0
@@ -1,3 +1,3 @@
1
1
  module UkAccountValidator
2
- VERSION = "0.0.1"
2
+ VERSION = '0.0.2'
3
3
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['hayden@haydenball.me.uk']
11
11
  spec.summary = 'Validate UK Account Numbers and Sort Codes'
12
12
  spec.description = spec.summary
13
- spec.homepage = ''
13
+ spec.homepage = 'https://github.com/ball-hayden/uk_account_validator'
14
14
  spec.license = '2 Clause BSD'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uk_account_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hayden Ball
@@ -37,8 +37,21 @@ files:
37
37
  - features/support/env.rb
38
38
  - features/two_modulus_check.feature
39
39
  - lib/uk_account_validator.rb
40
+ - lib/uk_account_validator/exceptions/base_exception.rb
41
+ - lib/uk_account_validator/exceptions/exception_1.rb
42
+ - lib/uk_account_validator/exceptions/exception_10.rb
43
+ - lib/uk_account_validator/exceptions/exception_12.rb
44
+ - lib/uk_account_validator/exceptions/exception_14.rb
45
+ - lib/uk_account_validator/exceptions/exception_2_9.rb
46
+ - lib/uk_account_validator/exceptions/exception_3.rb
47
+ - lib/uk_account_validator/exceptions/exception_4.rb
48
+ - lib/uk_account_validator/exceptions/exception_5.rb
49
+ - lib/uk_account_validator/exceptions/exception_6.rb
50
+ - lib/uk_account_validator/exceptions/exception_7.rb
51
+ - lib/uk_account_validator/exceptions/exception_8.rb
40
52
  - lib/uk_account_validator/modulus_weight.rb
41
53
  - lib/uk_account_validator/modulus_weights_table.rb
54
+ - lib/uk_account_validator/number_indices.rb
42
55
  - lib/uk_account_validator/validator.rb
43
56
  - lib/uk_account_validator/validators/base_validator.rb
44
57
  - lib/uk_account_validator/validators/double_alternate.rb
@@ -47,7 +60,7 @@ files:
47
60
  - lib/uk_account_validator/validators/standard_modulus.rb
48
61
  - lib/uk_account_validator/version.rb
49
62
  - uk_account_validator.gemspec
50
- homepage: ''
63
+ homepage: https://github.com/ball-hayden/uk_account_validator
51
64
  licenses:
52
65
  - 2 Clause BSD
53
66
  metadata: {}
@@ -82,3 +95,4 @@ test_files:
82
95
  - features/step_definitions/modulus_weights_table.rb
83
96
  - features/support/env.rb
84
97
  - features/two_modulus_check.feature
98
+ has_rdoc: