cfdi40 0.0.4 → 0.0.5
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/CHANGELOG.md +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/README_es-MX.md +18 -1
- data/lib/cfdi40/comprobante.rb +36 -12
- data/lib/cfdi40/concepto.rb +22 -24
- data/lib/cfdi40/impuestos.rb +2 -2
- data/lib/cfdi40/traslado.rb +2 -2
- data/lib/cfdi40/version.rb +1 -1
- data/lib/xsd/Pagos20.xsd +539 -0
- data/lib/xsd/TimbreFiscalDigitalv11.xsd +83 -0
- data/lib/xsd/catPagos.xsd +9 -0
- data/lib/xsd/cfdv40.xsd +2 -0
- data/lib/xslt/ComercioExterior11.xslt +181 -0
- data/lib/xslt/cadenaoriginal_TFD_1_1.xslt +47 -0
- data/lib/xslt/ecc12.xslt +99 -0
- data/lib/xslt/ine11.xslt +51 -30
- data/lib/xslt/ventavehiculos11.xslt +53 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d48bd150dec201d3a2b0812d49080313c5e4aec6efd836e5606e9e2edabd822f
|
4
|
+
data.tar.gz: 3f437736ebc91684c7652f217f64a0e04c9e8b18519a18a02397ab4f95ca8db9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4491ff366eeb72c4c6d1792227750e5c3f333d6df52f7d974c05eff8d4d94f30a44e98dfefaf03b1aaa41a8d1407e2765a3ef026617faa071fb86049cbbec9f9
|
7
|
+
data.tar.gz: 77c1ee1687c4b13af13768afa7a5b3ee0c7ab2071a4a3ddbf45d3bedcf4a18bb2a8e56b07bdf1762d6e833c052cf77c1b3272b04a75cb3f28d2c0494b76d66af
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
data/README_es-MX.md
CHANGED
@@ -14,7 +14,7 @@ que esta herramienta:
|
|
14
14
|
información esencial para la elaboración del CFDi.
|
15
15
|
* Realice los cálculos complementarios como impuestos,
|
16
16
|
totales, etcétera.
|
17
|
-
* Valide el CFDi contra los
|
17
|
+
* Valide el CFDi contra los XSD
|
18
18
|
* Selle el CFDi.
|
19
19
|
|
20
20
|
# Uso
|
@@ -55,6 +55,23 @@ que esta herramienta:
|
|
55
55
|
|
56
56
|
# Cambios
|
57
57
|
|
58
|
+
# 0.0.5
|
59
|
+
|
60
|
+
* IVA tasa 0 e IVA excento. Los conceptos con iva tasa 0 deben llevar el
|
61
|
+
nodo de traslados de impuestos. Los conceptos excentos de iva no
|
62
|
+
llevan el nodo de traslado. Al agregar el concepto usar `nil` para el
|
63
|
+
IVA cuando sea excento.
|
64
|
+
* Nuevo cálculo de impuestos e importes. El PAC solo acepta 2 decimales
|
65
|
+
en los nodos de traslado. Esto puede generar discrepancias al sumar
|
66
|
+
los conceptos si no se maneja el mismo número de decimales. Solamente
|
67
|
+
el valor unitario se manejará con 6 decimales.
|
68
|
+
|
69
|
+
# 0.0.4
|
70
|
+
|
71
|
+
* Atributos 'Total' y 'Subtotal' van con 2 decimales. Aunque el anexo 20
|
72
|
+
indica que el tipo es `t_Importe` (6 decimales) el PAC acepta solo 2
|
73
|
+
decimales si el CFDi está en pesos mexicanos.
|
74
|
+
|
58
75
|
# 0.0.3
|
59
76
|
|
60
77
|
* Lee RFC en certificados de personas morales. Los certificados de
|
data/lib/cfdi40/comprobante.rb
CHANGED
@@ -60,7 +60,7 @@ module Cfdi40
|
|
60
60
|
@sat_csd ||= SatCsd.new
|
61
61
|
@sat_csd.cert_der = cert_data
|
62
62
|
emisor.rfc = @sat_csd.rfc
|
63
|
-
emisor.nombre
|
63
|
+
emisor.nombre ||= @sat_csd.name
|
64
64
|
@no_certificado = @sat_csd.no_certificado
|
65
65
|
@certificado = @sat_csd.cert64
|
66
66
|
true
|
@@ -82,18 +82,42 @@ module Cfdi40
|
|
82
82
|
@docxml = nil
|
83
83
|
end
|
84
84
|
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
# clave_unidad
|
89
|
-
#
|
90
|
-
# descripcion
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
85
|
+
# ## Required attributes
|
86
|
+
#
|
87
|
+
# +clave_prod_serv+:: From SAT catalogue
|
88
|
+
# +clave_unidad+:: From SAT catalogue
|
89
|
+
# +cantidad+:: Must be greather than 0
|
90
|
+
# +descripcion+:: Product or service description
|
91
|
+
#
|
92
|
+
# ### Price and Taxes attributes
|
93
|
+
#
|
94
|
+
# +tasa_iva+:: Decimal between 0 and 1. Nil means exempt. Default value is 0.16
|
95
|
+
# +tasa_ieps+:: Decimal between 0 and 1. Nil means exempt. Default value is null
|
96
|
+
# +precio_bruto+:: Price before apply taxes or gross price.
|
97
|
+
# All quantities are calculated based on this price and taxes rate.
|
98
|
+
# +precio_neto+:: Precio after taxes or net price. All quantities are calculated from this prices.
|
99
|
+
# When both, +precio_neto+ and +precio_bruto+ exist, +precio_neto+ is used
|
100
|
+
#
|
101
|
+
# The most common usage requires only the net price (+precio_neto+).
|
102
|
+
#
|
103
|
+
# ## Optional attributes:
|
104
|
+
# +no_identificacion+::
|
105
|
+
# +unidad+::
|
106
|
+
# +descuento+:: PENDING
|
107
|
+
#
|
108
|
+
# ## Special attributes
|
109
|
+
#
|
110
|
+
# ### IEDU attributes
|
111
|
+
#
|
112
|
+
# IEDU node (path: cfdi:Comprobante/cfdi:Conceptos/cfdi:Concepto/cfdi:ComplementoConcepto/iedu:instEducativas) is
|
113
|
+
# generated when one of +iedu_nombre_alumno+, +iedu_curp+, +iedu_nivel_educativo+ exist.
|
114
|
+
#
|
115
|
+
# +iedu_nombre_alumno+::
|
116
|
+
# +iedu_curp+::
|
117
|
+
# +iedu_nivel_educativo+::
|
118
|
+
# +iedu_aut_rvoe+::
|
119
|
+
# +iedu_rfc_pago+::
|
95
120
|
#
|
96
|
-
# TODO: Document accepted attributes and its use
|
97
121
|
def add_concepto(attributes = {})
|
98
122
|
concepto = Concepto.new
|
99
123
|
concepto.parent_node = @conceptos
|
data/lib/cfdi40/concepto.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Represents node 'concepto'
|
2
2
|
#
|
3
|
-
# * Attribute +Importe+ represente gross amount. Gross amount
|
3
|
+
# * Attribute +Importe+ represente gross amount. Gross amount is before taxes and the result of multiply
|
4
4
|
# +ValorUnitario+ by +Cantidad+
|
5
5
|
#
|
6
6
|
module Cfdi40
|
@@ -24,7 +24,7 @@ module Cfdi40
|
|
24
24
|
|
25
25
|
def initialize
|
26
26
|
@tasa_iva = 0.16
|
27
|
-
@tasa_ieps =
|
27
|
+
@tasa_ieps = nil
|
28
28
|
super
|
29
29
|
end
|
30
30
|
|
@@ -33,6 +33,7 @@ module Cfdi40
|
|
33
33
|
def calculate!
|
34
34
|
set_defaults
|
35
35
|
assign_objeto_imp
|
36
|
+
# TODO: accept discount
|
36
37
|
if defined?(@precio_neto) && !@precio_neto.nil?
|
37
38
|
calculate_from_net_price
|
38
39
|
elsif defined?(@precio_bruto) && !@precio_bruto.nil?
|
@@ -61,33 +62,26 @@ module Cfdi40
|
|
61
62
|
|
62
63
|
def calculate_from_net_price
|
63
64
|
set_defaults
|
64
|
-
@
|
65
|
-
|
65
|
+
@precio_neto = @precio_neto.round(2)
|
66
|
+
@precio_bruto = (@precio_neto / ((1 + tasa_iva.to_f) * (1 + tasa_ieps.to_f))).round(6)
|
67
|
+
calculate_taxes
|
66
68
|
update_xml_attributes
|
67
69
|
end
|
68
70
|
|
69
|
-
def breakdown_taxes
|
70
|
-
@base_iva = @importe_neto / (1 + tasa_iva)
|
71
|
-
@iva = @importe_neto - @base_iva
|
72
|
-
@base_ieps = @base_iva / (1 + tasa_ieps)
|
73
|
-
@ieps = @base_iva - @base_ieps
|
74
|
-
@importe_bruto = @base_ieps
|
75
|
-
@precio_bruto = @importe_bruto / @cantidad
|
76
|
-
end
|
77
|
-
|
78
71
|
def calculate_from_gross_price
|
79
|
-
@
|
80
|
-
|
72
|
+
@precio_bruto = @precio_bruto.round(6)
|
73
|
+
calculate_taxes
|
74
|
+
@precio_neto = (@importe_neto / cantidad).round(2)
|
81
75
|
update_xml_attributes
|
82
76
|
end
|
83
77
|
|
84
|
-
def
|
85
|
-
@base_ieps = @
|
86
|
-
@ieps = @base_ieps * tasa_ieps
|
87
|
-
@base_iva = @base_ieps + @ieps
|
88
|
-
@iva = @base_iva * tasa_iva
|
89
|
-
@
|
90
|
-
@
|
78
|
+
def calculate_taxes
|
79
|
+
@base_ieps = (@precio_bruto * cantidad).round(2)
|
80
|
+
@ieps = (@base_ieps * tasa_ieps.to_f).round(2)
|
81
|
+
@base_iva = (@base_ieps + @ieps).round(2)
|
82
|
+
@iva = (@base_iva * tasa_iva.to_f).round(2)
|
83
|
+
@importe_bruto = @base_ieps
|
84
|
+
@importe_neto = (@base_iva + @iva).round(2)
|
91
85
|
end
|
92
86
|
|
93
87
|
def update_xml_attributes
|
@@ -96,7 +90,7 @@ module Cfdi40
|
|
96
90
|
end
|
97
91
|
|
98
92
|
def add_info_to_traslado_iva
|
99
|
-
return
|
93
|
+
return if @tasa_iva.nil?
|
100
94
|
|
101
95
|
traslado_iva_node.importe = @iva
|
102
96
|
traslado_iva_node.base = @base_iva
|
@@ -104,9 +98,13 @@ module Cfdi40
|
|
104
98
|
end
|
105
99
|
|
106
100
|
def assign_objeto_imp
|
101
|
+
#01 No objeto de impuesto.
|
102
|
+
#02 Sí objeto de impuesto.
|
103
|
+
#03 Sí objeto del impuesto y no obligado al desglose.
|
104
|
+
|
107
105
|
return if objeto_impuestos == '03'
|
108
106
|
|
109
|
-
self.objeto_impuestos = (
|
107
|
+
self.objeto_impuestos = (!@tasa_iva.nil? || !@tasa_ieps.nil? ? '02' : '01')
|
110
108
|
end
|
111
109
|
|
112
110
|
def impuestos_node
|
data/lib/cfdi40/impuestos.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cfdi40
|
2
2
|
class Impuestos < Node
|
3
|
-
define_attribute :total_impuestos_retenidos, xml_attribute: 'TotalImpuestosRetenidos', format: :
|
4
|
-
define_attribute :total_impuestos_trasladados, xml_attribute: 'TotalImpuestosTrasladados', format: :
|
3
|
+
define_attribute :total_impuestos_retenidos, xml_attribute: 'TotalImpuestosRetenidos', format: :t_ImporteMXN
|
4
|
+
define_attribute :total_impuestos_trasladados, xml_attribute: 'TotalImpuestosTrasladados', format: :t_ImporteMXN
|
5
5
|
|
6
6
|
def traslados
|
7
7
|
return @traslados if defined?(@traslados)
|
data/lib/cfdi40/traslado.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Cfdi40
|
2
2
|
class Traslado < Node
|
3
|
-
define_attribute :base, xml_attribute: 'Base', format: :
|
3
|
+
define_attribute :base, xml_attribute: 'Base', format: :t_ImporteMXN
|
4
4
|
define_attribute :impuesto, xml_attribute: 'Impuesto'
|
5
5
|
define_attribute :tipo_factor, xml_attribute: 'TipoFactor', default: 'Tasa'
|
6
6
|
define_attribute :tasa_o_cuota, xml_attribute: 'TasaOCuota', format: :t_Importe
|
7
|
-
define_attribute :importe, xml_attribute: 'Importe', format: :
|
7
|
+
define_attribute :importe, xml_attribute: 'Importe', format: :t_ImporteMXN
|
8
8
|
end
|
9
9
|
end
|
data/lib/cfdi40/version.rb
CHANGED