cuitar 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c558641038eaa45b9d00fe5f7e0c8fe46c06aaec4bc3d42a8edd53ea86d722fc
4
- data.tar.gz: ef534ebed29d24549b58bc1347d0620c0d5b6c5e52004c2d3af83ce5f208301f
3
+ metadata.gz: bae6b402ce2e5070cdbcb7bfd306aac2f2a74d4fe06c4a1de430e714dabb6b51
4
+ data.tar.gz: b0c9f2d97dea27f98eae78471822922e1d8d33b23801aabd32eaf6d790824272
5
5
  SHA512:
6
- metadata.gz: fd58ced15b82cb16b256addf25e279cf496b1b8c48e2cfc34a841c73e8fdb5b84178407bf19fe3f1cd03fcf4c6dc6b13c722a23a4a16a5ce4c61566dca388f8e
7
- data.tar.gz: e1d054a05a214b7c7991dd393b53af0b251d184bd89899f9249130789c8d64c81c8fb7a6b38d8dcb59d60f6befd60e58435cfa15c69ab46613716876dd9c3817
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/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  .ruby-version
10
+ *.gem
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
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
4
6
 
5
- gem 'rake', '~> 12.0'
6
- gem 'minitest', '~> 5.0'
7
+ group :development, :test do
8
+ gem 'minitest', '~> 5.0'
9
+ gem 'rake', '~> 12.0'
10
+ gem 'rubocop', '~> 1.7'
11
+ end
data/Gemfile.lock CHANGED
@@ -1,13 +1,43 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cuitar (1.2.0)
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
- Agrega la clase `Cuit` que permite validar y formatear una CUIT (Clave Única de
4
- Identificación Tributaria argentina).
3
+ [![Gem Version](https://badge.fury.io/rb/cuitar.svg)](https://badge.fury.io/rb/cuitar)
4
+ [![Ruby](https://github.com/srabuini/cuitar/actions/workflows/ruby.yml/badge.svg)](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
- Agregar en el Gemfile de la aplicación
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 ejecutar:
25
+ Y luego ejecuta:
15
26
 
16
- $ bundle install
27
+ ```bash
28
+ $ bundle install
29
+ ```
17
30
 
18
- O manualmente ejecutando en la línea de comando:
31
+ O instálala directamente:
19
32
 
20
- $ gem install cuitar
33
+ ```bash
34
+ $ gem install cuitar
35
+ ```
21
36
 
22
37
  ## Uso
23
38
 
24
- Se crea el objecto Cuit de la siguiente forma:
39
+ ### Crear y formatear una CUIT
25
40
 
26
41
  ```ruby
27
- cuit_number = '20228518310' # o '20-22851831-0' o 20228518310
42
+ # Desde string sin formato
43
+ cuit = Cuit.new('20228518310')
44
+ cuit.to_s # => '20-22851831-0'
28
45
 
29
- cuit = Cuit.new(cuit_number)
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
- `cuit_number` puede pasarse de cualquiera de las siguientes tres formas:
55
+ ### Validación
35
56
 
36
- * Un `String` conteniendo los 11 números que componen una CUIT.
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
- * Un `String` conteniendo los 11 números que componen una CUIT, formateado con guiones.
68
+ ### Manejo de errores
39
69
 
40
- * Un `Integer` comprendido por los 11 números que componen una CUIT.
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
- Instanciar la clase `Cuit` con una CUIT inválida genera un `ArgumentError`
79
+ ### Acceso a componentes
43
80
 
44
81
  ```ruby
45
- cuit_number = 123
82
+ cuit = Cuit.new('20228518310')
46
83
 
47
- cuit = Cuit.new(cuit_number) # => Invalid CUIT (ArgumentError)
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
- Es posible validar una CUIT
90
+ ## Formatos de entrada soportados
51
91
 
52
- ```ruby
53
- Cuit.valid?(123) # => false
92
+ La gema acepta CUIT en cualquiera de estos formatos:
54
93
 
55
- Cuit.valid?(20228518310) # => #<Cuit:0x000000010f589930 @check_digit=0, @cuit="20228518310", @dni="22851831", @type="20">
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
- Reporte de errores y pull requests son bienvenidos en https://github.com/srabuini/cuitar.
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
- Disponible como open source bajo los términos de [MIT License](https://opensource.org/licenses/MIT).
128
+ Esta gema está disponible como open source bajo los términos de la [Licencia MIT](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
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 = 'Valida y formatea CUIT argentinas.'
10
- spec.description = 'Validador y formateador de CUIT (Clave Única Tributaria) Argentina.'
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.3.0')
17
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
14
18
 
15
- spec.metadata['homepage_uri'] = spec.homepage
16
- spec.metadata['source_code_uri'] = 'https://github.com/srabuini/cuitar'
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
- begin
4
- new(cuit)
5
- rescue
6
- false
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.to_s.gsub(/\D/, '')
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
- [type, dni, check_digit].join('-')
49
+ "#{type_code}-#{document}-#{check_digit}"
18
50
  end
19
51
 
20
- private
52
+ # Alias para to_s
53
+ # @return [String] La CUIT formateada
54
+ def formatted
55
+ to_s
56
+ end
21
57
 
22
- def type
23
- @type ||= @cuit[0, 2]
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
- def dni
27
- @dni ||= @cuit[2, 8]
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
- def cuit_sequence
35
- (type + dni).chars.map(&:to_i)
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
- def calculated_digit
39
- sequence = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
40
- sum = sequence
41
- .zip(cuit_sequence)
42
- .reduce(0) { |a, e| a + e.reduce(:*) }
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
- diff = 11 - (sum % 11)
109
+ private
45
110
 
46
- diff == 11 ? 0 : diff
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
- def right_length?
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
- def checked?
54
- calculated_digit == check_digit
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
- def valid?
58
- right_length? && checked?
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cuitar
2
- VERSION = '1.2.0'.freeze
4
+ VERSION = '2.1.0'
3
5
  end
data/lib/cuitar.rb CHANGED
@@ -1,5 +1,7 @@
1
- require 'cuitar/version'
2
- require 'cuit'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cuitar/version'
4
+ require_relative 'cuit'
3
5
 
4
6
  module Cuitar
5
7
  class Error < StandardError; end
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: 1.2.0
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: 2023-03-31 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
- description: Validador y formateador de CUIT (Clave Única Tributaria) Argentina.
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.3.0
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.4.6
56
- signing_key:
62
+ rubygems_version: 3.6.9
57
63
  specification_version: 4
58
- summary: Valida y formatea CUIT argentinas.
64
+ summary: Validador y formateador de CUIT argentinas
59
65
  test_files: []