# Handoff — conturi 667/709 + analitice pe articol (catalog articole) Data: 2026-09-17. Sesiune: analiza + reproducere + proiectare. **Zero cod de productie modificat.** ## 1. Cerinta In facturarea din lista de preturi „catalog articole" (politica de stoc), un articol cu `NOM_ARTICOLE.CONT = 667` (sau `709`) da eroarea „articolul nu are cont de venit". Se cere: - `667`/`709` considerate conturi valide (nu blocate); - nota generata sa fie `667/709 = 4111` **cu suma negativa** (nu `4111 = ` standard); - pe articol sa se poata completa si **conturile analitice** (`ASCD`/`ASCC`), nu doar debit/credit, ca nota sa fie completa. ## 2. Decizii luate (NU se redeschid) - **Fix = nota per-articol creata automat** (nu nota la nivel de politica, care s-ar aplica tuturor articolelor din lista). Legatura: `CRM_POLITICI_PRET_ART.ID_NOTA`. - **`SCC` (contul de client) vine din optiunea `RF_CONT_ART_FARA_POL`**, fallback `4111`. - **Analiticele se salveaza in nota** (`NOTE_CONTABILE.ASCD/ASCC`), nu pe articol/politica. - Semnul negativ **nu are nevoie de cod nou**: exista deja in `scrie_nota` (vezi §4). - Se **adauga un overload** la `gaseste_sau_creeaza_nota_vanzare` (6 arg), ca sa nu rupa apelantii vechi de 4 arg si sa nu fie nevoie de deploy sincronizat EXE/DB. ## 3. Cauza (dovada pe cod) - Pre-check VFP la adaugarea liniei: `verifica_cont_venit_linie` (`D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_comun.prg:842`), apelat din `COMUN\clase\ofacturare.vc2:18737` si `:18972`. Rezolva `nvl(case when a.id_pol=stoc and a.id_nota is null then cont_venit_articol_stoc(art) end, d.scc)`; mesaj cand e NULL. - Derivare fara politica: `deriva_cont_venit_fara_pol` (`ofacturare_comun.prg:815`) — pentru `cont` 6xx intoarce `667` (dar e folosit ca SCC, directia e inversa). - Deducere Oracle: `PACK_FACTURARE.cont_venit_articol_stoc` (`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_16_04_COMUN_PACK_FACTURARE.sql:17794`) trateaza doar `7xx` (il intoarce) si `2xx/3xx` (prin `CORESP_CONT_VENCHELT`); **`6xx` → NULL**. - Garda Oracle: FACT-033 cand `V_SCC` e NULL (`ff_2026_09_16_04_...:7896-7901`). - Nota articolului e deja folosita la facturare: `cursor_articol` ia `D.SCD/D.SCC/D.ASCD/D.ASCC` (`ff_2026_09_16_04_...:7545-7546, 7864-7865, 7890-7893`), iar `scrie_nota` primeste `V_ASCD/V_ASCC`. ## 4. Mecanism deja existent (nu se rescrie) - `scrie_nota`, `ff_2026_09_16_04_...:12838` si `:12879-12887`: daca `V_SCD IN ('667','267','2678','709')` pe factura → `V_SEMN := -1` (suma negativa). - `scrie_tva`, `ff_2026_09_16_04_...:13064-13078`: comuta pe `4111/4427` pentru aceleasi conturi. - Componenta noua in `PACK_PRETURI` (`ff_2026_09_16_05_COMUN_PACK_PRETURI.sql`): `gaseste_sau_creeaza_nota_vanzare` (`:1305`), `salveaza_pret_nomenclator` (`:1261`), `asigura_politica_stoc` (`:1391`), `seteaza_nota_politica_stoc` (`:1440`). Azi `gaseste_sau_creeaza_nota_vanzare` scrie fortat `ascd/ascc` NULL (`:1339-1340, 1387`). ## 5. Plan de implementare (confirmat, NEINCEPUT) ### Pas 1 — Oracle: script nou `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_17_01_COMUN_PACK_PRETURI.sql` - overload `gaseste_creeaza_nota_vanzare(tcScd, tcAscd, tcScc, tcAscc, tnIdUtil, tnIdNota OUT)`; cautare pe toate 4 conturile; la creare scrie `ascd/ascc` reale. - pastreaza si signatura veche de 4 arg `(tcScd, tcScc, tnIdUtil, tnIdNota OUT)`, sub acelasi nume scurtat (numele original de 32 caractere nu compila pe Oracle 10/11). - procedura noua `asigura_nota_articol_disc(V_ID_ARTICOL, V_ID_UTIL)`: `cont ∈ (667,267,2678,709)` → `gaseste_sau_creeaza_nota_vanzare(cont, ascd, client, ascc, ...)`, `client = nvl(pack_sesiune.getoptiunefirma('RF_CONT_ART_FARA_POL'),'4111')`; `merge into crm_politici_pret_art set id_nota=... where id_pol=pack_facturare.nid_politica_stoc and id_articol=... and id_nota is null` (nu suprascrie nota pusa de utilizator). - apel in `salveaza_pret_nomenclator` cand `V_ID_NOTA IS NULL AND V_SCRIE_NOTA = 1`. - backfill idempotent pentru randurile existente din politica de stoc. - `exec pack_migrare.UpdateVersiune('ff_2026_09_17_01_COMUN_PACK_PRETURI'); commit;` - compatibil Oracle 10.2. Vezi skill `roa-oracle-migration`. ### Pas 2 — VFP clasa `cus_pret_nomenclator` (`COMUN\programe\ofacturare_comun.prg`) - clasa incepe la `:2366`; proprietati: `asigura_politica :2382`, `incarca :2400`, `valideaza :2483`, `salveaza :2500`, `incarca_nota_politica :2553`, `salveaza_nota_politica :2575`. - proprietati noi `cAscd`/`cAscc`; `incarca` si `incarca_nota_politica` le citesc din nota; `valideaza` — analitic optional, dar cer sintetic daca exista analitic; `salveaza`/`salveaza_nota_politica` le trimit in RPC. - apeluri RPC de actualizat: `:2513` si `:2591` (`gaseste_creeaza_nota_vanzare`). - NU se atinge `do_scrie_articole` (argumentul `cont_venit` ramane cum e, `:14279`/`:20246`). ### Pas 3 — VFP formular `COMUN\clase\onom_articole.vc2`, pagina Vanzare (Page3) - `Clb_tx_scd` (`:1589`, label „Cont debitor") → `ADD ...Text1` legat la `Thisform.oPretNom.cAscd`. - `Clb_tx_scc` (`:1571`, label „Cont creditor") → `Text1` legat la `cAscc`. - tipar de copiat: `Clb_tx_cont.Text1` (`:1104`, ControlSource `porec.acont`). - init `oPretNom` + ControlSource-uri: `:1931-1944`. - write-back `.vc2 -> .vcx` obligatoriu (`txt2vcx`), cp1252. Vezi skill `roa-vfp-text-edit`. ### Pas 4 — Test headless pe `MARIUSM_AUTO` - salveaza articol cont=667 fara acont (+ analitice), verifica `verifica_cont_venit_linie` = `[]` si rezolvarea tip `cursor_articol` = `SCD=667/SCC=4111/ASCD/ASCC`. - **tranzactie manuala obligatorie** (`SQLSETPROP(gnHandle,"Transactions",2)`), altfel scrierile se commmit (vezi §7). ## 6. Fisiere create in aceasta sesiune (probe, NU productie) In `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\`: - `probe_cont_667.prg/.fxp` + `out\probe_cont_667.log` - `probe_cont_667b.prg/.fxp` + `out\probe_cont_667b.log` - `probe_cont_667c.prg/.fxp` + `out\probe_cont_667c.log` - `probe_cont_667d.prg/.fxp` + `out\probe_cont_667d.log` - `restore_pol41.prg/.fxp` + `out\restore_pol41.log` Niciun fisier de productie (`.prg`/`.vc2`/`.vcx` din COMUN) nu a fost atins; niciun commit. ## 7. Capcane de mediu platite - **`goExecutor`/ODBC e pe auto-commit implicit** — `UPDATE` fara `SQLSETPROP(gnHandle,"Transactions",2)` se **commiteaza**. Am patit-o: `probe_cont_667b` a golit `id_nota` al politicii 41; **restaurat** la `6` (`restore_pol41.log`). Orice scriere de proba: `Transactions=2` + `ROLLBACK` la final. - `vfp9.exe` = `C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe`. - Precompilare izolata obligatorie inainte de rulare: `powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_precompile.ps1" -Prg ""` apoi `vfp9.exe -A ""` cu `WaitForExit`. `-A` porneste cu SAFETY ON → prima linie `SET SAFETY OFF`. - Init mediu: `DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL','MARIUSM_AUTO','ROMFASTSOFT'`, apoi `gnIdUtil = 8`. - Log-uri: `...\facturare_unificat\out\*.log`. ## 8. Date utile din baza vie (MARIUSM_AUTO, citite 2026-09-17) - `OPTIUNI.ROAFACTURARE.ID_POL_PRET_STOC = 41` („STOC PRODUSE"), `id_nota=6` (nota 6 = `4111/7015`). Exista si `id_pol=43` „STOC PRODUSE", tot `id_nota=6`. - Nota `2` = `DISCOUNT`, `SCD=667`, `SCC=4111` (politica 7 „DISCOUNT"). - 16 articole cu `cont=667` in politica 41, **fara nota per-articol** (nume: DISCOUNT, VOUCHER DISCOUNT, DISCOUNT 19%, STORNARE DISCOUNT..., etc.). - Singura nota per-articol existenta: `art=4294507172` („A1", `cont=371`) → `id_nota=7` (`4111/704`). - `PLCONT` 2026 contine `667`, `709`, `267`, `2678`, `4111`, `704`, `707`. - Politici fara nota: `32`, `33`, `41` (dupa restaur, 41 are din nou nota 6). ## 9. Interzis / atentie - Nu `git pull` in COMUN; nu `roa_sync` pe tree murdar; commit **doar** tintit si **doar** cu aprobarea lui Marius (skill `roa-git-svn-commit`). - Nu edita `.vcx` direct; doar `.vc2` + `txt2vcx`. - Nu lasa scrieri necommit-uite/auto-commit pe schema partajata `MARIUSM_AUTO`. - Deploy: DB inainte de EXE (overload-ul vechi face ordinea toleranta, dar EXE nou + DB vechi ar esua la apelul cu parametri noi). ## 10. Comanda de test rapida (dupa implementare) ``` powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_precompile.ps1" -Prg "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\.prg" # apoi: Start-Process vfp9.exe -ArgumentList '-A', '""' -Wait (NU '-A -T ...', nu porneste) # citeste out\.log ``` ## 11. STARE EXECUTIE (2026-09-17, orchestrator + subagenti) Pas 1-4 EXECUTATE. Zero commit, zero publicare in UPD_DATABASE, zero modificari pe schema in afara de scriptul de migrare aplicat pe MARIUSM_AUTO. - **Pas 1** `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_17_01_COMUN_PACK_PRETURI.sql` (nou, 2441 linii): overload 6 arg `gaseste_creeaza_nota_vanzare` (cauta pe toate 4 conturile, `nvl(trim(x),'~')` pentru 10.2), procedura `asigura_nota_articol_disc` (667/267/2678/709 -> nota `=`, doar pe rand fara id_nota), apel in `salveaza_pret_nomenclator` cand `V_ID_NOTA IS NULL AND V_SCRIE_NOTA=1`, backfill idempotent in politica de stoc, `UpdateVersiune('ff_2026_09_17_01_COMUN_PACK_PRETURI')`. **Aplicat pe MARIUSM_AUTO** (sqlplus, `@`): `PACK_PRETURI` VALID, 0 erori; backfill a legat toate cele 16 articole 667 la nota 2 (DISCOUNT 667=4111); nota 2 are in continuare un singur rand. **Compatibilitate Oracle 10.2 (corectie 17.09):** limita de 30 de caractere pe identificator. In `ff_2026_09_16_05` singurul nume peste limita era `gaseste_sau_creeaza_nota_vanzare` = 32 caractere (pica pe 10g/11g cu PLS-00114; MARIUSM_AUTO e pe o versiune care permite 128, de-aia compilase). Redenumit in `gaseste_creeaza_nota_vanzare` = 28. `asigura_nota_articol_discount` era 29 (legal), dar a fost scurtat preventiv la `asigura_nota_articol_disc` = 25. Verificat: 0 identificatori >30 in tot pachetul; fara constructii 11g+ (listagg/regexp/pivot/continue/with etc.). **Atentie la deploy:** numele vechi dispare din pachet, deci un EXE vechi care chema `gaseste_sau_creeaza_nota_vanzare` se rupe - componenta e noua (16.09), dar DB-ul nou trebuie livrat impreuna cu EXE-ul nou (nu mai exista toleranta la ordinea DB-inainte-de-EXE pentru acest apel). Audit luna 2026-09: acelasi nume de 32 caractere exista si in `ff_2026_09_15_01` (introducerea procedurii) si `ff_2026_09_16_05` - ambele corectate identic in surse; restul scripturilor lunii sunt curate (singurele tokenuri >30 sunt numele de script din stringul `UpdateVersiune` si un blob base64). **Atentie:** arhiva `database_20260901_20260930.zip` exista deja (generata 2026-09-17 00:07) si contine versiunile vechi - corectia ajunge la clienti doar dupa republicare. - **Pas 2** `COMUN\programe\ofacturare_comun.prg` (clasa `cus_pret_nomenclator`, ~2366-2630): proprietati `cAscd`/`cAscc`; `incarca`/`incarca_nota_politica` le citesc din nota; `valideaza` refuza analitic fara sintetic; `salveaza` trimite RPC-ul cu 6 argumente; `salveaza_nota_politica` primeste `tcAscd/tcAscc` optionali (apelantul din `ofacturare.vc2:24524` ramane pe 3 arg). - **Pas 3** `COMUN\clase\onom_articole.vc2` (+ write-back `.vcx`/`.vct` cu txt2vcx): pe Page3, `Clb_tx_scd.Text1` si `Clb_tx_scc.Text1` (MaxLength 4, Format `!k`), ControlSource `Thisform.oPretNom.cAscd` / `cAscc` setat in Init. Round-trip `.vcx -> .vc2` identic, +2 obiecte. - **Pas 4** trei probe E2E (toate verzi): - `utile\Teste\facturare_unificat\probe_e2e_cont_667.prg` - salvare reala prin clasa + rezolvare `cursor_articol` + fallback, in tranzactie manuala cu ROLLBACK: **24 PASS / 0 FAIL**. - `probe_e2e_cont_667_ui.prg` - smoke UI pe `frm_catalog_articole_nou` Page3 (cele doua Text1 exista si sunt legate): **10 PASS / 0 FAIL**. - `probe_e2e_cont_667_semn.sql` - `pack_facturare.scrie_nota` cu SCD=667/ASCD=11/SCC=4111/ASCC=12 -> `ACT_TEMP.SUMA=-84.03` (semn negativ), apoi ROLLBACK. Reziduuri verificate: 0. - Loguri: `out\probe_e2e_cont_667.log`, `out\probe_e2e_cont_667_ui.log`. ### Raman de facut (deliberat, NU in aceasta executie) - Commit tintit pe `COMUN` (`ofacturare_comun.prg`, `onom_articole.vc2`) + commit script SVN - **doar cu aprobarea lui Marius** (skill `roa-git-svn-commit`). - Import/publicare in `UPD_DATABASE` + regenerare arhiva lunara (NU s-a rulat; aprobat de Marius doar "corecteaza sursele"). Comanda (scrie 3 scripturi + arhiva septembrie, face backup): ``` powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\publicare_scripturi.ps1" -Luna 2026-09 ``` `-DryRun` a confirmat: `FF_2026_09_15_01` MODIFICAT, `FF_2026_09_16_05` MODIFICAT, `FF_2026_09_17_01` NOU, 26 scripturi in arhiva. DB inainte de EXE. ### Capcane noi platite - `vfp9.exe -A -T ""` NU porneste testul (proces mut, log gol). Forma corecta: `Start-Process vfp9.exe -ArgumentList '-A','""'` (ca in `_precompile.ps1`). - `scrie_nota` scrie in `ACT_TEMP` (toate coloanele NOT NULL au DEFAULT 0), deci e testabil direct din sqlplus in tranzactie, fara sa treci prin formular; nu are FK-uri. ## 12. PREDARE catre sesiunea urmatoare (stare la 2026-09-17, ~10:30) ### Livrabile si stare pe disc | Ce | Cale | Stare | |---|---|---| | Migrare noua | `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_17_01_COMUN_PACK_PRETURI.sql` | scris + **aplicat pe MARIUSM_AUTO**; `PACK_PRETURI` VALID, 0 erori, 0 identificatori >30 | | Migrari corectate | `...\ff_2026_09_15_01_COMUN_PACK_PRETURI.sql`, `...\ff_2026_09_16_05_COMUN_PACK_PRETURI.sql` | rename aplicat in sursa; **NU aplicate** (17_01 le inlocuieste), **NU publicate** | | Clasa VFP | `COMUN\programe\ofacturare_comun.prg` (clasa `cus_pret_nomenclator`, ~2366-2630) | `cAscd/cAscc`, RPC 6 arg la `:2530` si `:2616`; nemodificat de altcineva | | Formular VFP | `COMUN\clase\onom_articole.vc2` (+ `.vcx`/`.vct` regenerate cu txt2vcx) | `Clb_tx_scd.Text1` si `Clb_tx_scc.Text1` (Page3), ControlSource in Init `:1963-1964` | | Probe E2E | `COMUN\utile\Teste\facturare_unificat\probe_e2e_cont_667.prg`, `probe_e2e_cont_667_ui.prg`, `probe_e2e_cont_667_semn.sql` | rulate: **24/24**, **10/10**, `SUMA=-84.03` | | Backup formular | `COMUN\clase\onom_articole.vc2.pre_runda3_cont_analitic.bak` | creat de subagent, git-ignorat | Nume vehiculate dupa corectia Oracle 10: `pack_preturi.gaseste_creeaza_nota_vanzare` (28) si `pack_preturi.asigura_nota_articol_disc` (25). Numele vechi (`gaseste_sau_creeaza_nota_vanzare` = 32, `asigura_nota_articol_discount` = 29) **nu mai exista** nicaieri in cod. ### Stare date MARIUSM_AUTO (commisa, nu de test) - `OPTIUNI.ROAFACTURARE.ID_POL_PRET_STOC = 41`; politica 41 are `id_nota=6`; nota `2` = DISCOUNT `667=4111`. - 16 articole cu `cont 667/709` in politica 41 → toate au acum `id_nota=2` (backfill-ul din 17_01, **commis** de script). Zero articole fara nota. - Testele E2E nu au lasat reziduuri (verificat: 0 randuri `ACT_TEMP`/note noi). - Conexiune: `sqlplus MARIUSM_AUTO/ROMFASTSOFT@ROA_CENTRAL`, `TNS_ADMIN=D:\ROA\instantclient_19_18`. ### Ce NU s-a facut (blocat pe aprobare / decizie) 1. **Niciun commit** (nici `ROAFACTURARE`, nici `COMUN`). Tree murdar: `COMUN` are `M` pe `clase/onom_articole.vc2` si `programe/ofacturare_comun.prg`, plus probe E2E untracked; binarul `.vcx`/`.vct` e git-ignorat (by design). `ROAFACTURARE` are untracked doar handoff-ul. 2. **Nicio publicare**: `UPD_DATABASE` + `database_20260901_20260930.zip` (generat 2026-09-17 00:07) au inca versiunile vechi (nume de 32 caractere) → pe Oracle 10/11 update-ul lunii pica. Comanda de publicare (utilizatorul a ales sa NU o rulez acum): `powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\publicare_scripturi.ps1" -Luna 2026-09` `-DryRun` dovedit: 15_01 MODIFICAT, 16_05 MODIFICAT, 17_01 NOU, 26 scripturi in arhiva. 3. **Celelalte produse nu au fost atinse.** Numele vechi traieste inca in working copy-urile COMUN ale produselor: `ROAACNPRO, ROAAUTO, ROACONT, ROACONTRACTE, ROADEF, ROAGEST, ROAIMOB, ROAPRETURI, ROAREGISTRATURA` (`\COMUN\programe\ofacturare_comun.prg:2513` si `:2591`). Fiecare `\COMUN` e working copy SVN separat (`.svn` + `.git`). Propagarea se face prin commit SVN pe COMUN + `roa_sync` in fiecare produs + **rebuild EXE**. 4. **Decizie deschisa**: wrapper cu numele vechi de 32 caractere creat conditionat doar pe Oracle ≥12.2 (`$IF DBMS_DB_VERSION.VERSION >= 12 $THEN` + `EXECUTE IMMEDIATE`), pentru zero breakage la clientii ≥12.2 cu EXE vechi. Neconfirmat; daca nu se doreste, ramane doar rename. ### Ordinea recomandata pentru sesiunea urmatoare 1. Marius decide: wrapper conditionat da/nu. 2. Commit tintit pe `COMUN` (`ofacturare_comun.prg`, `onom_articole.vc2`) + commit SVN COMUN (skill `roa-git-svn-commit`; NU `git pull` in COMUN, NU `roa_sync` pe tree murdar). 3. Publicare septembrie (`publicare_scripturi.ps1 -Luna 2026-09`) dupa aprobare. 4. Sync COMUN in celelalte produse + rebuild EXE; livrare DB + EXE **impreuna** (numele vechi a disparut, deci EXE vechi = rupere la salvare nomenclator). ### Comenzi de re-rulare a testelor ```powershell # 1) precompilare izolata powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_precompile.ps1" -Prg "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_e2e_cont_667.prg" # 2) rulare (ATENTIE: NU `-A -T`, porneste mut) + asteapta terminarea + citeste logul $vfp='C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe' $p=Start-Process -FilePath $vfp -ArgumentList @('-A','"D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_e2e_cont_667.fxp"') -PassThru $p.WaitForExit(240000) Get-Content "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_e2e_cont_667.log" # idem pentru probe_e2e_cont_667_ui.prg (log out\probe_e2e_cont_667_ui.log) # 3) dovada semnului (Oracle, cu ROLLBACK) sqlplus MARIUSM_AUTO/ROMFASTSOFT@ROA_CENTRAL "@D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_e2e_cont_667_semn.sql" ``` Clasele/procedurile se incarca prin `test_init_env_auto_roafacturare.prg WITH 'CENTRAL', 'MARIUSM_AUTO','ROMFASTSOFT'` apoi `gnIdUtil=8`. Tranzactie manuala: `SQLSETPROP(gnHandle,"Transactions",2)` + `SQLROLLBACK` la final (altfel se commiteaza). ### Interzis - `git pull` in COMUN; `roa_sync` pe tree murdar; commit fara aprobarea lui Marius. - editare `.vcx` direct (doar `.vc2` + `txt2vcx`, cp1252). - scrieri necommise sau fara rollback pe `MARIUSM_AUTO`. - identificatori >30 caractere in orice obiect Oracle nou (10.2 = limita).