cfdi40 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d48bd150dec201d3a2b0812d49080313c5e4aec6efd836e5606e9e2edabd822f
4
- data.tar.gz: 3f437736ebc91684c7652f217f64a0e04c9e8b18519a18a02397ab4f95ca8db9
3
+ metadata.gz: 7901aac708d9a35630373ea7d4f38a43fdddd801defb286068fe7b96350db91c
4
+ data.tar.gz: 34ffabb2c0a58898656c5a652afdbc2e84d04bc0848c5927b7f673a0ebd5875e
5
5
  SHA512:
6
- metadata.gz: 4491ff366eeb72c4c6d1792227750e5c3f333d6df52f7d974c05eff8d4d94f30a44e98dfefaf03b1aaa41a8d1407e2765a3ef026617faa071fb86049cbbec9f9
7
- data.tar.gz: 77c1ee1687c4b13af13768afa7a5b3ee0c7ab2071a4a3ddbf45d3bedcf4a18bb2a8e56b07bdf1762d6e833c052cf77c1b3272b04a75cb3f28d2c0494b76d66af
6
+ metadata.gz: 9e04325fa2210081dc36519e8d9773110f386964d45e541b8273fbd7c22112d258ba249f0f04ad68cd8f12039648d466228c1759aad8b1b84a9eb69e23edd3a1
7
+ data.tar.gz: c1f87bc293e895fc4df9d3440413477f1d540142e879b85e3d13e534a69c1f9376080f41212bf26e3bc161726883c238f625121198e2de7db98aec99b0122bd7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfdi40 (0.0.5)
4
+ cfdi40 (0.0.7)
5
5
  nokogiri (>= 1.10.10)
6
6
 
7
7
  GEM
data/README_es-MX.md CHANGED
@@ -17,6 +17,12 @@ que esta herramienta:
17
17
  * Valide el CFDi contra los XSD
18
18
  * Selle el CFDi.
19
19
 
20
+ Hasta ahora:
21
+
22
+ * Genera CFDIs de ingreso básicos con IVA
23
+ * Genera CFDIs con complemento de pago para colegiaturas
24
+ * Genera CFDIs complementos de pago básicos.
25
+
20
26
  # Uso
21
27
 
22
28
  ## Ejemplo básico
@@ -53,8 +59,61 @@ que esta herramienta:
53
59
  # Genera CFDI firmado
54
60
  xml_string = cfdi.to_xml
55
61
 
62
+ ## Ejemplo CFDI con complemento de pago
63
+
64
+ # Inicia un cfdi
65
+ cfdi = Cfdi40.new
66
+ cfdi.tipo_de_comprobante = 'P'
67
+
68
+ # Datos del emisor.
69
+ # RFC y Nombre se extraen del certificado si no existen
70
+ cfdi.lugar_expedicion = '06000'
71
+ cfdi.emisor.regimen_fiscal = '612'
72
+
73
+ # Datos del receptor
74
+ cfdi.receptor.nombre = 'JUAN PUEBLO BUENO'
75
+ cfdi.receptor.rfc = 'XAXX010101000'
76
+ cfdi.receptor.domicilio_fiscal = '06000'
77
+ cfdi.receptor.regimen_fiscal = '616'
78
+ cfdi.receptor.uso_cfdi = 'CP01'
79
+
80
+ # Agrega un concepto en pesos,
81
+ # precio final al cliente (neto)
82
+ # causa IVA con tasa de 16% (default)
83
+ cfdi.add_pago(
84
+ monto: 200.17,
85
+ uuid: 'e40229b3-5c4b-46fb-9ba8-707df828a5bc',
86
+ serie: 'A',
87
+ folio: '12345',
88
+ num_parcialidad: 2,
89
+ fecha_pago: '2023-04-01T12:20:34',
90
+ forma_pago: '01',
91
+ importe_saldo_anterior: 845.673
92
+ )
93
+
94
+ # Archivos CSD
95
+ cfdi.cert_path = '/path_to/certificado.cer'
96
+ cfdi.key_path = '/path_to/llave_privada.key'
97
+ cfdi.key_pass = 'contraseña'
98
+
99
+ # Genera CFDI firmado
100
+ xml_string = cfdi.to_xml
101
+
102
+
103
+ # Lo que sigue
104
+
105
+ * Nodo de Traslados cuando hay tasa de IEPS
106
+ * Retenciones de impuestos
107
+ * CFDI de pagos con varios pagos y varios documentos en cada pago
108
+
56
109
  # Cambios
57
110
 
111
+ # 0.0.7
112
+ * Ajustes al CFDi con complemento de pagos por validaciones del PAC.
113
+
114
+ # 0.0.6
115
+ * CFDi con complemento de pagos
116
+
58
117
  # 0.0.5
59
118
 
60
119
  * IVA tasa 0 e IVA excento. Los conceptos con iva tasa 0 deben llevar el
@@ -95,7 +154,5 @@ que esta herramienta:
95
154
 
96
155
  # ¿Que sigue?
97
156
 
98
- * Complemento de pagos
99
157
  * Retenciones
100
- * IEPS
101
- * Complemento para colegiaturas
158
+ * Complemento de pagos con retenciones
@@ -0,0 +1,18 @@
1
+ module Cfdi40
2
+ class Complemento < Node
3
+ # See Comprobante#add_pago
4
+ def add_pago(attributes={})
5
+ pagos.totales_node
6
+ pagos.add_pago(attributes)
7
+ end
8
+
9
+ def pagos
10
+ return @pagos if defined?(@pagos)
11
+
12
+ @pagos = Pagos.new
13
+ @pagos.parent_node = self
14
+ @children_nodes << @pagos
15
+ @pagos
16
+ end
17
+ end
18
+ end
@@ -119,6 +119,8 @@ module Cfdi40
119
119
  # +iedu_rfc_pago+::
120
120
  #
121
121
  def add_concepto(attributes = {})
122
+ raise Error, 'CFDi tipo pago no acepta conceptos' if tipo_de_comprobante == 'P'
123
+
122
124
  concepto = Concepto.new
123
125
  concepto.parent_node = @conceptos
124
126
  attributes.each do |key, value|
@@ -135,6 +137,23 @@ module Cfdi40
135
137
  concepto
136
138
  end
137
139
 
140
+ # TODO: Doc params add_pago
141
+ # monto
142
+ # uuid
143
+ # folio
144
+ # serie
145
+ # num_parcialidad
146
+ # fecha_pago
147
+ # forma_pago
148
+ # importe_saldo_anterior
149
+ # objeto_impuestos
150
+ def add_pago(attributes = {})
151
+ raise Error, "CFDi debe ser tipo 'P'" unless tipo_de_comprobante == 'P'
152
+
153
+ add_node_concepto_actividad_pago
154
+ complemento.add_pago(attributes)
155
+ end
156
+
138
157
  def to_s
139
158
  to_xml
140
159
  end
@@ -167,6 +186,23 @@ module Cfdi40
167
186
 
168
187
  private
169
188
 
189
+ def add_node_concepto_actividad_pago
190
+ return if defined?(@concepto_actividad)
191
+
192
+ @receptor.uso_cfdi = 'CP01'
193
+ @concepto_actividad = Concepto.new
194
+ @concepto_actividad.clave_prod_serv = '84111506'
195
+ @concepto_actividad.cantidad = 1
196
+ @concepto_actividad.clave_unidad = 'ACT'
197
+ @concepto_actividad.descripcion = 'Pago'
198
+ @concepto_actividad.precio_bruto = 0
199
+ @concepto_actividad.tasa_iva = nil
200
+ @concepto_actividad.objeto_impuestos = '01'
201
+ @concepto_actividad.calculate!
202
+ @conceptos.add_child_node @concepto_actividad
203
+ calculate!
204
+ end
205
+
170
206
  def docxml
171
207
  return @docxml if defined?(@docxml) && !@docxml.nil?
172
208
 
@@ -245,7 +281,7 @@ module Cfdi40
245
281
  impuestos_node.traslados
246
282
  end
247
283
 
248
- # Eliminar
284
+ # TODO: Eliminar
249
285
  def traslado_iva_node
250
286
  impuestos_node.traslado_iva
251
287
  end
@@ -256,5 +292,14 @@ module Cfdi40
256
292
  @sat_csd ||= SatCsd.new
257
293
  @sat_csd.set_private_key(@key_data, (defined?(@key_pass) ? @key_pass : nil))
258
294
  end
295
+
296
+ def complemento
297
+ return @complemento if defined?(@complemento)
298
+
299
+ @complemento = Complemento.new
300
+ @complemento.parent_node = self
301
+ @children_nodes << @complemento
302
+ @complemento
303
+ end
259
304
  end
260
305
  end
@@ -71,7 +71,9 @@ module Cfdi40
71
71
  def calculate_from_gross_price
72
72
  @precio_bruto = @precio_bruto.round(6)
73
73
  calculate_taxes
74
- @precio_neto = (@importe_neto / cantidad).round(2)
74
+ # May be can not be rounded with 2 decimals.
75
+ # Example gross_price = 1.99512
76
+ @precio_neto = (@importe_neto / cantidad).round(6)
75
77
  update_xml_attributes
76
78
  end
77
79
 
@@ -0,0 +1,66 @@
1
+ module Cfdi40
2
+ class DoctoRelacionado < Node
3
+ define_attribute :id_documento, xml_attribute: 'IdDocumento'
4
+ define_attribute :serie, xml_attribute: 'Serie'
5
+ define_attribute :folio, xml_attribute: 'Folio'
6
+ define_attribute :moneda_dr, xml_attribute: 'MonedaDR', default: 'MXN'
7
+ define_attribute :equivalencia_dr, xml_attribute: 'EquivalenciaDR', default: '1'
8
+ define_attribute :num_parcialidad, xml_attribute: 'NumParcialidad'
9
+ define_attribute :imp_saldo_ant, xml_attribute: 'ImpSaldoAnt', format: :t_ImporteMXN
10
+ define_attribute :imp_pagado, xml_attribute: 'ImpPagado', format: :t_ImporteMXN
11
+ define_attribute :imp_saldo_insoluto, xml_attribute: 'ImpSaldoInsoluto', format: :t_ImporteMXN
12
+ define_attribute :objeto_imp_dr, xml_attribute: 'ObjetoImpDR', default: '02'
13
+
14
+ def calculate!
15
+ self.imp_saldo_insoluto = (imp_saldo_ant - imp_pagado).round(2)
16
+ add_impuestos
17
+ end
18
+
19
+ # Add nodes for 'traslado_dr' and/or 'retencion_dr' and intermediate nodes
20
+ def add_impuestos
21
+ add_traslado if objeto_imp_dr == '02'
22
+ end
23
+
24
+ def add_traslado
25
+ return unless objeto_imp_dr == '02'
26
+
27
+ # Taxes values for IVA rate 0.16 assumming that all 'conceptos' in the realted document
28
+ # has the same tax rate. This could not be true but the is the most common case.
29
+ traslado_dr = TrasladoDR.new
30
+ traslado_dr.monto_pago = imp_pagado.round(2)
31
+ traslado_dr.calculate!
32
+ traslados_dr.add_child_node(traslado_dr)
33
+ traslado_dr
34
+ end
35
+
36
+ # Return a hash. The key is an array [impuesto, tipo_factor, tasa_o_cuot]
37
+ # and the value is another hash with the keys :base, :importe
38
+ def traslados_summary
39
+ return {} unless defined?(@traslados_dr)
40
+
41
+ summary = {}
42
+ @traslados_dr.children_nodes.each do |traslado_dr|
43
+ key = [traslado_dr.impuesto_dr, traslado_dr.tipo_factor_dr, traslado_dr.tasa_o_cuota_dr]
44
+ summary[key] ||= { base: 0, importe: 0 }
45
+ summary[key][:base] += traslado_dr.base_dr.to_f
46
+ summary[key][:importe] += traslado_dr.importe_dr.to_f
47
+ end
48
+ summary
49
+ end
50
+
51
+ def traslados_dr
52
+ return @traslados_dr if defined?(@traslados_dr)
53
+
54
+ @traslados_dr = impuestos_dr.traslados_dr
55
+ end
56
+
57
+ def impuestos_dr
58
+ return @impuestos_dr if defined?(@impuestos_dr)
59
+
60
+ @impuestos_dr = ImpuestosDR.new
61
+ @impuestos_dr.parent_node = self
62
+ @children_nodes << @impuestos_dr
63
+ @impuestos_dr
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,12 @@
1
+ module Cfdi40
2
+ class ImpuestosDR < Node
3
+ def traslados_dr
4
+ return @traslados_dr if defined?(@traslados_dr)
5
+
6
+ @traslados_dr = TrasladosDR.new
7
+ @traslados_dr.parent_node = self
8
+ @children_nodes << @traslados_dr
9
+ @traslados_dr
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Cfdi40
2
+ class ImpuestosP < Node
3
+
4
+ def traslados_p
5
+ return @traslados_p if defined?(@traslados_p)
6
+
7
+ @traslados_p = TrasladosP.new
8
+ add_child_node @traslados_p
9
+ @traslados_p
10
+ end
11
+ end
12
+ end
data/lib/cfdi40/node.rb CHANGED
@@ -7,6 +7,7 @@ module Cfdi40
7
7
  def initialize
8
8
  self.class.verify_class_variables
9
9
  @children_nodes = []
10
+ set_defaults
10
11
  end
11
12
 
12
13
  # Use class variables to define attributes used to create nodes
@@ -87,6 +88,13 @@ module Cfdi40
87
88
  instance_variable_get("@#{accessor}".to_sym).nil?
88
89
  end
89
90
 
91
+ def add_child_node(child_node)
92
+ raise Error, 'child_node must be a Node object' unless child_node.is_a?(Node)
93
+
94
+ child_node.parent_node = self
95
+ @children_nodes << child_node
96
+ end
97
+
90
98
  def current_namespace
91
99
  return unless self.class.respond_to?(:namespaces)
92
100
  if self.class.namespaces.empty?
@@ -97,7 +105,8 @@ module Cfdi40
97
105
  end
98
106
 
99
107
  def create_xml_node
100
- set_defaults
108
+ # TODO: Quitar la siguiente linea (set_defaults) si funciona poniendo los defaults en initialize
109
+ # set_defaults
101
110
  if self.respond_to?(:before_add, true)
102
111
  self.before_add
103
112
  end
@@ -146,9 +155,9 @@ module Cfdi40
146
155
  def formated_value(accessor)
147
156
  case self.class.formats[accessor]
148
157
  when :t_Importe
149
- sprintf("%0.6f", public_send(accessor).to_f)
158
+ public_send(accessor).to_f == 0.0 ? '0' : sprintf("%0.6f", public_send(accessor).to_f)
150
159
  when :t_ImporteMXN
151
- sprintf("%0.2f", public_send(accessor).to_f)
160
+ public_send(accessor).to_f == 0.0 ? '0' : sprintf("%0.2f", public_send(accessor).to_f)
152
161
  else
153
162
  public_send(accessor)
154
163
  end
@@ -0,0 +1,56 @@
1
+ module Cfdi40
2
+ class Pago < Node
3
+ define_attribute :monto, xml_attribute: 'Monto'
4
+ define_attribute :fecha_pago, xml_attribute: 'FechaPago'
5
+ define_attribute :forma_pago, xml_attribute: 'FormaDePagoP'
6
+ define_attribute :moneda, xml_attribute: 'MonedaP', readonly: true, default: 'MXN'
7
+ define_attribute :tipo_cambio, xml_attribute: 'TipoCambioP', readonly: true, default: '1'
8
+
9
+ attr_accessor :uuid, :serie, :folio, :num_parcialidad, :importe_saldo_anterior, :objeto_impuestos
10
+
11
+ # Generate docto_relacionado node
12
+ # Data for dcto_relacionado node is obtained from de accessors
13
+ # uuid, serie, folio
14
+ def add_docto_relacionado
15
+ docto_relacionado = DoctoRelacionado.new
16
+ docto_relacionado.parent_node = self
17
+ docto_relacionado.id_documento = uuid
18
+ docto_relacionado.serie = serie
19
+ docto_relacionado.folio = folio
20
+ docto_relacionado.num_parcialidad = num_parcialidad
21
+ docto_relacionado.imp_saldo_ant = importe_saldo_anterior.round(2)
22
+ docto_relacionado.imp_pagado = monto
23
+ docto_relacionado.calculate!
24
+ @children_nodes << docto_relacionado
25
+ end
26
+
27
+ def add_impuestos_p
28
+ impuestos_p = ImpuestosP.new
29
+ add_child_node impuestos_p
30
+ impuestos_p.traslados_p.add_traslado_p_nodes
31
+ end
32
+
33
+ def docto_relacionados
34
+ return @docto_relacionados if defined?(@docto_relacionados)
35
+
36
+ @docto_relacionados =
37
+ @children_nodes.select do |child|
38
+ child if child.class.name == 'Cfdi40::DoctoRelacionado'
39
+ end
40
+ end
41
+
42
+ def traslados_summary
43
+ return @summary if defined?(@summary)
44
+
45
+ summary = {}
46
+ docto_relacionados.each do |docto|
47
+ docto.traslados_summary.each do |key, data|
48
+ summary[key] ||= {base: 0, importe: 0}
49
+ summary[key][:base] += data[:base]
50
+ summary[key][:importe] += data[:importe]
51
+ end
52
+ end
53
+ @summary = summary
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,73 @@
1
+ module Cfdi40
2
+ class Pagos < Node
3
+ define_namespace "pago20", "http://www.sat.gob.mx/Pagos20"
4
+ define_attribute :schema_location,
5
+ xml_attribute: 'xsi:schemaLocation',
6
+ readonly: true,
7
+ default: "http://www.sat.gob.mx/Pagos20 " \
8
+ "http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd"
9
+ define_attribute :version, xml_attribute: 'Version', readonly: true, default: '2.0'
10
+
11
+ def add_pago(attributes={})
12
+ pago = Pago.new
13
+ pago.parent_node = self
14
+ attributes.each do |key, value|
15
+ method_name = "#{key}=".to_sym
16
+ if pago.respond_to?(method_name)
17
+ pago.public_send(method_name, value)
18
+ else
19
+ raise Error, ":#{key} no se puede asignar al nodo Pago"
20
+ end
21
+ end
22
+ pago.monto = pago.monto.round(2)
23
+ pago.add_docto_relacionado
24
+ pago.add_impuestos_p
25
+ @children_nodes << pago
26
+ update_totales
27
+ true
28
+ end
29
+
30
+ def update_totales
31
+ update_totales_traslado_iva16
32
+ update_total_monto
33
+ end
34
+
35
+ def update_totales_traslado_iva16
36
+ key = ['002', 'Tasa', '0.160000']
37
+ return if traslados_summary[key].nil?
38
+
39
+ totales_node.base_iva16 = traslados_summary[key][:base]
40
+ totales_node.importe_iva16 = traslados_summary[key][:importe]
41
+ end
42
+
43
+ def update_total_monto
44
+ totales_node.monto_total = pago_nodes.map(&:monto).sum
45
+ end
46
+
47
+ def traslados_summary
48
+ @traslados_summary if defined?(@traslados_summary)
49
+
50
+ summary = {}
51
+ pago_nodes.each do |pago|
52
+ pago.traslados_summary.each do |key, data|
53
+ summary[key] ||= { base: 0, importe: 0 }
54
+ summary[key][:base] += data[:base]
55
+ summary[key][:importe] += data[:importe]
56
+ end
57
+ end
58
+ @traslados_summary = summary
59
+ end
60
+
61
+ def totales_node
62
+ return @totales_node if defined?(@totales_node)
63
+
64
+ @totales_node = Totales.new
65
+ add_child_node @totales_node
66
+ @totales_node
67
+ end
68
+
69
+ def pago_nodes
70
+ @children_nodes.select { |node| node.class.name == 'Cfdi40::Pago' }
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ module Cfdi40
2
+ class Totales < Node
3
+ define_attribute :ret_iva, xml_attribute: 'TotalRetencionesIVA'
4
+ define_attribute :ret_isr, xml_attribute: 'TotalRetencionesISR'
5
+ define_attribute :ret_ieps, xml_attribute: 'TotalRetencionesIEPS'
6
+ define_attribute :base_iva16, xml_attribute: 'TotalTrasladosBaseIVA16'
7
+ define_attribute :importe_iva16, xml_attribute: 'TotalTrasladosImpuestoIVA16'
8
+ define_attribute :base_iva8, xml_attribute: 'TotalTrasladosBaseIVA8'
9
+ define_attribute :importe_iva8, xml_attribute: 'TotalTrasladosImpuestoIVA8'
10
+ define_attribute :base_iva0, xml_attribute: 'TotalTrasladosBaseIVA0'
11
+ define_attribute :importe_iva0, xml_attribute: 'TotalTrasladosImpuestoIVA0'
12
+ define_attribute :base_iva_excento, xml_attribute: 'TotalTrasladosBaseIVAExento'
13
+ define_attribute :monto_total, xml_attribute: 'MontoTotalPagos'
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Cfdi40
2
+ class TrasladoDR < Node
3
+ define_attribute :base_dr, xml_attribute: 'BaseDR', format: :t_ImporteMXN
4
+ define_attribute :impuesto_dr, xml_attribute: 'ImpuestoDR', default: '002'
5
+ define_attribute :tipo_factor_dr, xml_attribute: 'TipoFactorDR', default: 'Tasa'
6
+ define_attribute :tasa_o_cuota_dr, xml_attribute: 'TasaOCuotaDR', default: '0.160000', format: :t_Importe
7
+ define_attribute :importe_dr, xml_attribute: 'ImporteDR', format: :t_ImporteMXN
8
+
9
+ attr_accessor :monto_pago
10
+
11
+ def calculate!
12
+ self.base_dr = (monto_pago / (1 + tasa_o_cuota_dr.to_f)).round(2)
13
+ self.importe_dr = (monto_pago - base_dr).round(2)
14
+ end
15
+ end
16
+ end
17
+
18
+
@@ -0,0 +1,9 @@
1
+ module Cfdi40
2
+ class TrasladoP < Node
3
+ define_attribute :base_p, xml_attribute: 'BaseP', format: :t_ImporteMXN
4
+ define_attribute :impuesto_p, xml_attribute: 'ImpuestoP', default: '002'
5
+ define_attribute :tipo_factor_p, xml_attribute: 'TipoFactorP', default: 'Tasa'
6
+ define_attribute :tasa_o_cuota_p, xml_attribute: 'TasaOCuotaP', default: '0.160000', format: :t_Importe
7
+ define_attribute :importe_p, xml_attribute: 'ImporteP', format: :t_ImporteMXN
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module Cfdi40
2
+ class TrasladosDR < Node
3
+ end
4
+ end
5
+
@@ -0,0 +1,16 @@
1
+ module Cfdi40
2
+ class TrasladosP < Node
3
+ def add_traslado_p_nodes
4
+ pago = parent_node.parent_node
5
+ pago.traslados_summary.each do |key, data|
6
+ traslado_p = TrasladoP.new
7
+ traslado_p.impuesto_p = key[0]
8
+ traslado_p.tipo_factor_p = key[1]
9
+ traslado_p.tasa_o_cuota_p = key[2]
10
+ traslado_p.base_p = data[:base]
11
+ traslado_p.importe_p = data[:importe]
12
+ add_child_node traslado_p
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cfdi40
4
- VERSION = "0.0.5"
4
+ VERSION = "0.0.7"
5
5
  end
data/lib/cfdi40.rb CHANGED
@@ -17,6 +17,17 @@ require_relative "cfdi40/traslados"
17
17
  require_relative "cfdi40/traslado"
18
18
  require_relative "cfdi40/complemento_concepto"
19
19
  require_relative "cfdi40/inst_educativas"
20
+ require_relative "cfdi40/complemento"
21
+ require_relative "cfdi40/pagos"
22
+ require_relative "cfdi40/pago"
23
+ require_relative "cfdi40/docto_relacionado"
24
+ require_relative "cfdi40/impuestos_dr"
25
+ require_relative "cfdi40/traslados_dr"
26
+ require_relative "cfdi40/traslado_dr"
27
+ require_relative "cfdi40/impuestos_p"
28
+ require_relative "cfdi40/traslados_p"
29
+ require_relative "cfdi40/traslado_p"
30
+ require_relative "cfdi40/totales.rb"
20
31
 
21
32
  # Leading module and entry point for all features and classes
22
33
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfdi40
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Israel Benítez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-08 00:00:00.000000000 Z
11
+ date: 2023-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -43,19 +43,30 @@ files:
43
43
  - Rakefile
44
44
  - cfdi40.gemspec
45
45
  - lib/cfdi40.rb
46
+ - lib/cfdi40/complemento.rb
46
47
  - lib/cfdi40/complemento_concepto.rb
47
48
  - lib/cfdi40/comprobante.rb
48
49
  - lib/cfdi40/concepto.rb
49
50
  - lib/cfdi40/conceptos.rb
51
+ - lib/cfdi40/docto_relacionado.rb
50
52
  - lib/cfdi40/emisor.rb
51
53
  - lib/cfdi40/impuestos.rb
54
+ - lib/cfdi40/impuestos_dr.rb
55
+ - lib/cfdi40/impuestos_p.rb
52
56
  - lib/cfdi40/inst_educativas.rb
53
57
  - lib/cfdi40/node.rb
58
+ - lib/cfdi40/pago.rb
59
+ - lib/cfdi40/pagos.rb
54
60
  - lib/cfdi40/receptor.rb
55
61
  - lib/cfdi40/sat_csd.rb
56
62
  - lib/cfdi40/schema_validator.rb
63
+ - lib/cfdi40/totales.rb
57
64
  - lib/cfdi40/traslado.rb
65
+ - lib/cfdi40/traslado_dr.rb
66
+ - lib/cfdi40/traslado_p.rb
58
67
  - lib/cfdi40/traslados.rb
68
+ - lib/cfdi40/traslados_dr.rb
69
+ - lib/cfdi40/traslados_p.rb
59
70
  - lib/cfdi40/version.rb
60
71
  - lib/xsd/Pagos20.xsd
61
72
  - lib/xsd/README.md