1
1
import os
2
2
from typing import Sequence
3
3
4
+ from satcfdi .zip import zip_create , ZipData , zip_file
5
+
6
+ from satcfdi .catalogs import select , catalog_code
7
+
4
8
from satcfdi .utils import iterate
5
9
6
10
from satcfdi .create .contabilidad .AuxiliarCtas13 import AuxiliarCtas , Cuenta , DetalleAux
@@ -29,21 +33,28 @@ def filename(file):
29
33
raise ValueError (f"Unknown file type: { file .tag } " )
30
34
31
35
32
- def output_file (file , folder , fiel = None , generate_pdf = False ):
36
+ def output_file (file , folder , fiel = None , generate_pdf = False , zip_xml = False ):
33
37
if fiel :
34
38
file .sign (fiel )
35
39
36
40
output_file = os .path .join (folder , filename (file ))
37
- file .xml_write (
38
- output_file ,
39
- pretty_print = True ,
40
- xml_declaration = True
41
- )
41
+ if zip_xml :
42
+ zip_file (output_file [:- 4 ] + '.zip' , [
43
+ ZipData (
44
+ filename (file ),
45
+ file .xml_bytes (xml_declaration = True )
46
+ )
47
+ ])
48
+ else :
49
+ file .xml_write (
50
+ output_file ,
51
+ pretty_print = True ,
52
+ xml_declaration = True
53
+ )
54
+
42
55
if generate_pdf :
43
- # render.html_write(file, output_file[:-4] + ".html")
44
56
render .pdf_write (file , output_file [:- 4 ] + ".pdf" )
45
57
else :
46
- # delete file
47
58
try :
48
59
os .remove (output_file [:- 4 ] + ".pdf" )
49
60
except FileNotFoundError :
@@ -52,40 +63,6 @@ def output_file(file, folder, fiel=None, generate_pdf=False):
52
63
return output_file
53
64
54
65
55
- def calcular_saldos (cuentas , polizas ):
56
- max_level = 1
57
- for c in cuentas .values ():
58
- # c['SaldoIni'] = 0
59
- c ['Debe' ] = 0
60
- c ['Haber' ] = 0
61
- c ['SaldoFin' ] = 0
62
- max_level = max (max_level , c ['Nivel' ])
63
-
64
- for p in polizas :
65
- for t in p ["Transaccion" ]:
66
- num_cta = t ["NumCta" ]
67
- cuenta = cuentas [num_cta ]
68
- cuenta ["Debe" ] += t ["Debe" ]
69
- cuenta ["Haber" ] += t ["Haber" ]
70
-
71
- # Fill Parents
72
- for level in range (max_level , 1 , - 1 ):
73
- for k , v in cuentas .items ():
74
- if v ['Nivel' ] == level :
75
- parent = v ['SubCtaDe' ]
76
- if parent :
77
- p_cuenta = cuentas [parent ]
78
- p_cuenta ['Debe' ] += v ['Debe' ]
79
- p_cuenta ['Haber' ] += v ['Haber' ]
80
-
81
- # Fill SaldoFin
82
- for c in cuentas .values ():
83
- if c ["Natur" ] == "D" :
84
- c ["SaldoFin" ] += c ["SaldoIni" ] + c ["Debe" ] - c ["Haber" ]
85
- else :
86
- c ["SaldoFin" ] += c ["SaldoIni" ] + c ["Haber" ] - c ["Debe" ]
87
-
88
-
89
66
def generar_contabilidad (
90
67
dp : DatePeriod ,
91
68
rfc_emisor : str ,
@@ -98,8 +75,10 @@ def generar_contabilidad(
98
75
numero_tramite = None ,
99
76
folder = None ,
100
77
fiel = None ,
101
- generate_pdf = False ):
102
-
78
+ generate_pdf = False ,
79
+ zip_xml = False
80
+ ):
81
+ validate_cuentas (cuentas )
103
82
validate_polizas (polizas )
104
83
calcular_saldos (cuentas , polizas )
105
84
@@ -112,15 +91,15 @@ def generar_contabilidad(
112
91
num_tramite = numero_tramite ,
113
92
poliza = polizas
114
93
)
115
- output_file (plz , folder , fiel , generate_pdf = generate_pdf )
94
+ output_file (plz , folder , fiel , generate_pdf = generate_pdf , zip_xml = zip_xml )
116
95
117
96
cat = Catalogo (
118
97
rfc = rfc_emisor ,
119
98
mes = str (dp .month ).zfill (2 ),
120
99
anio = dp .year ,
121
100
ctas = [
122
101
Ctas (
123
- cod_agrup = v ["CodAgrup" ]. split ( "_" )[ 0 ] ,
102
+ cod_agrup = v ["CodAgrup" ],
124
103
num_cta = k ,
125
104
desc = v ["Desc" ],
126
105
nivel = v ["Nivel" ],
@@ -129,7 +108,7 @@ def generar_contabilidad(
129
108
) for k , v in cuentas .items ()
130
109
]
131
110
)
132
- cato = output_file (cat , folder , fiel )
111
+ output_file (cat , folder , fiel , zip_xml = zip_xml )
133
112
134
113
ban = Balanza (
135
114
rfc = rfc_emisor ,
@@ -142,7 +121,7 @@ def generar_contabilidad(
142
121
** v ,
143
122
} for k , v in cuentas .items () if v ["SaldoIni" ] or v ["Debe" ] or v ["Haber" ] or v ["SaldoFin" ]],
144
123
)
145
- bano = output_file (ban , folder , fiel )
124
+ output_file (ban , folder , fiel , zip_xml = zip_xml )
146
125
147
126
aux_detalles = group_aux_cuentas (polizas )
148
127
aux = AuxiliarCtas (
@@ -162,7 +141,7 @@ def generar_contabilidad(
162
141
) for k , v in cuentas .items () if k in aux_detalles
163
142
]
164
143
)
165
- output_file (aux , folder , fiel , generate_pdf = generate_pdf )
144
+ output_file (aux , folder , fiel , generate_pdf = generate_pdf , zip_xml = zip_xml )
166
145
167
146
auxf = RepAuxFol (
168
147
rfc = rfc_emisor ,
@@ -173,11 +152,11 @@ def generar_contabilidad(
173
152
num_tramite = numero_tramite ,
174
153
det_aux_fol = list (group_aux_folios (polizas ))
175
154
)
176
- output_file (auxf , folder , fiel , generate_pdf = generate_pdf )
155
+ output_file (auxf , folder , fiel , generate_pdf = generate_pdf , zip_xml = zip_xml )
177
156
178
157
imprimir_contablidad (
179
- catalogo_cuentas = cato ,
180
- balanza_comprobacion = bano ,
158
+ catalogo_cuentas = cat ,
159
+ balanza_comprobacion = ban ,
181
160
archivo_excel = os .path .join (folder , filename (ban )[:- 4 ] + ".xlsx" )
182
161
)
183
162
@@ -230,30 +209,45 @@ def group_aux_folios(polizas):
230
209
)
231
210
232
211
212
+ def validate_cuentas (cuentas ):
213
+ # validar cuentas
214
+ for k , v in cuentas .items ():
215
+ assert k
216
+ v ['_Lowest' ] = True
217
+ assert v ['Natur' ] in ['A' , 'D' ]
218
+ if v ['SubCtaDe' ]:
219
+ assert v ['SubCtaDe' ] in cuentas , f"Parent account { v ['SubCtaDe' ]} not found for { k } "
220
+ v ['Nivel' ] = cuentas [v ['SubCtaDe' ]]['Nivel' ] + 1
221
+ else :
222
+ v ['Nivel' ] = 1
223
+
224
+ v ['CodAgrup' ] = catalog_code ('Cb9f_c_CodAgrup' , v ['CodAgrup' ])
225
+ assert v ['CodAgrup' ].description , f"Unknown CodAgrup: { v ['CodAgrup' ]} "
226
+
227
+ for k , v in cuentas .items ():
228
+ if v ['SubCtaDe' ]:
229
+ cuentas [v ['SubCtaDe' ]]['_Lowest' ] = False
230
+
231
+
232
+ def sign (cta ):
233
+ if cta ['Natur' ] == 'D' :
234
+ return 1
235
+ return - 1
236
+
237
+
233
238
def validate_saldos (cuentas ):
234
- total = 0
235
239
totales = {}
236
240
for k , v in cuentas .items ():
237
- if v ['Nivel' ] == 1 :
238
- if v ['Natur' ] == 'D' :
239
- total += v ['SaldoFin' ]
240
- else :
241
- total -= v ['SaldoFin' ]
242
- else :
243
- totales .setdefault (v ['SubCtaDe' ], 0 )
244
- if v ['Natur' ] == 'D' :
245
- totales [v ['SubCtaDe' ]] += v ['SaldoFin' ]
246
- else :
247
- totales [v ['SubCtaDe' ]] -= v ['SaldoFin' ]
241
+ sub_cta = v .get ('SubCtaDe' )
242
+ totales .setdefault (sub_cta , 0 )
243
+ totales [sub_cta ] += v ['SaldoFin' ] * sign (v )
248
244
249
- assert total == 0
250
245
for k , v in totales .items ():
251
- if cuentas [ k ][ 'Natur' ] == 'D' :
252
- if v != cuentas [k ]['SaldoFin' ]:
246
+ if k :
247
+ if v != cuentas [k ]['SaldoFin' ] * sign ( cuentas [ k ]) :
253
248
raise ValueError (f"Error in { k } : { v } != { cuentas [k ]['SaldoFin' ]} " )
254
249
else :
255
- if v != - cuentas [k ]['SaldoFin' ]:
256
- raise ValueError (f"Error in { k } : { v } != { cuentas [k ]['SaldoFin' ]} " )
250
+ assert v == 0
257
251
258
252
259
253
def validate_polizas (polizas ):
@@ -263,3 +257,36 @@ def validate_polizas(polizas):
263
257
if u in num_un :
264
258
raise ValueError (f"Repeated NumUnIdenPol: { u } " )
265
259
num_un .add (u )
260
+
261
+
262
+ def calcular_saldos (cuentas , polizas ):
263
+ max_level = 1
264
+ for c in cuentas .values ():
265
+ # c['SaldoIni'] = 0
266
+ c ['Debe' ] = 0
267
+ c ['Haber' ] = 0
268
+ c ['SaldoFin' ] = 0
269
+ max_level = max (max_level , c ['Nivel' ])
270
+
271
+ for p in polizas :
272
+ for t in p ["Transaccion" ]:
273
+ num_cta = t ["NumCta" ]
274
+ cuenta = cuentas [num_cta ]
275
+ assert cuenta ["_Lowest" ], f"Account { num_cta } is not a lowest level account"
276
+ cuenta ["Debe" ] += t ["Debe" ]
277
+ cuenta ["Haber" ] += t ["Haber" ]
278
+
279
+ # Fill Parents
280
+ for level in range (max_level , 1 , - 1 ):
281
+ for k , v in cuentas .items ():
282
+ if v ['Nivel' ] == level :
283
+ parent = v ['SubCtaDe' ]
284
+ if parent :
285
+ p_cuenta = cuentas [parent ]
286
+ p_cuenta ['Debe' ] += v ['Debe' ]
287
+ p_cuenta ['Haber' ] += v ['Haber' ]
288
+
289
+ # Fill SaldoFin
290
+ for c in cuentas .values ():
291
+ s = sign (c )
292
+ c ["SaldoFin" ] += c ["SaldoIni" ] + c ["Debe" ] * s - c ["Haber" ] * s
0 commit comments