Cititorul FDB: sume totale ca SAGA, analitice pastrate, baza oprita acceptata

Proba pe LACERTA (06/2026, firma reala) a gasit doua defecte in citire_fdb:
- precedentul netea si rulajele din an, deci conturile de cheltuieli/venituri
  pierdeau rulajul (CPP gresit). Acum: preluare netata + rulaj an brut;
  potriveste 44/44 sintetice din importul facut din exportul SAGA (inainte 19/44).
- analiticele se rulau in sintetic, deci facturile per document nu se foloseau
  si analiticele nepartener disparea. Acum balanta are toate nivelurile.

Baza primita se copiaza in temporar si copia se repune online (clientul o
trimite si in full shutdown). tests/test_lacerta.py: 48/53 frunze identice cu
REF, restul explicate; se sare fara fisierele clientului, care sunt ignorate
de git. README nou; analiza in docs/analiza_lacerta_fdb.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYeAtVxeS8m4oXekjX8Am2
This commit is contained in:
2026-09-25 16:14:14 +03:00
parent 3499a0946c
commit 99d9cf0aff
8 changed files with 453 additions and 44 deletions

135
docs/analiza_lacerta_fdb.md Normal file
View File

@@ -0,0 +1,135 @@
# Analiza LACERTA - drumul FDB comparat cu importul facut din exportul SAGA
25.09.2026. Prima proba a cititorului FDB pe o firma reala, cu analitice si volum.
Intrari (in `exemple/`, **nu in git** - contin nume de persoane si CNP-uri):
- `lacerta_CONT_BAZA-20-08_2026.FDB` - copia bazei, facuta la 20.08.2026;
- `lacerta_init_facturi_balanta_note-20-08_2026.xlsx` - xlsx-ul de initializare facut din
exportul de balanta SAGA, perioada **06/2026** (56 BALANTA + 46 FACTURA). Mai jos: **REF**.
Rulare (copie in scratchpad, `date/` si `iesiri/` neatinse):
```
gfix -online normal <copie>.FDB -user SYSDBA -password masterkey # vezi constatarea 1
py extrage.py --fisier <copie>.FDB --firma LACERTA --an 2026 --luna 6 --dir <tmp>
py genereaza.py --firma LACERTA --an 2026 --luna 6 --dir <tmp> --dir-iesire <tmp>\out
```
Rezultat: 54 de randuri, 4.323.688,60 pe ambele laturi, verificarile interne trec.
Verificarile trec, dar **iesirea e gresita** in doua moduri (constatarile 2 si 3).
---
## Constatari despre unealta noastra
### 1. Copia clientului vine in stare `full shutdown` - cititorul nu o deschide
`gstat -h` arata `Attributes: force write, full shutdown`; conectarea da `database ... shutdown`.
Clientul (sau SAGA) a oprit baza inainte de copiere - corect din partea lui. Pe **copia
noastra** `gfix -online normal` o repune; originalul ramane neatins.
### 2. Sumele totale sunt calculate gresit - afecteaza CPP-ul (defect)
`citire_fdb.py:84` neteaza **impreuna** soldul de preluare si rulajele lunilor anterioare din an:
`prec = net(init + an)`. SAGA (si REF) calculeaza `prec = net(init) + rulaj an`, **brut**.
| regula | conturi sintetice din REF potrivite |
|---|---|
| actuala: `net(init + an) + luna` | 19 / 44 |
| propusa: `net(init) + an + luna` | **44 / 44** |
Netul iese la fel in ambele cazuri, de aceea verificarile interne trec. Dar pe conturile de
cheltuieli si venituri rulajele Ian-Mai se anuleaza: `6022`, `6123`, `6231`, `6232`, `635`,
`667` ies cu `0 / 0` in loc de rulaj, iar `704` iese cu 684,68 in loc de 14.139,64.
Contul de profit si pierdere din ROA ar iesi gresit.
Pe firma de joaca regulile dau acelasi rezultat pe toate conturile. De aceea poarta a trecut,
si tot de aceea schimbarea nu o strica.
### 3. Cititorul arunca analiticele - pierde facturile si analiticele nepartener (defect)
`citire_fdb` ruleaza orice analitic in sintetic (`401.00002` -> `401`, `215.1` -> `215`). Baza
are planul analitic complet in `CONTURI`: 12 sintetice cu analitice in `REGISTRU`, inclusiv
`215.1-3` / `2815.1-3`, `4551.1-3`, `5121.1-2`, `542.01-02`, 15 furnizori, 26 clienti.
Consecinte:
- **Facturile nu se folosesc deloc.** `facturi_LACERTA.csv` are 74 de documente, dar generatorul
le cauta dupa analiticul partenerului (`genereaza_xlsx.py:265`), care nu mai exista. Rezultatul
e un singur `FACTURA` agregat pe cont, fara nume si fara cod fiscal real.
- **Analiticele nepartener dispar.** REF are `215` pe trei analitice; noi avem un singur rand.
- Facturile se potrivesc cu balanta: la **29 / 29** parteneri 401/4111, suma facturilor din baza
este egala cu netul analiticului. Deci, daca pastram analiticele, drumul "un FACTURA per
document" functioneaza fara nicio ajustare.
Aceasta este exact limita scrisa in docstring-ul lui `citire_fdb.py` ("NU dovedeste nimic despre
conturile analitice"). Acum e dovedita, si nu tine.
### 4. Analitice care nu intra in `acont` de 4 caractere
`419.NETOPIA`, `4428.M`, `4428.TI`, `4428.TP`, `461.SGR`. Dupa constatarea 3 vor ajunge la
mapare. `mapare.py` trebuie sa se opreasca pe ele si sa ceara o corectie (REF a pus `419.2`).
---
## Constatari despre REF (xlsx-ul deja facut din exportul SAGA)
Le scriu pentru ca REF a fost folosit la initializarea din ROA:
1. **REF nu e echilibrat**: are 6.315.365,48 pe debit si 5.043.406,14 pe credit. Cauza:
`215`, `2815` si `4091` apar si cu randul sintetic, si cu analiticele, adica de doua ori
(+1.530.528,54 D, +265.716,75 C, +7.810,92 D). Incalca regula "in xlsx intra doar frunzele".
**De verificat in ROA daca soldurile acestor conturi au intrat dublu.**
2. Pe **`4092` lipsesc 1.563,37, iar pe `419` lipsesc 900,00.** Sunt note inregistrate direct pe
sintetic, nu pe analitic (5 x 230 Starlink + 183,37 Netopia + 230 in iunie; 900 in februarie).
REF a luat doar analiticele. Regula noastra de "analitic de diferenta" le prinde.
3. Randurile `FACTURA` pe 401 insumeaza 9.220,75, fata de un net de 48.261,67. Multe au `sold`
gol, iar una are data `1910-05-13`.
Pe restul, REF si FDB coincid: 44 / 44 de sintetice pe sume totale, iar netul pe fiecare cont.
---
## Propuneri, in ordinea in care le-as face
| # | ce | marime | dovada ca a mers |
|---|---|---|---|
| P1 | `citire_fdb.py:84`: `prec = net(init) + an`, brut | ~2 linii | 44/44 pe LACERTA; testele pe firma de joaca raman verzi |
| P2 | `citire_fdb` emite si randurile analitice (sintetic + analitic, ca exportul SAGA "cu analitice"); poarta pe firma de joaca compara doar sinteticele | mediu | FACTURA per document pe 401/4111; `215.1-3` ca frunze |
| P3 | `extrage.py` pe drumul fdb copiaza baza in temporar si ruleaza `gfix -online` pe copie; procedura clientului mentioneaza ca oprirea bazei e acceptata | mic | LACERTA se deschide fara pas manual |
| P4 | test de regresie LACERTA: BALANTA pe frunze = REF, cu exceptiile de mai sus scrise explicit; se sare daca fisierele lipsesc (nu sunt in git) | mic | pica daca revine P1 sau P2 |
| P5 | `exemple/lacerta_*` in `.gitignore`: xlsx-ul are CNP-uri, iar acum nu e ignorat (FDB-ul este) | 1 linie | `git check-ignore` |
**Decizii care sunt ale tale, nu ale mele**, si nu le-am atins:
- `542` (decontari din avansuri): REF il trateaza ca cont cu parteneri (2 persoane); config-ul nostru nu.
- `461` si `4092`: config-ul le trateaza ca parteneri, REF nu.
- `config/conturi_parteneri.csv` descrie `4092` ca "Furnizori de imobilizari", dar 4092 e
"furnizori-debitori pt. prestari servicii" (furnizorii de imobilizari sunt 404). Verifica daca
e doar descrierea gresita sau si contul.
- Coloana `data` la BALANTA: noi scriem `01.06.2026`, REF are `30.06.2026`. Etalonul importat
foloseste forma noastra, deci probabil ambele sunt acceptate, dar confirma.
## Ce s-a facut (25.09.2026)
P1-P5 sunt facute. Rulare pe LACERTA dupa ele (`tests/test_lacerta.py`):
- `extrage.py` citeste direct fisierul oprit din `exemple/`; originalul ramane `full shutdown`;
- 97 de randuri de balanta (sintetice + analitice), 79 de randuri in xlsx, echilibrat
(4.775.134,59 pe ambele laturi), verificarile interne OK;
- **48 din 53** de frunze BALANTA sunt identice cu REF; restul diferentelor sunt listate
in test (`DIFERENTE_ASTEPTATE`), fiecare cu cauza;
- 401: 12 randuri FACTURA, cate unul per document nesoldat, cu numar, data, scadenta si
CUI real; suma e 9.220,75, cat in REF. Restul de 39.040,92 (preluarea postata direct pe
401, fara partener) ramane pe `NEREPARTIZAT`, ca in regula stabilita;
- poarta e reala: fara P1 testul pica pe sume, fara P2 pica la generare.
Corectiile folosite (in test, ca in REF): `419.NETOPIA -> 419 / 2`, `4428.TOATE -> 4428`.
## Intrebari deschise
1. **4428 iese pe doua randuri**: `4428` fara acont (373,14, analiticele M/TI/TP stranse
prin `.TOATE`) si `4428 / 99` (1.376,54, postarile direct pe sintetic). Nu stiu cum
trateaza importul un cont cu rand si fara acont, si cu acont. Varianta sigura:
corectia `4428.TOATE -> 4428 / 01`, ca sa iasa doua frunze curate. Decizia e a ta.
2. `.fbk`: procedura clientului recomanda backupul `.fbk` ca varianta preferata, dar
`extrage.py` nu il accepta (nu il restaureaza cu `gbak -c`). Deocamdata clientul
trebuie sa trimita `.FDB`.
3. Deciziile de config de mai sus (`542`, `461`, `4092`) si coloana `data`.
## Starea pe disc
Cod: `citire_fdb.py` (P1-P3), `tests/test_citire_fdb.py` (poarta restransa la sintetice),
`tests/test_lacerta.py` (P4), `.gitignore` (P5). Suita: `py -m unittest discover -s tests`,
37 de teste, toate trec. Fisierele LACERTA din `exemple/` sunt ignorate de git.