bravo 0.4.0 → 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # MacOS
18
+ .DS_Store
19
+
20
+ # TextMate
21
+ *.tmproj
22
+ tmtags
23
+
24
+ # Other
25
+ .rspec
26
+ log/
27
+ log/*.log
28
+ fixtures/
29
+ fixtures/*
30
+ *.gem
31
+ tmp/
32
+ bin/bravo-certs/
33
+ .ruby-version
34
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ bundler_args: --without test
5
+ branches:
6
+ only:
7
+ - master
8
+ env:
9
+ - TRAVISCI = yes
data/.yardopts ADDED
@@ -0,0 +1,13 @@
1
+ --charset utf-8
2
+ --readme README.md
3
+ --markup markdown
4
+ --markup-provider maruku
5
+ --template-path yard
6
+ --default-return ""
7
+ --title "Bravo Documentation"
8
+ --exclude lib/bravo/core_ext/*
9
+
10
+ --hide-void-return
11
+ --protected
12
+ --no-private
13
+ --no-highlight
data/CHANGELOG CHANGED
@@ -1,8 +1,12 @@
1
- *Bravo 0.4.0 (March 21, 2011)*
1
+ *Bravo 1.0.0.alpha (March 30, 2013)*
2
2
 
3
- * Auth service URL is now part of the config [miloops]
3
+ * Updated dependencies
4
+ * Added reference class that will pass any method to the api, without a message
5
+ * Added bravo binary, which handles CSR and pkey generation
6
+ * rdoc
7
+ * Added support for nota de credito and nota de debito
4
8
 
5
- *Bravo 0.3.6 (March 14, 2011)*
9
+ *Bravo 0.3.6 (March 14, 2011) *
6
10
 
7
11
  * Hash extensions play nice with Rails 2.3 ruby 1.9 [miloops]
8
12
 
data/Gemfile CHANGED
@@ -1,17 +1,9 @@
1
- source "http://rubygems.org"
2
- gem "savon", "~> 0.7.8"
1
+ source 'http://rubygems.org'
3
2
 
4
- group :development do
5
- platforms :ruby_18 do
6
- gem "ruby-debug"
7
- end
8
- platforms :ruby_19 do
9
- gem 'ruby-debug-base19', "0.11.24"
10
- gem 'ruby-debug19', "0.11.6"
11
- end
12
- gem "rspec", "~> 2.4.0"
13
- gem "bundler", "~> 1.0.0"
14
- gem "jeweler", "~> 1.5.1"
15
- gem "rcov", ">= 0"
3
+ unless ENV['TRAVISCI'] == "yes"
4
+ gem 'guard-rspec', '~> 2.4.0'
5
+ gem 'rb-fsevent', '~> 0.9.1'
6
+ gem 'debugger', '~> 1.3.0'
16
7
  end
17
8
 
9
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', cli: '--color --format nested' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/LICENSE.txt CHANGED
@@ -1,4 +1,6 @@
1
- Copyright (c) 2010 Leandro Marcucci & Vurbia Technologies International Inc
1
+ Copyright (c) 2010 Leandro Marcucci & Vurbia Technologies International Inc.
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
@@ -17,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Bravo ![Travis status](https://travis-ci.org/leanucci/bravo.png)
2
+
3
+ > la gema de facturación electrónica argentina
4
+
5
+ [~~Bravo~~](http://images.coveralia.com/audio/b/Bravo-Desierto_Sin_Amor-Frontal.jpg) Bravo permite la obtención del [~~C.A.E~~](http://www.muevamueva.com/masmusica/latina/cae/images/fotos.5.gif) C.A.E. (Código de Autorización Electrónico) por medio del Web Service de Facturación Electrónica provisto por AFIP.
6
+
7
+ ## Instalación
8
+
9
+ gem install bravo
10
+
11
+ o
12
+
13
+ gem 'bravo'
14
+
15
+
16
+ en tu `Gemfile`
17
+
18
+
19
+ ## Comenzar a usar Bravo
20
+
21
+ Para esto hace falta generar el CSR (Certificate Signature Request).
22
+
23
+ ## Uso
24
+
25
+ Los servicios de AFIP requieren la utilización del Web Service de Autorización y Autenticación [(más info)](http://www.afip.gov.ar/ws/WSAA/README.txt)
26
+
27
+ Luego de cumplidos los pasos indicados en el readme, basta con configurar Bravo con la ruta a los archivos. En tu aplicación:
28
+
29
+ require 'bravo'
30
+ Bravo.pkey = path_al_pkey
31
+ Bravo.cert = path_al_cert
32
+ Bravo.cuit = 20881234569
33
+
34
+
35
+ Bravo acepta más opciones, para más detalles ver el archivo [spec/spec_helper.rb](https://github.com/vurbia/Bravo/blob/master/spec/spec_helper.rb)
36
+
37
+ ## Uso
38
+
39
+ El uso de la gema se centra en el metodo `authorize`. Este método invoca `FECAESolicitar` y devuelve el resultado, que de ser exitoso incluye el CAE y su fecha de vencimento (ver [spec/bravo/bill_spec.rb:87](https://github.com/vurbia/Bravo/blob/master/spec/bravo/bill_spec.rb#L87)
40
+
41
+
42
+ ## TODO list
43
+
44
+ * rdoc
45
+ * mensajes de error más completos
46
+
47
+
48
+ ## Agradecimientos
49
+
50
+ * Emilio Tagua por sus consejos y contribuciones.
51
+
52
+ Copyright (c) 2010 Leandro Marcucci & Vurbia Technologies International Inc. See LICENSE.txt for further details.
data/Rakefile CHANGED
@@ -1,50 +1,10 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "bravo"
16
- gem.homepage = "http://github.com/Vurbia/Bravo"
17
- gem.license = "MIT"
18
- gem.summary = "Adaptador AFIP wsfe."
19
- gem.description = "Adaptador para el Web Service de Facturacion Electronica de AFIP"
20
- gem.email = "leanucci@vurbia.com"
21
- gem.authors = ["Leandro Marcucci"]
22
- # Include your dependencies below. Runtime dependencies are required when using your gem,
23
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
- # gem.add_development_dependency 'rspec', '> 1.2.3'
26
- end
27
- Jeweler::RubygemsDotOrgTasks.new
28
-
29
- require 'rspec/core'
30
- require 'rspec/core/rake_task'
31
- RSpec::Core::RakeTask.new(:spec) do |spec|
32
- spec.pattern = FileList['spec/**/*_spec.rb']
33
- end
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ FileList['tasks/**/*.rake'].each { |task| import task }
34
4
 
35
- RSpec::Core::RakeTask.new(:rcov) do |spec|
36
- spec.pattern = 'spec/**/*_spec.rb'
37
- spec.rcov = true
5
+ desc "Run tests"
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.verbose = false
38
8
  end
39
9
 
40
- task :default => :spec
41
-
42
- require 'rake/rdoctask'
43
- Rake::RDocTask.new do |rdoc|
44
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
-
46
- rdoc.rdoc_dir = 'rdoc'
47
- rdoc.title = "bravo #{version}"
48
- rdoc.rdoc_files.include('README*')
49
- rdoc.rdoc_files.include('lib/**/*.rb')
50
- end
10
+ task default: :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.3.6
data/bin/bravo ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ require 'thor'
5
+
6
+ module Bravo
7
+ # Bravo executable for certificate request generation
8
+ #
9
+ class Bravo < Thor
10
+
11
+ desc "gencsr", "Crea el Certificate Signature Request"
12
+ method_option :bin, type: :string, required: true, desc: "El path completo al binario de openssl"
13
+ method_option :pkey, type: :string, desc: "Path a una clave privada preexistente. Si se omite, se crea una clave en --out"
14
+ method_option :sn, type: :string, required: true, desc: "Nombre del servidor. Sin uso práctico, es requerido por AFIP"
15
+ method_option :cn, type: :string, required: true, desc: "Nombre de la compañía. Sin uso práctico, es requerido por AFIP"
16
+ method_option :cuit, type: :numeric, required: true, desc: "Número de CUIT sin guiones. Ejemplo: 20876543217"
17
+ method_option :out, type: :string, default: "bravo-certs", desc: "Directorio de destino para los archivos creados. Si se omite, se crea el directorio bravo-certs en pwd"
18
+
19
+ # Certificate Signature Request wrapper for bravo.
20
+ #
21
+ # @param bin [Sting] the path for `openssl` binary. Required.
22
+ # @param pkey [String] path for an existing private key. If ommitted, a new one will be generated in --out
23
+ #
24
+ def gencsr
25
+ bin = options[:bin]
26
+ sn = options[:sn]
27
+ cn = options[:cn]
28
+ cuit = options[:cuit]
29
+ out = options[:out]
30
+
31
+ Dir.mkdir(out) unless File.exists?(out)
32
+
33
+ out_path = "#{ Dir.pwd }/#{ out }/"
34
+
35
+ pkey = options[:pkey] || create_pkey(bin, out_path)
36
+
37
+ say("Creando CSR en #{ out_path } con CUIT=#{ cuit }, o=#{ sn } y cn=#{ cn }", :cyan)
38
+
39
+ `#{bin} req -new \
40
+ -key #{ pkey } \
41
+ -subj "/C=AR/O=#{ sn }/CN=#{ cn }/serialNumber=CUIT #{ cuit }"\
42
+ -out #{ out_path }pedido-#{ cuit }`
43
+
44
+ say("Hecho!", :green)
45
+ end
46
+
47
+ protected
48
+ # Creates a new private key
49
+ #
50
+ def create_pkey(bin,out_path)
51
+ say("Creando pkey", :cyan)
52
+ `#{ bin } genrsa -out #{ out_path }pkey 1024`
53
+ say("Hecho!\n\n", :green)
54
+ "#{ out_path }pkey"
55
+ end
56
+ end
57
+
58
+ Bravo.start
59
+ end
data/bravo.gemspec CHANGED
@@ -1,90 +1,26 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bravo/version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = %q{bravo}
8
- s.version = "0.4.0"
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "bravo"
8
+ gem.version = Bravo::VERSION
9
+ gem.authors = ["Leandro Marcucci"]
10
+ gem.email = ["leanucci@gmail.com"]
11
+ gem.description = %q{Adaptador para el Web Service de Facturacion Electrónica de AFIP}
12
+ gem.summary = %q{Adaptador WSFE}
13
+ gem.homepage = "http://github.com/leanucci/bravo"
14
+ gem.date = %q(2011-03-14)
9
15
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Leandro Marcucci"]
12
- s.date = %q{2011-03-21}
13
- s.description = %q{Adaptador para el Web Service de Facturacion Electronica de AFIP}
14
- s.email = %q{leanucci@vurbia.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.textile"
18
- ]
19
- s.files = [
20
- ".document",
21
- "CHANGELOG",
22
- "Gemfile",
23
- "Gemfile.lock",
24
- "LICENSE.txt",
25
- "README.textile",
26
- "Rakefile",
27
- "VERSION",
28
- "autotest/discover.rb",
29
- "bravo.gemspec",
30
- "lib/bravo.rb",
31
- "lib/bravo/auth_data.rb",
32
- "lib/bravo/authorizer.rb",
33
- "lib/bravo/bill.rb",
34
- "lib/bravo/constants.rb",
35
- "lib/bravo/core_ext/float.rb",
36
- "lib/bravo/core_ext/hash.rb",
37
- "lib/bravo/core_ext/string.rb",
38
- "lib/bravo/version.rb",
39
- "spec/bravo/auth_data_spec.rb",
40
- "spec/bravo/authorizer_spec.rb",
41
- "spec/bravo/bill_spec.rb",
42
- "spec/spec_helper.rb",
43
- "wsaa-client.sh"
44
- ]
45
- s.homepage = %q{http://github.com/Vurbia/Bravo}
46
- s.licenses = ["MIT"]
47
- s.require_paths = ["lib"]
48
- s.rubygems_version = %q{1.6.2}
49
- s.summary = %q{Adaptador AFIP wsfe.}
50
- s.test_files = [
51
- "spec/bravo/auth_data_spec.rb",
52
- "spec/bravo/authorizer_spec.rb",
53
- "spec/bravo/bill_spec.rb",
54
- "spec/spec_helper.rb"
55
- ]
56
-
57
- if s.respond_to? :specification_version then
58
- s.specification_version = 3
59
-
60
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
- s.add_runtime_dependency(%q<savon>, ["~> 0.7.8"])
62
- s.add_development_dependency(%q<ruby-debug>, [">= 0"])
63
- s.add_development_dependency(%q<ruby-debug-base19>, ["= 0.11.24"])
64
- s.add_development_dependency(%q<ruby-debug19>, ["= 0.11.6"])
65
- s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
66
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
67
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
68
- s.add_development_dependency(%q<rcov>, [">= 0"])
69
- else
70
- s.add_dependency(%q<savon>, ["~> 0.7.8"])
71
- s.add_dependency(%q<ruby-debug>, [">= 0"])
72
- s.add_dependency(%q<ruby-debug-base19>, ["= 0.11.24"])
73
- s.add_dependency(%q<ruby-debug19>, ["= 0.11.6"])
74
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
75
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
76
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
77
- s.add_dependency(%q<rcov>, [">= 0"])
78
- end
79
- else
80
- s.add_dependency(%q<savon>, ["~> 0.7.8"])
81
- s.add_dependency(%q<ruby-debug>, [">= 0"])
82
- s.add_dependency(%q<ruby-debug-base19>, ["= 0.11.24"])
83
- s.add_dependency(%q<ruby-debug19>, ["= 0.11.6"])
84
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
85
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
86
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
87
- s.add_dependency(%q<rcov>, [">= 0"])
88
- end
89
- end
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib", "bin"]
90
20
 
21
+ gem.add_runtime_dependency(%q<savon>, ["~> 2.1.0"])
22
+ gem.add_runtime_dependency(%q<thor>, ["~> 0.16.0"])
23
+ gem.add_development_dependency(%q<rspec>, ["~> 2.12.0"])
24
+ gem.add_development_dependency(%q<rspec-mocks>, ["~> 2.12.1"])
25
+ gem.add_development_dependency(%q<rake>, ["~> 10.0.3"])
26
+ end
@@ -1,29 +1,64 @@
1
1
  module Bravo
2
+
3
+ # This class handles authorization data
4
+ #
2
5
  class AuthData
3
6
 
4
7
  class << self
8
+
9
+ attr_accessor :environment
10
+
11
+ # Fetches WSAA Authorization Data to build the datafile for the day.
12
+ # It requires the private key file and the certificate to exist and
13
+ # to be configured as Bravo.pkey and Bravo.cert
14
+ #
5
15
  def fetch
6
16
  unless File.exists?(Bravo.pkey)
7
- raise "Archivo de llave privada no encontrado en #{Bravo.pkey}"
17
+ raise "Archivo de llave privada no encontrado en #{ Bravo.pkey }"
8
18
  end
9
19
 
10
20
  unless File.exists?(Bravo.cert)
11
- raise "Archivo certificado no encontrado en #{Bravo.cert}"
21
+ raise "Archivo certificado no encontrado en #{ Bravo.cert }"
12
22
  end
13
23
 
14
- todays_datafile = "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
15
- opts = "-u #{Bravo.auth_url}"
16
- opts += " -k #{Bravo.pkey}"
17
- opts += " -c #{Bravo.cert}"
18
-
19
- unless File.exists?(todays_datafile)
20
- %x(#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts})
24
+ unless File.exists?(todays_data_file_name)
25
+ Bravo::Wsaa.login
21
26
  end
22
27
 
23
- @data = YAML.load_file(todays_datafile).each do |k, v|
28
+ @data = YAML.load_file(todays_data_file_name).each do |k, v|
24
29
  Bravo.const_set(k.to_s.upcase, v) unless Bravo.const_defined?(k.to_s.upcase)
25
30
  end
26
31
  end
32
+
33
+ # Returns the authorization hash, containing the Token, Signature and Cuit
34
+ # @return [Hash]
35
+ #
36
+ def auth_hash
37
+ { "Token" => Bravo::TOKEN, "Sign" => Bravo::SIGN, "Cuit" => Bravo.cuit }
38
+ end
39
+
40
+ # Returns the right wsaa url for the specific environment
41
+ # @return [String]
42
+ #
43
+ def wsaa_url
44
+ raise "Environment not sent to either :test or :production" unless Bravo::URLS.keys.include? environment
45
+ Bravo::URLS[environment][:wsaa]
46
+ end
47
+
48
+ # Returns the right wsfe url for the specific environment
49
+ # @return [String]
50
+ #
51
+ def wsfe_url
52
+ raise "Environment not sent to either :test or :production" unless Bravo::URLS.keys.include? environment
53
+ Bravo::URLS[environment][:wsfe]
54
+ end
55
+
56
+ # Creates the data file name for a cuit number and the current day
57
+ # @return [String]
58
+ #
59
+ def todays_data_file_name
60
+ "/tmp/bravo_#{ Bravo.cuit }_#{ Time.new.strftime('%d_%m_%Y') }.yml"
61
+ end
27
62
  end
28
63
  end
29
64
  end