Module: IpsQrCode::Utils

Defined in:
lib/ips_qr_code/utils.rb

Constant Summary collapse

RENAME_KEYS =
{
  'kod'                   => :k,
  'verzija'               => :v,
  'version'               => :v,
  'characterEncodingType' => :c,
  'znakovniSkup'          => :c,
  'racunPrimaoca'         => :r,
  'nazivPrimaoca'         => :n,
  'iznos'                 => :i,
  'nazivPlatioca'         => :p,
  'sifraPlacanja'         => :sf,
  'svrhaPlacanja'         => :s,
  'merchantCodeCategory'  => :m,
  'jednokratnaSifra'      => :js,
  'pozivNaBroj'           => :ro,
  'referencaPrimaoca'     => :rl,
  'referencaPlacanja'     => :rp
}.freeze

Class Method Summary collapse

Class Method Details

.calculate_bank_account_control_number(input) ⇒ Object



50
51
52
# File 'lib/ips_qr_code/utils.rb', line 50

def self.(input)
  98 - modulo(input[0...-2] + '00', 97)
end

.mod22(input) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/ips_qr_code/utils.rb', line 118

def self.mod22(input)
  control = input.to_s.reverse.chars.map(&:to_i).each_with_index.reduce(0) do |sum,(char, idx)|
    sum + (idx + 1) * char
  end
  control = 11 - (control % 11)
  control % 10
end

.mod97(input) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/ips_qr_code/utils.rb', line 108

def self.mod97(input)
  control = 0
  base    = 100
  input.to_s.reverse.chars.map(&:to_i).each do |char|
    control = (control + base * char) % 97
    base    = (base * 10) % 97
  end
  98 - control
end

.modulo(divident, divisor) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/ips_qr_code/utils.rb', line 40

def self.modulo(divident, divisor)
  div     = divident.to_s
  divisor = divisor.to_i
  while div.length > 10
    part = div[0,10].to_i
    div  = (part % divisor).to_s + div[10..-1]
  end
  div.to_i % divisor
end

.normalize_bank_account(input) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/ips_qr_code/utils.rb', line 32

def self.(input)
  numerals = input.to_s.gsub(/\D/, '')
  bank     = numerals[0,3]
  control  = numerals[-2,2] || numerals[-2..-1]
    = numerals[3...-2] || ''
  "#{bank}#{account.rjust(13, '0')}#{control}"
end

.rename_keys(opts) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/ips_qr_code/utils.rb', line 22

def self.rename_keys(opts)
  result = {}
  opts.each do |key, value|
    key_str = key.to_s
    new_key = RENAME_KEYS[key_str] || key_str.to_sym
    result[new_key] = value
  end
  result
end

.sanitize22(input) ⇒ Object



97
98
99
100
101
102
103
104
105
106
# File 'lib/ips_qr_code/utils.rb', line 97

def self.sanitize22(input)
  input.to_s.gsub(/[ \-]/, '').chars.map.with_index do |char, idx|
    code = char.ord
    if code.between?(48, 57)
      (code - 48).to_s
    else
      raise ArgumentError, "Invalid character \"#{char}\" at position #{idx}"
    end
  end.join
end

.sanitize97(input) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ips_qr_code/utils.rb', line 84

def self.sanitize97(input)
  input.to_s.upcase.gsub(/[ \-]/, '').chars.map.with_index do |char, idx|
    code = char.ord
    if code.between?(65, 90)
      (code - 55).to_s
    elsif code.between?(48, 57)
      (code - 48).to_s
    else
      raise ArgumentError, "Invalid character \"#{char}\" at position #{idx}"
    end
  end.join
end

.validate_bank_account(input) ⇒ Object



54
55
56
57
58
59
# File 'lib/ips_qr_code/utils.rb', line 54

def self.(input)
  normalized        = (input)
  control_number    = normalized[-2,2]
  calculated_number = (normalized).to_s.rjust(2, '0')
  control_number == calculated_number
end

.validate_reference_number(input) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ips_qr_code/utils.rb', line 61

def self.validate_reference_number(input)
  return true if input.nil? || input.to_s.empty?
  input_str = input.to_s
  model     = input_str[0,2]
  case model
  when '97'
    sanitized = sanitize97(input_str)
    control   = sanitized[2,2]
    poziv     = sanitized[4..-1]
    control.to_i == mod97(poziv)
  when '22'
    sanitized = sanitize22(input_str)
    poziv     = sanitized[5...-1]
    control   = sanitized[-1]
    control.to_i == mod22(poziv)
  when '00'
    true
  else
    warn "Model #{model} is not supported."
    true
  end
end