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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4048e33cf4c2c3afc08006ea141c96431a4d407db2c15c62f16af9ec443e261
4
- data.tar.gz: 3d80d6b98b71753869048cf14eaa8fc8b7a6ead278b9d313ceebb1ea517cf701
3
+ metadata.gz: 02bfb08fdad25e520aaa46dbc50ff4ac1ce9d2f04cbf8f87d3d66b7e83d6a0d2
4
+ data.tar.gz: f186c0c05ad7db2ff0e42a7f0acc013d8cf6e596d548a314bf1173d57432b08d
5
5
  SHA512:
6
- metadata.gz: 266289fcbc480d8a0006b4847c72c18edd52deb6c343304a875cc1fc8335b90d5f16385fdeac70d94179e9efcdba9c4baef77efc1c200e107616f235f44ba2f1
7
- data.tar.gz: 7ea20d0a5949da3af27660205edd3c25086d2f0afe3873031018b795fcb0f3da97bc57e6965b1eb4ebfbcc3cae02c09bd00a76e03a12505ccdde54e41669f302
6
+ metadata.gz: fcc1c451322955e8a2492b8de10bc2c7e56033053fa796ef94a634ce4dca1c01e8426de64ecad99e88951b26fb3b3ece559fe4cc2f1f8340f5fa42425e207fde
7
+ data.tar.gz: cfa8a07b008ae446ad7f025ac4a72b8d8e95cad0f418c0b579c1b1c2f59a5c1b7d4fb985dd29d6959ee518f5c2134bda99e873fc38bc315fd22136cebf57d88d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfdi40 (0.4.6)
4
+ cfdi40 (0.4.8)
5
5
  nokogiri (>= 1.10.10)
6
6
 
7
7
  GEM
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 = 'G03'
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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cfdi40
4
+ class CfdiRelacionado < Node
5
+ define_attribute :uuid, xml_attribute: "UUID"
6
+ end
7
+ end
@@ -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
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cfdi40
4
- VERSION = "0.4.6"
4
+ VERSION = "0.4.8"
5
5
  end
@@ -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.6
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-03-12 00:00:00.000000000 Z
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