facturapi 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,70 @@
1
1
  module Facturapi
2
2
  module Helpers
3
+ # Corresponde a las lineas de referencia de una Boleta Electronica,
4
+ # etiqueta e informacion opcional con un maximo de 40
3
5
  class Referencia
4
- attr_accessor :nro_lin_ref, :cod_ref, :razon_ref
6
+ # Indica el numero secuencial de linea de referencia de la Boleta
7
+ # Electronica, el cual puede ser desde la linea 1 hasta la linea 40.
8
+ attr_accessor :nro_lin_ref
9
+
10
+ # Corresponde a un codigo que identifique el tipo de referencia que se
11
+ # presentara en el formato impreso de la Boleta Electronica, ya sea para
12
+ # control interno o para indicar algun dato al cliente que reciba el
13
+ # documento. El codigo es establecido por la empresa.
14
+ attr_accessor :cod_ref
15
+
16
+ # Corresponde al dato alfanumerico de un codigo de referencia.
17
+ attr_accessor :razon_ref
18
+
19
+ # Es el codigo de tipo de documento al que se hace referencia, con un
20
+ # maximo de 3 caracteres. Si corresponde a un documento tributario,
21
+ # corresponde a un valor numerico, el cual esta codificado por el
22
+ # Servicio de Impuestos Internos.
23
+ #
24
+ # - 29: FACTURA
25
+ # - 31: FACTURA EXENTA
26
+ # - 32: FACTURA ELECTRONICA
27
+ # - 33: FACTURA EXENTA ELECTRONICA
28
+ # - 34: BOLETA
29
+ # - 37: BOLETA EXENTA
30
+ # - 38: BOLETA ELECTRONICA
31
+ # - 39: LIQUIDACION FACTURA
32
+ # - 44: FACTURA DE COMPRA
33
+ # - 45: FACTURA DE COMPRA ELECTRONICA
34
+ # - 49: GUIA DE DESPACHO
35
+ # - 51: GUIA DE DESPACHO ELECTRONICA
36
+ # - 54: NOTA DE DEBITO
37
+ # - 55: NOTA DE DEBITO ELECTRONICA
38
+ # - 59: NOTA DE CREDITO
39
+ # - 60: NOTA DE CREDITO ELECTRONICA
40
+ # - 800: ORDEN DE COMPRA
41
+ # - 801: NOTA DE PEDIDO
42
+ # - 802: CONTRATO
43
+ # - 813: CERTIFICADO DE DEPOSITO BOLSA PROD. CHILE
44
+ # - 814: VALE DE PRENDA BOLSA PROD. CHILE
45
+ #
46
+ # Si es alfabetico, corresponde a documentos no tributarios, normalmente
47
+ # definidos por requerimiento de su cliente.
48
+ # - HES: HOJA DE ESTADO DE SERVICIO
49
+ # - HAS: HOJA DE ACEPTACION DE SERVICIO
50
+ # - HEM: RECEPCION DE MATERIAL
51
+ attr_accessor :tpo_doc_ref
52
+
53
+ # Es el folio del documento referenciado, indica el numero del documento
54
+ # que se alterara.
55
+ attr_accessor :folio_ref
56
+
57
+ # Es la fecha de emision del documento al que se hace referencia, el
58
+ # formato de la fecha es "AAAA-MM-DD" (anio, mes, dia)
59
+ attr_accessor :fecha_ref
5
60
 
6
61
  def initialize(params = {})
7
62
  @nro_lin_ref = params[:nro_lin_ref]
8
63
  @cod_ref = params[:cod_ref]
9
64
  @razon_ref = params[:razon_ref]
65
+ @tpo_doc_ref = params[:tpo_doc_ref]
66
+ @folio_ref = params[:folio_ref]
67
+ @fecha_ref = params[:fecha_ref]
10
68
  end
11
69
 
12
70
  def as_node
@@ -14,6 +72,9 @@ module Facturapi
14
72
  referencia << create_node('NroLinRef') { |n| n << nro_lin_ref }
15
73
  referencia << create_node('CodRef') { |n| n << cod_ref }
16
74
  referencia << create_node('RazonRef') { |n| n << razon_ref }
75
+ referencia << create_node('TpoDocRef') { |n| n << tpo_doc_ref } if tpo_doc_ref
76
+ referencia << create_node('FolioRef') { |n| n << folio_ref } if folio_ref
77
+ referencia << create_node('FechaRef') { |n| n << fecha_ref } if fecha_ref
17
78
  end
18
79
  end
19
80
  end
@@ -1,18 +1,97 @@
1
1
  module Facturapi
2
2
  module Helpers
3
+ # Corresponde a los valores totales de una Boleta Electronica.
3
4
  class Totales
4
- attr_accessor :mnt_neto, :mnt_exe, :iva, :mnt_total, :monto_nf,
5
- :total_periodo, :saldo_anterior, :vlr_pagar
5
+ IVA = 0.19
6
+
7
+ # Corresponde al valor Neto de la boleta electronica, solamente se indica
8
+ # en el caso que el sea una boleta afecta y que IndMntNeto tenga el
9
+ # valor 2. Al ser un campo de monto, se debe indicar sin decimales y sin
10
+ # separadores de miles. Se calcula de la siguiente forma:
11
+ #
12
+ # MntNeto = Suma de MontoItem por linea de detalle - Descuentos + Recargos
13
+ # # Solamente MontoItem de los items que tienen IndExe = 0
14
+ # # Descuentos y Recargos basados en etiqueta <DscRcgGlobal>
15
+ attr_accessor :mnt_neto
16
+
17
+ # Corresponde al valor Exento de la boleta electronica. Al ser un campo de
18
+ # monto, se debe indicar sin decimales y sin separadores de miles.
19
+ # Se calcula de la siguiente forma:
20
+ #
21
+ # MntExe = Suma de ValorExento por linea de detalle
22
+ # # Solamente MontoItem de los items que tienen IndExe = 1
23
+ attr_accessor :mnt_exe
24
+
25
+ # Corresponde al valor IVA (Impuesto al Valor Agregado) de la boleta
26
+ # electronica, solamente se indica en el caso que el sea una boleta afecta
27
+ # y que IndMntNeto tenga el valor 2. Al ser un campo de monto, se debe
28
+ # indicar sin decimales y sin separadores de miles.
29
+ # Se calcula de la siguiente forma:
30
+ #
31
+ # IVA = MntNeto * 19%
32
+ attr_accessor :iva
33
+
34
+ # Corresponde al valor total de la boleta electronica y se puede calcular
35
+ # de dos maneras diferentes. Al ser un campo de monto, se debe indicar sin
36
+ # decimales y sin separadores de miles.
37
+ # Se calcula de la siguiente forma:
38
+ #
39
+ # # Para el caso que se indique una boleta afecta y que IndMntNeto tenga
40
+ # # el valor 2, se calcula:
41
+ # MntTotal = MntNeto + IVA + MntExe
42
+ # # Para el caso que no se indique IndMntNeto, o tenga el valor 0, se
43
+ # # calcula:
44
+ # MntTotal = Suma de MontoItem por linea de detalle - Descuentos + Recargos
45
+ # # Solamente MontoItem de los items que tienen IndExe = 0
46
+ # # Descuentos y Recargos basados en etiqueta <DscRcgGlobal>
47
+ attr_accessor :mnt_total
48
+
49
+ # Corresponde a la suma de los montos de bienes o servicios no facturables
50
+ # de la boleta electronica. Los montos no facturables pueden ser
51
+ # negativos. Al ser un campo de monto, se debe indicar sin decimales y sin
52
+ # separadores de miles. Se calcula de la siguiente forma:
53
+ #
54
+ # MontoNF = Suma de MontoItem por linea de detalle
55
+ # # Solamente MontoItem de los items que tienen IndExe igual a 2 y 6.
56
+ attr_accessor :monto_nf
57
+
58
+ # Corresponde a la suma final del documento, tomando el total y el monto
59
+ # no facturable en la boleta electronica. Al ser un campo de monto, se
60
+ # debe indicar sin decimales y sin separadores de miles.
61
+ # Se calcula de la siguiente forma:
62
+ #
63
+ # TotalPeriodo = MntTotal + MontoNF
64
+ attr_accessor :total_periodo
65
+
66
+ # Corresponde al saldo anterior de un periodo, esta es informacion
67
+ # ilustrativa en la boleta electronica, es decir, que se utiliza para el
68
+ # formato impreso del documento. Si no se desea usar, se debe asignar
69
+ # 0 (cero). Al ser un campo de monto, se debe indicar sin decimales y sin
70
+ # separadores de miles.
71
+ attr_accessor :saldo_anterior
72
+
73
+ # Es el valor cobrado de la transaccion realizada. Al ser un campo de
74
+ # monto, se debe indicar sin decimales y sin separadores de miles.
75
+ # Se calcula de la siguiente forma:
76
+ #
77
+ # VlrPagar = MntTotal + SaldoAnterior
78
+ attr_accessor :vlr_pagar
79
+
80
+ # Corresponde a la tasa de impuesto al valor agregado (IVA), este valor
81
+ # debe ser expresado en porcentaje
82
+ attr_accessor :tasa_iva
6
83
 
7
84
  def initialize(params = {})
8
- @mnt_neto = params[:mnt_neto]
9
- @mnt_exe = params[:mnt_exe]
10
- @iva = params[:iva]
11
- @mnt_total = params[:mnt_total]
12
- @monto_nf = params[:monto_nf]
13
- @total_periodo = params[:total_periodo]
14
- @saldo_anterior = params[:saldo_anterior]
15
- @vlr_pagar = params[:vlr_pagar]
85
+ @mnt_neto = params[:mnt_neto].to_i if params[:mnt_neto]
86
+ @mnt_exe = params[:mnt_exe].to_i if params[:mnt_exe]
87
+ @iva = params[:iva].to_i if params[:iva]
88
+ @mnt_total = params[:mnt_total].to_i if params[:mnt_total]
89
+ @monto_nf = params[:monto_nf].to_i if params[:monto_nf]
90
+ @total_periodo = params[:total_periodo].to_i if params[:total_periodo]
91
+ @saldo_anterior = params[:saldo_anterior].to_i
92
+ @vlr_pagar = params[:vlr_pagar].to_i if params[:vlr_pagar]
93
+ @tasa_iva = params[:tasa_iva]
94
+ autocomplete! if params[:auto]
16
95
  end
17
96
 
18
97
  def as_node
@@ -21,11 +100,37 @@ module Facturapi
21
100
  totales << create_node('MntExe') { |n| n << mnt_exe }
22
101
  totales << create_node('IVA') { |n| n << iva }
23
102
  totales << create_node('MntTotal') { |n| n << mnt_total }
24
- totales << create_node('MontoNF') { |n| n << monto_nf }
25
- totales << create_node('TotalPeriodo') { |n| n << total_periodo }
26
- totales << create_node('SaldoAnterior') { |n| n << saldo_anterior }
27
- totales << create_node('VlrPagar') { |n| n << vlr_pagar }
103
+ totales << create_node('MontoNF') { |n| n << monto_nf } if monto_nf
104
+ totales << create_node('TotalPeriodo') { |n| n << total_periodo } if total_periodo
105
+ totales << create_node('SaldoAnterior') { |n| n << saldo_anterior } if saldo_anterior
106
+ totales << create_node('VlrPagar') { |n| n << vlr_pagar } if vlr_pagar
107
+ totales << create_node('TasaIVA') { |n| n << tasa_iva } if tasa_iva
108
+ end
109
+ end
110
+
111
+ def autocomplete!(params = {})
112
+ is_monto_neto = params[:is_monto_neto]
113
+ mnt_neto = params[:mnt_neto]
114
+ mnt_exe = params[:mnt_exe]
115
+ monto_nf = params[:monto_nf]
116
+ is_boleta = params[:is_boleta]
117
+ self.tasa_iva = IVA * 100 if !is_boleta && tasa_iva.blank?
118
+ if is_monto_neto && mnt_neto
119
+ self.mnt_neto = mnt_neto if self.mnt_neto.blank?
120
+ self.iva = (mnt_neto * (tasa_iva || IVA * 100) / 100).to_i if iva.blank?
28
121
  end
122
+ self.mnt_exe = mnt_exe || 0 if self.mnt_exe.blank?
123
+ self.monto_nf = monto_nf || 0 if self.monto_nf.blank?
124
+
125
+ if mnt_total.blank? && mnt_neto
126
+ self.mnt_total = is_monto_neto ? auto_mnt_total : mnt_neto
127
+ end
128
+ self.total_periodo = mnt_total + self.monto_nf if total_periodo.blank?
129
+ self.vlr_pagar = mnt_total + saldo_anterior if vlr_pagar.blank?
130
+ end
131
+
132
+ def auto_mnt_total
133
+ mnt_neto + iva + mnt_exe
29
134
  end
30
135
  end
31
136
  end
@@ -0,0 +1,2 @@
1
+ require 'facturapi/services/obtener_link'
2
+ require 'facturapi/services/procesar'
@@ -0,0 +1,50 @@
1
+ require 'facturapi/services/responses/obtener_link'
2
+
3
+ module Facturapi
4
+ module Services
5
+ # Obtiene el Link de descarga del Documento Tributario una vez que este ha
6
+ # sido generado y enviado al SII.
7
+ # Se puede utilizar directamente el indicador "IncluyeLink" al procesar, en
8
+ # caso que se desee obtener los link de Impresion al emitir.
9
+ class ObtenerLink
10
+ # Corresponde al tipo de movimiento asociado al documento enviado:
11
+ # C = Compra
12
+ # V = Venta
13
+ # B = Boleta
14
+ attr_accessor :tpomov
15
+
16
+ # Corresponde al numero de Folio del Documento.
17
+ attr_accessor :folio
18
+
19
+ # Corresponde al Tipo de Documento (Tipo DTE)
20
+ attr_accessor :tipo
21
+
22
+ # Indica si se obtendra la copia cedible del PDF.
23
+ # True = Se obtiene copia Cedible.
24
+ # False = Se obtiene la copia Original.
25
+ attr_accessor :cedible
26
+
27
+ def initialize(params)
28
+ @tpomov = Base64.strict_encode64(params[:tpomov] || 'B')
29
+ @folio = Base64.strict_encode64(params[:folio].to_s)
30
+ @tipo = Base64.strict_encode64 (params[:tipo] || '39').to_s
31
+ @cedible = Base64.strict_encode64(params[:cedible] ? 'True' : 'False')
32
+ end
33
+
34
+ def send
35
+ response = Facturapi::Client.call(:obtener_link, params)
36
+ Facturapi::Services::Responses::ObtenerLink.new(
37
+ response.body[:obtener_link_response][:obtener_link_result]
38
+ )
39
+ end
40
+
41
+ def params
42
+ { tpomov: tpomov, folio: folio, tipo: tipo, cedible: cedible }
43
+ end
44
+
45
+ def to_s
46
+ Facturapi::Client.xml(:obtener_link, params)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ require 'facturapi/services/responses/procesar'
2
+
3
+ module Facturapi
4
+ module Services
5
+ # Permite procesar el archivo de Integracion y generar el DTE (Documento
6
+ # Tributario Electronico).
7
+ class Procesar
8
+ attr_accessor :dte
9
+
10
+ def initialize(dte)
11
+ @dte = dte
12
+ end
13
+
14
+ def send
15
+ response = Facturapi::Client.call(:procesar, params)
16
+ Facturapi::Services::Responses::Procesar.new(
17
+ response.body[:procesar_response][:procesar_result]
18
+ )
19
+ end
20
+
21
+ def params
22
+ { file: Base64.strict_encode64(dte.as_node.to_s), formato: 2 }
23
+ end
24
+
25
+ def to_s
26
+ Facturapi::Client.xml(:procesar, params)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1 @@
1
+ require 'facturapi/services/responses/procesar'
@@ -0,0 +1,17 @@
1
+ module Facturapi
2
+ module Services
3
+ module Responses
4
+ class ObtenerLink
5
+ attr_reader :response
6
+
7
+ def initialize(response)
8
+ @response = Nokogiri::XML(response)
9
+ end
10
+
11
+ def url
12
+ Base64.strict_decode64 response.css('WSPLANO>Mensaje').text
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ module Facturapi
2
+ module Services
3
+ module Responses
4
+ class Procesar
5
+ attr_reader :response
6
+
7
+ def initialize(response)
8
+ @response = Nokogiri::XML(response)
9
+ end
10
+
11
+ def valid?
12
+ response.css('WSPLANO>Resultado').text == 'True'
13
+ end
14
+
15
+ def error
16
+ response.css('Documento>Error').text
17
+ end
18
+
19
+ def folio
20
+ response.css('Documento>Folio').text.to_i
21
+ end
22
+
23
+ def tipo_dte
24
+ response.css('Documento>TipoDte').text.to_i
25
+ end
26
+
27
+ def fecha
28
+ Time.strptime(response.css('Documento>Fecha').text, '%FT%T')
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1 @@
1
+ require 'facturapi/utils/dte_types'
@@ -0,0 +1,38 @@
1
+ require 'i18n'
2
+
3
+ module Facturapi
4
+ module Utils
5
+ module DteTypes
6
+ DOCUMENTS = {
7
+ 30 => :factura,
8
+ 32 => :factura_ex,
9
+ 33 => :factura_elec,
10
+ 34 => :factura_ex_elec,
11
+ 35 => :boleta,
12
+ 38 => :boleta_ex,
13
+ 39 => :boleta_elec,
14
+ 40 => :liq_factura,
15
+ 41 => :boleta_ex_elec,
16
+ 43 => :liq_factura_elec,
17
+ 45 => :factura_compra,
18
+ 46 => :factura_compra_elec,
19
+ 50 => :guia_despacho,
20
+ 52 => :guia_despacho_elec,
21
+ 55 => :nota_deb,
22
+ 56 => :nota_deb_elec,
23
+ 60 => :nota_cred,
24
+ 61 => :nota_cred_elec
25
+ }.freeze
26
+
27
+ VALID_REGEXP = Regexp.new("^#{DOCUMENTS.keys.join('|')}$")
28
+
29
+ def self.sym(dte_type)
30
+ DOCUMENTS[dte_type]
31
+ end
32
+
33
+ def self.humanized(dte_type)
34
+ I18n.t "facturapi.dte_type.#{sym(dte_type)}"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Facturapi
2
- VERSION = "0.0.1"
2
+ VERSION = '0.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facturapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alter Lagos
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-03 00:00:00.000000000 Z
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -59,19 +59,19 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: 1.4.0
61
61
  - !ruby/object:Gem::Dependency
62
- name: bundler
62
+ name: i18n
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.13'
68
- type: :development
67
+ version: '0.6'
68
+ type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '1.13'
74
+ version: '0.6'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +100,34 @@ dependencies:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '3.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: pry-byebug
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 3.4.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 3.4.0
117
+ - !ruby/object:Gem::Dependency
118
+ name: guard-rspec
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 4.7.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 4.7.0
103
131
  description:
104
132
  email:
105
133
  - alter.strife@gmail.com
@@ -114,33 +142,40 @@ files:
114
142
  - ".travis.yml"
115
143
  - CODE_OF_CONDUCT.md
116
144
  - Gemfile
145
+ - Guardfile
117
146
  - LICENSE.txt
118
147
  - README.md
119
148
  - Rakefile
120
149
  - bin/console
121
150
  - bin/setup
151
+ - config/locales/es.yml
122
152
  - facturapi.gemspec
123
- - foo.xml
124
- - lala.html
125
153
  - lib/facturapi.rb
126
154
  - lib/facturapi/client.rb
127
155
  - lib/facturapi/config.rb
128
156
  - lib/facturapi/helpers.rb
157
+ - lib/facturapi/helpers/descuento_global.rb
129
158
  - lib/facturapi/helpers/detalle.rb
130
159
  - lib/facturapi/helpers/dsc_rcg_global.rb
131
160
  - lib/facturapi/helpers/dte.rb
132
161
  - lib/facturapi/helpers/emisor.rb
133
162
  - lib/facturapi/helpers/encabezado.rb
134
163
  - lib/facturapi/helpers/id_doc.rb
164
+ - lib/facturapi/helpers/recargo_global.rb
135
165
  - lib/facturapi/helpers/receptor.rb
136
166
  - lib/facturapi/helpers/referencia.rb
137
167
  - lib/facturapi/helpers/totales.rb
138
- - lib/facturapi/service.rb
139
- - lib/facturapi/service/procesar.rb
168
+ - lib/facturapi/services.rb
169
+ - lib/facturapi/services/obtener_link.rb
170
+ - lib/facturapi/services/procesar.rb
171
+ - lib/facturapi/services/responses.rb
172
+ - lib/facturapi/services/responses/obtener_link.rb
173
+ - lib/facturapi/services/responses/procesar.rb
174
+ - lib/facturapi/utils.rb
175
+ - lib/facturapi/utils/dte_types.rb
140
176
  - lib/facturapi/version.rb
141
177
  - lib/facturapi/xml.rb
142
- - todo.rb
143
- homepage:
178
+ homepage: https://github.com/meloncargo/facturapi
144
179
  licenses:
145
180
  - MIT
146
181
  metadata: {}