MX-ID 0.0.1.pre

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.
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module MX::ID::Auxiliar
3
+
4
+ module ClassMethods
5
+ def en_blanco?(cadena)
6
+ cadena.nil? or cadena.empty?
7
+ end
8
+
9
+ def fecha_con_formato(fecha)
10
+ fecha.strftime("%y%m%d")
11
+ end
12
+
13
+ def obtener_primer_nombre_valido(nombres)
14
+ arr_nombres = nombres.split(" ")
15
+ if arr_nombres.size <= 1
16
+ nombres
17
+ else
18
+ arr_nombres[0] =~ /(JOSE)|(J\.)|J|(MARIA)|(MA)|(MA\.)/ ? arr_nombres[1] : arr_nombres[0]
19
+ end
20
+ end
21
+
22
+ # TODO: Anexar/crear biblioteca para convertir número a palabras y poder hacer esta una clase independiente
23
+ def numero_a_palabras(numero_entero)
24
+ quitar_acentos(::I18n.with_locale(:es) { numero_entero.to_words }).upcase
25
+ end
26
+
27
+ def quitar_acentos(cadena)
28
+ I18n.transliterate(cadena)
29
+ end
30
+
31
+ def fecha_coincide?(dia_str, mes_str, año_str, fecha_coincidente = nil, tipo_fecha = "nacimiento", msg = [])
32
+ errores = false
33
+ begin
34
+ if Date.valid_date?(año_str.to_i, mes_str.to_i, dia_str.to_i)
35
+ unless fecha_coincidente.nil?
36
+ fn = Date.parse("#{año_str}-#{mes_str}-#{dia_str}")
37
+ unless fn.year == fecha_coincidente.year and fn.month == fecha_coincidente.month and fn.day == fecha_coincidente.day
38
+ errores = true
39
+ msg << "La fecha de #{tipo_fecha} no coincide con la fecha de #{tipo_fecha} proporcionada."
40
+ end
41
+ end
42
+ else
43
+ errores = true
44
+ msg << "La fecha de #{tipo_fecha} es incorrecta."
45
+ end
46
+ rescue
47
+ errores = true
48
+ msg << "La fecha de #{tipo_fecha} está mal formada."
49
+ end
50
+ return !errores
51
+ end
52
+ end
53
+
54
+ def self.included(base)
55
+ base.extend ClassMethods
56
+ end
57
+
58
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module MX
3
+ module ID
4
+ VERSION = "0.0.1.pre"
5
+ end
6
+ end
@@ -0,0 +1,45 @@
1
+ module NumeroRomano
2
+ @digitos_base = {
3
+ 1 => 'I',
4
+ 4 => 'IV',
5
+ 5 => 'V',
6
+ 9 => 'IX',
7
+ 10 => 'X',
8
+ 40 => 'XL',
9
+ 50 => 'L',
10
+ 90 => 'XC',
11
+ 100 => 'C',
12
+ 400 => 'CD',
13
+ 500 => 'D',
14
+ 900 => 'CM',
15
+ 1000 => 'M'
16
+ }
17
+
18
+ def self.a_romano valor
19
+ resultado = ''
20
+ @digitos_base.keys.reverse.each do |decimal|
21
+ while valor >= decimal
22
+ valor -= decimal
23
+ resultado += @digitos_base[decimal]
24
+ end
25
+ end
26
+ resultado
27
+ end
28
+
29
+ def self.a_decimal valor
30
+ valor = valor.upcase
31
+ resultado = 0
32
+ @digitos_base.values.reverse.each do |romano|
33
+ while valor.start_with? romano
34
+ valor = valor.slice(romano.length, valor.length)
35
+ resultado += @digitos_base.key romano
36
+ end
37
+ end
38
+ resultado
39
+ end
40
+
41
+ def self.romano? valor
42
+ valor = valor.upcase
43
+ !(valor.scan(/^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/).empty?)
44
+ end
45
+ end
@@ -0,0 +1,415 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe MX::ID::RFC, :rfc do
4
+
5
+ describe ".persona_fisica" do
6
+ describe "Regla 4ª" do
7
+ context "cuando el apellido paterno de la persona física se componga de una letra" do
8
+ it "es la primera letra del apellido paterno, la primera letra del apellido materno y la a primera y segunda letra del nombre" do
9
+ nombres = "ALVARO"
10
+ apellido_paterno = "DE LA O"
11
+ apellido_materno = "LOZANO"
12
+ fecha_nacimiento = Date.new(1940, 12, 1)
13
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "OLAL401201R99"
14
+ end
15
+ end
16
+
17
+ context "cuando el apellido paterno de la persona física se componga de dos letras" do
18
+ it "es la primera letra del apellido paterno, la primera letra del apellido materno y la a primera y segunda letra del nombre" do
19
+ nombres = "ERNESTO"
20
+ apellido_paterno = "EK"
21
+ apellido_materno = "RIVERA"
22
+ fecha_nacimiento = Date.new(1907, 11, 20)
23
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "ERER0711209E3"
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "Regla 7ª: casos en que la persona física tenga un solo apellido" do
29
+ context "cuando el apellido paterno está en blanco" do
30
+ it "es la primera y segunda letras del apellido materno, más la primera y segunda letras del nombre" do
31
+ nombres = "GERARDO"
32
+ apellido_paterno = ""
33
+ apellido_materno = "ZAFRA"
34
+ fecha_nacimiento = Date.new(1925, 11, 15)
35
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "ZAGE251115EK7"
36
+ end
37
+ end
38
+
39
+ context "cuando el apellido materno está en blanco" do
40
+ it "es la primera y segunda letras del apellido paterno, más la primera y segunda letras del nombre" do
41
+ nombres = "JUAN"
42
+ apellido_paterno = "MARTINEZ"
43
+ apellido_materno = ""
44
+ fecha_nacimiento = Date.new(1942, 1, 16)
45
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "MAJU420116BP3"
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "Regla 10ª: casos en los que aparezcan formando parte del nombre, apellido paterno y apellido materno los caracteres especiales" do
51
+ context "cuando están en forma individual dentro del nombre" do
52
+ it "se interpretan los caracteres especiales" do
53
+ nombres = "LUZ MA."
54
+ apellido_paterno = "FERNANDEZ"
55
+ apellido_materno = "JUAREZ"
56
+ fecha_nacimiento = Date.new(1983, 1, 20)
57
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "FEJL8301207E3"
58
+ end
59
+ end
60
+
61
+ context "cuando están en forma individual dentro del apellido paterno" do
62
+ it "se interpretan los caracteres especiales" do
63
+ nombres = "RUBEN"
64
+ apellido_paterno = "D'ANGELO"
65
+ apellido_materno = "FARGO"
66
+ fecha_nacimiento = Date.new(1971, 1, 8)
67
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "DAFR7101081P4"
68
+ end
69
+ end
70
+ end
71
+
72
+ it 'RUAP791104413' do
73
+ nombres = "PABLO JAVIER"
74
+ apellido_paterno = "RUIZ"
75
+ apellido_materno = "ABRIN"
76
+ fecha_nacimiento = Date.new(1979, 11, 4)
77
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "RUAP791104413"
78
+ end
79
+
80
+ it 'LIOA800822N4A' do
81
+ nombres = "JOSE ANGEL"
82
+ apellido_paterno = "LINARES"
83
+ apellido_materno = "ORRALA"
84
+ fecha_nacimiento = Date.new(1980, 8, 22)
85
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "LIOA800822N4A"
86
+ end
87
+
88
+ it 'IXCA8008222H4' do
89
+ nombres = "ANDRES"
90
+ apellido_paterno = "ICH"
91
+ apellido_materno = "CHEM"
92
+ fecha_nacimiento = Date.new(1980, 8, 22)
93
+ expect(described_class.persona_fisica(nombres, apellido_paterno, apellido_materno, fecha_nacimiento)).to eq "IXCA8008222H4"
94
+ end
95
+ end
96
+
97
+ describe ".persona_moral" do
98
+ describe 'Regla 4ª' do
99
+ context "cuando la denominación o razón social esté compuesta sólo de iniciales" do
100
+ it 'FAZ110304UT4' do
101
+ razon_social = "F.A.Z. SA DE CV"
102
+ fecha_constitucion = Date.new(2011, 3, 4)
103
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "FAZ110304ET3"
104
+ end
105
+
106
+ it 'USR110304UT4' do
107
+ razon_social = "U.S. ROBOTICS SA DE CV"
108
+ fecha_constitucion = Date.new(2011, 3, 4)
109
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "USR110304S80"
110
+ end
111
+
112
+ it 'HPM841221L9A' do
113
+ razon_social = "H. PRIETO Y MARTINEZ S DE RL"
114
+ fecha_constitucion = Date.new(1984, 12, 21)
115
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "HPM841221L9A"
116
+ end
117
+ end
118
+ end
119
+
120
+ describe 'Regla 6ª' do
121
+ context 'Cuando la denominación o razón social se comprende de dos elementos' do
122
+ it 'Para efectos de la conformación de la clave, se tomará la letra inicial de la primera palabra y las dos primeras letras de la segunda' do
123
+ razon_social = "OPERATIVO EVENPLAN SC"
124
+ fecha_constitucion = Date.new(1999, 7, 15)
125
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "OEV990715MMA"
126
+ end
127
+ end
128
+ end
129
+
130
+ describe 'Regla 7ª' do
131
+ context 'Cuando la denominación o razón social se compone de un solo elemento' do
132
+ it 'Para efectos de conformación de la clave, se tomarán las tres primeras letras consecutivas del mismo' do
133
+ razon_social = "YOMERO SC"
134
+ fecha_constitucion = Date.new(20011, 7, 15)
135
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "YOM110715PR3"
136
+ end
137
+ end
138
+ end
139
+
140
+ describe 'Regla 8ª' do
141
+ context 'Cuando la denominación o razón social se componga de un solo elemento y sus letras no completen las tres requeridas' do
142
+ it 'Para efectos de conformación de la clave, se tomaran las empleadas por el contribuyente y las restantes se suplirán con una “X”' do
143
+ razon_social = "YO SC"
144
+ fecha_constitucion = Date.new(20011, 7, 15)
145
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "YOX110715NJ9"
146
+ end
147
+ end
148
+ end
149
+
150
+ describe 'Regla 10ª' do
151
+ context 'Cuando la denominación o razón social contenga en algún o en sus tres primeros elementos números arábigos, o números romanos' do
152
+ context 'se sustituyen los números romanos por números en letra' do
153
+ it 'ESV841221GB1' do
154
+ razon_social = "EDITORIAL SIGLO XXI SA DE CV"
155
+ fecha_constitucion = Date.new(1984, 12, 21)
156
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "ESV841221GB1"
157
+ end
158
+ end
159
+
160
+ context 'se sustituyen los números por números en letra' do
161
+ it 'DOC841221R87' do
162
+ razon_social = "EL 12 SA"
163
+ fecha_constitucion = Date.new(1984, 12, 21)
164
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "DOC841221R87"
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe 'Regla 12ª' do
171
+ context 'Cuando aparezcan formando parte de la denominación o razón social los caracteres especiales' do
172
+ context 'Cuando deben de excluirse para el cálculo del homónimo y del dígito verificador' do
173
+ context 'Cuando están en forma individual dentro del texto de la denominación o razón social (Anexo VI)' do
174
+ it 'SND861121BW5' do
175
+ razon_social = "LA S@NDIA SA DE CV"
176
+ fecha_constitucion = Date.new(1986, 11, 21)
177
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "SND861121BW5"
178
+ end
179
+
180
+ it 'ACO861121BW5' do
181
+ razon_social = "@ COMER SA DE CV"
182
+ fecha_constitucion = Date.new(1986, 11, 21)
183
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "ACO861121N51"
184
+ end
185
+
186
+ it 'DSU861121CL5' do
187
+ razon_social = "LA / DEL SUR SA"
188
+ fecha_constitucion = Date.new(1986, 11, 21)
189
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "DSU861121CL5"
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ it 'CSP020827Q18' do
197
+ razon_social = "CONSULTORIA Y SERVICIOS PETROLEROS SA DE CV"
198
+ fecha_constitucion = Date.new(2002, 8, 27)
199
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "CSP020827Q18"
200
+ end
201
+
202
+ it 'MTS110304UT4' do
203
+ razon_social = "MAQUECH TECHNOLOGY SERVICES SA DE CV"
204
+ fecha_constitucion = Date.new(2011, 3, 4)
205
+ expect(described_class.persona_moral(razon_social, fecha_constitucion)).to eq "MTS110304UT4"
206
+ end
207
+ end
208
+
209
+ describe ".valido?" do
210
+ context "la cadena dada es nil" do
211
+ let!(:msgs){ "" }
212
+ let!(:respuesta){ described_class.valido?(nil, nil, msgs) }
213
+
214
+ it "false" do
215
+ expect(respuesta).to be_falsey
216
+ end
217
+
218
+ it "mensaje debe ser 'No debe estar vacío.'" do
219
+ expect(msgs).to eq "No debe estar vacío."
220
+ end
221
+ end
222
+
223
+ context "la cadena dada es la cadena vacía" do
224
+ let!(:msgs){ "" }
225
+ let!(:respuesta){ described_class.valido?("", nil, msgs) }
226
+
227
+ it "false" do
228
+ expect(respuesta).to be_falsey
229
+ end
230
+
231
+ it "mensaje debe ser 'No debe estar vacío.'" do
232
+ expect(msgs).to eq "No debe estar vacío."
233
+ end
234
+ end
235
+
236
+ context "cuando es un RFC inválido" do
237
+ context "cuando las iniciales son incorrectas" do
238
+ context "cuando la fecha de nacimiento proporcionada es nil" do
239
+ let!(:msgs){ "" }
240
+ let!(:respuesta){ described_class.valido?("R12A791504413", nil, msgs) }
241
+ it "false" do
242
+ expect(respuesta).to be_falsey
243
+ end
244
+
245
+ it "mensaje debe ser 'No tiene el formato correcto.'" do
246
+ expect(msgs).to eq "No tiene el formato correcto."
247
+ end
248
+ end
249
+ end
250
+
251
+ context "cuando la fecha es incorrecta" do
252
+ context "cuando la fecha de nacimiento proporcionada es nil" do
253
+ let!(:msgs){ "" }
254
+ let!(:respuesta){ described_class.valido?("RUAP791504411", nil, msgs) }
255
+ it "false" do
256
+ expect(respuesta).to be_falsey
257
+ end
258
+
259
+ it "mensaje debe ser 'La fecha de nacimiento es incorrecta.'" do
260
+ expect(msgs).to eq "La fecha de nacimiento es incorrecta."
261
+ end
262
+ end
263
+
264
+ context "cuando la fecha de nacimiento proporcionada no coincide" do
265
+ let!(:msgs){ "" }
266
+ let!(:respuesta){ described_class.valido?("RUAP79110541A", Date.new(1979, 11, 04), msgs) }
267
+ it "false" do
268
+ expect(respuesta).to be_falsey
269
+ end
270
+
271
+ it "mensaje debe ser 'La fecha de nacimiento no coincide con la fecha de nacimiento proporcionada.'" do
272
+ expect(msgs).to eq "La fecha de nacimiento no coincide con la fecha de nacimiento proporcionada."
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ context "cuando es un RFC válido" do
279
+ context "cuando es de persona moral" do
280
+ let!(:msgs){ "" }
281
+ let!(:respuesta){ described_class.valido?("MTS110304UT4", nil, msgs, false) }
282
+ it "true" do
283
+ expect(respuesta).to be_truthy
284
+ end
285
+
286
+ it "mensaje debe estar en blanco" do
287
+ expect(msgs).to eq ""
288
+ end
289
+
290
+ context "cuando las iniciales son caracteres especiales" do
291
+ let!(:msgs){ "" }
292
+ let!(:respuesta){ described_class.valido?("Ñ&P791104410", nil, msgs, false) }
293
+ it "true" do
294
+ expect(respuesta).to be_truthy
295
+ end
296
+
297
+ it "mensaje debe estar en blanco" do
298
+ expect(msgs).to eq ""
299
+ end
300
+ end
301
+
302
+ context "cuando la fecha de constitución proporcionada es nil" do
303
+ let!(:msgs){ "" }
304
+ let!(:respuesta){ described_class.valido?("MTS110304UT4", nil, msgs, false) }
305
+ it "true" do
306
+ expect(respuesta).to be_truthy
307
+ end
308
+
309
+ it "mensaje debe estar en blanco" do
310
+ expect(msgs).to eq ""
311
+ end
312
+ end
313
+
314
+ context "cuando la fecha de constitución proporcionada no coincide" do
315
+ let!(:msgs){ "" }
316
+ let!(:respuesta){ described_class.valido?("MTS110304UT4", Date.new(1979, 12, 04), msgs, false) }
317
+ it "false" do
318
+ expect(respuesta).to be_falsey
319
+ end
320
+
321
+ it "mensaje debe ser 'La fecha de constitución no coincide con la fecha de constitución proporcionada.'" do
322
+ expect(msgs).to eq "La fecha de constitución no coincide con la fecha de constitución proporcionada."
323
+ end
324
+ end
325
+
326
+ context "cuando la fecha de constitución proporcionada coincide" do
327
+ let!(:msgs){ "" }
328
+ let!(:respuesta){ described_class.valido?("MTS110304UT4", Date.new(2011, 03, 04), msgs, false) }
329
+ it "true" do
330
+ expect(respuesta).to be_truthy
331
+ end
332
+
333
+ it "mensaje debe estar en blanco" do
334
+ expect(msgs).to eq ""
335
+ end
336
+ end
337
+
338
+ context 'cuando el dígito verificador es incorrecto' do
339
+ let!(:msgs){ "" }
340
+ let!(:respuesta){ described_class.valido?("MTS110304UT5", Date.new(2011, 03, 04), msgs, false) }
341
+ it "false" do
342
+ expect(respuesta).to be_falsey
343
+ end
344
+
345
+ it "mensaje debe ser 'El dígito verificador es incorrecto.'" do
346
+ expect(msgs).to eq "El dígito verificador es incorrecto."
347
+ end
348
+ end
349
+ end
350
+
351
+ context "cuando es de persona física" do
352
+ let!(:msgs){ "" }
353
+ let!(:respuesta){ described_class.valido?("RUAP791104413", nil, msgs) }
354
+ it "true" do
355
+ expect(respuesta).to be_truthy
356
+ end
357
+
358
+ it "mensaje debe estar en blanco" do
359
+ expect(msgs).to eq ""
360
+ end
361
+
362
+ context "cuando la fecha de nacimiento proporcionada es nil" do
363
+ let!(:msgs){ "" }
364
+ let!(:respuesta){ described_class.valido?("RUAP791104413", nil, msgs) }
365
+ it "true" do
366
+ expect(respuesta).to be_truthy
367
+ end
368
+
369
+ it "mensaje debe estar en blanco" do
370
+ expect(msgs).to eq ""
371
+ end
372
+ end
373
+
374
+ context "cuando la fecha de nacimiento proporcionada no coincide" do
375
+ let!(:msgs){ "" }
376
+ let!(:respuesta){ described_class.valido?("RUAP791104413", Date.new(1979, 12, 04), msgs) }
377
+ it "false" do
378
+ expect(respuesta).to be_falsey
379
+ end
380
+
381
+ it "mensaje debe ser 'La fecha de nacimiento no coincide con la fecha de nacimiento proporcionada.'" do
382
+ expect(msgs).to eq "La fecha de nacimiento no coincide con la fecha de nacimiento proporcionada."
383
+ end
384
+ end
385
+
386
+ context "cuando la fecha de nacimiento proporcionada coincide" do
387
+ let!(:msgs){ "" }
388
+ let!(:respuesta){ described_class.valido?("RUAP791104413", Date.new(1979, 11, 04), msgs) }
389
+ it "true" do
390
+ expect(respuesta).to be_truthy
391
+ end
392
+
393
+ it "mensaje debe estar en blanco" do
394
+ expect(msgs).to eq ""
395
+ end
396
+ end
397
+ end
398
+
399
+
400
+ end
401
+
402
+ context "cuando el formato del RFC es inválido" do
403
+ let!(:msgs){ "" }
404
+ let!(:respuesta){ described_class.valido?("RUAP791104", nil, msgs) }
405
+ it "false" do
406
+ expect(respuesta).to be_falsey
407
+ end
408
+
409
+ it "mensaje debe ser 'No tiene la longitud correcta (13 caracteres).'" do
410
+ expect(msgs).to eq "No tiene la longitud correcta (13 caracteres)."
411
+ end
412
+ end
413
+ end
414
+
415
+ end