Files
roafacturare/docs/cercetare/rec_s8_creare_variante.md
Marius Mutu d9f5ca4226 docs: planurile, proiectarile si rapoartele de lucru intra in versionare
Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git,
nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de
cercetare pe care se sprijina modificarile din cod. O stergere acolo era
definitiva.

Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au
fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele
fisierelor de test la care se refereau.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-11 22:17:17 +03:00

217 lines
16 KiB
Markdown

# S8 — Creare documente lipsa (aviz, factura din aviz, factura din contract) pe fluxul REAL
> # OPRESTE-TE — SARCINA E INCHISA, 10.08.2026 ora ~12:35
>
> **NU relua depanarea crash-ului `frm_alte_date` si NU mai rula `creeaza_documente_s8.prg`.**
> Scopul acestui raport — sa EXISTE cele trei documente — **e deja atins pe alta cale**: Marius le-a
> emis manual din aplicatie, prin fluxul real (ceea ce satisface regula „niciodata `INSERT` direct"
> mai bine decat orice harness).
>
> | Tip sursa | `id_vanzare` | `cod` | `id_fact` | totaluri |
> |---|---|---|---|---|
> | aviz (tip 22) | **1052** | 1140908 | 8009677 | 271.17 / 56.94 / 328.11 |
> | factura din aviz (tip 4) | **1054** | 1140910 | 8009679 | 252.07 / 52.93 / 305.00 |
> | factura din contract (tip 2) | **1055** | 1140911 | 8009680 | 200.00 / 42.00 / 242.00 |
>
> Verificate prin `sqlplus` de orchestrator: toate `data_act = 10.08.2026`, `sters = 0`, cu linii,
> note `ACT` si rulaje. Impreuna cu `1048` (lista de preturi), matricea S8 e completa pe toate patru
> tipurile de sursa.
>
> **Fiecare rulare a harness-ului strica date.** Rularea de la **12:28:31** a creat `1056` si `1057`
> — documente malformate: totaluri `0/0/0`, `RUL` gol, si **acelasi numar `SSS/14` alocat la toti trei
> pasii** (log liniile 12, 23, 29), deci cu numar duplicat. Ele **nu se folosesc** in matrice si
> urmeaza sa fie sterse prin aplicatie. Nu mai adauga altele.
>
> **Ce a mai ramas din S8 nu e automatizarea, ci matricea**: cele patru documente
> (`1048 / 1052 / 1054 / 1055`) editate fiecare **de doua ori** — o data din ROAFACTURARE, o data din
> registrul jurnal ROACONT — cu verificarile din `plan_06_editare_factura.md:282-291`.
> Starea la zi e in `docs\progres.md`, sectiunea „S8 — DOCUMENTELE EXISTA".
>
> *De pastrat din investigatia de mai jos, indiferent de sarcina*: pe masina ruleaza mai multi agenti
> cu procese `vfp9.exe` concurente — **progresul unei rulari se citeste DOAR din log**, niciodata prin
> `tasklist`/`Get-Process`/PID (PID-ul intors de `Start-Process` poate fi un launcher care iese imediat).
Status istoric: **PREDARE (Regula zero) — NEFINALIZAT** la momentul scrierii. Niciun document creat de
harness la acea ora. Investigatia de cod de mai jos ramane valida si citata cu `fisier:linie`, utila
daca automatizarea se reia candva — dar **nu e nevoie de ea pentru S8**.
Continua `rec_s8_creare_variante_plan.md` (plan) si
`rec_s8_inventar.md` (de ce lipsesc). Scop strict: **crearea** celor 3 documente prin fluxul real de
emitere (`ofacturare.prg::factureaza` -> `do_scrie_factura` -> `PACK_FACTURARE`), zero INSERT direct,
zero editare de cod productie. Editarea propriu-zisa (matricea S8) NU intra in scopul acestei runde.
## Plan de executie (din `rec_s8_creare_variante_plan.md`)
1. AVIZ (`tnTip=22`) din lista de preturi.
2. FACTURA DIN AVIZ (`tnTip=4`), sursa = avizul de la pasul 1.
3. FACTURA DIN CONTRACT (`tnTip=2`), pe `id_ctr=235` (NU `id_ctr=222`).
Interzis: INSERT/UPDATE direct pe documente, editare cod productie, commit, alta schema decat
`MARIUSM_AUTO`, atingerea `id_vanzare` 1048/1049/1050, input real (keybd_event/SendInput).
## Progres
- [x] Citit `frm_date_aviz.inainte_de_do_termin` (garda, `ofacturare.vc2:7277-7352`) si `Init` (7354-7600)
- [x] Citit `frm_date_factura.inainte_de_do_termin` (`ofacturare.vc2:9455-9561`)
- [x] Citit `oDateFactura.Init`/`initializeaza_setari_document` (`ofacturare_comun.prg:223-359`)
- [x] Citit `oGeneratorNumere.creeaza_cursor_serii`/`aloca_numar`/`verifica_numar` (`oserii_numere.prg:128-234`)
- [x] Citit `do_scrie_factura` integral (`ofacturare.vc2:14197-14554`) si `frm_facturare_articole.inainte_de_do_termin` (14806-14974)
- [x] Citit `frm_alte_date.inainte_de_do_termin`/`Init` (`ferestre_cere_date.vc2:3044-3200`)
- [x] Citit precedentele: `test_pret_cu_tva_nivel2.prg`, `test_s5_al_doilea_intrare.prg`, `test_init_env_auto.prg`
- [x] Gasit al treilea modal neanticipat de plan: `Do Form verificare` (`ofacturare.vc2:14404`, in `do_scrie_factura`) - rezolvat cu stub-ul EXISTENT `COMUN\utile\Teste\achizitie_import\stub_verificare\verificare.sc2` (Init->`gnButon=1`+`RETURN .F.`), pus PRIMUL in `SET PATH`
- [x] Verificat in Oracle: `id_fdoc` e AUTO-DERIVAT de `oDateFactura.Init` (`actualizeaza_document()`), nu trebuie setat manual; `dataireg`/`dataact`/`datascad`/`zi_curs` la fel
- [x] Verificat contract `id_ctr=235`: 4 randuri `CTR_SCADENTAR`, toate cu `ID_ACT` NULL (nefacturate) - document real, neconsumat, nu fabricat
- [x] Verificat delegat `id_part=256` ("DELEGAT"), client `463`=RAJA, client `598`=ABSOLUT SRL - toti valizi in `NOM_PARTENERI`
- [x] Scris harness `creeaza_documente_s8.prg` (`COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg`)
- [ ] Rulat pas 1 (AVIZ) + verificare Oracle
- [ ] Rulat pas 2 (FACTURA DIN AVIZ) + verificare Oracle
- [ ] Rulat pas 3 (FACTURA DIN CONTRACT) + verificare Oracle
- [ ] Verificare finala: zero vfp9.exe, zero tranzactii deschise
## Design harness (creeaza_documente_s8.prg)
Reproduce corpul lui `Procedure factureaza` (`ofacturare.prg:81-560`) per `tnTip`, cu conexiune
Oracle REALA (`goConn.Connect('CENTRAL','MARIUSM_AUTO','ROMFASTSOFT')`, spre deosebire de
`test_pret_cu_tva_nivel2.prg` care avea `goExecutor` mock). Doua inlocuiri, ambele DOAR de
conducere UI:
1. Dialogul modal de antet (`frm_date_aviz`/`frm_date_factura`) -> setare directa `poDate.id_client`,
`poDate.listaid`, `poDate.id_delegat`; `poDate.nract`/`serie_act` din
`poGeneratorNumere.creeaza_cursor_serii()`+`aloca_numar()` REAL (acelasi apel facut de controlul
`clb_serie_act` din dialog, `serii_numere.vc2:114-136`).
2. Al doilea modal, `frm_alte_date` - condus cu driverul `driverAlteDate8` (Timer pe `_SCREEN`,
cauta clasa `FRM_ALTE_DATE`, apeleaza `.do_termin()` direct).
Al treilea modal (`Do Form verificare`) evitat prin stub existent in `SET PATH`, nu prin driver.
Ordine reala: `do_adauga_tot()` -> `do_calculeaza_totaluri()` -> `do_termin()` ->
`inainte_de_do_termin()` -> `do_scrie_factura()` -> `PACK_FACTURARE` (neatins). Rezultatul
(`id_vanzare`) vine din `poDate.nid_vanzare`, populat de parametrul OUT al procedurii PL/SQL reale.
## Note pe parcurs
Iteratii de depanare headless (log: `creeaza_documente_s8_log.txt`, langa `.prg`):
1. **Bug structural**: `PROCEDURE S8Log`/`S8Err` erau plasate INAINTE de `TRY` in fisier -> VFP
"cade" (fall-through) in corpul lor la executia liniara, inainte sa apuce sa intre in `TRY`.
Corectat: mutate DUPA `QUIT`, ca in toate precedentele (`test_pret_cu_tva_nivel2.prg`,
`test_s5_al_doilea_intrare.prg` au aceeasi conventie - procedurile dupa `QUIT`).
2. **Variabila lipsa** `gcSettingsFile`/`goApi` - cerute de `get_ora()` (apelat din
`oDateFactura.Init`). Adaugate din `test_init_env_auto.prg:209-230`.
3. **Data curs EUR lipsa**: `cursor_preturi`/`cursor_contract` cad cu eroarea Oracle reala "Nu este
setat cursul din data de 10/08/2026 pentru EURO!" - verificat in Oracle, nu exista curs EUR
pentru 10.08.2026 in `MARIUSM_AUTO` (ultimul: 07.08.2026 = 5.29, tot in luna curenta). Productia
trateaza asta cu un dialog editabil (`vizualizeaza_curs`); headless am setat
`poDate.zi_curs = {^2026-08-07}` (camp distinct de `dataact`/`dataireg` - nu schimba data
documentului, doar ziua de curs folosita pt. articolele in valuta din lista de preturi/contract).
4. **Bug propriu**: cleanup-ul cursoarelor `jtva_coloane`/`jtva_coloane_temp` lipsea pe caile de
iesire timpurie (eroare cursor / Reccount=0) din `CreeazaDocument` - factorizat in
`S8CurataJtva`, apelat pe toate caile.
5. **Variabile globale lipsa** `gnFactSeturi`/`gnCoefKFact`/`gnListareAvizBonFiscal`, cerute de
`frm_facturare_articole.inainte_de_do_termin`. Adaugate (`gnFactSeturi=0`, ramurile respective
raman inactive pt. documentele noastre).
6. **In curs**: dupa `do_adauga_tot()` (Reccount(crsfactura)=1, AVIZ tip=22), driverul
`driverAlteDate8` detecteaza `FRM_ALTE_DATE` si apeleaza `.do_termin()` - logul se opreste imediat
dupa acel apel, fara eroare prinsa de `TRY/CATCH` din driver si fara linia urmatoare din
`CreeazaDocument`. De investigat daca e blocaj real sau doar Oracle lent pe primul apel PL/SQL
din acel punct (`pack_facturare.scrie_factura2`/etc). **ATENTIE constatata in aceasta runda**:
masina ruleaza MAI MULTI agenti in paralel, fiecare cu propriile procese `vfp9.exe` - PID-ul
raportat de `Start-Process` in PowerShell corespunde unui proces-lansator care iese rapid
(`WaitForExit` intoarce `True` desi scriptul REAL continua intr-un proces `vfp9.exe` copil cu alt
PID) - `tasklist`/`Get-Process vfp9` NU se poate folosi ca sa identifice procesul propriu fara
ambiguitate cand alti agenti au procese vfp9 concurente. Verificarea de progres se face DOAR prin
continutul logului, niciodata prin PID/`Responding`. `Stop-Process` pe `vfp9` e evitat cu
exceptia cazurilor cu dovada tare (PID exact, pornit chiar de comanda curenta).
Confirmat prin doua rulari succesive (ultima: pornita 11:50:29, monitor extern a asteptat inca
~120s, TIMEOUT, log neschimbat): blocajul e **reproductibil**, nu tranzitoriu — se opreste mereu
imediat dupa linia `driverAlteDate8: FRM_ALTE_DATE detectat, apas do_termin()`, fara nicio linie
ulterioara (nici succes, nici CATCH din `TRY` al driverului, nici `ON ERROR` de la nivelul
programului principal).
## HANDOFF (Regula zero) — STARE LA OPRIRE
**NIMIC PERICULOS**: verificat, nu presupus.
| Ce | Cum s-a verificat | Rezultat |
|---|---|---|
| Documente create in Oracle | `select ... from vanzari where trunc(data_act)=trunc(sysdate) and id_part in (463,598)` prin sqlplus | **zero randuri** — nu s-a scris niciun document, nici partial |
| Tranzactii Oracle deschise | `v$transaction` join `v$session` pentru `MARIUSM_AUTO` prin sqlplus | **zero** |
| Sesiuni Oracle active pe `MARIUSM_AUTO` | `v$session where username='MARIUSM_AUTO'` | doar `plsqldev.exe`/`sqlplus.exe` (ale mele, de verificare) — **niciun `vfp9.exe` conectat** |
| Procese `vfp9.exe` ramase | `Get-Process -Name vfp9` | **niciunul** (procesul harness-ului s-a terminat/crash-uit fara sa ramana agatat) |
| Fisiere editate fara write-back | harness-ul e `.prg` text simplu (nu `.vc2`/`.sc2`), scris direct — nu exista pas de conversie binar | N/A |
**Date de test consumate — posibil, de verificat prima data in sesiunea urmatoare**: rularea a
apucat sa apeleze `poGeneratorNumere.aloca_numar(6, NULL)` REAL pentru AVIZ (`nIdTipDoc=6`,
serie `SSS`, numar alocat **12** — vezi log linia 12), INAINTE de crash. Daca
`pack_serii_numere.aloca_numar` face commit intern (nu e in tranzactia manuala deschisa abia mai
tarziu de `do_scrie_articole`/`do_deschide_tranzactie`), numarul **12** din seria `SSS` (tip doc 6 =
AVIZ) ar putea fi ars fara sa existe niciun document care sa-l foloseasca. **De verificat cu
sqlplus** inainte de a relua (interogare pe cursorul de serii / tabela care tine `paPlaje`-ul in
Oracle, echivalentul `NOM_SERII_NUMERE`/`NOM_SERII_NUMERE_PLAJE` sau similar — nu identificat inca
numele exact al tabelei) — daca da, following runda trebuie doar sa noteze faptul (nu e o problema
de corectitudine, seria oricum sare numere cand un document e anulat, e comportament normal de
productie), nu sa incerce sa-l "recupereze".
**Ce e facut**:
- Harness complet scris: `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg`
(singurul fisier nou, cf. restrictiilor din briefing).
- Mediu real (Oracle `MARIUSM_AUTO`, clase/proceduri ROAFACTURARE) se initializeaza corect si
ajunge pana in mijlocul fluxului de scriere pentru PRIMUL document (AVIZ, tip=22):
`crsarticole` populat real (1 rand), `crsfactura` populat real prin `do_adauga_tot()`,
`frm_alte_date` detectat corect de driver.
- Toate cele 6 probleme de mai sus (`Note pe parcurs`) sunt REZOLVATE si verificate ca depasite
(log-ul avanseaza pana la linia 16 de fiecare data, deterministic).
**Ce NU e facut / blocajul curent**:
- `driverAlteDate8.Executa` apeleaza `loForm.do_termin()` pe `FRM_ALTE_DATE` (gasit prin
`_SCREEN.Forms`, din Timer) si procesul **nu mai avanseaza deloc** dupa acel apel — fara eroare
prinsa (nici de `TRY/CATCH` din driver, nici de `ON ERROR` global), ceea ce sugereaza un
**crash dur al motorului VFP** (access violation sau similar), nu o eroare VFP normala. Ipoteza
cea mai probabila: apelarea `.do_termin()` DIRECT pe un formular aflat inca in interiorul
propriului `.Show(1)` (modal, apelat sincron din `frm_facturare_articole.inainte_de_do_termin`,
`ofacturare.vc2:14935`), din interiorul unui callback de `Timer` legat pe `_SCREEN`, e mai fragil
pentru `frm_alte_date` decat a fost pentru `frm_articol_factura` in precedentul
`test_pret_cu_tva_nivel2.prg` (acolo a functionat cu acelasi tipar exact). Posibile cauze de
investigat, in ordinea propusa:
1. `frm_alte_date` ar putea avea un `Release`/`Hide` in `do_termin` sau in gard-ul lui
(`ferestre_cere_date.vc2:3044-3103`, deja citit) care intra in conflict cu contextul de apel
din Timer — de comparat linie cu linie cu `_frmbase.do_termin` (neexaminat inca in aceasta
runda) ca sa se inteleaga EXACT ce face `do_termin` generic (posibil `This.Hide()` +
`Thisform.Release()` pe un `Thisform` care in acel moment NU mai e valid din perspectiva
stivei de apel Timer).
2. Incearca sa gaseasca un buton real (`but_termin1` sau similar) in interiorul lui
`frm_alte_date` si sa apeleze `.Click()` pe el in loc de `.do_termin()` direct — mai aproape de
ce ar face un operator, posibil mai stabil (nu s-a gasit inca numele exact al butonului in
aceasta runda — `grep but_termin` pe clasa n-a dat rezultate in intervalul cautat, de reluat cu
`vfp_symbols.ps1 -Class frm_alte_date` pentru lista completa de metode/controale).
3. Verifica daca boxarea `TRY/CATCH` din `driverAlteDate8.Executa` chiar prinde un access
violation (de regula NU — un AV omoara procesul indiferent de `TRY` VFP) — daca da, solutia nu
e mai mult `TRY`, ci evitarea completa a apelului direct de metoda pe un formular modal activ;
alternativa: `PostMessage` catre handle-ul ferestrei cu un mesaj de „Enter”/„buton implicit”
(permis explicit de reguli, spre deosebire de `SendInput`), ca sa se comporte ca un click real
fara reintrare in stiva VFP.
4. Ruleaza harness-ul o data cu `_SCREEN.Visible=.T.` FARA driver deloc, doar ca sa se vada daca
`frm_alte_date` apare normal pe ecran si daca poate fi inchis manual din log (confirma ca
restul lantului pana acolo e sanatos) — util ca test de izolare, nu ca solutie finala (fara
input real ramane interzis).
**Comanda de reluare** (sterge `.fxp` vechi intai):
```powershell
$fxp = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\creeaza_documente_s8.fxp"
if (Test-Path $fxp) { Remove-Item $fxp -Force }
$log = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\creeaza_documente_s8_log.txt"
if (Test-Path $log) { Remove-Item $log -Force }
Start-Process 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe' -ArgumentList '-A','-T','"D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg"'
```
**ATENTIE**: `Start-Process ... -PassThru; $p.WaitForExit(...)` NU e de incredere pe aceasta masina
(vezi nota 6 de mai sus) — verifica progresul prin `Get-Content` pe log, in bucla cu `sleep`
(Monitor/Bash, nu PowerShell `Start-Sleep` lung), niciodata prin PID/`Responding`. Nu folosi
`Stop-Process -Name vfp9` — alti agenti pot avea procese `vfp9.exe` proprii concurente pe aceasta
masina; omoara DOAR PID-uri pentru care exista dovada tare (pornite chiar de comanda curenta, deloc
ambiguu).
**Fisiere atinse**: doar `creeaza_documente_s8.prg` (nou) si acest raport. Zero cod de productie.
Zero commit. Scripturile `.sql` de verificare sunt in scratchpad, exploratorii, nu fac parte din
livrare.