snoopy_afip 4.3.0 → 4.3.1

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.
@@ -1,106 +1,89 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ RSpec.describe Snoopy::Bill do
4
+ def valid_attrs(overrides = {})
5
+ {
6
+ cuit: "20111111112",
7
+ sale_point: "0001",
8
+ total_net: 100.0,
9
+ concept: "Productos",
10
+ document_type: "CUIT",
11
+ document_num: "30710151543",
12
+ issuer_iva_cond: Snoopy::RESPONSABLE_INSCRIPTO,
13
+ receiver_iva_cond: :factura_a,
14
+ receiver_iva_condition: :responsable_inscripto,
15
+ currency: :peso,
16
+ service_date_from: "20240101",
17
+ service_date_to: "20240131",
18
+ alicivas: [{ id: 0.21, amount: 21.0, taxeable_base: 100.0 }]
19
+ }.merge(overrides)
20
+ end
2
21
 
3
- describe "Bill" do
4
- it "should setup a header hash" do
5
- @header = Snoopy::Bill.header(0)
6
- @header.size.should == 3
7
- ["CantReg", "CbteTipo", "PtoVta"].each do |key|
8
- @header.has_key?(key).should == true
22
+ describe "#cbte_type" do
23
+ it "deriva el código del comprobante desde receiver_iva_cond" do
24
+ expect(described_class.new(valid_attrs).cbte_type).to eq("01") # BILL_TYPE[:factura_a]
25
+ expect(described_class.new(valid_attrs(receiver_iva_cond: :factura_b)).cbte_type).to eq("06")
9
26
  end
10
27
  end
11
28
 
12
- describe "instance" do
13
- before(:each) {@bill = Snoopy::Bill.new}
14
-
15
- it "should initialize according to Snoopy defaults" do
16
- @bill.client.class.name.should == "Savon::Client"
17
- ["Token", "Sign", "Cuit"].each do |key|
18
- @bill.body["Auth"][key].should_not == nil
19
- end
20
- @bill.documento.should == Snoopy.default_documento
21
- @bill.moneda.should == Snoopy.default_moneda
29
+ describe "#iva_sum y #total" do
30
+ it "suma las alícuotas y calcula el total neto + IVA" do
31
+ bill = described_class.new(valid_attrs)
32
+ expect(bill.iva_sum).to eq(21.0)
33
+ expect(bill.total).to eq(121.0)
22
34
  end
23
35
 
24
- it "should calculate it's cbte_tipo for Responsable Inscripto" do
25
- @bill.iva_cond = :responsable_inscripto
26
- @bill.cbte_type.should == "01"
36
+ it "total es 0 cuando el neto es 0" do
37
+ expect(described_class.new(valid_attrs(total_net: 0)).total).to eq(0)
27
38
  end
39
+ end
28
40
 
29
- it "should calculate it's cbte_tipo for Consumidor Final" do
30
- @bill.iva_cond = :consumidor_final
31
- @bill.cbte_type.should == "06"
41
+ describe "#exchange_rate" do
42
+ it "es 1 para pesos" do
43
+ expect(described_class.new(valid_attrs(currency: :peso)).exchange_rate).to eq(1)
32
44
  end
45
+ end
33
46
 
34
- it "raise error on nil iva cond" do
35
- @bill.iva_cond = 12
36
- expect{@bill.cbte_type}.to raise_error(Snoopy::NullOrInvalidAttribute)
47
+ describe "#receiver_iva_condition_id" do
48
+ it "mapea la condición de IVA del receptor (RG 5616)" do
49
+ expect(described_class.new(valid_attrs).receiver_iva_condition_id).to eq("1")
50
+ expect(described_class.new(valid_attrs(receiver_iva_condition: :consumidor_final)).receiver_iva_condition_id).to eq("5")
37
51
  end
38
52
 
39
- it "should fetch non Peso currency's exchange rate" do
40
- @bill.moneda = :dolar
41
- @bill.exchange_rate.to_i.should be > 0
53
+ it "es '' cuando no se informó la condición" do
54
+ expect(described_class.new(valid_attrs(receiver_iva_condition: nil)).receiver_iva_condition_id).to eq("")
42
55
  end
56
+ end
43
57
 
44
- it "should return 1 for Peso currency" do
45
- @bill.moneda = :peso
46
- @bill.exchange_rate.should == 1
58
+ describe "estado del resultado" do
59
+ it "refleja el veredicto de AFIP" do
60
+ bill = described_class.new(valid_attrs)
61
+ bill.result = "A"
62
+ expect(bill.approved?).to be(true)
63
+ bill.result = "R"
64
+ expect(bill.rejected?).to be(true)
65
+ bill.result = "P"
66
+ expect(bill.partial_approved?).to be(true)
47
67
  end
68
+ end
48
69
 
49
- it "should calculate the IVA array values" do
50
- @bill.iva_cond = :responsable_inscripto
51
- @bill.moneda = :peso
52
- @bill.net = 100.89
53
- @bill.aliciva_id = 2
54
-
55
- @bill.iva_sum.should be_within(0.05).of(21.18)
56
- @bill.total.should be_within(0.05).of(122.07)
70
+ describe "#valid?" do
71
+ it "es válido con atributos completos y correctos" do
72
+ bill = described_class.new(valid_attrs)
73
+ expect(bill.valid?).to be(true)
74
+ expect(bill.errors).to be_empty
57
75
  end
58
76
 
59
- it "should use give due date an service dates, or todays date" do
60
- @bill.net = 100
61
- @bill.aliciva_id = 2
62
- @bill.doc_num = "30710151543"
63
- @bill.iva_cond = :responsable_inscripto
64
- @bill.concepto = "Servicios"
65
-
66
- @bill.setup_bill
67
-
68
- detail = @bill.body["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"]
69
-
70
- detail["FchServDesde"].should == Time.new.strftime('%Y%m%d')
71
- detail["FchServHasta"].should == Time.new.strftime('%Y%m%d')
72
- detail["FchVtoPago"].should == Time.new.strftime('%Y%m%d')
73
-
74
- @bill.due_date = Date.new(2011, 12, 10).strftime('%Y%m%d')
75
- @bill.fch_serv_desde = Date.new(2011, 11, 01).strftime('%Y%m%d')
76
- @bill.fch_serv_hasta = Date.new(2011, 11, 30).strftime('%Y%m%d')
77
-
78
- @bill.setup_bill
79
-
80
- detail = @bill.body["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"]
81
-
82
- detail["FchServDesde"].should == "20111101"
83
- detail["FchServHasta"].should == "20111130"
84
- detail["FchVtoPago"].should == "20111210"
77
+ it "marca currency inválida" do
78
+ bill = described_class.new(valid_attrs(currency: :yen))
79
+ expect(bill.valid?).to be(false)
80
+ expect(bill.errors).to have_key(:currency)
85
81
  end
86
82
 
87
- Snoopy::BILL_TYPE[Snoopy.own_iva_cond].keys.each do |target_iva_cond|
88
- it "should authorize a valid bill for #{target_iva_cond.to_s}" do
89
- @bill.net = 1000000
90
- @bill.aliciva_id = 2
91
- @bill.doc_num = "30710151543"
92
- @bill.iva_cond = target_iva_cond
93
- @bill.concepto = "Servicios"
94
-
95
- @bill.authorized?.should == false
96
- @bill.authorize.should == true
97
- @bill.authorized?.should == true
98
-
99
- response = @bill.response
100
-
101
- response.length.should == 28
102
- response.cae.length.should == 14
103
- end
83
+ it "marca document_type inválido" do
84
+ bill = described_class.new(valid_attrs(document_type: "NOPE"))
85
+ bill.valid?
86
+ expect(bill.errors).to have_key(:document_type)
104
87
  end
105
88
  end
106
89
  end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ RSpec.describe Snoopy::Exception do
4
+ # Regresión #14: ServerTimeout debe seguir siendo un Timeout::Error (compat
5
+ # hacia atrás) y a la vez quedar bajo el paraguas Snoopy::Exception::Error.
6
+ describe "jerarquía de ServerTimeout" do
7
+ subject(:ancestors) { Snoopy::Exception::ServerTimeout.ancestors }
8
+
9
+ it "sigue siendo un Timeout::Error" do
10
+ expect(ancestors).to include(Timeout::Error)
11
+ end
12
+
13
+ it "queda bajo el paraguas Snoopy::Exception::Error" do
14
+ expect(ancestors).to include(Snoopy::Exception::Error)
15
+ end
16
+ end
17
+
18
+ it "el paraguas Error cubre también a las excepciones de la base" do
19
+ expect(Snoopy::Exception::ClientError.ancestors).to include(Snoopy::Exception::Error)
20
+ expect(Snoopy::Exception::AuthorizeAdapter::BuildBodyRequest.ancestors).to include(Snoopy::Exception::Error)
21
+ end
22
+
23
+ it "un rescue del paraguas atrapa tanto el timeout como los errores de cliente" do
24
+ expect { raise Snoopy::Exception::ServerTimeout }.to raise_error(Snoopy::Exception::Error)
25
+ expect { raise Snoopy::Exception::ClientError.new("x") }.to raise_error(Snoopy::Exception::Error)
26
+ end
27
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,19 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- require 'snoopy'
3
- require 'rspec'
4
- require 'ruby-debug'
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
5
2
 
6
- class SpecHelper
7
- include Savon::Logger
8
- end
3
+ require "snoopy_afip"
4
+ # Bill#valid? usa blank?/present? (ActiveSupport); en producción lo provee Rails.
5
+ require "active_support/core_ext/object/blank"
6
+ require "rspec"
9
7
 
10
- # Requires supporting files with custom matchers and macros, etc,
11
- # in ./support/ and its subdirectories.
12
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
8
+ # Config base de homologación para construir adapters en los specs.
9
+ # Nunca credenciales reales: pkey/cert/cuit son placeholders de prueba.
10
+ Snoopy.auth_url = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl"
11
+ Snoopy.service_url = "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL"
12
+ Snoopy.default_currency = :peso
13
+ Snoopy.default_concept = "Productos"
14
+ Snoopy.default_document_type = "CUIT"
13
15
 
14
- Snoopy.pkey = "spec/fixtures/pkey"
15
- Snoopy.cert = "spec/fixtures/cert.crt"
16
- Snoopy.cuit = ENV["CUIT"] || raise(Snoopy::NullOrInvalidAttribute.new, "Please set CUIT env variable.")
17
- Snoopy.sale_point = "0002"
18
- Snoopy.auth_url = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms"
19
- Snoopy.service_url = "http://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL"
20
- Snoopy.default_concepto = "Productos y Servicios"
21
- Snoopy.default_documento = "CUIT"
22
- Snoopy.default_moneda = :peso
23
- Snoopy.own_iva_cond = :responsable_inscripto
16
+ RSpec.configure do |config|
17
+ config.expect_with(:rspec) { |e| e.syntax = :expect }
18
+ config.disable_monkey_patching!
19
+ end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snoopy_afip
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - g.edera
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 2017-06-29 00:00:00.000000000 Z
11
+ date: 2026-06-29 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: savon
@@ -23,6 +24,34 @@ dependencies:
23
24
  - - "~>"
24
25
  - !ruby/object:Gem::Version
25
26
  version: 2.12.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
26
55
  description: Adaptador para Web Service de Facturación Electrónica Argentina (AFIP)
27
56
  email: gab.edera@gmail.com
28
57
  executables: []
@@ -30,8 +59,12 @@ extensions: []
30
59
  extra_rdoc_files: []
31
60
  files:
32
61
  - ".document"
62
+ - ".github/workflows/main.yml"
63
+ - ".github/workflows/release.yml"
33
64
  - ".gitignore"
34
- - CHANGELOG
65
+ - AGENTS.md
66
+ - CHANGELOG.md
67
+ - CLAUDE.md
35
68
  - Gemfile
36
69
  - Gemfile.lock
37
70
  - LICENSE.txt
@@ -40,6 +73,14 @@ files:
40
73
  - Rakefile
41
74
  - VERSION
42
75
  - autotest/discover.rb
76
+ - docs/behavior/behavior.md
77
+ - docs/config/configuracion.md
78
+ - docs/consumed/afip.md
79
+ - docs/errors/errors.md
80
+ - docs/glossary/glossary.md
81
+ - docs/interface/interface.md
82
+ - docs/test/testing.md
83
+ - docs/topology/topology.md
43
84
  - lib/snoopy_afip.rb
44
85
  - lib/snoopy_afip/authentication_adapter.rb
45
86
  - lib/snoopy_afip/authorize_adapter.rb
@@ -51,9 +92,13 @@ files:
51
92
  - lib/snoopy_afip/core_ext/string.rb
52
93
  - lib/snoopy_afip/exceptions.rb
53
94
  - lib/snoopy_afip/version.rb
95
+ - skill/SKILL.md
96
+ - skills.yml
54
97
  - snoopy_afip.gemspec
55
- - spec/snoopy_afip/authorizer_spec.rb
98
+ - spec/snoopy_afip/authentication_adapter_spec.rb
99
+ - spec/snoopy_afip/authorize_adapter_spec.rb
56
100
  - spec/snoopy_afip/bill_spec.rb
101
+ - spec/snoopy_afip/exceptions_spec.rb
57
102
  - spec/spec_helper.rb
58
103
  - wsaa-client.sh
59
104
  - xds_login.xml
@@ -61,6 +106,7 @@ homepage: https://github.com/gedera/snoopy_afip
61
106
  licenses:
62
107
  - MIT
63
108
  metadata: {}
109
+ post_install_message:
64
110
  rdoc_options: []
65
111
  require_paths:
66
112
  - lib
@@ -68,17 +114,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
114
  requirements:
69
115
  - - ">="
70
116
  - !ruby/object:Gem::Version
71
- version: '0'
117
+ version: '2.5'
72
118
  required_rubygems_version: !ruby/object:Gem::Requirement
73
119
  requirements:
74
120
  - - ">="
75
121
  - !ruby/object:Gem::Version
76
122
  version: '0'
77
123
  requirements: []
78
- rubygems_version: 3.6.9
124
+ rubygems_version: 3.4.19
125
+ signing_key:
79
126
  specification_version: 4
80
127
  summary: Adaptador AFIP wsfe.
81
128
  test_files:
82
- - spec/snoopy_afip/authorizer_spec.rb
129
+ - spec/snoopy_afip/authentication_adapter_spec.rb
130
+ - spec/snoopy_afip/authorize_adapter_spec.rb
83
131
  - spec/snoopy_afip/bill_spec.rb
132
+ - spec/snoopy_afip/exceptions_spec.rb
84
133
  - spec/spec_helper.rb
data/CHANGELOG DELETED
@@ -1,27 +0,0 @@
1
- # Changelog
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
-
7
- ## [3.0.2] - July 14, 2017
8
- ### Added
9
- - `Cms Builder exception`.
10
-
11
- ## [3.0.0] - June 29, 2017
12
- ### Added
13
- - `Authentication Class` destinada a la comunicación con el **WSAA**.
14
- - `Authorize Class` destinada a la comunicación con el **WSFE**.
15
- - `Client Class` destinada para crear el cliente de `Savon`.
16
- - Mejor manejo de Exceptions.
17
- - Validaciones en el modelo `Bill`.
18
-
19
- ### Changed
20
- - Se pasó toda la logica de comunicación con el **WSFE** del modelo `Bill` al modelo `Authorize`.
21
- - No se crea mas el rchivo para la clave privada, devuelve en RAW.
22
- - No se crea mas un archivo para almacenar el _token_, _sign_, se devuelve en RAW.
23
- - Evitar raisear si se logró autorizar una factura con el **WSFE**. Manejo en el errors del `Bill` o el `Authorize`.
24
-
25
- ### Removed
26
- - Eliminiado modulo `AuthData`.
27
- - Eliminado el uso de `Bash` para autenticar en el **WSAA**.
@@ -1,9 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
-
3
- describe "Authorizer" do
4
- it "should read credentials on initialize" do
5
- authorizer = Snoopy::Authorizer.new
6
- authorizer.pkey.should == 'spec/fixtures/pkey'
7
- authorizer.cert.should == 'spec/fixtures/cert.crt'
8
- end
9
- end