# S8 — Plan de creare a documentelor lipsa (aviz, factura din aviz, factura din contract), pe fluxul REAL Continua `rec_s8_inventar.md` (verdict: in dev, luna curenta, exista un singur candidat — 1048, lista de preturi; zero comanda/contract/aviz). Scop: **creeaza** in `MARIUSM_AUTO` documentele lipsa, prin fluxul real de emitere, nu prin `INSERT`. ## Intrarea reala, dovedita pe cod `Procedure factureaza`, `D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare.prg:81-560` — punctul unic de emitere folosit de aplicatie pentru orice tip de document (`tnTip`). Mapare relevanta (comentarii `:117-167`): - `tnTip=1` — factura pe lista de preturi (deja acoperit, id_vanzare=1048) - `tnTip=22` — AVIZ catre clienti din lista de preturi (`nIdTipDoc=6`, AVIZ) — **de creat** - `tnTip=2`/`6` — factura pe contract — **de creat** - `tnTip=4` — factura din avize — **de creat, dupa tnTip=22** Secventa (`ofacturare.prg`): 1. `poDate = Createobject("oDateFactura", lnIdSet, tnTip)` (:184) 2. dialogul de antet: `frm_date_aviz` (tip>=21 sau 30) sau `frm_date_factura` (tip<21 sau 45/48/49/51/52) — `:217-235`, populeaza `poDate.*` din campuri legate direct (`ControlSource="poDate.xxx"`), apoi `.Show()` 3. cursorul de articole sursa, ales dupa `tnTip` (`:266-308`): - `cursor_preturi` pt. 1/5/7/10/22/23/29 (`:279-282`) - `cursor_contract` pt. 2/6/26/52 (`:283-291`) - `cursor_avize` pt. 4 (`:294-295`, `poDate.listaid` = id_vanzare-urile avizelor sursa) 4. `creeaza_facturacrs('crsfactura')` (:338), apoi `frm_facturare_articole` (sau `frm_avizare_lucrare` pt. 27) — `.Show()` la `:477` 5. Scrierea reala in Oracle se intampla **in interiorul** acestui `Show()`, prin `frm_facturare_articole.do_scrie_factura` (`ofacturare.vc2:14197-14554`), apelat din `inainte_de_do_termin` (`:14806-14974`, apelul e la `:14947`) — cheama `PACK_FACTURARE`. ## Tehnica: ocolire dialoguri de antet prin setare directa `poDate`, NU prin INSERT `poDate` e un obiect simplu (`oDateFactura`), ale carui proprietati sunt legate 1:1 de `ControlSource`-urile dialogului (`frm_date_aviz`/`frm_date_factura`) — a le seta direct din script produce STAREA IDENTICA cu ce ar produce operatorul prin UI. Scrierea reala ramane 100% in codul de productie (`PACK_FACTURARE`, `do_scrie_factura`), neatins. Precedent deja acceptat de proiect: `test_s5_al_doilea_intrare.prg` (bypass `frm_modific2024`, pastreaza `ScrieArticoleFacturaEditate` reala) si `test_pret_cu_tva_nivel2.prg` (seteaza `poDate.tip=1` direct, fara meniu). Campurile obligatorii, dovedite din garda `frm_date_factura.inainte_de_do_termin` (`ofacturare.vc2:9455-9561`) — **frm_date_aviz are propria garda, de citit separat inainte de implementare, posibil cu cerinte suplimentare** (nu verificat inca in aceasta runda): `dataireg`, `dataact` (luna curenta), `datascad>=dataact`, `id_fdoc` (orice rand nesters din `NOM_FDOC`; nu se salveaza pe `VANZARI`, doar validare UI), `nract` (obligatoriu prin `poGeneratorNumere.creeaza_cursor_serii()`+`verifica_numar()`, NU inventat), `id_client` (=`id_part` valid), `listaid` (gol interzis pt. tip 2/6/52/3/4/45; liber pt. 1/5/7/8/9/10/22/48/49). ## Al doilea dialog modal, inevitabil: `frm_alte_date` `frm_facturare_articole.inainte_de_do_termin` deschide necontitionat `frm_alte_date` (Show(1)) pt. orice `poDate.tip<>30` (`ofacturare.vc2:14921-14935`), INAINTE de `do_scrie_factura`. Garda lui (`ferestre_cere_date.vc2:3044-3103`) cere, cand `gcNumeProgram=[ROAFACTURARE]` si nu e proforma/bonfiscal: `poDate.id_delegat` nenul si `poDate.dataora_exp` nenul (acesta din urma deja setat de `factureaza()`-echivalent la `poDate.dataora_exp = Get_Ora()`, `:14921` — de reprodus). **Tehnica de condus acest modal**: driverul deja dovedit din `COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_nivel2.prg:539-630` (`driverdeblocare3`, `Timer` legat pe `_SCREEN`, cauta formularul nou aparut prin `_SCREEN.Forms` dupa `.Class`) — de extins cu un caz nou pentru `FRM_ALTE_DATE` (apel `.do_termin()` direct pe obiectul gasit, dupa ce `poDate.id_delegat` a fost presetat). ## Ocolirea celui de-al treilea modal (`frm_articol_factura`, per linie) `frm_facturare_articole.do_adauga_tot` (`:13169-13198`) cheama `do_adauga_articol(.T.)` pt. fiecare rand din `crsarticole` — cu `tlImplicit=.T.`, `do_adauga_articol` (`:12813-12880`) SARE peste `Show(1)` cand `poArticol.gestionabil=0 OR gnScadereStoc=0 OR poDate.tip=45` (`:12871`). **Cel mai simplu**: seteaza global `gnScadereStoc = 0` in harness (deja folosit asa in `test_pret_cu_tva_nivel2.prg:177`) — orice articol trece fara dialog, fara sa cauti unul anume non-gestionabil. ## Instantierea `frm_facturare_articole`: modeless, apel direct de metode Ca in `test_pret_cu_tva_nivel2.prg:266-272`: `CREATEOBJECT('frm_facturare_articole')`, `WindowType=0`, `.Show()` (nu blocheaza), apoi apel DIRECT `goFrm.do_adauga_tot()`, `goFrm.do_calculeaza_totaluri()`, `goFrm.do_termin()` — cu driverul de mai sus deja armat inainte de `do_termin()`, ca sa prinda `frm_alte_date` cand apare. ## Date de referinta confirmate in `MARIUSM_AUTO` (10.08.2026, doar SELECT) - Delegat valid: `id_delegat=256` (folosit real pe `id_vanzare=1048`). - `id_fdoc` valid: orice din `NOM_FDOC` cu `sters=0`, ex. `5` (`AVIZ EXP`). - Client: `id_part=463` (RAJA) — folosit deja de 1048; sau alt partener existent, la alegere. - `id_gestiune`: NULL pe toate documentele tip 1/22 existente — NU se seteaza pentru lista de preturi/aviz din lista. - **Contract pentru tip=2**: `id_ctr=235` (`opt_facturare=1`, rata/scadentar, `id_part=598`, `id_nota=5`) — acelasi tipar ca documentul real deja existent `id_vanzare=1039`/`1040` (tip=2, 30.06.2026, aceeasi schema). Ruta trece prin `contabilizeaza_rata` (vezi `docs\cercetare\idpol_comanda_contract.md`, sectiunea 0c), nu prin articole de nomenclator — e un document real, de productie, nu o fabricatie. **Evita `id_ctr=222`**: are 3 randuri `CTR_ARTICOLE`, unul cu `id_pol_art` NULL, risc de FACT-024 daca acel rand ajunge selectat. - Politica de pret pt. lista de preturi/aviz: `id_pol=1` are articole (ex. `id_articol` 1-5). ## Ordinea de executie recomandata 1. `factureaza(22, .NULL.)`-echivalent -> creeaza AVIZUL (tip=22). Verifica in Oracle (`VANZARI`+`VANZARI_DETALII`+`ACT`+`RUL`, `id_fact` alocat). 2. Citeste `id_vanzare` al avizului nou creat -> `poDate.listaid = ` pentru `factureaza(4, .NULL.)`-echivalent -> FACTURA DIN AVIZ. Verifica la fel. 3. `factureaza(2, .NULL.)`-echivalent cu `poDate.listaid = '235'` -> FACTURA DIN CONTRACT (rata). Verifica la fel; noteaza explicit ca liniile sunt de tip RATA (fara `id_articol`), nu articole de nomenclator — mentioneaza asta in raportul final, nu ascunde. ## Ce NU e verificat inca (de facut in implementare, nu presupus) - Garda proprie a lui `frm_date_aviz` (separata de `frm_date_factura.inainte_de_do_termin` citita mai sus) — posibil cere campuri suplimentare (ex. gestiune destinatie pt. aviz). De citit clasa `frm_date_aviz` (`ofacturare.vc2:6566-8203`) inainte de a scrie harnessul. - Semnatura exacta `oDateFactura(lnIdSet, tnTip)` si `poGeneratorNumere.creeaza_cursor_serii`/ `verifica_numar` — de citit in `ofacturare_comun.vc2`/`oserii_numere.prg` inainte de implementare. - Daca `do_scrie_factura` mai cere alte proprietati `poDate` netestate aici (ex. `id_agent`, `proc_tva`) — de citit `:14197-14554` complet inainte de rulare. ## Reguli neschimbate (din briefing-ul initial) Doar `MARIUSM_AUTO`; nu se ating `1048`/`1049`/`1050`; zero editare de cod/pachete; zero commit; zero input real (`keybd_event`/`SendInput`); verificare finala: zero `vfp9.exe`, zero tranzactii deschise.