cfdi40 0.4.6 → 0.4.8
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README_es-MX.md +1 -1
- data/lib/cfdi40/cfdi_relacionado.rb +7 -0
- data/lib/cfdi40/cfdi_relacionados.rb +19 -0
- data/lib/cfdi40/comprobante.rb +38 -2
- data/lib/cfdi40/concepto_rep.rb +1 -1
- data/lib/cfdi40/node.rb +5 -0
- data/lib/cfdi40/version.rb +1 -1
- data/lib/cfdi40/xml_loader.rb +20 -0
- data/lib/cfdi40.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02bfb08fdad25e520aaa46dbc50ff4ac1ce9d2f04cbf8f87d3d66b7e83d6a0d2
|
|
4
|
+
data.tar.gz: f186c0c05ad7db2ff0e42a7f0acc013d8cf6e596d548a314bf1173d57432b08d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcc1c451322955e8a2492b8de10bc2c7e56033053fa796ef94a634ce4dca1c01e8426de64ecad99e88951b26fb3b3ece559fe4cc2f1f8340f5fa42425e207fde
|
|
7
|
+
data.tar.gz: cfa8a07b008ae446ad7f025ac4a72b8d8e95cad0f418c0b579c1b1c2f59a5c1b7d4fb985dd29d6959ee518f5c2134bda99e873fc38bc315fd22136cebf57d88d
|
data/Gemfile.lock
CHANGED
data/README_es-MX.md
CHANGED
|
@@ -39,7 +39,7 @@ Hasta ahora:
|
|
|
39
39
|
cfdi.receptor.rfc = 'XAXX010101000'
|
|
40
40
|
cfdi.receptor.domicilio_fiscal = '06000'
|
|
41
41
|
cfdi.receptor.regimen_fiscal = '616'
|
|
42
|
-
cfdi.receptor.uso_cfdi = '
|
|
42
|
+
cfdi.receptor.uso_cfdi = 'S01'
|
|
43
43
|
|
|
44
44
|
# Agrega un concepto en pesos,
|
|
45
45
|
# precio final al cliente (neto)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cfdi40
|
|
4
|
+
class CfdiRelacionados < Node
|
|
5
|
+
define_attribute :tipo_relacion, xml_attribute: "TipoRelacion"
|
|
6
|
+
|
|
7
|
+
def add_cfdi(uuid)
|
|
8
|
+
cfdi_relacionado = CfdiRelacionado.new
|
|
9
|
+
cfdi_relacionado.uuid = uuid
|
|
10
|
+
cfdi_relacionado.parent_node = self
|
|
11
|
+
@children_nodes << cfdi_relacionado
|
|
12
|
+
cfdi_relacionado
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def cfdi_relacionados
|
|
16
|
+
@children_nodes
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/cfdi40/comprobante.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Cfdi40
|
|
|
31
31
|
define_attribute :lugar_expedicion, xml_attribute: "LugarExpedicion"
|
|
32
32
|
define_attribute :confirmacion, xml_attribute: "Confirmacion"
|
|
33
33
|
|
|
34
|
-
attr_reader :emisor, :receptor, :conceptos, :private_key, :sat_csd, :errors, :cadena_original
|
|
34
|
+
attr_reader :emisor, :receptor, :conceptos, :private_key, :sat_csd, :errors, :cadena_original, :cfdi_relacionados
|
|
35
35
|
attr_writer :key_data, :key_pass, :namespace_pagos_on_root
|
|
36
36
|
attr_accessor :loaded_xml
|
|
37
37
|
|
|
@@ -47,6 +47,7 @@ module Cfdi40
|
|
|
47
47
|
@sat_csd = SatCsd.new
|
|
48
48
|
@fecha ||= Time.now
|
|
49
49
|
@children_nodes = [@emisor, @receptor, @conceptos]
|
|
50
|
+
@cfdi_relacionados = []
|
|
50
51
|
@namespace_pagos_on_root = false
|
|
51
52
|
set_defaults
|
|
52
53
|
end
|
|
@@ -162,6 +163,16 @@ module Cfdi40
|
|
|
162
163
|
concepto
|
|
163
164
|
end
|
|
164
165
|
|
|
166
|
+
# Load node 'Concepto' (rep) from a Nokogiri::XML::Element
|
|
167
|
+
def load_concepto_rep(ng_node)
|
|
168
|
+
concepto = ConceptoRep.new
|
|
169
|
+
concepto.parent_node = @conceptos
|
|
170
|
+
concepto.load_from_ng_node(ng_node)
|
|
171
|
+
concepto.precio_bruto = concepto.valor_unitario.to_f
|
|
172
|
+
@conceptos.children_nodes << concepto
|
|
173
|
+
concepto
|
|
174
|
+
end
|
|
175
|
+
|
|
165
176
|
# Load node cfdi:Comprobante/cfdi:Impuestos
|
|
166
177
|
#
|
|
167
178
|
# Normally this node is calculated but must be read from the
|
|
@@ -199,7 +210,7 @@ module Cfdi40
|
|
|
199
210
|
complemento.pagos.remove_pago(index.to_i)
|
|
200
211
|
end
|
|
201
212
|
|
|
202
|
-
# See test_adding_pago_with_n_docto_relacionados in file test/test_cfdi40_rep.rb
|
|
213
|
+
# See test_adding_pago_with_n_docto_relacionados in file test/test_cfdi40_rep.rb
|
|
203
214
|
def add_splitted_pago(attributes = {})
|
|
204
215
|
raise Error, "CFDi debe ser tipo 'P'" unless tipo_de_comprobante == "P"
|
|
205
216
|
|
|
@@ -207,6 +218,31 @@ module Cfdi40
|
|
|
207
218
|
complemento.add_splitted_pago(attributes)
|
|
208
219
|
end
|
|
209
220
|
|
|
221
|
+
def add_cfdi_relacionado(tipo_relacion, uuid)
|
|
222
|
+
cfdi_relacionados_node = CfdiRelacionados.new
|
|
223
|
+
cfdi_relacionados_node.tipo_relacion = tipo_relacion
|
|
224
|
+
cfdi_relacionados_node.parent_node = self
|
|
225
|
+
cfdi_relacionados_node.add_cfdi(uuid)
|
|
226
|
+
@children_nodes << cfdi_relacionados_node
|
|
227
|
+
@cfdi_relacionados ||= []
|
|
228
|
+
@cfdi_relacionados << cfdi_relacionados_node
|
|
229
|
+
cfdi_relacionados_node
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def cfdi_relacionados_nodes
|
|
233
|
+
@cfdi_relacionados
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def remove_cfdi_relacionado(index)
|
|
237
|
+
return if @cfdi_relacionados.empty?
|
|
238
|
+
|
|
239
|
+
nodo = @cfdi_relacionados[index.to_i]
|
|
240
|
+
return unless nodo
|
|
241
|
+
|
|
242
|
+
delete_child(nodo)
|
|
243
|
+
@cfdi_relacionados.delete_at(index.to_i)
|
|
244
|
+
end
|
|
245
|
+
|
|
210
246
|
def to_s
|
|
211
247
|
to_xml
|
|
212
248
|
end
|
data/lib/cfdi40/concepto_rep.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Cfdi40
|
|
|
10
10
|
define_element_name 'Concepto'
|
|
11
11
|
define_attribute :clave_prod_serv, xml_attribute: "ClaveProdServ", default: "84111506"
|
|
12
12
|
define_attribute :no_identificacion, xml_attribute: "NoIdentificacion"
|
|
13
|
-
define_attribute :cantidad, xml_attribute: "Cantidad", default: 1
|
|
13
|
+
define_attribute :cantidad, xml_attribute: "Cantidad", default: 1, format: :integer
|
|
14
14
|
define_attribute :clave_unidad, xml_attribute: "ClaveUnidad", default: "ACT"
|
|
15
15
|
define_attribute :unidad, xml_attribute: "Unidad"
|
|
16
16
|
define_attribute :descripcion, xml_attribute: "Descripcion", no_writer: true, default: "Pago"
|
data/lib/cfdi40/node.rb
CHANGED
|
@@ -48,6 +48,11 @@ module Cfdi40
|
|
|
48
48
|
|
|
49
49
|
def self.define_reader(accessor, format)
|
|
50
50
|
case format.to_s
|
|
51
|
+
when 'integer'
|
|
52
|
+
define_method("#{accessor}".to_sym) do
|
|
53
|
+
value = instance_variable_defined?("@#{accessor}".to_sym) ? instance_variable_get("@#{accessor}".to_sym) : 0
|
|
54
|
+
value.to_i
|
|
55
|
+
end
|
|
51
56
|
when 't_Importe', 'decimal'
|
|
52
57
|
define_method("#{accessor}".to_sym) do
|
|
53
58
|
value = instance_variable_defined?("@#{accessor}".to_sym) ? instance_variable_get("@#{accessor}".to_sym) : 0
|
data/lib/cfdi40/version.rb
CHANGED
data/lib/cfdi40/xml_loader.rb
CHANGED
|
@@ -19,6 +19,7 @@ module Cfdi40
|
|
|
19
19
|
load_impuestos
|
|
20
20
|
load_pagos
|
|
21
21
|
load_tfd
|
|
22
|
+
load_cfdi_relacionados
|
|
22
23
|
|
|
23
24
|
@cfdi.lock if readonly?
|
|
24
25
|
@cfdi.loaded_xml = xml_string
|
|
@@ -34,6 +35,8 @@ module Cfdi40
|
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def load_conceptos
|
|
38
|
+
return load_concepto_rep if @cfdi.tipo_de_comprobante == 'P'
|
|
39
|
+
|
|
37
40
|
n_concepto = 0
|
|
38
41
|
xml_doc.xpath("//cfdi:Concepto").each do |node|
|
|
39
42
|
n_concepto += 1
|
|
@@ -44,6 +47,13 @@ module Cfdi40
|
|
|
44
47
|
end
|
|
45
48
|
end
|
|
46
49
|
|
|
50
|
+
def load_concepto_rep
|
|
51
|
+
node = xml_doc.xpath("//cfdi:Concepto").first
|
|
52
|
+
return if node.nil?
|
|
53
|
+
|
|
54
|
+
@cfdi.load_concepto_rep(node)
|
|
55
|
+
end
|
|
56
|
+
|
|
47
57
|
def load_emisor
|
|
48
58
|
ng_emisor_node = xml_doc.xpath("//cfdi:Emisor").first
|
|
49
59
|
return if ng_emisor_node.nil?
|
|
@@ -79,5 +89,15 @@ module Cfdi40
|
|
|
79
89
|
|
|
80
90
|
@cfdi.load_pagos(pagos_node)
|
|
81
91
|
end
|
|
92
|
+
|
|
93
|
+
def load_cfdi_relacionados
|
|
94
|
+
xml_doc.xpath("//cfdi:CfdiRelacionados").each do |cfdi_rel_node|
|
|
95
|
+
tipo_relacion = cfdi_rel_node.attributes["TipoRelacion"].value
|
|
96
|
+
cfdi_rel_node.xpath("cfdi:CfdiRelacionado").each do |cfdi_node|
|
|
97
|
+
uuid = cfdi_node.attributes["UUID"].value
|
|
98
|
+
@cfdi.add_cfdi_relacionado(tipo_relacion, uuid)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
82
102
|
end
|
|
83
103
|
end
|
data/lib/cfdi40.rb
CHANGED
|
@@ -22,6 +22,8 @@ require_relative "cfdi40/traslado"
|
|
|
22
22
|
require_relative "cfdi40/complemento_concepto"
|
|
23
23
|
require_relative "cfdi40/inst_educativas"
|
|
24
24
|
require_relative "cfdi40/complemento"
|
|
25
|
+
require_relative "cfdi40/cfdi_relacionados"
|
|
26
|
+
require_relative "cfdi40/cfdi_relacionado"
|
|
25
27
|
require_relative "cfdi40/concepto_rep"
|
|
26
28
|
require_relative "cfdi40/pagos"
|
|
27
29
|
require_relative "cfdi40/pago"
|
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.4.
|
|
4
|
+
version: 0.4.8
|
|
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: 2026-
|
|
11
|
+
date: 2026-04-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|
|
@@ -43,6 +43,8 @@ files:
|
|
|
43
43
|
- Rakefile
|
|
44
44
|
- cfdi40.gemspec
|
|
45
45
|
- lib/cfdi40.rb
|
|
46
|
+
- lib/cfdi40/cfdi_relacionado.rb
|
|
47
|
+
- lib/cfdi40/cfdi_relacionados.rb
|
|
46
48
|
- lib/cfdi40/complemento.rb
|
|
47
49
|
- lib/cfdi40/complemento_concepto.rb
|
|
48
50
|
- lib/cfdi40/comprobante.rb
|