1use serde::Serialize;
2
3#[derive(Debug, Clone, Serialize)]
4pub struct Comprobante {
5 pub version: String,
6 pub serie: Option<String>,
7 pub folio: Option<String>,
8 pub fecha: String,
9 pub sello: String,
10 pub no_certificado: String,
11 pub certificado: String,
12 pub forma_pago: Option<String>,
13 pub condiciones_de_pago: Option<String>,
14 pub sub_total: String,
15 pub descuento: Option<String>,
16 pub moneda: String,
17 pub tipo_cambio: Option<String>,
18 pub total: String,
19 pub tipo_de_comprobante: String,
20 pub metodo_pago: Option<String>,
21 pub lugar_expedicion: String,
22 pub exportacion: Option<String>,
23 pub emisor: Emisor,
24 pub receptor: Receptor,
25 pub conceptos: Vec<Concepto>,
26 pub impuestos: Option<Impuestos>,
27 pub complemento: Option<Complemento>,
28}
29
30#[derive(Debug, Clone, Serialize)]
31pub struct Emisor {
32 pub rfc: String,
33 pub nombre: Option<String>,
34 pub regimen_fiscal: String,
35}
36
37#[derive(Debug, Clone, Serialize)]
38pub struct Receptor {
39 pub rfc: String,
40 pub nombre: Option<String>,
41 pub uso_cfdi: String,
42 pub domicilio_fiscal_receptor: Option<String>,
43 pub regimen_fiscal_receptor: Option<String>,
44}
45
46#[derive(Debug, Clone, Serialize)]
47pub struct Concepto {
48 pub clave_prod_serv: String,
49 pub cantidad: String,
50 pub clave_unidad: String,
51 pub unidad: Option<String>,
52 pub descripcion: String,
53 pub valor_unitario: String,
54 pub importe: String,
55 pub descuento: Option<String>,
56 pub objeto_imp: Option<String>,
57 pub impuestos: Option<ConceptoImpuestos>,
58}
59
60#[derive(Debug, Clone, Serialize)]
61pub struct ConceptoImpuestos {
62 pub traslados: Vec<Traslado>,
63 pub retenciones: Vec<Retencion>,
64}
65
66#[derive(Debug, Clone, Serialize)]
67pub struct Traslado {
68 pub base: String,
69 pub impuesto: String,
70 pub tipo_factor: String,
71 pub tasa_o_cuota: Option<String>,
72 pub importe: Option<String>,
73}
74
75#[derive(Debug, Clone, Serialize)]
76pub struct Retencion {
77 pub base: Option<String>,
78 pub impuesto: String,
79 pub tipo_factor: Option<String>,
80 pub tasa_o_cuota: Option<String>,
81 pub importe: String,
82}
83
84#[derive(Debug, Clone, Serialize)]
85pub struct Impuestos {
86 pub total_impuestos_trasladados: Option<String>,
87 pub total_impuestos_retenidos: Option<String>,
88 pub traslados: Vec<Traslado>,
89 pub retenciones: Vec<Retencion>,
90}
91
92#[derive(Debug, Clone, Serialize)]
93pub struct Complemento {
94 pub timbre_fiscal: Option<TimbreFiscalDigital>,
95}
96
97#[derive(Debug, Clone, Serialize)]
98pub struct TimbreFiscalDigital {
99 pub uuid: String,
100 pub fecha_timbrado: String,
101 pub rfc_prov_certif: Option<String>,
102 pub sello_cfd: String,
103 pub no_certificado_sat: String,
104 pub sello_sat: String,
105}
106
107impl Comprobante {
108 pub fn uuid(&self) -> Option<&str> {
109 self.complemento
110 .as_ref()
111 .and_then(|c| c.timbre_fiscal.as_ref())
112 .map(|t| t.uuid.as_str())
113 }
114
115 pub fn tipo_comprobante_str(&self) -> &str {
116 match self.tipo_de_comprobante.as_str() {
117 "I" => "Ingreso",
118 "E" => "Egreso",
119 "T" => "Traslado",
120 "P" => "Pago",
121 "N" => "Nomina",
122 other => other,
123 }
124 }
125}