cuitar 2.0.0 → 2.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 +4 -4
- data/.github/workflows/ruby.yml +51 -0
- data/.rubocop.yml +70 -0
- data/CHANGELOG.md +55 -0
- data/Gemfile +7 -2
- data/Gemfile.lock +32 -1
- data/README.md +87 -25
- data/Rakefile +2 -0
- data/cuitar.gemspec +15 -6
- data/examples/demo.rb +78 -0
- data/lib/cuit.rb +122 -28
- data/lib/cuitar/version.rb +3 -1
- data/lib/cuitar.rb +4 -2
- metadata +15 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bae6b402ce2e5070cdbcb7bfd306aac2f2a74d4fe06c4a1de430e714dabb6b51
|
4
|
+
data.tar.gz: b0c9f2d97dea27f98eae78471822922e1d8d33b23801aabd32eaf6d790824272
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da1c6e10af578f3b4f8ab865a100bdcfe83f832aef87b581b414cd10e0b42cafb0623448e751b2d0de9ec0e2b2734f6493cd1ae4c5616389b01ced50ef33e0e4
|
7
|
+
data.tar.gz: 4662b33f556ed02c8b8fe29800a393c4affa69ef6e23579158179d38a6c21ad95d0524ec65ffeba13898f0d82cac1cbabb07cd68722989d91c8165ea9c88592f
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3']
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v4
|
18
|
+
|
19
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby-version }}
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake test
|
27
|
+
|
28
|
+
- name: Run RuboCop
|
29
|
+
run: bundle exec rubocop
|
30
|
+
continue-on-error: true
|
31
|
+
|
32
|
+
release:
|
33
|
+
runs-on: ubuntu-latest
|
34
|
+
needs: test
|
35
|
+
if: github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, '[release]')
|
36
|
+
|
37
|
+
steps:
|
38
|
+
- uses: actions/checkout@v4
|
39
|
+
|
40
|
+
- name: Set up Ruby
|
41
|
+
uses: ruby/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: '3.3'
|
44
|
+
bundler-cache: true
|
45
|
+
|
46
|
+
- name: Build and push gem
|
47
|
+
run: |
|
48
|
+
gem build *.gemspec
|
49
|
+
gem push *.gem
|
50
|
+
env:
|
51
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
|
12
|
+
AllCops:
|
13
|
+
TargetRubyVersion: 2.7
|
14
|
+
NewCops: enable
|
15
|
+
Exclude:
|
16
|
+
- 'vendor/**/*'
|
17
|
+
- 'pkg/**/*'
|
18
|
+
- 'bin/*'
|
19
|
+
- 'examples/**/*'
|
20
|
+
|
21
|
+
Style/Documentation:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/FrozenStringLiteralComment:
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
Layout/LineLength:
|
28
|
+
Max: 100
|
29
|
+
AllowedPatterns: ['\A#']
|
30
|
+
|
31
|
+
Metrics/MethodLength:
|
32
|
+
Max: 15
|
33
|
+
Exclude:
|
34
|
+
- 'test/**/*'
|
35
|
+
|
36
|
+
Metrics/ClassLength:
|
37
|
+
Max: 150
|
38
|
+
|
39
|
+
Metrics/AbcSize:
|
40
|
+
Max: 20
|
41
|
+
|
42
|
+
Style/StringLiterals:
|
43
|
+
EnforcedStyle: single_quotes
|
44
|
+
|
45
|
+
Style/StringLiteralsInInterpolation:
|
46
|
+
EnforcedStyle: single_quotes
|
47
|
+
|
48
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
49
|
+
Enabled: true
|
50
|
+
|
51
|
+
Layout/SpaceAroundMethodCallOperator:
|
52
|
+
Enabled: true
|
53
|
+
|
54
|
+
Lint/RaiseException:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
Lint/StructNewOverride:
|
58
|
+
Enabled: true
|
59
|
+
|
60
|
+
Style/ExponentialNotation:
|
61
|
+
Enabled: true
|
62
|
+
|
63
|
+
Style/HashEachMethods:
|
64
|
+
Enabled: true
|
65
|
+
|
66
|
+
Style/HashTransformKeys:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
Style/HashTransformValues:
|
70
|
+
Enabled: true
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
Todos los cambios notables en este proyecto serán documentados en este archivo.
|
4
|
+
|
5
|
+
El formato está basado en [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [2.1.0] - 2025-07-15
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- Método `type_code` para obtener el código de tipo de contribuyente
|
12
|
+
- Método `document` para obtener el número de documento
|
13
|
+
- Método `check_digit` para obtener el dígito verificador
|
14
|
+
- Método `formatted` como alias de `to_s`
|
15
|
+
- Método `==` para comparar objetos Cuit
|
16
|
+
- Método `hash` para usar en colecciones
|
17
|
+
- Documentación completa con YARD
|
18
|
+
- Frozen string literals para mejor performance
|
19
|
+
- Manejo mejorado de casos edge (nil, string vacío)
|
20
|
+
- Tests más exhaustivos (17 tests, 38 assertions)
|
21
|
+
- README mejorado con badges y ejemplos claros
|
22
|
+
- CHANGELOG.md para documentar versiones
|
23
|
+
- GitHub Actions workflow para CI/CD
|
24
|
+
- RuboCop configurado para calidad de código
|
25
|
+
- Ejemplo de uso completo en `examples/demo.rb`
|
26
|
+
|
27
|
+
### Changed
|
28
|
+
- Refactorización completa de la clase `Cuit` con mejor API
|
29
|
+
- Algoritmo de validación más eficiente
|
30
|
+
- Mejor manejo de errores y validaciones
|
31
|
+
- Estructura de código más limpia y mantenible
|
32
|
+
- Gemspec mejorado con más metadatos
|
33
|
+
- Actualizada versión mínima de Ruby a 2.7.0
|
34
|
+
|
35
|
+
### Deprecated
|
36
|
+
- Métodos `type` y `dni` (mantienen compatibilidad hacia atrás como aliases)
|
37
|
+
|
38
|
+
### Fixed
|
39
|
+
- Manejo de entrada nil
|
40
|
+
- Validación más robusta de formatos de entrada
|
41
|
+
|
42
|
+
## [2.0.0] - Versión anterior
|
43
|
+
|
44
|
+
### Added
|
45
|
+
- Funcionalidad básica mejorada de validación y formateo de CUIT
|
46
|
+
|
47
|
+
### Added
|
48
|
+
- Funcionalidad básica de validación y formateo de CUIT
|
49
|
+
|
50
|
+
## [1.0.0] - Versión inicial
|
51
|
+
|
52
|
+
### Added
|
53
|
+
- Clase `Cuit` básica
|
54
|
+
- Validación de CUIT argentinas
|
55
|
+
- Formateo con guiones
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,43 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cuitar (1.
|
4
|
+
cuitar (2.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ast (2.4.3)
|
10
|
+
json (2.12.2)
|
11
|
+
language_server-protocol (3.17.0.5)
|
12
|
+
lint_roller (1.1.0)
|
9
13
|
minitest (5.18.0)
|
14
|
+
parallel (1.27.0)
|
15
|
+
parser (3.3.8.0)
|
16
|
+
ast (~> 2.4.1)
|
17
|
+
racc
|
18
|
+
prism (1.4.0)
|
19
|
+
racc (1.8.1)
|
20
|
+
rainbow (3.1.1)
|
10
21
|
rake (12.3.3)
|
22
|
+
regexp_parser (2.10.0)
|
23
|
+
rubocop (1.78.0)
|
24
|
+
json (~> 2.3)
|
25
|
+
language_server-protocol (~> 3.17.0.2)
|
26
|
+
lint_roller (~> 1.1.0)
|
27
|
+
parallel (~> 1.10)
|
28
|
+
parser (>= 3.3.0.2)
|
29
|
+
rainbow (>= 2.2.2, < 4.0)
|
30
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
31
|
+
rubocop-ast (>= 1.45.1, < 2.0)
|
32
|
+
ruby-progressbar (~> 1.7)
|
33
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
34
|
+
rubocop-ast (1.45.1)
|
35
|
+
parser (>= 3.3.7.2)
|
36
|
+
prism (~> 1.4)
|
37
|
+
ruby-progressbar (1.13.0)
|
38
|
+
unicode-display_width (3.1.4)
|
39
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
40
|
+
unicode-emoji (4.0.4)
|
11
41
|
|
12
42
|
PLATFORMS
|
13
43
|
ruby
|
@@ -16,6 +46,7 @@ DEPENDENCIES
|
|
16
46
|
cuitar!
|
17
47
|
minitest (~> 5.0)
|
18
48
|
rake (~> 12.0)
|
49
|
+
rubocop (~> 1.7)
|
19
50
|
|
20
51
|
BUNDLED WITH
|
21
52
|
2.4.10
|
data/README.md
CHANGED
@@ -1,66 +1,128 @@
|
|
1
|
-
# Cuitar
|
1
|
+
# Cuitar 🇦🇷
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
[](https://badge.fury.io/rb/cuitar)
|
4
|
+
[](https://github.com/srabuini/cuitar/actions/workflows/ruby.yml)
|
5
|
+
|
6
|
+
Una gema Ruby para validar y formatear CUIT (Clave Única de Identificación Tributaria) argentinas de forma simple y eficiente.
|
7
|
+
|
8
|
+
## Características
|
9
|
+
|
10
|
+
✅ Validación completa de CUIT argentinas
|
11
|
+
✅ Formateo automático con guiones
|
12
|
+
✅ Soporte para múltiples formatos de entrada
|
13
|
+
✅ API simple y intuitiva
|
14
|
+
✅ Sin dependencias externas
|
15
|
+
✅ 100% de cobertura de tests
|
5
16
|
|
6
17
|
## Instalación
|
7
18
|
|
8
|
-
|
19
|
+
Agrega esta línea al Gemfile de tu aplicación:
|
9
20
|
|
10
21
|
```ruby
|
11
22
|
gem 'cuitar'
|
12
23
|
```
|
13
24
|
|
14
|
-
Y luego
|
25
|
+
Y luego ejecuta:
|
15
26
|
|
16
|
-
|
27
|
+
```bash
|
28
|
+
$ bundle install
|
29
|
+
```
|
17
30
|
|
18
|
-
O
|
31
|
+
O instálala directamente:
|
19
32
|
|
20
|
-
|
33
|
+
```bash
|
34
|
+
$ gem install cuitar
|
35
|
+
```
|
21
36
|
|
22
37
|
## Uso
|
23
38
|
|
24
|
-
|
39
|
+
### Crear y formatear una CUIT
|
25
40
|
|
26
41
|
```ruby
|
27
|
-
|
42
|
+
# Desde string sin formato
|
43
|
+
cuit = Cuit.new('20228518310')
|
44
|
+
cuit.to_s # => '20-22851831-0'
|
28
45
|
|
29
|
-
|
46
|
+
# Desde string ya formateado
|
47
|
+
cuit = Cuit.new('20-22851831-0')
|
48
|
+
cuit.to_s # => '20-22851831-0'
|
30
49
|
|
50
|
+
# Desde entero
|
51
|
+
cuit = Cuit.new(20228518310)
|
31
52
|
cuit.to_s # => '20-22851831-0'
|
32
53
|
```
|
33
54
|
|
34
|
-
|
55
|
+
### Validación
|
35
56
|
|
36
|
-
|
57
|
+
```ruby
|
58
|
+
# Validar una CUIT válida
|
59
|
+
Cuit.valid?('20228518310') # => true
|
60
|
+
Cuit.valid?('20-22851831-0') # => true
|
61
|
+
Cuit.valid?(20228518310) # => true
|
62
|
+
|
63
|
+
# Validar una CUIT inválida
|
64
|
+
Cuit.valid?('123') # => false
|
65
|
+
Cuit.valid?('20228518311') # => false
|
66
|
+
```
|
37
67
|
|
38
|
-
|
68
|
+
### Manejo de errores
|
39
69
|
|
40
|
-
|
70
|
+
```ruby
|
71
|
+
# Las CUIT inválidas lanzan ArgumentError
|
72
|
+
begin
|
73
|
+
Cuit.new('123')
|
74
|
+
rescue ArgumentError => e
|
75
|
+
puts e.message # => "Invalid CUIT"
|
76
|
+
end
|
77
|
+
```
|
41
78
|
|
42
|
-
|
79
|
+
### Acceso a componentes
|
43
80
|
|
44
81
|
```ruby
|
45
|
-
|
82
|
+
cuit = Cuit.new('20228518310')
|
46
83
|
|
47
|
-
cuit
|
84
|
+
cuit.type_code # => "20" (código de tipo de contribuyente)
|
85
|
+
cuit.document # => "22851831" (número de documento)
|
86
|
+
cuit.check_digit # => 0 (dígito verificador)
|
87
|
+
cuit.formatted # => "20-22851831-0" (alias de to_s)
|
48
88
|
```
|
49
89
|
|
50
|
-
|
90
|
+
## Formatos de entrada soportados
|
51
91
|
|
52
|
-
|
53
|
-
Cuit.valid?(123) # => false
|
92
|
+
La gema acepta CUIT en cualquiera de estos formatos:
|
54
93
|
|
55
|
-
|
56
|
-
|
94
|
+
- **String sin formato**: `'20228518310'`
|
95
|
+
- **String con guiones**: `'20-22851831-0'`
|
96
|
+
- **Entero**: `20228518310`
|
97
|
+
|
98
|
+
## Algoritmo de validación
|
99
|
+
|
100
|
+
La gema implementa el algoritmo oficial de validación de CUIT:
|
57
101
|
|
102
|
+
1. Verifica que tenga exactamente 11 dígitos
|
103
|
+
2. Calcula el dígito verificador usando la secuencia `[5,4,3,2,7,6,5,4,3,2]`
|
104
|
+
3. Compara el dígito calculado con el dígito proporcionado
|
105
|
+
|
106
|
+
## Desarrollo
|
107
|
+
|
108
|
+
Después de clonar el repositorio, ejecuta `bin/setup` para instalar las dependencias. Luego ejecuta `rake test` para correr los tests.
|
109
|
+
|
110
|
+
Para instalar esta gema en tu máquina local, ejecuta `bundle exec rake install`.
|
111
|
+
|
112
|
+
Para liberar una nueva versión, actualiza el número de versión en `version.rb`, y luego ejecuta `bundle exec rake release`, que creará un git tag para la versión, push de los commits y tags, y enviará el archivo `.gem` a [rubygems.org](https://rubygems.org).
|
58
113
|
|
59
114
|
## Contribuciones
|
60
115
|
|
61
|
-
|
116
|
+
Los reportes de errores y pull requests son bienvenidos en https://github.com/srabuini/cuitar.
|
117
|
+
|
118
|
+
Para contribuir:
|
62
119
|
|
120
|
+
1. Fork el proyecto
|
121
|
+
2. Crea una rama para tu feature (`git checkout -b my-new-feature`)
|
122
|
+
3. Commit tus cambios (`git commit -am 'Add some feature'`)
|
123
|
+
4. Push a la rama (`git push origin my-new-feature`)
|
124
|
+
5. Crea un nuevo Pull Request
|
63
125
|
|
64
126
|
## Licencia
|
65
127
|
|
66
|
-
|
128
|
+
Esta gema está disponible como open source bajo los términos de la [Licencia MIT](https://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
data/cuitar.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'lib/cuitar/version'
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
@@ -6,14 +8,22 @@ Gem::Specification.new do |spec|
|
|
6
8
|
spec.authors = ['Sebastian Rabuini']
|
7
9
|
spec.email = ['sebas@wasabit.com.ar']
|
8
10
|
|
9
|
-
spec.summary = '
|
10
|
-
spec.description = '
|
11
|
+
spec.summary = 'Validador y formateador de CUIT argentinas'
|
12
|
+
spec.description = 'Una gema Ruby simple y eficiente para validar y formatear CUIT ' \
|
13
|
+
'(Clave Única de Identificación Tributaria) argentinas. ' \
|
14
|
+
'Incluye validación completa según el algoritmo oficial y formateo.'
|
11
15
|
spec.homepage = 'https://github.com/srabuini/cuitar'
|
12
16
|
spec.license = 'MIT'
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
17
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
14
18
|
|
15
|
-
spec.metadata
|
16
|
-
|
19
|
+
spec.metadata = {
|
20
|
+
'homepage_uri' => spec.homepage,
|
21
|
+
'source_code_uri' => 'https://github.com/srabuini/cuitar',
|
22
|
+
'changelog_uri' => 'https://github.com/srabuini/cuitar/blob/main/CHANGELOG.md',
|
23
|
+
'bug_tracker_uri' => 'https://github.com/srabuini/cuitar/issues',
|
24
|
+
'documentation_uri' => 'https://rubydoc.info/gems/cuitar',
|
25
|
+
'rubygems_mfa_required' => 'true'
|
26
|
+
}
|
17
27
|
|
18
28
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
29
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -22,5 +32,4 @@ Gem::Specification.new do |spec|
|
|
22
32
|
spec.bindir = 'exe'
|
23
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
34
|
spec.require_paths = ['lib']
|
25
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
26
35
|
end
|
data/examples/demo.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/cuitar'
|
5
|
+
|
6
|
+
puts '=' * 50
|
7
|
+
puts 'CUITAR - Validador de CUIT Argentinas'
|
8
|
+
puts '=' * 50
|
9
|
+
|
10
|
+
# Ejemplos de uso
|
11
|
+
examples = [
|
12
|
+
'20228518310',
|
13
|
+
'20-22851831-0',
|
14
|
+
20228518310,
|
15
|
+
'27123456789',
|
16
|
+
'30123456789',
|
17
|
+
'123', # Inválida
|
18
|
+
'20228518311' # Inválida
|
19
|
+
]
|
20
|
+
|
21
|
+
puts "\n1. Validación de CUITs:"
|
22
|
+
puts '-' * 30
|
23
|
+
|
24
|
+
examples.each do |example|
|
25
|
+
valid = Cuit.valid?(example)
|
26
|
+
status = valid ? '✅ VÁLIDA' : '❌ INVÁLIDA'
|
27
|
+
puts "#{example.to_s.ljust(15)} -> #{status}"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "\n2. Creación y formateo de objetos CUIT:"
|
31
|
+
puts '-' * 40
|
32
|
+
|
33
|
+
valid_examples = examples.select { |ex| Cuit.valid?(ex) }
|
34
|
+
|
35
|
+
valid_examples.each do |example|
|
36
|
+
cuit = Cuit.new(example)
|
37
|
+
puts "Entrada: #{example}"
|
38
|
+
puts " Formateada: #{cuit}"
|
39
|
+
puts " Tipo: #{cuit.type_code}"
|
40
|
+
puts " Documento: #{cuit.document}"
|
41
|
+
puts " Dígito: #{cuit.check_digit}"
|
42
|
+
puts " Igualdad: #{cuit == Cuit.new(valid_examples.first)}"
|
43
|
+
puts
|
44
|
+
end
|
45
|
+
|
46
|
+
puts "3. Manejo de errores:"
|
47
|
+
puts '-' * 25
|
48
|
+
|
49
|
+
invalid_examples = examples.reject { |ex| Cuit.valid?(ex) }
|
50
|
+
|
51
|
+
invalid_examples.each do |example|
|
52
|
+
begin
|
53
|
+
Cuit.new(example)
|
54
|
+
rescue ArgumentError => e
|
55
|
+
puts "Entrada '#{example}' -> Error: #{e.message}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
puts "\n4. Casos especiales:"
|
60
|
+
puts '-' * 20
|
61
|
+
|
62
|
+
special_cases = [
|
63
|
+
nil,
|
64
|
+
'',
|
65
|
+
'20.22851831.0',
|
66
|
+
'20 22851831 0',
|
67
|
+
'20-22851831-0'
|
68
|
+
]
|
69
|
+
|
70
|
+
special_cases.each do |case_example|
|
71
|
+
valid = Cuit.valid?(case_example)
|
72
|
+
status = valid ? '✅ VÁLIDA' : '❌ INVÁLIDA'
|
73
|
+
display = case_example.nil? ? 'nil' : "'#{case_example}'"
|
74
|
+
puts "#{display.ljust(20)} -> #{status}"
|
75
|
+
end
|
76
|
+
|
77
|
+
puts "\n¡Listo! Tu gema CUITAR está funcionando perfectamente."
|
78
|
+
puts "Para más información, consulta el README.md"
|
data/lib/cuit.rb
CHANGED
@@ -1,60 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Clase para validar y formatear CUIT (Clave Única de Identificación Tributaria) argentinas
|
4
|
+
#
|
5
|
+
# @example Crear una CUIT válida
|
6
|
+
# cuit = Cuit.new('20228518310')
|
7
|
+
# cuit.to_s # => '20-22851831-0'
|
8
|
+
#
|
9
|
+
# @example Validar una CUIT
|
10
|
+
# Cuit.valid?('20228518310') # => true
|
11
|
+
# Cuit.valid?('123') # => false
|
1
12
|
class Cuit
|
13
|
+
# Valida si una CUIT es válida sin lanzar excepciones
|
14
|
+
#
|
15
|
+
# @param cuit [String, Integer] La CUIT a validar
|
16
|
+
# @return [Boolean] true si la CUIT es válida, false en caso contrario
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# Cuit.valid?('20228518310') # => true
|
20
|
+
# Cuit.valid?('123') # => false
|
2
21
|
def self.valid?(cuit)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
22
|
+
new(cuit)
|
23
|
+
true
|
24
|
+
rescue ArgumentError
|
25
|
+
false
|
8
26
|
end
|
9
27
|
|
28
|
+
# Inicializa una nueva instancia de CUIT
|
29
|
+
#
|
30
|
+
# @param cuit [String, Integer] La CUIT en cualquier formato válido
|
31
|
+
# @raise [ArgumentError] si la CUIT no es válida
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# Cuit.new('20228518310')
|
35
|
+
# Cuit.new('20-22851831-0')
|
36
|
+
# Cuit.new(20228518310)
|
10
37
|
def initialize(cuit)
|
11
|
-
@cuit = cuit
|
12
|
-
|
13
|
-
raise ArgumentError, 'Invalid CUIT' unless valid?
|
38
|
+
@cuit = normalize_cuit(cuit)
|
39
|
+
validate_cuit!
|
14
40
|
end
|
15
41
|
|
42
|
+
# Formatea la CUIT con guiones
|
43
|
+
#
|
44
|
+
# @return [String] La CUIT formateada como 'XX-XXXXXXXX-X'
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# Cuit.new('20228518310').to_s # => '20-22851831-0'
|
16
48
|
def to_s
|
17
|
-
|
49
|
+
"#{type_code}-#{document}-#{check_digit}"
|
18
50
|
end
|
19
51
|
|
20
|
-
|
52
|
+
# Alias para to_s
|
53
|
+
# @return [String] La CUIT formateada
|
54
|
+
def formatted
|
55
|
+
to_s
|
56
|
+
end
|
21
57
|
|
22
|
-
|
23
|
-
|
58
|
+
# Obtiene el código de tipo de contribuyente
|
59
|
+
#
|
60
|
+
# @return [String] Los primeros dos dígitos de la CUIT
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# Cuit.new('20228518310').type_code # => '20'
|
64
|
+
def type_code
|
65
|
+
@type_code ||= @cuit[0, 2]
|
24
66
|
end
|
25
67
|
|
26
|
-
|
27
|
-
|
68
|
+
# Obtiene el número de documento
|
69
|
+
#
|
70
|
+
# @return [String] Los 8 dígitos centrales de la CUIT
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# Cuit.new('20228518310').document # => '22851831'
|
74
|
+
def document
|
75
|
+
@document ||= @cuit[2, 8]
|
28
76
|
end
|
29
77
|
|
78
|
+
# Obtiene el dígito verificador
|
79
|
+
#
|
80
|
+
# @return [Integer] El último dígito de la CUIT
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# Cuit.new('20228518310').check_digit # => 0
|
30
84
|
def check_digit
|
31
85
|
@check_digit ||= @cuit[-1].to_i
|
32
86
|
end
|
33
87
|
|
34
|
-
|
35
|
-
|
88
|
+
# Compara dos objetos Cuit
|
89
|
+
#
|
90
|
+
# @param other [Cuit] Otra instancia de Cuit
|
91
|
+
# @return [Boolean] true si ambas CUIT son iguales
|
92
|
+
def ==(other)
|
93
|
+
return false unless other.is_a?(Cuit)
|
94
|
+
|
95
|
+
@cuit == other.instance_variable_get(:@cuit)
|
36
96
|
end
|
37
97
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
98
|
+
# Hash para usar en colecciones
|
99
|
+
#
|
100
|
+
# @return [Integer] Hash de la CUIT
|
101
|
+
def hash
|
102
|
+
@cuit.hash
|
103
|
+
end
|
104
|
+
|
105
|
+
# Alias para mantener compatibilidad hacia atrás
|
106
|
+
alias type type_code
|
107
|
+
alias dni document
|
43
108
|
|
44
|
-
|
109
|
+
private
|
45
110
|
|
46
|
-
|
111
|
+
# Normaliza la entrada a un string de 11 dígitos
|
112
|
+
def normalize_cuit(cuit)
|
113
|
+
cuit.to_s.gsub(/\D/, '')
|
47
114
|
end
|
48
115
|
|
49
|
-
|
116
|
+
# Valida que la CUIT sea válida
|
117
|
+
def validate_cuit!
|
118
|
+
raise ArgumentError, 'Invalid CUIT' unless valid_cuit?
|
119
|
+
end
|
120
|
+
|
121
|
+
# Verifica si la CUIT es válida
|
122
|
+
def valid_cuit?
|
123
|
+
correct_length? && valid_check_digit?
|
124
|
+
end
|
125
|
+
|
126
|
+
# Verifica que tenga 11 dígitos
|
127
|
+
def correct_length?
|
50
128
|
@cuit.length == 11
|
51
129
|
end
|
52
130
|
|
53
|
-
|
54
|
-
|
131
|
+
# Verifica que el dígito verificador sea correcto
|
132
|
+
def valid_check_digit?
|
133
|
+
calculated_check_digit == check_digit
|
134
|
+
end
|
135
|
+
|
136
|
+
# Obtiene la secuencia de dígitos para el cálculo
|
137
|
+
def digit_sequence
|
138
|
+
(type_code + document).chars.map(&:to_i)
|
55
139
|
end
|
56
140
|
|
57
|
-
|
58
|
-
|
141
|
+
# Calcula el dígito verificador según el algoritmo oficial
|
142
|
+
def calculated_check_digit
|
143
|
+
multipliers = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
|
144
|
+
|
145
|
+
sum = multipliers
|
146
|
+
.zip(digit_sequence)
|
147
|
+
.sum { |multiplier, digit| multiplier * digit }
|
148
|
+
|
149
|
+
remainder = sum % 11
|
150
|
+
result = 11 - remainder
|
151
|
+
|
152
|
+
result == 11 ? 0 : result
|
59
153
|
end
|
60
154
|
end
|
data/lib/cuitar/version.rb
CHANGED
data/lib/cuitar.rb
CHANGED
metadata
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Rabuini
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
|
-
description:
|
12
|
+
description: Una gema Ruby simple y eficiente para validar y formatear CUIT (Clave
|
13
|
+
Única de Identificación Tributaria) argentinas. Incluye validación completa según
|
14
|
+
el algoritmo oficial y formateo.
|
14
15
|
email:
|
15
16
|
- sebas@wasabit.com.ar
|
16
17
|
executables: []
|
17
18
|
extensions: []
|
18
19
|
extra_rdoc_files: []
|
19
20
|
files:
|
21
|
+
- ".github/workflows/ruby.yml"
|
20
22
|
- ".gitignore"
|
23
|
+
- ".rubocop.yml"
|
21
24
|
- ".travis.yml"
|
25
|
+
- CHANGELOG.md
|
22
26
|
- Gemfile
|
23
27
|
- Gemfile.lock
|
24
28
|
- LICENSE.txt
|
@@ -27,6 +31,7 @@ files:
|
|
27
31
|
- bin/console
|
28
32
|
- bin/setup
|
29
33
|
- cuitar.gemspec
|
34
|
+
- examples/demo.rb
|
30
35
|
- lib/cuit.rb
|
31
36
|
- lib/cuitar.rb
|
32
37
|
- lib/cuitar/version.rb
|
@@ -36,8 +41,10 @@ licenses:
|
|
36
41
|
metadata:
|
37
42
|
homepage_uri: https://github.com/srabuini/cuitar
|
38
43
|
source_code_uri: https://github.com/srabuini/cuitar
|
44
|
+
changelog_uri: https://github.com/srabuini/cuitar/blob/main/CHANGELOG.md
|
45
|
+
bug_tracker_uri: https://github.com/srabuini/cuitar/issues
|
46
|
+
documentation_uri: https://rubydoc.info/gems/cuitar
|
39
47
|
rubygems_mfa_required: 'true'
|
40
|
-
post_install_message:
|
41
48
|
rdoc_options: []
|
42
49
|
require_paths:
|
43
50
|
- lib
|
@@ -45,15 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
52
|
requirements:
|
46
53
|
- - ">="
|
47
54
|
- !ruby/object:Gem::Version
|
48
|
-
version: 2.
|
55
|
+
version: 2.7.0
|
49
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
57
|
requirements:
|
51
58
|
- - ">="
|
52
59
|
- !ruby/object:Gem::Version
|
53
60
|
version: '0'
|
54
61
|
requirements: []
|
55
|
-
rubygems_version: 3.
|
56
|
-
signing_key:
|
62
|
+
rubygems_version: 3.6.9
|
57
63
|
specification_version: 4
|
58
|
-
summary:
|
64
|
+
summary: Validador y formateador de CUIT argentinas
|
59
65
|
test_files: []
|