rfc_facil 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +24 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/rfc_facil/homoclave_calculator.rb +73 -0
- data/lib/rfc_facil/person.rb +16 -0
- data/lib/rfc_facil/rfc.rb +22 -0
- data/lib/rfc_facil/ten_digits_code_calculator.rb +122 -0
- data/lib/rfc_facil/verification_digit_calculator.rb +32 -0
- data/lib/rfc_facil/version.rb +3 -0
- data/lib/rfc_facil.rb +11 -0
- data/logo.png +0 -0
- data/rfc_facil.gemspec +26 -0
- data/tests/rfc_facil/test_homoclave_calculator.rb +61 -0
- data/tests/rfc_facil/test_rfc.rb +11 -0
- data/tests/rfc_facil/test_ten_digits_code_calculator.rb +79 -0
- data/tests/rfc_facil/test_verification_digit_calculator.rb +9 -0
- data/tests/tests_helper.rb +6 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 90d241e12a7657fe09501ed8d060af1f0b563c4e
|
4
|
+
data.tar.gz: 84a309812ff7c1e5161446d88882a6dae3dbdf6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 793b87293071c2ae0870bf405bc531119f891eaad72816061c03c32d841fb2355230d86efb979169cac04593987b707199d02d58c5ec339e7649b0da67f8c664
|
7
|
+
data.tar.gz: 580a7adbfb39eaf743274a3827d547e8ea5ca30e15b21558cb3b6c67097ac2b6b28b6171258faf5802e53a544667751f2a5b1288f6859f66ddf918fabc5626c3
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Rfc Fácil
|
2
|
+

|
3
|
+
|
4
|
+
Libreria para calcular el Registro Federal de Contribuyentes en México (RFC) en Ruby.
|
5
|
+
|
6
|
+
## Uso
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'rfc_facil'
|
10
|
+
```
|
11
|
+
Calcular el rfc de una persona física es muy sencillo:
|
12
|
+
```ruby
|
13
|
+
rfc = Rfc.new(name: 'Adrián Marcelo', first_last_name: 'Rangel', second_last_name: 'Araujo', day: 27, month: 11, year: 1992)
|
14
|
+
rfc.to_s # => 'RAAA921127RI6'
|
15
|
+
```
|
16
|
+
|
17
|
+
## Fuente
|
18
|
+
Esta librería se basa en documentación oficial obtenida por medio del IFAI (Instituto Federal de Acceso a la Información). El documento puede ser consultado en el sitio de [INFOMEX](https://www.infomex.org.mx/gobiernofederal/moduloPublico/moduloPublico.action) con el folio 0610100135506.
|
19
|
+
|
20
|
+
### Agradecimiento
|
21
|
+
El código es una version en Ruby de [rfc-facil](https://github.com/josketres/rfc-facil) hecha en Java por [josketres](https://github.com/josketres)
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
Errores y pull requests son bienvenidos en Github: https://github.com/acrogenesis/rfc_facil.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rfc_facil'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require 'pry'
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
class HomoclaveCalculator
|
2
|
+
HOMOCLAVE_DIGITS = '123456789ABCDEFGHIJKLMNPQRSTUVWXYZ'
|
3
|
+
FULL_NAME_MAPPING = {
|
4
|
+
' ' => '00', '0' => '00', '1' => '01', '2' => '02', '3' => '03', '4' => '04',
|
5
|
+
'5' => '05', '6' => '06', '7' => '07', '8' => '08', '9' => '09', '&' => '10',
|
6
|
+
'A' => '11', 'B' => '12', 'C' => '13', 'D' => '14', 'E' => '15', 'F' => '16',
|
7
|
+
'G' => '17', 'H' => '18', 'I' => '19', 'J' => '21', 'K' => '22', 'L' => '23',
|
8
|
+
'M' => '24', 'N' => '25', 'O' => '26', 'P' => '27', 'Q' => '28', 'R' => '29',
|
9
|
+
'S' => '32', 'T' => '33', 'U' => '34', 'V' => '35', 'W' => '36', 'X' => '37',
|
10
|
+
'Y' => '38', 'Z' => '39', 'Ñ' => '40'
|
11
|
+
}
|
12
|
+
attr_accessor :person, :full_name, :mapped_full_name, :pairs_of_digits_sum, :homoclave
|
13
|
+
|
14
|
+
def initialize(person)
|
15
|
+
@person = person
|
16
|
+
end
|
17
|
+
|
18
|
+
def calculate
|
19
|
+
normalize_full_name
|
20
|
+
map_full_name_to_digits_code
|
21
|
+
sum_pairs_of_digits
|
22
|
+
build_homoclave
|
23
|
+
|
24
|
+
@homoclave
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def build_homoclave
|
30
|
+
last_three_digits = (@pairs_of_digits_sum % 1000)
|
31
|
+
quo = (last_three_digits / 34)
|
32
|
+
reminder = (last_three_digits % 34)
|
33
|
+
@homoclave = "#{HOMOCLAVE_DIGITS[quo]}#{HOMOCLAVE_DIGITS[reminder]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def sum_pairs_of_digits
|
37
|
+
@pairs_of_digits_sum = 0
|
38
|
+
# @mapped_full_name[0..-2].each_char do |c, i|
|
39
|
+
(0..@mapped_full_name.length - 2).each do |i|
|
40
|
+
num1 = @mapped_full_name[i..i + 1].to_i
|
41
|
+
num2 = @mapped_full_name[i + 1..i + 1].to_i
|
42
|
+
|
43
|
+
@pairs_of_digits_sum += num1 * num2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def map_full_name_to_digits_code
|
48
|
+
@mapped_full_name = '0'
|
49
|
+
@full_name.each_char do |c|
|
50
|
+
@mapped_full_name << map_character_to_two_digit_code(c)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def map_character_to_two_digit_code(c)
|
55
|
+
return FULL_NAME_MAPPING[c] if FULL_NAME_MAPPING.key?(c)
|
56
|
+
fail ArgumentError, "No two-digit-code mapping for char: #{c}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def normalize_full_name
|
60
|
+
raw_full_name = UnicodeUtils.upcase("#{@person}")
|
61
|
+
@full_name = I18n.transliterate(raw_full_name)
|
62
|
+
@full_name.gsub!(/[-.']/, '') # remove .'-
|
63
|
+
add_missing_char_to_full_name(raw_full_name, 'Ñ')
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_missing_char_to_full_name(raw_full_name, missing_char)
|
67
|
+
index = raw_full_name.index(missing_char)
|
68
|
+
until index.nil?
|
69
|
+
@full_name[index] = missing_char
|
70
|
+
index = raw_full_name.index(missing_char, index + 1)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Person
|
2
|
+
attr_accessor :name, :first_last_name, :second_last_name, :day, :month, :year
|
3
|
+
|
4
|
+
def initialize(name, first_last_name, second_last_name, day, month, year)
|
5
|
+
@name = name
|
6
|
+
@first_last_name = first_last_name
|
7
|
+
@second_last_name = second_last_name
|
8
|
+
@day = day
|
9
|
+
@month = month
|
10
|
+
@year = year
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"#{@first_last_name} #{@second_last_name} #{@name}"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Rfc
|
2
|
+
attr_accessor :name, :first_last_name, :second_last_name, :day, :month, :year,
|
3
|
+
:ten_digits_code, :homoclave, :verification_digit
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@name = args[:name]
|
7
|
+
@first_last_name = args[:first_last_name]
|
8
|
+
@second_last_name = args[:second_last_name]
|
9
|
+
@day = args[:day]
|
10
|
+
@month = args[:month]
|
11
|
+
@year = args[:year]
|
12
|
+
|
13
|
+
@person = Person.new(@name, @first_last_name, @second_last_name, @day, @month, @year)
|
14
|
+
@ten_digits_code = TenDigitsCodeCalculator.new(@person).calculate
|
15
|
+
@homoclave = HomoclaveCalculator.new(@person).calculate
|
16
|
+
@verification_digit = VerificationDigitCalculator.new(@ten_digits_code << @homoclave).calculate
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{@ten_digits_code}#{@homoclave}#{@verification_digit}"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class TenDigitsCodeCalculator
|
2
|
+
VOWEL_PATTERN = /[AEIOU]+/
|
3
|
+
attr_accessor :person
|
4
|
+
SPECIAL_PARTICLES = %w(DE LA LAS MC VON DEL LOS Y MAC VAN MI)
|
5
|
+
FORBIDDEN_WORDS = %w(
|
6
|
+
BUEI BUEY CACA CACO CAGA KOGE KAKA MAME KOJO KULO
|
7
|
+
CAGO COGE COJE COJO FETO JOTO KACO KAGO MAMO MEAR MEON
|
8
|
+
MION MOCO MULA PEDA PEDO PENE PUTA PUTO QULO RATA RUIN
|
9
|
+
)
|
10
|
+
|
11
|
+
def initialize(person)
|
12
|
+
@person = person
|
13
|
+
end
|
14
|
+
|
15
|
+
def calculate
|
16
|
+
"#{obfuscate_forbidden_words(name_code)}#{birthday_code}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def obfuscate_forbidden_words(name_code)
|
20
|
+
FORBIDDEN_WORDS.each do |forbidden|
|
21
|
+
return "#{name_code[0..2]}X" if forbidden == name_code
|
22
|
+
end
|
23
|
+
name_code
|
24
|
+
end
|
25
|
+
|
26
|
+
def name_code
|
27
|
+
return first_last_name_empty_form if first_last_name_empty?
|
28
|
+
return second_last_name_empty_form if second_last_name_empty?
|
29
|
+
return first_last_name_too_short_form if first_last_name_is_too_short?
|
30
|
+
normal_form
|
31
|
+
end
|
32
|
+
|
33
|
+
def second_last_name_empty_form
|
34
|
+
first_two_letters_of(@person.first_last_name) <<
|
35
|
+
first_two_letters_of(filter_name(@person.name))
|
36
|
+
end
|
37
|
+
|
38
|
+
def birthday_code
|
39
|
+
"#{@person.year.to_s[-2, 2]}#{format('%02d', @person.month)}#{format('%02d', @person.day)}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def second_last_name_empty?
|
43
|
+
normalize(@person.second_last_name).nil? || normalize(@person.second_last_name).empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def first_last_name_empty_form
|
47
|
+
first_two_letters_of(@person.second_last_name) <<
|
48
|
+
first_two_letters_of(filter_name(@person.name))
|
49
|
+
end
|
50
|
+
|
51
|
+
def first_last_name_empty?
|
52
|
+
normalize(@person.first_last_name).nil? || normalize(@person.first_last_name).empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def first_last_name_too_short_form
|
56
|
+
first_letter_of(@person.first_last_name) <<
|
57
|
+
first_letter_of(@person.second_last_name) <<
|
58
|
+
first_two_letters_of(filter_name(@person.name))
|
59
|
+
end
|
60
|
+
|
61
|
+
def first_two_letters_of(word)
|
62
|
+
normalized_word = normalize(word)
|
63
|
+
normalized_word[0..1]
|
64
|
+
end
|
65
|
+
|
66
|
+
def first_last_name_is_too_short?
|
67
|
+
normalize(@person.first_last_name).length <= 2
|
68
|
+
end
|
69
|
+
|
70
|
+
def normal_form
|
71
|
+
first_letter_of(@person.first_last_name) <<
|
72
|
+
first_vowel_excluding_first_character_of(@person.first_last_name) <<
|
73
|
+
first_letter_of(@person.second_last_name) <<
|
74
|
+
first_letter_of(filter_name(@person.name))
|
75
|
+
end
|
76
|
+
|
77
|
+
def filter_name(name)
|
78
|
+
raw_name = normalize(name).strip
|
79
|
+
if raw_name.include?(' ') && (raw_name.start_with?('MARIA') || raw_name.start_with?('JOSE'))
|
80
|
+
return raw_name.split(' ')[1]
|
81
|
+
end
|
82
|
+
name
|
83
|
+
end
|
84
|
+
|
85
|
+
def formatted_in_two_digits(number)
|
86
|
+
format('%02d', number)
|
87
|
+
end
|
88
|
+
|
89
|
+
def last_two_digits_of(number)
|
90
|
+
formatted_in_two_digits(number % 100)
|
91
|
+
end
|
92
|
+
|
93
|
+
def first_letter_of(word)
|
94
|
+
normalized_word = normalize(word)
|
95
|
+
normalized_word[0]
|
96
|
+
end
|
97
|
+
|
98
|
+
def normalize(word)
|
99
|
+
return word if word.nil? || word.empty?
|
100
|
+
normalized_word = UnicodeUtils.upcase(I18n.transliterate(word))
|
101
|
+
remove_special_particles(normalized_word, SPECIAL_PARTICLES)
|
102
|
+
end
|
103
|
+
|
104
|
+
def remove_special_particles(word, special_particles)
|
105
|
+
new_word = word
|
106
|
+
special_particles.each do |particle|
|
107
|
+
pp = "#{particle} "
|
108
|
+
while new_word.include?(pp)
|
109
|
+
i = new_word.to_s.index(pp).to_i
|
110
|
+
new_word.slice!(i..i + pp.length - 1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
new_word.to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
def first_vowel_excluding_first_character_of(word)
|
117
|
+
normalized_word = normalize(word)[1..-1]
|
118
|
+
m = VOWEL_PATTERN.match(normalized_word)
|
119
|
+
fail ArgumentError, "Word doesn't contain a vowel: #{normalized_word}" if m.nil?
|
120
|
+
normalized_word[m.to_s[0]]
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class VerificationDigitCalculator
|
2
|
+
attr_accessor :rfc12_digits
|
3
|
+
MAPPING = {
|
4
|
+
'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6,
|
5
|
+
'7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13,
|
6
|
+
'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20,
|
7
|
+
'L' => 21, 'M' => 22, 'N' => 23, '&' => 24, 'O' => 25, 'P' => 26, 'Q' => 27,
|
8
|
+
'R' => 28, 'S' => 29, 'T' => 30, 'U' => 31, 'V' => 32, 'W' => 33, 'X' => 34,
|
9
|
+
'Y' => 35, 'Z' => 36, ' ' => 37, 'Ñ' => 38
|
10
|
+
}
|
11
|
+
|
12
|
+
def initialize(rfc12_digits)
|
13
|
+
@rfc12_digits = rfc12_digits
|
14
|
+
end
|
15
|
+
|
16
|
+
def calculate
|
17
|
+
sum = 0
|
18
|
+
(0..11).each do |i|
|
19
|
+
sum += map_digit(@rfc12_digits[i]) * (13 - i)
|
20
|
+
end
|
21
|
+
reminder = sum % 11
|
22
|
+
|
23
|
+
return '0' if (reminder == 0)
|
24
|
+
return 'A' if (reminder == 10)
|
25
|
+
(11 - reminder).to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def map_digit(c)
|
29
|
+
return MAPPING[c] if MAPPING.key?(c)
|
30
|
+
0
|
31
|
+
end
|
32
|
+
end
|
data/lib/rfc_facil.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rfc_facil/version'
|
2
|
+
require 'rfc_facil/homoclave_calculator'
|
3
|
+
require 'rfc_facil/person'
|
4
|
+
require 'rfc_facil/rfc'
|
5
|
+
require 'rfc_facil/ten_digits_code_calculator'
|
6
|
+
require 'rfc_facil/verification_digit_calculator'
|
7
|
+
require 'i18n'
|
8
|
+
require 'unicode_utils/upcase'
|
9
|
+
module RfcFacil
|
10
|
+
I18n.available_locales = :en
|
11
|
+
end
|
data/logo.png
ADDED
Binary file
|
data/rfc_facil.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rfc_facil/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rfc_facil'
|
8
|
+
spec.version = RfcFacil::VERSION
|
9
|
+
spec.authors = ['Adrian Rangel']
|
10
|
+
spec.email = ['adrian.rangel@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Libreria para calcular el Registro Federal de Contribuyentes en México (RFC).'
|
13
|
+
spec.homepage = 'https://github.com/acrogenesis/rfc_facil'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = 'exe'
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'i18n', '~> 0.7.0'
|
21
|
+
spec.add_dependency 'unicode_utils', '~> 1.4'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'minitest', '~> 5.8'
|
26
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class TestHomoclaveCalculator < Minitest::Test
|
2
|
+
def test_calculate_homoclave_for_simple_test_case
|
3
|
+
assert_equal(homoclave('Juan', 'Perez', 'Garcia'), 'LN')
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_calculate_same_homoclave_for_names_with_and_without_accents
|
7
|
+
assert_equal(homoclave('Juan', 'Perez', 'Garcia'),
|
8
|
+
homoclave('Juan', 'Pérez', 'García'))
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_calculate_homoclave_for_person_with_more_than_one_name
|
12
|
+
assert_equal(homoclave('Jose Antonio', 'Del real', 'Anzures'), 'N9')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_calculate_homoclave_for_name_with_n_with_tilde
|
16
|
+
assert_equal(homoclave('Juan', 'Muñoz', 'Ortega'), 'T6')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_calculate_homoclave_for_name_with_multiple_n_with_tilde
|
20
|
+
assert_equal(homoclave('Juan', 'Muñoz', 'Muñoz'), 'RZ')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_calculate_different_homoclave_for_name_with_n_with_tilde_and_without
|
24
|
+
refute_equal(homoclave('Juan', 'Muñoz', 'Ortega'),
|
25
|
+
homoclave('Juan', 'Munoz', 'Ortega'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_calculate_homoclave_for_name_with_u_with_umlaut
|
29
|
+
assert_equal(homoclave('Jesus', 'Argüelles', 'Ortega'), 'JF')
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_calculate_same_homoclave_for_name_with_u_with_umlaut_and_without
|
33
|
+
assert_equal(homoclave('Jesus', 'Argüelles', 'Ortega'),
|
34
|
+
homoclave('Jesus', 'Arguelles', 'Ortega'))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_calculate_homoclave_for_name_with_ampersand
|
38
|
+
assert_equal(homoclave('Juan', 'Perez&Gomez', 'Garcia'), '2R')
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_calculate_same_homoclave_for_name_with_and_without_special_characters
|
42
|
+
assert_equal(homoclave('Juan', 'Mc.Gregor', "O'Connor-Juarez"),
|
43
|
+
homoclave('Juan', 'McGregor', 'OConnorJuarez'))
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_calculate_different_homoclave_for_names_with_and_without_ampersand
|
47
|
+
refute_equal(homoclave('Juan', 'Perez&Gomez', 'Garcia'),
|
48
|
+
homoclave('Juan', 'PerezGomez', 'Garcia'))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_calculate_same_homoclave_for_different_birthdays
|
52
|
+
assert_equal(
|
53
|
+
HomoclaveCalculator.new(Person.new('Juan', 'Perez', 'Garcia', 1, 1, 1901)).calculate,
|
54
|
+
HomoclaveCalculator.new(Person.new('Juan', 'Perez', 'Garcia', 5, 8, 1987)).calculate
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def homoclave(name, firstLastName, secondLastName)
|
59
|
+
HomoclaveCalculator.new(Person.new(name, firstLastName, secondLastName, 1, 1, 1901)).calculate
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class TestRfc < Minitest::Test
|
2
|
+
def should_build_rfc
|
3
|
+
Rfc.new(name: 'Adrian Marcelo', first_last_name: 'Rangel',
|
4
|
+
second_last_name: 'Araujo', day: 27, month: 11, year: 1992)
|
5
|
+
|
6
|
+
assert_equal(rfc.ten_digits_code, 'RAAA921127')
|
7
|
+
assert_equal(rfc.homoclave, 'RI')
|
8
|
+
assert_equal(rfc.verification_digit, '6')
|
9
|
+
assert_equal(rfc.to_s, 'RAAA921127RI6')
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class TestTenDigitsCodeCalculator < Minitest::Test
|
2
|
+
def test_calculate_ten_digits_code_for_simple_test_case
|
3
|
+
assert_equal(ten_digits_code('Juan', 'Barrios', 'Fernandez', 13, 12, 1970), 'BAFJ701213')
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_calculate_ten_digits_code_for_date_after_year_2000
|
7
|
+
assert_equal(ten_digits_code('Juan', 'Barrios', 'Fernandez', 1, 12, 2001), 'BAFJ011201')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_exclude_special_particles_in_both_last_names
|
11
|
+
# DE, LA, LAS, MC, VON, DEL, LOS, Y, MAC, VAN, MI
|
12
|
+
assert_equal(ten_digits_code('Eric', 'Mc Gregor', 'Von Juarez', 13, 12, 1970), 'GEJE701213')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_exclude_special_particles_in_the_first_last_name
|
16
|
+
assert_equal(ten_digits_code('Josue', 'Zarzosa', 'de la Torre', 13, 12, 1970), 'ZATJ701213')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_exclude_special_particles_in_the_second_last_name
|
20
|
+
assert_equal(ten_digits_code('Josue', 'de la Torre', 'Zarzosa', 13, 12, 1970), 'TOZJ701213')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_use_first_word_of_compound_second_last_name
|
24
|
+
assert_equal(ten_digits_code('Antonio', 'Jiménez', 'Ponce de León', 13, 12, 1970), 'JIPA701213')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_use_first_word_of_compound_first_last_name
|
28
|
+
assert_equal(ten_digits_code('Antonio', 'Ponce de León', 'Juarez', 13, 12, 1970), 'POJA701213')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_use_use_first_two_letters_of_first_name_if_first_last_name_has_just_one_letter
|
32
|
+
assert_equal(ten_digits_code('Alvaro', 'de la O', 'Lozano', 13, 12, 1970), 'OLAL701213')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_use_use_first_two_letters_of_first_name_if_first_last_name_has_just_two_letters
|
36
|
+
assert_equal(ten_digits_code('Ernesto', 'Ek', 'Rivera', 13, 12, 1970), 'ERER701213')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_use_first_name_if_person_has_multiple_names
|
40
|
+
assert_equal(ten_digits_code('Luz María', 'Fernández', 'Juárez', 13, 12, 1970), 'FEJL701213')
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_use_second_name_if_person_has_multiple_names_and_first_name_is_jose
|
44
|
+
assert_equal(ten_digits_code('José Antonio', 'Camargo', 'Hernández', 13, 12, 1970), 'CAHA701213')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_use_second_name_if_person_has_multiple_names_and_first_name_is_maria
|
48
|
+
assert_equal(ten_digits_code('María Luisa', 'Ramírez', 'Sánchez', 13, 12, 1970), 'RASL701213')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_use_first_two_letters_of_second_last_name_if_empty_first_last_name_is_provided
|
52
|
+
assert_equal(ten_digits_code('Juan', '', 'Martínez', 13, 12, 1970), 'MAJU701213')
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_use_first_two_letters_of_second_last_name_if_nil_first_last_name_is_provided
|
56
|
+
assert_equal(ten_digits_code('Juan', nil, 'Martínez', 13, 12, 1970), 'MAJU701213')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_use_first_two_letters_of_first_last_name_if_empty_second_last_name_is_provided
|
60
|
+
assert_equal(ten_digits_code('Gerarda', 'Zafra', '', 13, 12, 1970), 'ZAGE701213')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_use_first_two_letters_of_first_last_name_if_nil_second_last_name_is_provided
|
64
|
+
assert_equal(ten_digits_code('Gerarda', 'Zafra', nil, 13, 12, 1970), 'ZAGE701213')
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_replace_last_letter_with_x_if_code_makes_forbidden_word
|
68
|
+
# BUEI -> BUEX
|
69
|
+
assert_equal(ten_digits_code('Ingrid', 'Bueno', 'Ezquerra', 13, 12, 1970), 'BUEX701213')
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def ten_digits_code(name, first_last_name, second_last_name, day, month, year)
|
75
|
+
TenDigitsCodeCalculator.new(
|
76
|
+
Person.new(name, first_last_name, second_last_name, day, month, year)
|
77
|
+
).calculate
|
78
|
+
end
|
79
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfc_facil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adrian Rangel
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: i18n
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.7.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.7.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: unicode_utils
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.8'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- adrian.rangel@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- bin/console
|
96
|
+
- bin/setup
|
97
|
+
- lib/rfc_facil.rb
|
98
|
+
- lib/rfc_facil/homoclave_calculator.rb
|
99
|
+
- lib/rfc_facil/person.rb
|
100
|
+
- lib/rfc_facil/rfc.rb
|
101
|
+
- lib/rfc_facil/ten_digits_code_calculator.rb
|
102
|
+
- lib/rfc_facil/verification_digit_calculator.rb
|
103
|
+
- lib/rfc_facil/version.rb
|
104
|
+
- logo.png
|
105
|
+
- rfc_facil.gemspec
|
106
|
+
- tests/rfc_facil/test_homoclave_calculator.rb
|
107
|
+
- tests/rfc_facil/test_rfc.rb
|
108
|
+
- tests/rfc_facil/test_ten_digits_code_calculator.rb
|
109
|
+
- tests/rfc_facil/test_verification_digit_calculator.rb
|
110
|
+
- tests/tests_helper.rb
|
111
|
+
homepage: https://github.com/acrogenesis/rfc_facil
|
112
|
+
licenses: []
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.4.8
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Libreria para calcular el Registro Federal de Contribuyentes en México (RFC).
|
134
|
+
test_files: []
|
135
|
+
has_rdoc:
|