Skip to content

Commit

Permalink
Update Contabilidad
Browse files Browse the repository at this point in the history
  • Loading branch information
satcfdi committed Apr 11, 2024
1 parent 476fed7 commit db1e20c
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 128 deletions.
165 changes: 96 additions & 69 deletions satcfdi/accounting/contabilidad.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import os
from typing import Sequence

from satcfdi.zip import zip_create, ZipData, zip_file

from satcfdi.catalogs import select, catalog_code

from satcfdi.utils import iterate

from satcfdi.create.contabilidad.AuxiliarCtas13 import AuxiliarCtas, Cuenta, DetalleAux
Expand Down Expand Up @@ -29,21 +33,28 @@ def filename(file):
raise ValueError(f"Unknown file type: {file.tag}")


def output_file(file, folder, fiel=None, generate_pdf=False):
def output_file(file, folder, fiel=None, generate_pdf=False, zip_xml=False):
if fiel:
file.sign(fiel)

output_file = os.path.join(folder, filename(file))
file.xml_write(
output_file,
pretty_print=True,
xml_declaration=True
)
if zip_xml:
zip_file(output_file[:-4] + '.zip', [
ZipData(
filename(file),
file.xml_bytes(xml_declaration=True)
)
])
else:
file.xml_write(
output_file,
pretty_print=True,
xml_declaration=True
)

if generate_pdf:
# render.html_write(file, output_file[:-4] + ".html")
render.pdf_write(file, output_file[:-4] + ".pdf")
else:
# delete file
try:
os.remove(output_file[:-4] + ".pdf")
except FileNotFoundError:
Expand All @@ -52,40 +63,6 @@ def output_file(file, folder, fiel=None, generate_pdf=False):
return output_file


def calcular_saldos(cuentas, polizas):
max_level = 1
for c in cuentas.values():
# c['SaldoIni'] = 0
c['Debe'] = 0
c['Haber'] = 0
c['SaldoFin'] = 0
max_level = max(max_level, c['Nivel'])

for p in polizas:
for t in p["Transaccion"]:
num_cta = t["NumCta"]
cuenta = cuentas[num_cta]
cuenta["Debe"] += t["Debe"]
cuenta["Haber"] += t["Haber"]

# Fill Parents
for level in range(max_level, 1, -1):
for k, v in cuentas.items():
if v['Nivel'] == level:
parent = v['SubCtaDe']
if parent:
p_cuenta = cuentas[parent]
p_cuenta['Debe'] += v['Debe']
p_cuenta['Haber'] += v['Haber']

# Fill SaldoFin
for c in cuentas.values():
if c["Natur"] == "D":
c["SaldoFin"] += c["SaldoIni"] + c["Debe"] - c["Haber"]
else:
c["SaldoFin"] += c["SaldoIni"] + c["Haber"] - c["Debe"]


def generar_contabilidad(
dp: DatePeriod,
rfc_emisor: str,
Expand All @@ -98,8 +75,10 @@ def generar_contabilidad(
numero_tramite=None,
folder=None,
fiel=None,
generate_pdf=False):

generate_pdf=False,
zip_xml=False
):
validate_cuentas(cuentas)
validate_polizas(polizas)
calcular_saldos(cuentas, polizas)

Expand All @@ -112,15 +91,15 @@ def generar_contabilidad(
num_tramite=numero_tramite,
poliza=polizas
)
output_file(plz, folder, fiel, generate_pdf=generate_pdf)
output_file(plz, folder, fiel, generate_pdf=generate_pdf, zip_xml=zip_xml)

cat = Catalogo(
rfc=rfc_emisor,
mes=str(dp.month).zfill(2),
anio=dp.year,
ctas=[
Ctas(
cod_agrup=v["CodAgrup"].split("_")[0],
cod_agrup=v["CodAgrup"],
num_cta=k,
desc=v["Desc"],
nivel=v["Nivel"],
Expand All @@ -129,7 +108,7 @@ def generar_contabilidad(
) for k, v in cuentas.items()
]
)
cato = output_file(cat, folder, fiel)
output_file(cat, folder, fiel, zip_xml=zip_xml)

ban = Balanza(
rfc=rfc_emisor,
Expand All @@ -142,7 +121,7 @@ def generar_contabilidad(
**v,
} for k, v in cuentas.items() if v["SaldoIni"] or v["Debe"] or v["Haber"] or v["SaldoFin"]],
)
bano = output_file(ban, folder, fiel)
output_file(ban, folder, fiel, zip_xml=zip_xml)

aux_detalles = group_aux_cuentas(polizas)
aux = AuxiliarCtas(
Expand All @@ -162,7 +141,7 @@ def generar_contabilidad(
) for k, v in cuentas.items() if k in aux_detalles
]
)
output_file(aux, folder, fiel, generate_pdf=generate_pdf)
output_file(aux, folder, fiel, generate_pdf=generate_pdf, zip_xml=zip_xml)

auxf = RepAuxFol(
rfc=rfc_emisor,
Expand All @@ -173,11 +152,11 @@ def generar_contabilidad(
num_tramite=numero_tramite,
det_aux_fol=list(group_aux_folios(polizas))
)
output_file(auxf, folder, fiel, generate_pdf=generate_pdf)
output_file(auxf, folder, fiel, generate_pdf=generate_pdf, zip_xml=zip_xml)

imprimir_contablidad(
catalogo_cuentas=cato,
balanza_comprobacion=bano,
catalogo_cuentas=cat,
balanza_comprobacion=ban,
archivo_excel=os.path.join(folder, filename(ban)[:-4] + ".xlsx")
)

Expand Down Expand Up @@ -230,30 +209,45 @@ def group_aux_folios(polizas):
)


def validate_cuentas(cuentas):
# validar cuentas
for k, v in cuentas.items():
assert k
v['_Lowest'] = True
assert v['Natur'] in ['A', 'D']
if v['SubCtaDe']:
assert v['SubCtaDe'] in cuentas, f"Parent account {v['SubCtaDe']} not found for {k}"
v['Nivel'] = cuentas[v['SubCtaDe']]['Nivel'] + 1
else:
v['Nivel'] = 1

v['CodAgrup'] = catalog_code('Cb9f_c_CodAgrup', v['CodAgrup'])
assert v['CodAgrup'].description, f"Unknown CodAgrup: {v['CodAgrup']}"

for k, v in cuentas.items():
if v['SubCtaDe']:
cuentas[v['SubCtaDe']]['_Lowest'] = False


def sign(cta):
if cta['Natur'] == 'D':
return 1
return -1


def validate_saldos(cuentas):
total = 0
totales = {}
for k, v in cuentas.items():
if v['Nivel'] == 1:
if v['Natur'] == 'D':
total += v['SaldoFin']
else:
total -= v['SaldoFin']
else:
totales.setdefault(v['SubCtaDe'], 0)
if v['Natur'] == 'D':
totales[v['SubCtaDe']] += v['SaldoFin']
else:
totales[v['SubCtaDe']] -= v['SaldoFin']
sub_cta = v.get('SubCtaDe')
totales.setdefault(sub_cta, 0)
totales[sub_cta] += v['SaldoFin'] * sign(v)

assert total == 0
for k, v in totales.items():
if cuentas[k]['Natur'] == 'D':
if v != cuentas[k]['SaldoFin']:
if k:
if v != cuentas[k]['SaldoFin'] * sign(cuentas[k]):
raise ValueError(f"Error in {k}: {v} != {cuentas[k]['SaldoFin']}")
else:
if v != -cuentas[k]['SaldoFin']:
raise ValueError(f"Error in {k}: {v} != {cuentas[k]['SaldoFin']}")
assert v == 0


def validate_polizas(polizas):
Expand All @@ -263,3 +257,36 @@ def validate_polizas(polizas):
if u in num_un:
raise ValueError(f"Repeated NumUnIdenPol: {u}")
num_un.add(u)


def calcular_saldos(cuentas, polizas):
max_level = 1
for c in cuentas.values():
# c['SaldoIni'] = 0
c['Debe'] = 0
c['Haber'] = 0
c['SaldoFin'] = 0
max_level = max(max_level, c['Nivel'])

for p in polizas:
for t in p["Transaccion"]:
num_cta = t["NumCta"]
cuenta = cuentas[num_cta]
assert cuenta["_Lowest"], f"Account {num_cta} is not a lowest level account"
cuenta["Debe"] += t["Debe"]
cuenta["Haber"] += t["Haber"]

# Fill Parents
for level in range(max_level, 1, -1):
for k, v in cuentas.items():
if v['Nivel'] == level:
parent = v['SubCtaDe']
if parent:
p_cuenta = cuentas[parent]
p_cuenta['Debe'] += v['Debe']
p_cuenta['Haber'] += v['Haber']

# Fill SaldoFin
for c in cuentas.values():
s = sign(c)
c["SaldoFin"] += c["SaldoIni"] + c["Debe"] * s - c["Haber"] * s
6 changes: 2 additions & 4 deletions satcfdi/accounting/contabilidad_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ def imprimir_contablidad(
balanza_comprobacion,
archivo_excel
):
ct = CFDI.from_file(catalogo_cuentas)
bc = CFDI.from_file(balanza_comprobacion)
# ct = catalogo_cuentas
# bc = balanza_comprobacion
ct = catalogo_cuentas
bc = balanza_comprobacion

ctas = {
c['NumCta']: {
Expand Down
20 changes: 18 additions & 2 deletions satcfdi/zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
def zip_create(target: io.BytesIO, files: list[ZipData]):
p = target.tell()

for f in files:
with ZipFile(target, "w") as myzip:
with ZipFile(target, "w") as myzip:
for f in files:
zinfo = ZipInfo(
filename=f.filename
)
Expand All @@ -24,3 +24,19 @@ def zip_create(target: io.BytesIO, files: list[ZipData]):

with target.getbuffer() as view: # change zip flag bytes
view[p + 6:p + 8] = b"\x08\x08"


def zip_file(zipfile, files: list[ZipData]):
# Create a ZipFile object in write mode
with ZipFile(zipfile, 'w') as zipf:
# Add the input file to the zip archive with its base name
for f in files:
zinfo = ZipInfo(
filename=f.filename,
# date_time=datetime_to_tuple(datetime.now())
)
zinfo.compress_type = 8
zinfo.create_system = 0

with zipf.open(zinfo, 'w') as stream:
stream.write(f.data)
7 changes: 0 additions & 7 deletions tests/contabilidad_electronica/cuentas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Desc: Activos
Natur: D
CodAgrup: '100' # Activo
Nivel: 1
SubCtaDe:
SaldoIni: 0

Expand All @@ -13,21 +12,18 @@
Desc: Bancos
Natur: D
CodAgrup: '102' # Bancos nacionales
Nivel: 2
SubCtaDe: '1000'
SaldoIni: 0
'1020.01':
Desc: Bancos Nacionales
Natur: D
CodAgrup: '102.01' # Bancos nacionales
Nivel: 2
SubCtaDe: '1020'
SaldoIni: 0
'1020.02':
Desc: Bancos Extranjeros
Natur: D
CodAgrup: '102.02' # Bancos extranjeros
Nivel: 2
SubCtaDe: '1020'
SaldoIni: 0

Expand All @@ -36,20 +32,17 @@
Desc: Clientes
Natur: D
CodAgrup: '105' # Clientes
Nivel: 2
SubCtaDe: '1000'
SaldoIni: 0
'1050.01':
Desc: Clientes Nacionales
Natur: D
CodAgrup: '105.01' # Clientes nacionales
Nivel: 2
SubCtaDe: '1050'
SaldoIni: 0
'1050.02':
Desc: Clientes Extranjeros
Natur: D
CodAgrup: '105.02' # Clientes extranjeros
Nivel: 2
SubCtaDe: '1050'
SaldoIni: 0
Loading

0 comments on commit db1e20c

Please sign in to comment.