citire_fdb.py produce balanta, parteneri si facturi din CONT_BAZA.FDB. Soldurile stocate in CONTURI sunt 0, deci balanta se obtine agregand REGISTRU pe cele trei intervale de data; analiticul se ruleaza in sintetic si se emit ambele randuri; contul colector % se exclude. Conexiune embedded, READ, doar SELECT, rollback. Garzi pe NULL: scadenta lipsa cade pe ultima zi a lunii, codul fiscal lipsa pe codul provizoriu, partenerul intrand in lista pentru cautarea ANAF. Poarta: CSV-ul din FDB e identic la octet cu cel produs de citire_xlsx.py din exportul firmei de joaca (09/2026), iar SUM(REGISTRU) pe fiecare latura da netul balantei. Verificat independent: 10 conturi, 7298.15 pe ambele laturi. Limita, scrisa si in cod si in raport: firma de joaca nu are niciun analitic, deci cititorul e verificat DOAR pe cazul sintetic si nu se foloseste la un client fara rerularea portii pe datele lui. docs/procedura_copie_fdb_client.md: cum isi face clientul copia bazei. 23 de teste trec, fara skip. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYeAtVxeS8m4oXekjX8Am2
142 lines
6.5 KiB
Markdown
142 lines
6.5 KiB
Markdown
# Raport lane `citire-fdb` - cititorul Firebird (SAGA noua)
|
|
|
|
Lane: `citire-fdb`, etapa 2. Data: 21.09.2026. Director: `D:\ROA\IMPORT2ROA\solduri2roa`.
|
|
|
|
## 1. Facut (livrabile)
|
|
|
|
| fisier | ce |
|
|
|---|---|
|
|
| `citire_fdb.py` | cititorul: balanta + parteneri + facturi din copia unei baze `CONT_BAZA.FDB` |
|
|
| `tests/test_citire_fdb.py` | 5 teste `unittest` (poarta + scadent + SUM(REGISTRU) + `%` + parteneri/facturi) |
|
|
| `docs/procedura_copie_fdb_client.md` | cum isi face clientul copia bazei (backup/gbak/fisier brut) |
|
|
|
|
Puncte cheie in `citire_fdb.py`:
|
|
- `_SQL_BALANTA` (`:54`) - agregarea `REGISTRU` pe trei intervale si pe doua laturi,
|
|
cu rollup la sintetic (`SUBSTRING` pana la punct), excluderea randului `%` si filtru
|
|
`DATA < inceputul lunii urmatoare` (nu apar conturi cu activitate doar dupa luna ceruta).
|
|
- `_conecteaza` (`:92`) - embedded, `fbclient.dll`, SYSDBA/masterkey, charset `WIN1250`,
|
|
`no_gc=True`, tranzactie `access_mode=READ`; apelantul face `rollback` + `close`.
|
|
- `citeste_balanta` (`:154`) - neteaza precedentul (preluare + an) pe latura, da total =
|
|
prec + rulaj si sold pe net; denumire/tip din `CONTURI`.
|
|
- `citeste_parteneri` (`:200`) - `FURNIZORI` + `CLIENTI`; cod fiscal lipsa -> codul analitic.
|
|
- `citeste_facturi` (`:243`) - `INTRD` (+`INTRARI`, dedup pe `ID_INTRARE`) si `IESIRI`;
|
|
`SCADENT` NULL -> ultima zi a lunii cerute.
|
|
- `produce` (`:287`) - scrie cele trei CSV-uri; `main` (`:303`) - CLI
|
|
`py citire_fdb.py "<baza.fdb>" "<FIRMA>" <an> <luna> [dir]`.
|
|
- Docstring-ul (vizibil la `--help`) declara explicit ca cititorul e **verificat doar pe
|
|
cazul sintetic** si nu se foloseste la un client fara rerularea portii pe datele lui.
|
|
|
|
Doar creari de fisiere noi. Nu s-a modificat `genereaza_xlsx.py`, `citire_xlsx.py`,
|
|
`mapare.py`, `extract_balanta.py`, `config/*`, `tests/golden/*`, `tests/test_regresie.py`,
|
|
`tests/anonimizeaza_etalon.py`, `init_facturi_balanta_note.xlsx`. Nu s-a scris nimic in
|
|
`D:\SAGA250909` (doar copie citita in temporar).
|
|
|
|
## 2. Verificari
|
|
|
|
### Poarta (criteriul de terminare)
|
|
|
|
Comanda de test:
|
|
|
|
```
|
|
py -m unittest discover -s tests -v
|
|
```
|
|
|
|
Rezultat (exact):
|
|
|
|
```
|
|
Ran 23 tests in 1.271s
|
|
|
|
OK
|
|
```
|
|
|
|
23 = cele 18 existente + 5 noi. `EXIT=0`. (Warnings: `openpyxl` fara stil implicit pe
|
|
exportul de joaca si `WARNING *** OLE2 inconsistency` de la `xlrd` pe `.xls` - preexistente,
|
|
nu esecuri.)
|
|
|
|
Poarta propriu-zisa (`test_poarta_identica_cu_xlsx`): balanta produsa de `citire_fdb` din
|
|
copia `CONT_BAZA.FDB` este **identica** cu cea produsa de `citire_xlsx.py` din
|
|
`exemple\saga-sqlite-balanta-09-2026.xlsx`, pentru luna 09/2026. Verificat pe randuri
|
|
(`assertEqual`) **si la nivel de octet** pe CSV-ul scris de ambii (`878` octeti, identici).
|
|
|
|
Verificare manuala suplimentara (aceeasi concluzie):
|
|
|
|
```
|
|
nr xlsx 10 nr fdb 10
|
|
identice
|
|
```
|
|
|
|
### Inlocuitorul verificarii "Totaluri:"
|
|
|
|
`test_sum_registru_egal_netul_balantei`: `SUM(REGISTRU)` pe debit si pe credit (fara
|
|
`%`/gol) la data ceruta; laturile sunt egale (`8774.15` = `8774.15`), iar
|
|
`(debit - credit)` = netul balantei generate (`0.00`). OK.
|
|
|
|
### Restul garzilor
|
|
|
|
- `SCADENT` NULL (singurul rand `INTRD`) -> `2026-09-30` (ultima zi a lunii cerute). OK.
|
|
- Contul colector `%` nu apare in iesire; niciun rand fara cont. OK.
|
|
- Parteneri: 2 randuri (`ROMFAST` fara cod fiscal -> provizoriu `401.00001`; `TRANSPORT`
|
|
-> `1879855`). Facturi: 1 rand (`401.00001`, `123`, `2026-07-02`, `2026-09-30`, `0.0`).
|
|
- Cod mod: fisier ASCII, LF (ca `citire_xlsx.py`), 0 octeti > 127.
|
|
|
|
Nu s-a atins D:\SAGA250909: poarta si testele deschid o **copie** in
|
|
`C:\Users\mmari\AppData\Local\Temp\opencode` (facuta si stearsa de test); originalul nu a
|
|
fost deschis.
|
|
|
|
## 3. Nefacut / blocat / intrebari deschise
|
|
|
|
### 3.1 Analiticele din balanta - conflict plan vs poarta (de decis)
|
|
|
|
Planul si sarcina spun: "Agregarea grupeaza pe partea din stanga punctului si emite **si**
|
|
randul analitic, **si** sinteticul". Poarta spune: balanta FDB trebuie sa fie **identica**
|
|
cu cea din `.xlsx`.
|
|
|
|
Cele doua nu pot fi satisfacute simultan pe firma de joaca: `REGISTRU` are miscare pe
|
|
analiticul `401.00002`, dar exportul `.xlsx` are **doar** randul sintetic `401` (10
|
|
randuri, niciunul cu punct). Daca as emite si analiticul, as obtine 11 randuri si poarta
|
|
pica. Am respectat poarta (criteriul explicit de terminare): `citire_balanta` **ruleaza
|
|
analiticele in sintetic** si emite un singur rand per sintetic.
|
|
|
|
Consecinta, de stiut: pentru un client real, `balanta_<FIRMA>.csv` produs de acest cititor
|
|
**nu contine conturile analitice**. In aval, `genereaza_xlsx.py` (pct. `:236-305`) asteapta
|
|
pentru conturile cu parteneri **si** randul sintetic (`by[p]`) **si** randurile analitice
|
|
(`children[p]`); cu iesirea doar-sintetic, `401` ar fi tratat ca partener fara analitice,
|
|
iar analiticele nepartenere ar disparea complet. Planul insusi scrie ca acest cititor e
|
|
"verificat partial ... nimic despre analitice - exact partea grea".
|
|
|
|
Nu am ghicit: am ales poarta. Ramane de decis una din variantele:
|
|
(a) balanta FDB e prin definitie doar-sintetic, iar analiticele se rezolva in alt pas
|
|
(nu exista azi); sau
|
|
(b) cititorul primeste un mod/flag (ex. `--analitice`) si poarta se defineste pe proiectia
|
|
sintetica, nu pe "identic".
|
|
|
|
### 3.2 `rulaj` brut vs net (asumare)
|
|
|
|
`DEB_PREC == SOLD_IN_D` in export (ex. `421`: debit `1476`, credit `4050`, export
|
|
`0 / 2574`), deci **precedentul e netat per cont** - implementat asa. Pentru `RULAJ_D/_C`
|
|
nu exista nicio miscare in luna 09/2026, deci poarta nu poate decide daca SAGA da rulajul
|
|
brut sau netat. Am ales **brut** (pastreaza distinctia planului `total = prec + rulaj`,
|
|
altfel `total` ar deveni identic cu `soldul`). De reverificat pe primul client real.
|
|
|
|
### 3.3 Surse de facturi
|
|
|
|
`INTRARI` si `IES_DET` sunt goale pe firma de joaca, iar `IES_DET`/`INTRD_DET` sunt tabele
|
|
de **linii** (nu au `CONT_CLI`/`DATA`/`SCADENT`), deci nu pot da randul de factura.
|
|
Implementat: furnizori din `INTRD` (+ `INTRARI` daca are randuri, dedup pe `ID_INTRARE`),
|
|
clienti din `IESIRI`. Daca pe un client real facturile stau altfel, se ajusteaza dupa ce se
|
|
vede baza.
|
|
|
|
### 3.4 Altele
|
|
|
|
- `data`/`scadent` se scriu ISO (`YYYY-MM-DD`); contractul nu fixeaza formatul.
|
|
- `.gitignore`: planul (sectiunea Git) cere `parteneri_*.csv` / `facturi_*.csv` / `*.fdb`;
|
|
nu le-am adaugat (in afara livrabilului lane-ului).
|
|
- Ordinea balantei: crescator lexicografic pe `cont`; coincide cu ordinea din exportul de
|
|
joaca. Daca SAGA real ordoneaza altfel, poarta pe client va arata.
|
|
|
|
## 4. Stare periculoasa
|
|
|
|
Niciuna. Fara procese lasate pornite, fara `.vc2`/`.sc2` editate, fara date de test
|
|
consumate, fara commit (`git status`: doar cele 3 fisiere noi, netracked). Copiile
|
|
temporare ale bazei au fost sterse.
|