cfdi 0.1.8 → 0.1.9

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
  SHA1:
3
- metadata.gz: cb914ef37f91ddda191093e06888b40df2bec153
4
- data.tar.gz: 4bdd0e633c0a5493e40abb247a0a3dcdaa294dc9
3
+ metadata.gz: 10a721b62d24a67b264b69d2e04c3a08fbcb115c
4
+ data.tar.gz: f664e747c70a95880fddda44a722ee3cf9d18894
5
5
  SHA512:
6
- metadata.gz: bac36231875ce770144431a887faea011fc055df402c8414b400c89ee57489f5d779270f69983be59b65525356786b147b8bc6a9cc80a6c7486f6b9240d9d7bf
7
- data.tar.gz: e4204295e3f4c07b51b89e198166ef14fb9e30a12e557c0cff77ac96677d2c7c02c4f62b09d49b28167c0f3a2595c9edc0c51d5e494f6a18a9d0b97752886d26
6
+ metadata.gz: c85d9c7eeeace5094efa16869101e732bfe695622c70dbf9dad3e8feebb6c984b7887cecb73627d382910c70c1992d087d1426d87a5e33519ef7c360b5898860
7
+ data.tar.gz: 7e68eb183eae021e6c0ec4d950843540499c54048addcdf8a893ea6dd653162684f32c8bb8b93035f17fbab62c517d2d736e67b0edba2e769b45a1e32b336d64
@@ -58,7 +58,7 @@ factura.conceptos << CFDI::Concepto.new({
58
58
  unidad: 'Kilos',
59
59
  noIdentificacion: 'KDV',
60
60
  descripcion: 'Verga',
61
- valorUnitario:5500.00 #el importe se calcula solo
61
+ valorUnitario: 5500.00 #el importe se calcula solo
62
62
  })
63
63
 
64
64
  # Todavía no agarro bien el pedo sobre como salen los impuestos, pull request?
data/lib/comprobante.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  module CFDI
2
2
  # La clase principal para crear Comprobantes
3
3
  class Comprobante
4
-
4
+
5
5
  # los datos para la cadena original en el órden correcto
6
6
  # @private
7
7
  @@datosCadena = [:version, :fecha, :tipoDeComprobante, :formaDePago, :condicionesDePago, :subTotal, :TipoCambio, :moneda, :total, :metodoDePago, :lugarExpedicion, :NumCtaPago]
8
8
  # Todos los datos del comprobante
9
9
  # @private
10
10
  @@data = @@datosCadena+[:emisor, :receptor, :conceptos, :serie, :folio, :sello, :noCertificado, :certificado, :conceptos, :complemento, :cancelada, :impuestos]
11
- attr_accessor *@@data
12
-
11
+ attr_accessor(*@@data)
12
+
13
13
  @addenda = nil
14
-
14
+
15
15
  @@options = {
16
16
  tasa: 0.16,
17
17
  defaults: {
@@ -24,9 +24,9 @@ module CFDI
24
24
  tipoDeComprobante: 'ingreso'
25
25
  }
26
26
  }
27
-
27
+
28
28
  # Configurar las opciones default de los comprobantes
29
- #
29
+ #
30
30
  # == Parameters:
31
31
  # options::
32
32
  # Las opciones del comprobante: tasa (de impuestos), defaults: un Hash con la moneda (pesos), version (3.2), TipoCambio (1), y tipoDeComprobante (ingreso)
@@ -37,7 +37,7 @@ module CFDI
37
37
  @@options = Comprobante.rmerge @@options, options
38
38
  @@options
39
39
  end
40
-
40
+
41
41
  # Crear un comprobante nuevo
42
42
  #
43
43
  # @param data [Hash] Los datos de un comprobante
@@ -51,7 +51,7 @@ module CFDI
51
51
  # @option data [String] :metodoDePago ('') El método de pago (depósito bancario? efectivo?)
52
52
  # @option data [String] :lugarExpedicion ('') El lugar dónde se expide la factura (Nutopía, México?)
53
53
  # @option data [String] :NumCtaPago (nil) El número de cuenta para el pago
54
- #
54
+ #
55
55
  # @param options [Hash] Las opciones para este comprobante
56
56
  # @see [Comprobante@@options] Opciones
57
57
  #
@@ -67,16 +67,16 @@ module CFDI
67
67
  self.send method, v
68
68
  end
69
69
  end
70
-
71
-
70
+
71
+
72
72
  def addenda= addenda
73
73
  addenda = Addenda.new addenda unless addenda.is_a? Addenda
74
74
  @addenda = addenda
75
75
  end
76
-
76
+
77
77
 
78
78
  # Regresa el subtotal de este comprobante, tomando el importe de cada concepto
79
- #
79
+ #
80
80
  # @return [Float] El subtotal del comprobante
81
81
  def subTotal
82
82
  ret = 0
@@ -85,41 +85,41 @@ module CFDI
85
85
  end
86
86
  ret
87
87
  end
88
-
89
-
88
+
89
+
90
90
  # Regresa el total
91
- #
91
+ #
92
92
  # @return [Float] El subtotal multiplicado por la tasa
93
93
  def total
94
94
  self.subTotal+(self.subTotal*@opciones[:tasa])
95
95
  end
96
-
97
-
96
+
97
+
98
98
  # Asigna un emisor de tipo {CFDI::Entidad}
99
99
  # @param emisor [Hash, CFDI::Entidad] Los datos de un emisor
100
- #
100
+ #
101
101
  # @return [CFDI::Entidad] Una entidad
102
- def emisor= emisor
102
+ def emisor= emisor
103
103
  emisor = Entidad.new emisor unless emisor.is_a? Entidad
104
104
  @emisor = emisor;
105
105
  end
106
-
107
-
106
+
107
+
108
108
  # Asigna un receptor
109
109
  # @param receptor [Hash, CFDI::Entidad] Los datos de un receptor
110
- #
110
+ #
111
111
  # @return [CFDI::Entidad] Una entidad
112
- def receptor= receptor
112
+ def receptor= receptor
113
113
  receptor = Entidad.new receptor unless receptor.is_a? Entidad
114
114
  @receptor = receptor;
115
115
  receptor
116
116
  end
117
-
117
+
118
118
  # Agrega uno o varios conceptos
119
119
  # @param conceptos [Array, Hash, CFDI::Concepto] Uno o varios conceptos
120
- #
120
+ #
121
121
  # En caso de darle un Hash o un {CFDI::Concepto}, agrega este a los conceptos, de otro modo, sobreescribe los conceptos pre-existentes
122
- #
122
+ #
123
123
  # @return [Array] Los conceptos de este comprobante
124
124
  def conceptos= conceptos
125
125
  if conceptos.is_a? Array
@@ -131,26 +131,26 @@ module CFDI
131
131
  elsif conceptos.is_a? Concepto
132
132
  conceptos << conceptos
133
133
  end
134
-
134
+
135
135
  @conceptos = conceptos
136
136
  conceptos
137
137
  end
138
-
138
+
139
139
 
140
140
  # Asigna un complemento al comprobante
141
141
  # @param complemento [Hash, CFDI::Complemento] El complemento a agregar
142
- #
142
+ #
143
143
  # @return [CFDI::Complemento]
144
144
  def complemento= complemento
145
145
  complemento = Complemento.new complemento unless complemento.is_a? Complemento
146
146
  @complemento = complemento
147
147
  complemento
148
148
  end
149
-
149
+
150
150
 
151
151
  # Asigna una fecha al comprobante
152
152
  # @param fecha [Time, String] La fecha y hora (YYYY-MM-DDTHH:mm:SS) de la emisión
153
- #
153
+ #
154
154
  # @return [String] la fecha en formato '%FT%R:%S'
155
155
  def fecha= fecha
156
156
  fecha = fecha.strftime('%FT%R:%S') unless fecha.is_a? String
@@ -159,7 +159,7 @@ module CFDI
159
159
 
160
160
 
161
161
  # El comprobante como XML
162
- #
162
+ #
163
163
  # @return [String] El comprobante namespaceado en versión 3.2 (porque soy un huevón)
164
164
  def to_xml
165
165
  ns = {
@@ -171,9 +171,9 @@ module CFDI
171
171
  fecha: @fecha,
172
172
  formaDePago: @formaDePago,
173
173
  condicionesDePago: @condicionesDePago,
174
- subTotal: self.subTotal,
174
+ subTotal: sprintf('%.2f', self.subTotal),
175
175
  Moneda: @moneda,
176
- total: self.total,
176
+ total: sprintf('%.2f', self.total),
177
177
  metodoDePago: @metodoDePago,
178
178
  tipoDeComprobante: @tipoDeComprobante,
179
179
  LugarExpedicion: @lugarExpedicion,
@@ -181,27 +181,27 @@ module CFDI
181
181
  ns[:serie] = @serie if @serie
182
182
  ns[:TipoCambio] = @TipoCambio if @TipoCambio
183
183
  ns[:NumCtaPago] = @NumCtaPago if @NumCtaPago && @NumCtaPago!=''
184
-
184
+
185
185
  if (@addenda)
186
186
  # Si tenemos addenda, entonces creamos el campo "xmlns:ElNombre" y agregamos sus definiciones al SchemaLocation
187
187
  ns["xmlns:#{@addenda.nombre}"] = @addenda.namespace
188
188
  ns['xsi:schemaLocation'] += ' '+[@addenda.namespace, @addenda.xsd].join(' ')
189
189
  end
190
-
190
+
191
191
  if @noCertificado
192
192
  ns[:noCertificado] = @noCertificado
193
193
  ns[:certificado] = @certificado
194
194
  end
195
-
195
+
196
196
  if @sello
197
197
  ns[:sello] = @sello
198
198
  end
199
-
199
+
200
200
  @builder = Nokogiri::XML::Builder.new do |xml|
201
201
  xml.Comprobante(ns) do
202
202
  ins = xml.doc.root.add_namespace_definition('cfdi', 'http://www.sat.gob.mx/cfd/3')
203
203
  xml.doc.root.namespace = ins
204
-
204
+
205
205
  xml.Emisor(@emisor.ns) {
206
206
  xml.DomicilioFiscal(@emisor.domicilioFiscal.to_h.reject {|k,v| v == nil})
207
207
  xml.ExpedidoEn(@emisor.expedidoEn.to_h.reject {|k,v| v == nil || v == ''})
@@ -213,32 +213,43 @@ module CFDI
213
213
  xml.Conceptos {
214
214
  @conceptos.each do |concepto|
215
215
  # select porque luego se caga el xml si incluyo noIdentificacion y es empty
216
- xml.Concepto(concepto.to_h.select {|k,v| v!=nil && v != ''}) {
216
+
217
+ cc = concepto.to_h.select {|k,v| v!=nil && v != ''}
218
+
219
+ cc = cc.map {|k,v|
220
+ v = sprintf('%.2f', v) if v.is_a? Float
221
+ [k,v]
222
+ }.to_h
223
+
224
+ xml.Concepto(cc) {
217
225
  xml.ComplementoConcepto
218
226
  }
219
227
  end
220
228
  }
221
- xml.Impuestos({totalImpuestosTrasladados: self.subTotal*@opciones[:tasa]}) {
229
+ xml.Impuestos({totalImpuestosTrasladados: sprintf('%.2f', self.subTotal*@opciones[:tasa])}) {
222
230
  xml.Traslados {
223
231
  @impuestos.each do |impuesto|
224
- xml.Traslado({impuesto: impuesto[:impuesto], tasa:(@opciones[:tasa]*100).to_i, importe: self.subTotal*@opciones[:tasa]})
232
+ xml.Traslado({
233
+ impuesto: impuesto[:impuesto],
234
+ tasa:(@opciones[:tasa]*100).to_i,
235
+ importe: sprintf('%.2f', self.subTotal*@opciones[:tasa])})
225
236
  end
226
237
  }
227
238
  }
228
239
  xml.Complemento {
229
-
240
+
230
241
  if @complemento
231
242
  nsTFD = {
232
243
  'xsi:schemaLocation' => 'http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/TimbreFiscalDigital/TimbreFiscalDigital.xsd',
233
244
  'xmlns:tfd' => 'http://www.sat.gob.mx/TimbreFiscalDigital',
234
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
245
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
235
246
  }
236
247
  xml['tfd'].TimbreFiscalDigital(@complemento.to_h.merge nsTFD) {
237
248
  }
238
-
249
+
239
250
  end
240
251
  }
241
-
252
+
242
253
  if (@addenda)
243
254
  xml.Addenda {
244
255
  @addenda.data.each do |k,v|
@@ -252,7 +263,7 @@ module CFDI
252
263
  end
253
264
  }
254
265
  end
255
-
266
+
256
267
  end
257
268
  end
258
269
  @builder.to_xml
@@ -260,7 +271,7 @@ module CFDI
260
271
 
261
272
 
262
273
  # Un hash con todos los datos del comprobante, listo para Hash.to_json
263
- #
274
+ #
264
275
  # @return [Hash] El comprobante como Hash
265
276
  def to_h
266
277
  hash = {}
@@ -268,30 +279,30 @@ module CFDI
268
279
  data = deep_to_h send(key)
269
280
  hash[key] = data
270
281
  end
271
-
282
+
272
283
  return hash
273
284
  end
274
-
285
+
275
286
 
276
287
  # La cadena original del CFDI
277
- #
288
+ #
278
289
  # @return [String] Separada por pipes, because fuck you that's why
279
290
  def cadena_original
280
291
  params = []
281
-
282
- @@datosCadena.each {|key| params.push send(key) }
292
+
293
+ @@datosCadena.each {|key| params.push send(key) }
283
294
  params += @emisor.cadena_original
284
295
  params << @regimen
285
296
  params += @receptor.cadena_original
286
-
297
+
287
298
  @conceptos.each do |concepto|
288
299
  params += concepto.cadena_original
289
300
  end
290
-
301
+
291
302
  @impuestos.each do |traslado|
292
303
  params += [traslado[:impuesto], (@opciones[:tasa]*100).to_i, self.subTotal*@opciones[:tasa], self.subTotal*@opciones[:tasa]]
293
304
  end
294
-
305
+
295
306
  params.select! { |i| i != nil && i != '' }
296
307
  params.map! do |elem|
297
308
  if elem.is_a? Float
@@ -301,14 +312,14 @@ module CFDI
301
312
  end
302
313
  elem
303
314
  end
304
-
315
+
305
316
  return "||#{params.join '|'}||"
306
317
  end
307
318
 
308
319
 
309
320
  # Revisa que el timbre de un comprobante sea válido
310
321
  # @param [String] El certificado del PAC
311
- #
322
+ #
312
323
  # @return [Boolean] El resultado de la validación
313
324
  def timbre_valido? cert=nil
314
325
  return false unless complemento && complemento.selloSAT
@@ -343,21 +354,21 @@ module CFDI
343
354
 
344
355
  private
345
356
  def deep_to_h value
346
-
357
+
347
358
  if value.is_a? ElementoComprobante
348
359
  original = value.to_h
349
360
  value = {}
350
361
  original.each do |k,v|
351
362
  value[k] = deep_to_h v
352
363
  end
353
-
364
+
354
365
  elsif value.is_a?(Array)
355
366
  value = value.map do |v|
356
367
  deep_to_h v
357
368
  end
358
369
  end
359
- value
360
-
370
+ # value
371
+
361
372
  #value = value.to_h if value.respond_to? :to_h
362
373
  #if value.each do |vi|
363
374
  # value.map do |k,v|
@@ -366,6 +377,6 @@ module CFDI
366
377
  #end
367
378
  value
368
379
  end
369
-
380
+
370
381
  end
371
382
  end
data/lib/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module CFDI
2
2
  # La versión de este gem
3
- VERSION = '0.1.8'
3
+ VERSION = '0.1.9'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfdi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Hidalgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-04 00:00:00.000000000 Z
11
+ date: 2014-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri