module Faker module Russian module Inn def inn(options = {}) region_number = find_region_number(options[:region_number]) kind = find_kind(options[:kind]) sequence_digits = find_sequence_digits(kind, options[:sequence_number]) inn_without_check_digit = region_number + sequence_digits inn_without_check_digit + check_digit(inn_without_check_digit) end private def find_region_number(number = nil) if number.present? raise('there is no region with that number!') unless REGION_NUMBERS.include?(number) number else REGION_NUMBERS.sample end end def find_kind(kind) case kind when :individual then :individual when :legal then :legal when nil then [:individual, :legal].sample else raise 'there is no any kind other than :individual or :legal' end end def find_sequence_digits(kind, sequence_number) sequence = sequence_number || Random.new_seed Random.srand(sequence) (kind == :legal) ? Random.rand(1_000_000..9_999_999).to_s : Random.rand(10_000_000..99_999_999).to_s end def check_digit(digits) if digits.length == 9 calc(P10, digits) else calc(P11, digits) + calc(P12, digits + calc(P11, digits)) end end def calc(p, inn) (p.each_with_index.inject(0){ |s, p| s + p[0] * inn[p[1]].to_i } % 11 % 10).to_s end REGION_NUMBERS = %w{01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 83 86 87 89} # TODO move to specific place P10 = [2, 4, 10, 3, 5, 9, 4, 6, 8] P11 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8] P12 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8] private_constant :P10, :P11, :P12 end end end