diff --git a/satcfdi/accounting/contabilidad.py b/satcfdi/accounting/contabilidad.py index 68afa4a..526aebd 100644 --- a/satcfdi/accounting/contabilidad.py +++ b/satcfdi/accounting/contabilidad.py @@ -50,10 +50,42 @@ def output_file(file, folder, fiel=None, generate_pdf=False): return output_file +def calcular_saldos(cuentas, polizas): + for c in cuentas.values(): + # c['SaldoIni'] = 0 + c['Debe'] = 0 + c['Haber'] = 0 + c['SaldoFin'] = 0 + + 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(4, 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, - ctas: dict, + cuentas: dict, polizas: Sequence[Poliza], tipo_envio='N', fecha_mod_bal=None, @@ -63,6 +95,7 @@ def generar_contabilidad( folder=None, fiel=None, generate_pdf=False): + calcular_saldos(cuentas, polizas) plz = Polizas( rfc=rfc_emisor, @@ -80,15 +113,15 @@ def generar_contabilidad( mes=str(dp.month).zfill(2), anio=dp.year, ctas=[ - Ctas( - cod_agrup=v["CodAgrup"].split("_")[0], - num_cta=k, - desc=v["Desc"], - nivel=v["Nivel"], - natur=v["Natur"], - sub_cta_de=v['SubCtaDe'], - ) for k, v in ctas.items() - ] + Ctas( + cod_agrup=v["CodAgrup"].split("_")[0], + num_cta=k, + desc=v["Desc"], + nivel=v["Nivel"], + natur=v["Natur"], + sub_cta_de=v['SubCtaDe'], + ) for k, v in cuentas.items() + ] ) output_file(cat, folder, fiel) @@ -101,7 +134,7 @@ def generar_contabilidad( ctas=[{ "NumCta": k, **v, - } for k, v in ctas.items() if v["SaldoIni"] or v["Debe"] or v["Haber"] or v["SaldoFin"]], + } for k, v in cuentas.items() if v["SaldoIni"] or v["Debe"] or v["Haber"] or v["SaldoFin"]], ) output_file(ban, folder, fiel) @@ -120,7 +153,7 @@ def generar_contabilidad( saldo_ini=v["SaldoIni"], saldo_fin=v["SaldoFin"], detalle_aux=aux_detalles[k] - ) for k, v in ctas.items() if k in aux_detalles + ) for k, v in cuentas.items() if k in aux_detalles ] ) output_file(aux, folder, fiel, generate_pdf=generate_pdf) @@ -142,7 +175,7 @@ def generar_contabilidad( archivo_excel=filename(ban)[:-4] + ".xlsx" ) - validate_saldos(ctas) + validate_saldos(cuentas) def group_aux_cuentas(polizas): diff --git a/tests/MOLE870717DRA202402BN.xlsx b/tests/MOLE870717DRA202402BN.xlsx index 55c81e0..62450dd 100644 Binary files a/tests/MOLE870717DRA202402BN.xlsx and b/tests/MOLE870717DRA202402BN.xlsx differ diff --git a/tests/contabilidad_electronica/cuentas.yaml b/tests/contabilidad_electronica/cuentas.yaml new file mode 100644 index 0000000..f6bd679 --- /dev/null +++ b/tests/contabilidad_electronica/cuentas.yaml @@ -0,0 +1,55 @@ +### CUENTAS PRINCIPALES ### +'1000': + Desc: Activos + Natur: D + CodAgrup: '100' # Activo + Nivel: 1 + SubCtaDe: + SaldoIni: 0 + +### ACTIVOS 100 ### +# BANCOS +'1020': + 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 + +# CLIENTES +'1050': + 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 diff --git a/tests/test_contabilidad.py b/tests/test_contabilidad.py index 20eda80..2731653 100644 --- a/tests/test_contabilidad.py +++ b/tests/test_contabilidad.py @@ -2,6 +2,9 @@ import os import pytest +import yaml +from satdigitalinvoice.file_data_managers import DuplicateKeySafeLoader + from satcfdi.models import DatePeriod from satcfdi import render @@ -54,7 +57,7 @@ def test_generate_contabilidad_empty(): generar_contabilidad( dp=DatePeriod(2024, 2), rfc_emisor="MOLE870717DRA", - ctas={}, + cuentas={}, polizas=[], folder=os.path.join(current_dir, 'test_contabilidad_electronica/out/empty'), ) @@ -68,10 +71,13 @@ def test_generate_contabilidad_empty(): def test_generate_contabilidad_simple(): os.makedirs(os.path.join(current_dir, 'test_contabilidad_electronica/out/simple'), exist_ok=True) + with open(os.path.join(current_dir, 'contabilidad_electronica', 'cuentas.yaml'), 'r', encoding='utf-8') as f: + cuentas = yaml.load(f, Loader=DuplicateKeySafeLoader) + generar_contabilidad( dp=DatePeriod(2024, 2), rfc_emisor="MOLE870717DRA", - ctas={}, + cuentas=cuentas, polizas=[], folder=os.path.join(current_dir, 'test_contabilidad_electronica/out/simple'), ) diff --git a/tests/test_contabilidad_electronica/ref/simple/MOLE870717DRA202402CT.xml b/tests/test_contabilidad_electronica/ref/simple/MOLE870717DRA202402CT.xml index b6389c5..7f8b530 100644 --- a/tests/test_contabilidad_electronica/ref/simple/MOLE870717DRA202402CT.xml +++ b/tests/test_contabilidad_electronica/ref/simple/MOLE870717DRA202402CT.xml @@ -1,2 +1,10 @@ - + + + + + + + + +