cfdi40 0.4.1 → 0.4.3

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: 0640bebb04d18652cf33f6dbd3f21a1628bb0df9602f9c4644d89a52da9a8604
4
- data.tar.gz: ca5d8c18c35dc547f7321089c6e932bea09a8304bc02d7604ee1b042de7440f0
3
+ metadata.gz: 463e9e9afbe82401d3664da4e110e8c3be599db170884715b0b2a43762aad5b8
4
+ data.tar.gz: c688efebca0b62e00c85d0edc2d24be6d3b5add127aa8ee1f9217dd9234be17d
5
5
  SHA512:
6
- metadata.gz: 6bdf05c00a3161967b2c053896a3d8575a2d9a0c519980fd3b22e28ba33751cc1a312f8d8944dc34a2183012e3f58468704657c904247691d2bb2ff123f3723d
7
- data.tar.gz: 26e267b91dec8b0ebcd41cf7c9fc09951bcbda73610a97375b9536ef605e2c0e8c70d52e010257aefe6260a696f037f2365092c240bd71823f28d57b59c44c12
6
+ metadata.gz: aac1fa7a86a1a8fcffe9b435b718f3ce665777da9a27f747e2a170d4d28b675b37e7e9656d2a522558926674dcaaafc08776448ad6652be5f3ab678d58d83d50
7
+ data.tar.gz: abedeb3fad410bd0e338b91279ceec3652b4dbf182acd884da53c8fdeee88e1259e698e798b3c264d430ea315dcfd8d184d13a02965494658350794cd191ddba
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfdi40 (0.4.1)
4
+ cfdi40 (0.4.3)
5
5
  nokogiri (>= 1.10.10)
6
6
 
7
7
  GEM
@@ -8,6 +8,11 @@ module Cfdi40
8
8
  pagos.add_pago(attributes)
9
9
  end
10
10
 
11
+ def add_splitted_pago(attributes = {})
12
+ pagos.totales_node
13
+ pagos.add_splitted_pago(attributes)
14
+ end
15
+
11
16
  def pago_nodes
12
17
  return [] unless defined?(@pagos)
13
18
 
@@ -23,6 +28,19 @@ module Cfdi40
23
28
  @pagos
24
29
  end
25
30
 
31
+ def load_pagos(pagos_node)
32
+ @pagos = Cfdi40::Pagos.new
33
+ @pagos.load_from_ng_node(pagos_node)
34
+ @pagos.parent_node = self
35
+ pagos_node.xpath("//pago20:Pago", Cfdi40::Pagos::NG_NAMESPACE).each do |pago_node|
36
+ @pagos.load_pago(pago_node)
37
+ end
38
+ totales_node = pagos_node.xpath("//pago20:Totales", Cfdi40::Pagos::NG_NAMESPACE).first
39
+ @pagos.load_totales(totales_node) unless totales_node.nil?
40
+ @children_nodes << @pagos
41
+ @pagos
42
+ end
43
+
26
44
  def timbre
27
45
  @children_nodes.select { |children| children.is_a?(Cfdi40::Timbre) }.first
28
46
  end
@@ -198,6 +198,14 @@ module Cfdi40
198
198
  complemento.pagos.remove_pago(index.to_i)
199
199
  end
200
200
 
201
+ # See test_adding_pago_with_n_docto_relacionados in file test/test_cfdi40_rep.rb
202
+ def add_splitted_pago(attributes = {})
203
+ raise Error, "CFDi debe ser tipo 'P'" unless tipo_de_comprobante == "P"
204
+
205
+ add_node_concepto_actividad_pago
206
+ complemento.add_splitted_pago(attributes)
207
+ end
208
+
201
209
  def to_s
202
210
  to_xml
203
211
  end
@@ -282,6 +290,10 @@ module Cfdi40
282
290
  timbre
283
291
  end
284
292
 
293
+ def load_pagos(pagos_node)
294
+ complemento.load_pagos(pagos_node)
295
+ end
296
+
285
297
  def timbre
286
298
  return nil unless defined?(@complemento)
287
299
 
@@ -64,5 +64,15 @@ module Cfdi40
64
64
  @children_nodes << @impuestos_dr
65
65
  @impuestos_dr
66
66
  end
67
+
68
+ def load_impuestos_dr(impuestos_dr_node)
69
+ @impuestos_dr = ImpuestosDR.new
70
+ @impuestos_dr.load_from_ng_node(impuestos_dr_node)
71
+ @impuestos_dr.parent_node = self
72
+ @children_nodes << @impuestos_dr
73
+ tr_dr_node = impuestos_dr_node.xpath("//pago20:TrasladosDR", Cfdi40::Pagos::NG_NAMESPACE).first
74
+ @impuestos_dr.load_traslados_dr(tr_dr_node) unless tr_dr_node.nil?
75
+ @impuestos_dr
76
+ end
67
77
  end
68
78
  end
@@ -10,5 +10,16 @@ module Cfdi40
10
10
  @children_nodes << @traslados_dr
11
11
  @traslados_dr
12
12
  end
13
+
14
+ def load_traslados_dr(traslados_dr_node)
15
+ @traslados_dr = TrasladosDR.new
16
+ @traslados_dr.load_from_ng_node(traslados_dr_node)
17
+ @traslados_dr.parent_node = self
18
+ @children_nodes << @traslados_dr
19
+ traslados_dr_node.xpath("//pago20:TrasladoDR", Cfdi40::Pagos::NG_NAMESPACE).each do |tr_dr_node|
20
+ @traslados_dr.load_traslado_dr(tr_dr_node)
21
+ end
22
+ @traslados_dr
23
+ end
13
24
  end
14
25
  end
data/lib/cfdi40/node.rb CHANGED
@@ -277,7 +277,5 @@ module Cfdi40
277
277
 
278
278
  parent_node&.clean_cached_xml
279
279
  end
280
-
281
-
282
280
  end
283
281
  end
data/lib/cfdi40/pago.rb CHANGED
@@ -14,15 +14,15 @@ module Cfdi40
14
14
  # Generate docto_relacionado node
15
15
  # Data for dcto_relacionado node is obtained from de accessors
16
16
  # uuid, serie, folio
17
- def add_docto_relacionado
17
+ def add_docto_relacionado(attributes = {})
18
18
  docto_relacionado = DoctoRelacionado.new
19
19
  docto_relacionado.parent_node = self
20
- docto_relacionado.id_documento = uuid
21
- docto_relacionado.serie = serie
22
- docto_relacionado.folio = folio
23
- docto_relacionado.num_parcialidad = num_parcialidad
24
- docto_relacionado.imp_saldo_ant = importe_saldo_anterior.round(2)
25
- docto_relacionado.imp_pagado = monto
20
+ docto_relacionado.id_documento = attributes[:uuid]
21
+ docto_relacionado.serie = attributes[:serie]
22
+ docto_relacionado.folio = attributes[:folio]
23
+ docto_relacionado.num_parcialidad = attributes[:num_parcialidad]
24
+ docto_relacionado.imp_saldo_ant = attributes[:importe_saldo_anterior].round(2)
25
+ docto_relacionado.imp_pagado = attributes[:imp_pagado]
26
26
  docto_relacionado.calculate!
27
27
  @children_nodes << docto_relacionado
28
28
  end
@@ -55,5 +55,15 @@ module Cfdi40
55
55
  end
56
56
  @summary = summary
57
57
  end
58
+
59
+ def load_dr(dr_node)
60
+ dr = DoctoRelacionado.new
61
+ dr.load_from_ng_node(dr_node)
62
+ dr.parent_node = self
63
+ @children_nodes << dr
64
+ imp_dr_node = dr_node.xpath("//pago20:ImpuestosDR", Cfdi40::Pagos::NG_NAMESPACE).first
65
+ dr.load_impuestos_dr(imp_dr_node) unless imp_dr_node.nil?
66
+ dr
67
+ end
58
68
  end
59
69
  end
data/lib/cfdi40/pagos.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Cfdi40
4
4
  class Pagos < Node
5
+ NG_NAMESPACE = { "pago20" => "http://www.sat.gob.mx/Pagos20" }
5
6
  define_namespace "pago20", "http://www.sat.gob.mx/Pagos20"
6
7
  define_attribute :schema_location,
7
8
  xml_attribute: "xsi:schemaLocation",
@@ -13,18 +14,41 @@ module Cfdi40
13
14
  def add_pago(attributes = {})
14
15
  pago = Pago.new
15
16
  pago.parent_node = self
17
+ attributes_doc_rel = { imp_pagado: attributes[:monto] }
18
+ doc_rel_keys = [:uuid, :serie, :folio, :num_parcialidad, :importe_saldo_anterior, :objeto_impuestos]
19
+ attributes.each do |key, value|
20
+ if doc_rel_keys.include?(key)
21
+ attributes_doc_rel[key] = value
22
+ else
23
+ method_name = "#{key}=".to_sym
24
+ raise Error, ":#{key} no se puede asignar al nodo Pago" unless pago.respond_to?(method_name)
25
+
26
+ pago.public_send(method_name, value)
27
+ end
28
+ end
29
+ pago.monto = pago.monto.round(2)
30
+ pago.add_docto_relacionado(attributes_doc_rel)
31
+ pago.add_impuestos_p
32
+ @children_nodes << pago
33
+ update_totales
34
+ true
35
+ end
36
+
37
+ def add_splitted_pago(attributes = {})
38
+ pago = Pago.new
39
+ pago.parent_node = self
40
+ docs = attributes.delete(:docs)
16
41
  attributes.each do |key, value|
17
42
  method_name = "#{key}=".to_sym
18
43
  raise Error, ":#{key} no se puede asignar al nodo Pago" unless pago.respond_to?(method_name)
19
44
 
20
45
  pago.public_send(method_name, value)
21
46
  end
22
- pago.monto = pago.monto.round(2)
23
- pago.add_docto_relacionado
47
+ docs.each { |doc_attributes| pago.add_docto_relacionado(doc_attributes) }
48
+ pago.monto = docs.map { |doc_attributes| doc_attributes[:imp_pagado].to_f }.sum.round(2)
24
49
  pago.add_impuestos_p
25
50
  @children_nodes << pago
26
51
  update_totales
27
- true
28
52
  end
29
53
 
30
54
  def remove_pago(index)
@@ -75,5 +99,24 @@ module Cfdi40
75
99
  def pago_nodes
76
100
  @children_nodes.select { |node| node.instance_of?(::Cfdi40::Pago) }
77
101
  end
102
+
103
+ def load_pago(pago_node)
104
+ pago = Pago.new
105
+ pago.load_from_ng_node(pago_node)
106
+ pago.parent_node = self
107
+ @children_nodes << pago
108
+ pago_node.xpath("//pago20:DoctoRelacionado", { "pago20" => "http://www.sat.gob.mx/Pagos20" }).each do |dr_node|
109
+ pago.load_dr(dr_node)
110
+ end
111
+ pago
112
+ end
113
+
114
+ def load_totales(totales_node)
115
+ cp_totales = CpTotales.new
116
+ cp_totales.load_from_ng_node(totales_node)
117
+ cp_totales.parent_node = self
118
+ @children_nodes << cp_totales
119
+ cp_totales
120
+ end
78
121
  end
79
122
  end
@@ -2,5 +2,12 @@
2
2
 
3
3
  module Cfdi40
4
4
  class TrasladosDR < Node
5
+ def load_traslado_dr(tr_dr_node)
6
+ tr_dr = TrasladoDR.new
7
+ tr_dr.load_from_ng_node(tr_dr_node)
8
+ tr_dr.parent_node = self
9
+ @children_nodes << tr_dr
10
+ tr_dr
11
+ end
5
12
  end
6
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cfdi40
4
- VERSION = "0.4.1"
4
+ VERSION = "0.4.3"
5
5
  end
@@ -17,6 +17,7 @@ module Cfdi40
17
17
  load_receptor
18
18
  load_conceptos
19
19
  load_impuestos
20
+ load_pagos
20
21
  load_tfd
21
22
 
22
23
  @cfdi.lock if readonly?
@@ -71,5 +72,12 @@ module Cfdi40
71
72
 
72
73
  @cfdi.load_tfd(tfd_node)
73
74
  end
75
+
76
+ def load_pagos
77
+ pagos_node = xml_doc.xpath("//pago20:Pagos", Cfdi40::Pagos::NG_NAMESPACE).first
78
+ return if pagos_node.nil?
79
+
80
+ @cfdi.load_pagos(pagos_node)
81
+ end
74
82
  end
75
83
  end
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.1
4
+ version: 0.4.3
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: 2025-12-03 00:00:00.000000000 Z
11
+ date: 2025-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri