Class: Croatia::UMCN

Inherits:
Object
  • Object
show all
Defined in:
lib/croatia/umcn.rb

Overview

JMBG - Jedinstveni Matični Broj Građana UMCN - Unique Master Citizen Number

Constant Summary collapse

WEIGHTS =
[ 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 ]
REGION_CODES =
{
  # Special / Foreign
  0 => "Yugoslavia",
  1 => "Foreigner in BiH",
  2 => "Foreigner in Montenegro",
  3 => "Foreigner in Croatia",
  4 => "Foreigner in North Macedonia",
  5 => "Foreigner in Slovenia",
  6 => "Foreigner in Serbia",
  7 => "Foreigner in Vojvodina",
  8 => "Foreigner in Kosovo",
  9 => "Yugoslavia",

  # Bosnia and Herzegovina (10–19)
  10 => "Banja Luka",
  11 => "Bihac",
  12 => "Doboj",
  13 => "Gorazde",
  14 => "Livno",
  15 => "Mostar",
  16 => "Prijedor",
  17 => "Sarajevo",
  18 => "Tuzla",
  19 => "Zenica",

  # Montenegro (21–29)
  21 => "Podgorica",
  22 => "Bar",
  23 => "Budva",
  24 => "Herceg Novi",
  25 => "Cetinje",
  26 => "Niksic",
  27 => "Berane",
  28 => "Bijelo Polje",
  29 => "Pljevlja",

  # Croatia (30–39)
  30 => "Slavonia",
  31 => "Podravina",
  32 => "Medimurje",
  33 => "Zagreb",
  34 => "Kordun",
  35 => "Lika",
  36 => "Istria",
  37 => "Banovina",
  38 => "Dalmatia",
  39 => "Zagorje",

  # North Macedonia (41–49)
  41 => "Bitola",
  42 => "Kumanovo",
  43 => "Ohrid",
  44 => "Prilep",
  45 => "Skopje",
  46 => "Strumica",
  47 => "Tetovo",
  48 => "Veles",
  49 => "Stip",

  # Slovenia (50)
  50 => "Slovenia",

  # Serbia (70–79)
  70 => "Serbia Abroad",
  71 => "Belgrade",
  72 => "Sumadija",
  73 => "Nis",
  74 => "Morava",
  75 => "Zajecar",
  76 => "Podunavlje",
  77 => "Kolubara",
  78 => "Kraljevo",
  79 => "Uzice",

  # Vojvodina (80–89)
  80 => "Novi Sad",
  81 => "Sombor",
  82 => "Subotica",
  83 => "Zrenjanin",
  84 => "Kikinda",
  85 => "Pancevo",
  86 => "Vrbas",
  87 => "Sremska Mitrovica",
  88 => "Ruma",
  89 => "Backa Topola",

  # Kosovo (90–99)
  90 => "Pristina",
  91 => "Prizren",
  92 => "Pec",
  93 => "Djakovica",
  94 => "Mitrovica",
  95 => "Gnjilane",
  96 => "Ferizaj",
  97 => "Decan",
  98 => "Klina",
  99 => "Malisevo"
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(birthday:, region_code:, sequence_number:) ⇒ UMCN

Returns a new instance of UMCN.



137
138
139
140
141
# File 'lib/croatia/umcn.rb', line 137

def initialize(birthday:, region_code:, sequence_number:)
  @birthday = birthday
  @region_code = region_code
  @sequence_number = sequence_number
end

Instance Attribute Details

#birthdayObject

Returns the value of attribute birthday.



107
108
109
# File 'lib/croatia/umcn.rb', line 107

def birthday
  @birthday
end

#checkusmObject

Returns the value of attribute checkusm.



107
108
109
# File 'lib/croatia/umcn.rb', line 107

def checkusm
  @checkusm
end

#region_codeObject

Returns the value of attribute region_code.



107
108
109
# File 'lib/croatia/umcn.rb', line 107

def region_code
  @region_code
end

#sequence_numberObject

Returns the value of attribute sequence_number.



107
108
109
# File 'lib/croatia/umcn.rb', line 107

def sequence_number
  @sequence_number
end

Class Method Details

.parse(umcn) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/croatia/umcn.rb', line 118

def self.parse(umcn)
  digits = umcn.chars.map(&:to_i)

  day = digits[0..1].join.to_i
  month = digits[2..3].join.to_i
  year = digits[4..6].join.to_i
  millenium = case digits[4]
  when 0 then 2000
  else 1000
  end
  full_year = millenium + year

  birthday = Date.new(full_year, month, day)
  region_code = digits[7..8].join.to_i
  sequence_number = digits[9..11].join.to_i

  new(birthday: birthday, region_code: region_code, sequence_number: sequence_number)
end

.valid?(umcn) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
# File 'lib/croatia/umcn.rb', line 109

def self.valid?(umcn)
  return false if umcn.nil?
  return false unless umcn.match?(/\A\d{13}\Z/)

  parse(umcn).checksum == umcn.strip[-1].to_i
rescue Date::Error, ArgumentError
  false
end

Instance Method Details

#checksumObject



188
189
190
# File 'lib/croatia/umcn.rb', line 188

def checksum
  to_s[-1].to_i
end

#region_of_birthObject



167
168
169
# File 'lib/croatia/umcn.rb', line 167

def region_of_birth
  REGION_CODES[region_code]
end

#sexObject



163
164
165
# File 'lib/croatia/umcn.rb', line 163

def sex
  sequence_number <= 499 ? :male : :female
end

#to_sObject



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/croatia/umcn.rb', line 171

def to_s
  parts = []
  parts << birthday.strftime("%d%m")
  parts << format("%03d", birthday.year % 1000)
  parts << format("%02d", region_code)
  parts << format("%03d", sequence_number)

  digits = parts.join.chars.map(&:to_i)
  sum = digits.each_with_index.sum { |digit, i| digit * WEIGHTS[i] }
  mod = sum % 11

  checksum = (mod == 0 || mod == 1) ? 0 : (11 - mod)

  parts << checksum.to_s
  parts.join
end