diff --git a/docs/decizii_import.md b/docs/decizii_import.md index f548a2d..a8e7266 100644 --- a/docs/decizii_import.md +++ b/docs/decizii_import.md @@ -95,8 +95,12 @@ Revizuit 20.09.2026 (inlocuieste forma din pct. 11 si 14 pentru aceste conturi). - **`5311`** (casa, fara analitice): rand `BALANTA` pe `5311` (acont gol) + rand `FACTURA` pe `5311` (acont gol), partener `CENTRALA`. - **`5125`**: **doar analitice**, fara parteneri. Se trateaza ca orice cont obisnuit cu analitice. -- Un analitic cu soldul pe latura opusa laturii fixate in cod (`:379`, trezoreria merge pe debit) - nu primeste rand FACTURA; ramane doar randul BALANTA si formularul ii pune `NEREPARTIZAT`. +- Un analitic cu soldul pe **latura opusa** laturii fixate in cod (`:379` - trezoreria merge pe + debit) primeste totusi rand FACTURA: suma se scrie **cu semn negativ pe latura formularului**, + atat in randul `BALANTA` (`totdeb = -20,80`, `totcred` gol) cat si in `sold`-ul randului + `FACTURA` (`-20,80`). Soldul ramane pe latura corecta, balanta ramane inchisa + (`SUM(totdeb) = SUM(totcred)`), randul FACTURA consuma exact randul BALANTA si nu mai ramane + nimic pe `NEREPARTIZAT`. Pretul: nota contine o suma negativa - acceptat (decis 20.09.2026). Caz gasit: MASTER `5121.01 PIRAEUS BANK - RON`, sold creditor 20,80. ## 16. Regula generala: randul FACTURA trebuie sa aiba acelasi `acont` ca randul BALANTA pe care il consuma diff --git a/docs/raport_genxlsx.md b/docs/raport_genxlsx.md index 23e2338..352ea87 100644 --- a/docs/raport_genxlsx.md +++ b/docs/raport_genxlsx.md @@ -1,4 +1,4 @@ -# Raport lane `genxlsx` (v2) +# Raport lane `genxlsx` (v3) Script: `genereaza_xlsx.py`. Produce pentru fiecare firma xlsx-ul de initializare (`init__2025_12.xlsx`, un sheet, randul 1 = capul de tabel, fara instructiuni/exemple) @@ -6,7 +6,7 @@ si raportul de verificare (`docs/verificare_.md`). ## Livrabile - `init_FUNDATIA_2025_12.xlsx` - 75 randuri (47 BALANTA, 28 FACTURA) -- `init_MASTER_2025_12.xlsx` - 79 randuri (46 BALANTA, 33 FACTURA) +- `init_MASTER_2025_12.xlsx` - 80 randuri (46 BALANTA, 34 FACTURA) - `docs/verificare_FUNDATIA.md`, `docs/verificare_MASTER.md` - `genereaza_xlsx.py` @@ -14,44 +14,43 @@ si raportul de verificare (`docs/verificare_.md`). | Firma | SUM(totdeb)=SUM(totcred) | frunze pierdute | parteneri | lungimi/dubluri | |---|---|---|---|---| | FUNDATIA | 7068369.50 = 7068369.50 (net 0.00) | 0 | OK | OK | -| MASTER | 2318592.91 = 2318592.91 (net 0.00) | 0 | OK | OK | +| MASTER | 2318572.11 = 2318572.11 (net 0.00) | 0 | OK | OK | -## Corectii v2 (fata de v1) -1. **Randul FACTURA `DIFERENTA SINTETIC ` a fost eliminat** de pe conturile cu parteneri. - Formularul scade singur suma randurilor FACTURA din randul BALANTA de pe acelasi - `(cont, acont, latura)` si pune restul pe partenerul `NEREPARTIZAT` pe care il creeaza el - (`frm..sc2:415-431`). Diferenta nu se mai inventa de noi. -2. **Analitice cu sold pe latura opusa nu mai primesc FACTURA.** Latura FACTURA e fixa in cod - (`frm..sc2:379`/'383'): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. - Analiticul sarit ramane doar in randul BALANTA (pe latura lui corecta) si formularul ii pune - `NEREPARTIZAT`. Fiecare caz e listat in raport (sectiunea 4). -3. **Randul BALANTA reprezinta contul sintetic intreg.** La partenerii cu un singur BALANTA - agregat, `totdeb` = suma `total_d` a tuturor analiticelor + postarea directa pe sintetic - (idem `totcred`), nu doar analiticele pentru care s-a emis FACTURA. -4. **pct. 15 (revizuit 20.09.2026):** - - `5121`/`5124`: analiticele **raman analitice** si in plus primesc partener. Pentru fiecare - analitic se scriu **doua randuri pe acelasi `(cont, acont)`**: un `BALANTA` cu acont si - `totdeb`/`totcred` ale analiticului, si un `FACTURA` cu **acelasi acont**, `cod_fiscal` = - codul SAGA, `sold` = soldul analiticului. Acelasi `acont` e obligatoriu, altfel scaderea din - cod nu se potriveste si suma se dubleaza. - - `5125`: NU mai e cont cu parteneri - doar randuri BALANTA cu acont, fara FACTURA. - - `5311`: BALANTA (acont gol) + FACTURA (acont gol), partener `CENTRALA`. - - `401, 4092, 4111, 461, 462, 4551`: neschimbate - un BALANTA agregat pe sintetic (acont gol) - + cate un FACTURA per analitic (acont gol). +## Corectia v3 (fata de v2) +**Analiticul cu sold pe latura opusa laturii fixate de formular (`frm..sc2:379`) NU mai este +sarit.** Primeste rand `FACTURA`, iar suma se scrie cu **semn negativ pe latura formularului**: +- randul `BALANTA` al analiticului: `totdeb = -|sold|` (daca latura formularului e D) sau + `totcred = -|sold|` (daca e C), cealalta latura goala; +- randul `FACTURA`: `sold = -|sold|`, pe aceeasi latura si cu **acelasi `acont`** ca BALANTA. + +Soldul ramane pe latura corecta, `SUM(totdeb) = SUM(totcred)` se pastreaza (ambele laturi scad +cu aceeasi suma), randul FACTURA consuma exact randul BALANTA si nu mai ramane nimic pe +`NEREPARTIZAT`. Regula se aplica general, la orice cont cu parteneri. Pretul acceptat: nota +contine o suma negativa. + +Efecte pe MASTER: +1 rand (FACTURA pentru `5121.01`), iar `SUM(totdeb)`/`SUM(totcred)` scad +cu 20.80 si ajung exact peste `Totaluri.total_d`/`total_c` din PDF (diferenta 0.00, fata de +20.80 in v2). ## Ce ramane pe `NEREPARTIZAT`, per cont (sectiunea 3 din verificari) -`net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. +`net sintetic - SUM(sold FACTURA cu semn) = postare directa pe sintetic`. Rezultat: toate conturile ies 0, mai putin MASTER `5121`: -| cont | SUM FACTURA | net sintetic | sarite | postare directa | NEREPARTIZAT asteptat | diferenta | -|---|---|---|---|---|---|---| -| MASTER 5121 | 15599.25 | 15730.61 | -20.80 (`5121.01` creditor) | +152.16 | 131.36 | 131.36 | +| cont | SUM FACTURA | net sintetic | postare directa | NEREPARTIZAT asteptat | diferenta | +|---|---|---|---|---|---| +| MASTER 5121 | 15578.45 | 15730.61 | +152.16 | 152.16 | 152.16 | -- MASTER `5121.01 PIRAEUS BANK - RON` (sold creditor 20,80): fara FACTURA, doar - `BALANTA 5121 acont 01` pe credit -> formularul ii pune `NEREPARTIZAT`. +- MASTER `5121.01 PIRAEUS BANK - RON` (sold creditor 20,80): `BALANTA acont 01 totdeb=-20.80` + + `FACTURA acont 01 sold=-20.80` -> se consuma exact, fara `NEREPARTIZAT`. - MASTER `5121` postare directa +152.16: rand `BALANTA 5121 acont 99` `DIFERENTA SINTETIC SAGA` (fara FACTURA) -> `NEREPARTIZAT`. +## Analitice cu semn negativ (sectiunea 4 din verificari) +| Firma | cont | analitic | sold (semnat) | latura formularului | +|---|---|---|---|---| +| MASTER | 5121 | 5121.01 | -20.8 | D | +| FUNDATIA | - | niciunul | - | - | + ## Randuri de diferenta (pct. 13-15) generate - MASTER `117` (nepartener): +2635.87 -> rand `BALANTA` cont 117, acont `99`, nume `DIFERENTA SINTETIC SAGA`. @@ -59,7 +58,8 @@ Rezultat: toate conturile ies 0, mai putin MASTER `5121`: - FUNDATIA: niciunul (1171.01 are diferenta net zero - doar netare SAGA). ## Observatii -- SUM(totdeb) difera de `Totaluri.total_d` din PDF (FUNDATIA +739831.67, MASTER +20.80): - gross-ul sinteticelor netate de SAGA nu se poate reconstrui din frunze; netul coincide exact. +- FUNDATIA: SUM(totdeb) difera de `Totaluri.total_d` din PDF cu +739831.67 (gross-ul + sinteticelor netate de SAGA nu se poate reconstrui din frunze); netul coincide exact. +- MASTER: dupa corectia v3, SUM(totdeb) = `Totaluri.total_d` = 2318572.11 (diferenta 0.00). - Coloana `explicatia` (control D/C) este goala in xlsx-ul final. - Nu s-a facut niciun commit. diff --git a/docs/verificare_FUNDATIA.md b/docs/verificare_FUNDATIA.md index e0323eb..633c5e0 100644 --- a/docs/verificare_FUNDATIA.md +++ b/docs/verificare_FUNDATIA.md @@ -20,25 +20,25 @@ Generat de `genereaza_xlsx.py` din `balanta_FUNDATIA.csv`. Randuri de date: 75 ( ## 3. Conturi partener: FACTURA + NEREPARTIZAT = net sintetic -Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. +Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = postare directa pe sintetic`. -| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | -|---|---|---|---|---|---|---|---| -| 401 | -314703.58 | -314703.58 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4092 | 809.33 | 809.33 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4111 | 15126.48 | 15126.48 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4551 | -1571531.33 | -1571531.33 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 461 | 477938.37 | 477938.37 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 462 | -3400771.0 | -3400771.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 5121 | 81966.8 | 81966.8 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 5124 | 2492540.28 | 2492540.28 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 5311 | 72433.56 | 72433.56 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| cont | SUM(sold FACTURA) | net sintetic | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | +|---|---|---|---|---|---|---| +| 401 | -314703.58 | -314703.58 | 0.0 | 0.0 | 0.0 | OK | +| 4092 | 809.33 | 809.33 | 0.0 | 0.0 | 0.0 | OK | +| 4111 | 15126.48 | 15126.48 | 0.0 | 0.0 | 0.0 | OK | +| 4551 | -1571531.33 | -1571531.33 | 0.0 | 0.0 | 0.0 | OK | +| 461 | 477938.37 | 477938.37 | 0.0 | 0.0 | 0.0 | OK | +| 462 | -3400771.0 | -3400771.0 | 0.0 | 0.0 | 0.0 | OK | +| 5121 | 81966.8 | 81966.8 | 0.0 | 0.0 | 0.0 | OK | +| 5124 | 2492540.28 | 2492540.28 | 0.0 | 0.0 | 0.0 | OK | +| 5311 | 72433.56 | 72433.56 | 0.0 | 0.0 | 0.0 | OK | Rezultat: OK -## 4. Analitice sarite (sold pe latura opusa formularului) +## 4. Analitice cu semn negativ (sold pe latura opusa formularului) -Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu primeste rand FACTURA; ramane in BALANTA si formularul ii pune `NEREPARTIZAT`. +Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa primeste totusi rand FACTURA, iar suma se scrie cu **semn negativ pe latura formularului**, atat in randul BALANTA cat si in `sold`-ul randului FACTURA. Soldul ramane pe latura corecta, balanta ramane inchisa, iar randul FACTURA consuma exact randul BALANTA (fara `NEREPARTIZAT`). Niciunul. diff --git a/docs/verificare_MASTER.md b/docs/verificare_MASTER.md index 5f5b4d4..e8602c6 100644 --- a/docs/verificare_MASTER.md +++ b/docs/verificare_MASTER.md @@ -1,15 +1,15 @@ # Verificare `init_MASTER_2025_12.xlsx` -Generat de `genereaza_xlsx.py` din `balanta_MASTERJOB.csv`. Randuri de date: 79 (46 BALANTA, 33 FACTURA). +Generat de `genereaza_xlsx.py` din `balanta_MASTERJOB.csv`. Randuri de date: 80 (46 BALANTA, 34 FACTURA). ## 1. Balanta generala (SUM totdeb = SUM totcred) -- SUM(totdeb) = 2318592.91 -- SUM(totcred) = 2318592.91 +- SUM(totdeb) = 2318572.11 +- SUM(totcred) = 2318572.11 - diferenta (totdeb - totcred) = 0.0 -> OK - Totaluri balanta: total_d=2318572.11 total_c=2318572.11 net=0.0 - NET xlsx (0.0) vs NET Totaluri (0.0) -> OK -- Nota: SUM(totdeb)=2318592.91 difera de Totaluri.total_d=2318572.11 cu 20.8; suma pe laturi a PDF-ului nu se poate reconstrui din frunze acolo unde SAGA a netat sinteticul (gross-ul parintelui e netat). Netul se pastreaza exact. +- Nota: SUM(totdeb)=2318572.11 difera de Totaluri.total_d=2318572.11 cu 0.0; suma pe laturi a PDF-ului nu se poate reconstrui din frunze acolo unde SAGA a netat sinteticul (gross-ul parintelui e netat). Netul se pastreaza exact. ## 2. Conturi frunza din CSV, reprezentate o singura data @@ -20,29 +20,29 @@ Generat de `genereaza_xlsx.py` din `balanta_MASTERJOB.csv`. Randuri de date: 79 ## 3. Conturi partener: FACTURA + NEREPARTIZAT = net sintetic -Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. +Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = postare directa pe sintetic`. -| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | -|---|---|---|---|---|---|---|---| -| 401 | -547108.99 | -547108.99 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4092 | 4.0 | 4.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4111 | 12000.0 | 12000.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 4551 | -751724.61 | -751724.61 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 461 | 69289.0 | 69289.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 462 | -9810.0 | -9810.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 5121 | 15599.25 | 15730.61 | -20.8 | 152.16 | 131.36 | 131.36 | OK | -| 5124 | 1060090.96 | 1060090.96 | 0.0 | 0.0 | 0.0 | 0.0 | OK | -| 5311 | 98460.87 | 98460.87 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| cont | SUM(sold FACTURA) | net sintetic | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | +|---|---|---|---|---|---|---| +| 401 | -547108.99 | -547108.99 | 0.0 | 0.0 | 0.0 | OK | +| 4092 | 4.0 | 4.0 | 0.0 | 0.0 | 0.0 | OK | +| 4111 | 12000.0 | 12000.0 | 0.0 | 0.0 | 0.0 | OK | +| 4551 | -751724.61 | -751724.61 | 0.0 | 0.0 | 0.0 | OK | +| 461 | 69289.0 | 69289.0 | 0.0 | 0.0 | 0.0 | OK | +| 462 | -9810.0 | -9810.0 | 0.0 | 0.0 | 0.0 | OK | +| 5121 | 15578.45 | 15730.61 | 152.16 | 152.16 | 152.16 | OK | +| 5124 | 1060090.96 | 1060090.96 | 0.0 | 0.0 | 0.0 | OK | +| 5311 | 98460.87 | 98460.87 | 0.0 | 0.0 | 0.0 | OK | Rezultat: OK -## 4. Analitice sarite (sold pe latura opusa formularului) +## 4. Analitice cu semn negativ (sold pe latura opusa formularului) -Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu primeste rand FACTURA; ramane in BALANTA si formularul ii pune `NEREPARTIZAT`. +Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa primeste totusi rand FACTURA, iar suma se scrie cu **semn negativ pe latura formularului**, atat in randul BALANTA cat si in `sold`-ul randului FACTURA. Soldul ramane pe latura corecta, balanta ramane inchisa, iar randul FACTURA consuma exact randul BALANTA (fara `NEREPARTIZAT`). -| cont | analitic | sold (semnat) | motiv | +| cont | analitic | sold (semnat) | latura formularului | |---|---|---|---| -| 5121 | 5121.01 | -20.8 | sold creditor vs latura D a formularului | +| 5121 | 5121.01 | -20.8 | D | ## 5. Lungimi si dubluri diff --git a/genereaza_xlsx.py b/genereaza_xlsx.py index 355d3b3..7fb410d 100644 --- a/genereaza_xlsx.py +++ b/genereaza_xlsx.py @@ -19,8 +19,9 @@ Forma randurilor (revizuit 20.09.2026, vezi pct. 14-15): 5121/5124 devine rand BALANTA de diferenta (analitic nou, fara FACTURA); la ceilalti parteneri se include in BALANTA agregat. NU se mai emite FACTURA de diferenta (o rezolva formularul, prin NEREPARTIZAT). -- analiticul cu sold pe latura opusa celei fixate de formular (':379') nu primeste - FACTURA; ramane doar in BALANTA si apare ca NEREPARTIZAT. +- analiticul cu sold pe latura opusa celei fixate de formular (':379') primeste + FACTURA, cu suma scrisa cu semn negativ pe latura formularului (atat in BALANTA + cat si in sold-ul FACTURA); soldul ramane pe latura corecta si nu apare NEREPARTIZAT. """ import csv @@ -155,8 +156,8 @@ def rand(header, **kw): return r -def _semn_sold(net): - return "creditor" if net < 0 else "debitor" +def este_latura_formular(net, side): + return (net > 0) == (side == "D") def genereaza(rows, header): @@ -183,7 +184,7 @@ def genereaza(rows, header): out = [] leaf_map = {} # frunza -> randurile dedicate (folosite la dubluri) leaf_rep = set() # toate frunzele reprezentate (inclusiv in BALANTA agregat) - sarite = [] # (cont, analitic, sold_semnat, motiv) + negative = [] # (cont, analitic, sold_semnat, latura_formular) def add(r, leaf=None): out.append(r) @@ -220,21 +221,25 @@ def genereaza(rows, header): for k in direct: kd = by[k] kac = split_cont(k)[1] - add(rand(header, TIP="BALANTA", cont=p, acont=kac, numar=1, - nume=kd["denumire"], totdeb=round(kd["total_d"], 2), - totcred=round(kd["total_c"], 2)), leaf=k) net = round(kd["total_d"] - kd["total_c"], 2) + if net != 0 and not este_latura_formular(net, side): + neg = -abs(net) + negative.append((p, k, neg, side)) + if side == "D": + td, tc = neg, None + else: + td, tc = None, neg + else: + td, tc = round(kd["total_d"], 2), round(kd["total_c"], 2) + add(rand(header, TIP="BALANTA", cont=p, acont=kac, numar=1, + nume=kd["denumire"], totdeb=td, totcred=tc), leaf=k) if net == 0: continue - if (net > 0) == (side == "D"): - add(rand(header, TIP="FACTURA", cont=p, acont=kac, - numar=k.replace(".", ""), - nume=kd["denumire"] or f"FURNIZOR {k}", - cod_fiscal=k, sold=abs(net), explicatia=side)) - else: - sarite.append((p, k, net, - f"sold {_semn_sold(net)} vs latura {side} " - f"a formularului")) + sold = abs(net) if este_latura_formular(net, side) else -abs(net) + add(rand(header, TIP="FACTURA", cont=p, acont=kac, + numar=k.replace(".", ""), + nume=kd["denumire"] or f"FURNIZOR {k}", + cod_fiscal=k, sold=sold, explicatia=side)) if p in diff_by_parent: d = diff_by_parent[p] ac = acont_diferenta(p, direct) @@ -246,8 +251,20 @@ def genereaza(rows, header): # 401/4092/4111/461/462/4551 si 5311 if direct: - base_d = sum(by[k]["total_d"] for k in direct) - base_c = sum(by[k]["total_c"] for k in direct) + base_d = 0.0 + base_c = 0.0 + for k in direct: + net = round(by[k]["total_d"] - by[k]["total_c"], 2) + if net != 0 and not este_latura_formular(net, side): + neg = -abs(net) + negative.append((p, k, neg, side)) + if side == "D": + base_d += neg + else: + base_c += neg + else: + base_d += by[k]["total_d"] + base_c += by[k]["total_c"] d = diff_by_parent.get(p, 0.0) add(rand(header, TIP="BALANTA", cont=p, acont=None, numar=1, nume=by[p]["denumire"], @@ -258,33 +275,33 @@ def genereaza(rows, header): if net == 0: leaf_rep.add(k) continue - if (net > 0) == (side == "D"): - add(rand(header, TIP="FACTURA", cont=p, acont=None, - numar=k.replace(".", ""), - nume=by[k]["denumire"] or f"FURNIZOR {k}", - cod_fiscal=k, sold=abs(net), explicatia=side), - leaf=k) - else: - sarite.append((p, k, net, - f"sold {_semn_sold(net)} vs latura {side} " - f"a formularului")) - leaf_rep.add(k) + sold = abs(net) if este_latura_formular(net, side) else -abs(net) + add(rand(header, TIP="FACTURA", cont=p, acont=None, + numar=k.replace(".", ""), + nume=by[k]["denumire"] or f"FURNIZOR {k}", + cod_fiscal=k, sold=sold, explicatia=side), + leaf=k) else: net = round(by[p]["total_d"] - by[p]["total_c"], 2) - add(rand(header, TIP="BALANTA", cont=p, acont=None, numar=1, - nume=by[p]["denumire"], totdeb=round(by[p]["total_d"], 2), - totcred=round(by[p]["total_c"], 2)), leaf=p) - if net != 0: - if (net > 0) == (side == "D"): - nume = "CENTRALA" if p == "5311" else by[p]["denumire"] - add(rand(header, TIP="FACTURA", cont=p, acont=None, - numar=p, nume=nume, cod_fiscal=p, sold=abs(net), - explicatia=side)) + if net != 0 and not este_latura_formular(net, side): + neg = -abs(net) + negative.append((p, p, neg, side)) + if side == "D": + td, tc = neg, None else: - sarite.append((p, p, net, - f"sold {_semn_sold(net)} vs latura {side} " - f"a formularului")) - return out, diffs, leaf_map, leaf_rep, sarite + td, tc = None, neg + else: + td = round(by[p]["total_d"], 2) + tc = round(by[p]["total_c"], 2) + add(rand(header, TIP="BALANTA", cont=p, acont=None, numar=1, + nume=by[p]["denumire"], totdeb=td, totcred=tc), leaf=p) + if net != 0: + nume = "CENTRALA" if p == "5311" else by[p]["denumire"] + sold = abs(net) if este_latura_formular(net, side) else -abs(net) + add(rand(header, TIP="FACTURA", cont=p, acont=None, + numar=p, nume=nume, cod_fiscal=p, sold=sold, + explicatia=side)) + return out, diffs, leaf_map, leaf_rep, negative def scrie_xlsx(header, rows, path): @@ -302,7 +319,7 @@ def scrie_xlsx(header, rows, path): def verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, leaf_rep, - sarite, header): + negative, header): by, children = arbore(rows) leaves = [c for c in by if c not in children] diff_by_parent = dict(diffs) @@ -334,24 +351,19 @@ def verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, leaf_rep, semn = 1 if latura_factura(r["cont"]) == "D" else -1 part_rows[r["cont"]] = part_rows.get(r["cont"], 0.0) + semn * (r["sold"] or 0) - sarite_by_cont = {} - for cont, _k, s, _motiv in sarite: - sarite_by_cont[cont] = round(sarite_by_cont.get(cont, 0.0) + s, 2) - part_verif = [] for p in sorted({c.split(".")[0] for c in by if este_partener(c)}): net_sint = round(by[p]["total_d"] - by[p]["total_c"], 2) suma = round(part_rows.get(p, 0.0), 2) - sarit = round(sarite_by_cont.get(p, 0.0), 2) direct = round(diff_by_parent.get(p, 0.0), 2) - asteptat = round(sarit + direct, 2) + asteptat = direct diferenta = round(net_sint - suma, 2) ok = abs(diferenta - asteptat) <= 0.005 - part_verif.append((p, suma, net_sint, sarit, direct, asteptat, diferenta, ok)) + part_verif.append((p, suma, net_sint, direct, asteptat, diferenta, ok)) ok_bal = abs(net) <= 0.005 ok_leaves = not pierdute and not duplicate_leaf - ok_part = all(x[7] for x in part_verif) + ok_part = all(x[6] for x in part_verif) ok_lung = not lungimi and not dubluri_bal L = [] @@ -392,30 +404,33 @@ def verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, leaf_rep, L.append("Formularul scade din randul BALANTA suma randurilor FACTURA de pe " "acelasi `(cont, acont, latura)` si lasa restul pe partenerul " "`NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = " - "analitice sarite + postare directa pe sintetic`.") + "postare directa pe sintetic`.") L.append("") - L.append("| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat |") - L.append("|---|---|---|---|---|---|---|---|") - for p, suma, net_sint, sarit, direct, asteptat, diferenta, ok in part_verif: - L.append(f"| {p} | {suma} | {net_sint} | {sarit} | {direct} | {asteptat} " + L.append("| cont | SUM(sold FACTURA) | net sintetic | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat |") + L.append("|---|---|---|---|---|---|---|") + for p, suma, net_sint, direct, asteptat, diferenta, ok in part_verif: + L.append(f"| {p} | {suma} | {net_sint} | {direct} | {asteptat} " f"| {diferenta} | {'OK' if ok else '**ESEC**'} |") L.append("") L.append(f"Rezultat: {'OK' if ok_part else '**ESEC**'}") L.append("") - L.append("## 4. Analitice sarite (sold pe latura opusa formularului)") + L.append("## 4. Analitice cu semn negativ (sold pe latura opusa formularului)") L.append("") L.append("Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> " - "CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu " - "primeste rand FACTURA; ramane in BALANTA si formularul ii pune " - "`NEREPARTIZAT`.") + "CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa " + "primeste totusi rand FACTURA, iar suma se scrie cu **semn negativ pe " + "latura formularului**, atat in randul BALANTA cat si in `sold`-ul " + "randului FACTURA. Soldul ramane pe latura corecta, balanta ramane " + "inchisa, iar randul FACTURA consuma exact randul BALANTA (fara " + "`NEREPARTIZAT`).") L.append("") - if not sarite: + if not negative: L.append("Niciunul.") else: - L.append("| cont | analitic | sold (semnat) | motiv |") + L.append("| cont | analitic | sold (semnat) | latura formularului |") L.append("|---|---|---|---|") - for cont, k, s, motiv in sarite: - L.append(f"| {cont} | {k} | {s} | {motiv} |") + for cont, k, s, side in negative: + L.append(f"| {cont} | {k} | {s} | {side} |") L.append("") L.append("## 5. Lungimi si dubluri") L.append("") @@ -459,7 +474,7 @@ def verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, leaf_rep, "totdeb": totdeb, "totcred": totcred, "net": net, "pierdute": pierdute, "dubluri_leaf": duplicate_leaf, "dubluri_bal": list(dubluri_bal), "lungimi": lungimi, - "part_verif": part_verif, "sarite": sarite} + "part_verif": part_verif, "negative": negative} def main(): @@ -467,11 +482,11 @@ def main(): assert len(header) == 39, f"cap de tabel neasteptat: {len(header)} coloane" for firma, csv_path in FIRME: rows = citeste_balanta(csv_path) - out, diffs, leaf_map, leaf_rep, sarite = genereaza(rows, header) + out, diffs, leaf_map, leaf_rep, negative = genereaza(rows, header) xlsx_path = f"init_{firma}_2025_12.xlsx" scrie_xlsx(header, out, xlsx_path) rez = verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, - leaf_rep, sarite, header) + leaf_rep, negative, header) print(f"=== {firma} ===") print(f" rows: {len(out)} totdeb={rez['totdeb']} totcred={rez['totcred']} net={rez['net']}") print(f" balanta={'OK' if rez['bal'] else 'ESEC'} " @@ -479,8 +494,8 @@ def main(): f"parteneri={'OK' if rez['part'] else 'ESEC'} " f"lungimi={'OK' if rez['lung'] else 'ESEC'}") print(f" scris {xlsx_path} si docs/verificare_{firma}.md") - if rez["sarite"]: - print(f" analitice sarite: {rez['sarite']}") + if rez["negative"]: + print(f" analitice cu semn negativ: {rez['negative']}") if rez["pierdute"] or rez["dubluri_leaf"] or rez["dubluri_bal"] or rez["lungimi"]: print(" ATENTIE:", rez["pierdute"], rez["dubluri_leaf"], rez["dubluri_bal"], rez["lungimi"]) diff --git a/init_FUNDATIA_2025_12.xlsx b/init_FUNDATIA_2025_12.xlsx index 7a4555b..d9aa688 100644 Binary files a/init_FUNDATIA_2025_12.xlsx and b/init_FUNDATIA_2025_12.xlsx differ diff --git a/init_MASTER_2025_12.xlsx b/init_MASTER_2025_12.xlsx index ee919b2..8c471c0 100644 Binary files a/init_MASTER_2025_12.xlsx and b/init_MASTER_2025_12.xlsx differ