# Tabele + SP-uri Service Auto — VFP ground truth audit (v2) > **Status:** v2 generat 2026-04-11 de Claude pe baza analizei `gitea.romfast.ro/romfast/vfp_roaauto` > (clonat în `/workspace/vfp_roaauto`). **Acum se bazează și pe `Scripturi_instalare/packages.sql`, > `initializari.sql`, `triggere.sql`, `tabele.sql`** — nu doar pe .prg files. **DE CONFIRMAT** în > săpt 3 prin interogări reale pe schema MARIUSM_AUTO. > > **Scop:** înlocuiește task-ul "deschide VFP producție cu grijă" din planul v2. Sursa e > gitea, zero risc de modificare accidentală. > > **Corecție v2 (2026-04-11):** v1 presupunea că tabela principală e `comenzi`. **REALITATE:** > tabela fizică e **`DEV_ORDL`** (PK: `id_ordl`). `vcomenzi` e un view denormalizat care face > JOIN cu `dev_tip_deviz`, `dev_masiniclienti`, `parteneri`, etc. Planul v2 referință corectă: > DB = `dev_ordl`, UI = "comandă". --- ## 1. Entități — terminologie reconciliată **Confirmat de Marius 2026-04-11**: terminologia vine din ierarhia ROA (ERP generic) vs ROAAUTO (extensie service auto). Pattern de **inheritance prin două tabele**: | Nivel | Termen | Tabelă | Ce conține | |---|---|---|---| | **Base** (ROA ERP) | **comandă** | `nom_lucrari` | Doar numele/nrord-ul comenzii — vizibil în ACT (registrul jurnal) și RUL (rulaje gestiune) când comanda e referențiată la facturare | | **Extension** (ROAAUTO) | **deviz auto** | `dev_ordl` | Toate detaliile specifice auto: mașină, km, termen, asigurator, tip deviz, inspector, observații | **"Comandă"** = generic (valabil pentru orice industrie — service, construcții, producție...). **"Deviz"** e mai specific: e calculul costului (manoperă + materiale consumate) pentru o comandă într-un context de industrie: `deviz auto`, `deviz construcții`, etc. În ROAAUTO, fiecare comandă de service auto ARE un deviz auto atașat (prin `dev_ordl` + `dev_oper` + `dev_mat`). **Relația FK**: ``` nom_lucrari (id_lucrare PK) ↑ │ FK (id_lucrare) │ dev_ordl (id_ordl PK, id_lucrare FK → nom_lucrari.id_lucrare) ``` Confirmat în `tabele.sql:634`: ```sql alter table DEV_ORDL add constraint FK_... references NOM_LUCRARI (ID_LUCRARE); ``` **Consecință pentru prototype**: crearea unei comenzi face INSERT în **AMBELE tabele**, în ordine: 1. `INSERT INTO nom_lucrari (nrord, id_mod) VALUES (...)` — creează header-ul generic 2. `INSERT INTO dev_ordl (id_lucrare, id_tip, id_masiniclient, kmint, ...) VALUES (...)` — creează extensia auto, legată prin `id_lucrare` **ACT și RUL**: `nom_lucrari.nrord` e **vizibil** în ACT (registrul jurnal) și RUL (rulaje gestiune) când comanda e referențiată la facturare. Dar **crearea comenzii NU touch-uiește nici ACT nici RUL** — acestea sunt hit-uite doar la facturare, care e NOT IN SCOPE pentru prototype. Correction 3 din planul v2 rămâne validă. **Componente backend Pydantic**: `ComandaCreate`, `ComandaCreated` (termen UI), backend service face cele două INSERT-uri într-o tranzacție, returnează `id_ordl` și `nr_comanda`. --- ## 2. Tabela principală: `comenzi` (view: `vcomenzi`) Schema extrasă din `COMUN/programe/onom_comenzi.prg:72-79`. **Partea vizibilă în UI**: | Coloană | Tip VFP | Tip Oracle probabil | Note | |---|---|---|---| | `id_comanda` | `N(20)` | `NUMBER(20)` | PK, alias-ul pentru `id_ordl` | | `id_ordl` | — | `NUMBER(20)` | Numele intern în PL/SQL (OUT param din SP) | | `comanda_externa` | `C(20)` | `VARCHAR2(20)` | Nr. comandă extern client | | `id_codclient` | `C(20)` | `VARCHAR2(20)` | FK client (**char**, nu numeric!) | | `id_lucrare` | `N(20)` | `NUMBER(20)` | FK la `vlucrari_detalii` | | `id_part` | `N(20)` | `NUMBER(20)` | FK partener | | `id_agent` | `N(20)` | `NUMBER(20)` | FK agent vânzări | | `id_delegat` | `N(20)` | `NUMBER(20)` | FK delegat | | `id_masina` | `N(20)` | `NUMBER(20)` | FK la `masini_client` (id_mc) | | `nr_comanda` | `C(100)` | `VARCHAR2(100)` | Nr. comandă intern cu prefix tip (ex: `G123`, `R456`) | | `data_comanda` | `T` | `TIMESTAMP` | Data creării | | `nume` | `C(70)` | `VARCHAR2(70)` | Nume client (denormalizat) | | `tip_comanda` | `C(20)` sau `C(50)` | `VARCHAR2(50)` | **Display name denormalizat** (ex: "Garanție") | | `data_livrare` | `T` | `TIMESTAMP` | Termen execuție/livrare | | `nume_agent` | `C(70)` | — | Denormalizat | | `nume_delegat` | `C(70)` | — | Denormalizat | | `nrinmat` | `C(10)` | `VARCHAR2(10)` | Nr. înmatriculare mașină | | `nrord` | `C(30)` | `VARCHAR2(30)` | Nr. ordine (intern) | | `facturat` | `N(1)` | `NUMBER(1)` | Flag facturat (0/1) | | `dataora` | `T` | `TIMESTAMP` | Audit | | `utilizator` | `C(40)` | `VARCHAR2(40)` | Username creator | | `data_livrat` | `T` | `TIMESTAMP` | Data livrării efective | | `interna` | `N(1)` | `NUMBER(1)` | Flag comandă internă | | `nr_livrare` | `C(50)` | `VARCHAR2(50)` | Nr. bon livrare | | `inchisa` | `N(1)` | `NUMBER(1)` | Flag închisă | | `id_sectie` | `N(5)` | `NUMBER(5)` | **Secția care a creat comanda (MANDATORY)** | | `id_sectie2` | `N(5)` | `NUMBER(5)` | Secția care execută (dacă diferă) | | `id_facturare` | `N(5)` | `NUMBER(5)` | FK adresa facturare | | `id_livrare` | `N(5)` | `NUMBER(5)` | FK adresa livrare | | `id_ctr` | `N(10)` | `NUMBER(10)` | FK contract (pentru clienți B2B cu discount-uri) | | `numar_contract` | `C(100)` | `VARCHAR2(100)` | Nr. contract denormalizat | **Total: ~28 coloane în view-ul `vcomenzi`.** Planul prototype-ului (4 fields: tip, client, mașină, operații) e o simplificare **agresivă** — e OK pentru learning, dar să fii conștient că VFP-ul real captează mult mai multă informație. --- ## 3. Tabele conexe (referențiate la create) | Tabelă / view | Rol | Folosită de prototype? | |---|---|---| | `vcomenzi_elemente` | Linii detaliu (articole, cantități) — "rețeta" comenzii | **NU** — prototype scope wall, doar header | | `vlucrari_detalii` | Lucrări / operații finalizate | **NU** — execuție post-creare | | `vlucrari_elemente` | Articole consumate pe o lucrare | **NU** | | `masini_client` | Mașinile clienților (FK `id_mc`) | **NU** — dropdown hardcodat în Vue | | `parteneri` | Clienți (FK `id_codclient`) | **NU** — dropdown hardcodat | | `optiuni` | Configurare per-secție (Key/Value) | Doar indirect prin `pack_comenzi.extrage_optiuni` | | `adrese_parteneri` | Adrese facturare/livrare | **NU** — valoare default din partener | | `contracte` | Contracte cu discount-uri B2B | **NU** — scope wall | **Pentru prototype**: insert-ul simplificat atinge **doar `comenzi`** (view `vcomenzi`), zero JOIN-uri cross-table. Scope wall ține. --- ## 4. SP-ul real de creare — DOUĂ versiuni Surpriză importantă: **există două versiuni** ale `dev_adauga_lucrare` în sursele ROAAUTO, în pachete diferite. ### 4.1. Versiunea INSTALL-TIME: `pack_devize.dev_adauga_lucrare` (12 IN + 1 OUT) **Sursa:** `Scripturi_instalare/packages.sql:182-212` — body-ul complet e vizibil. **Semnătura:** ```sql procedure dev_adauga_lucrare( v_gcs in varchar2, -- schema tnan in number, -- an tnluna in number, -- luna tnIdUtil in number, -- id user pcNr in varchar2, -- nr comandă cu prefix (ex: 'G12345') pnIdInsp in number, -- id inspector pnIdAsig in number, -- id asigurator pnIdMC in number, -- id mașină client (dev_masiniclienti.id_masiniclient) pnKmInt in number, -- km la bord pdTermen in date, -- termen execuție pnTipCom in number, -- id tip (FK dev_tip_deviz.id_tip) pnIdOrdl out number -- OUT: id_ordl generat ) ``` **Body real (din `packages.sql:196-212`):** ```sql begin -- 1. Side effect: creează rând în NOM_LUCRARI cu id_mod=1200 execute immediate 'INSERT INTO ' || v_gcs || '.NOM_LUCRARI (NRORD, ID_MOD) VALUES (:1, 1200)' using pcNr; -- 2. Insert principal în DEV_ORDL execute immediate 'insert into ' || v_gcs || '.dev_ordl (an, luna, id_inspector, id_lucrare, datai, id_util_ad, id_masiniclient, id_asigurator, id_tip, kmint, termen, dataoraad) values (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12) returning id_ordl into :13' using tnAn, tnLuna, pnIdInsp, pack_sesiune.dev_idLucrare, -- <-- session state dependency! v_dataora, tnIdUtil, pnIdMC, pnIdAsig, pnTipCom, pnKmInt, pdTermen, V_DATAORA returning into pnIdOrdl; -- 3. Side effect: update km la mașina clientului execute immediate 'update ' || v_gcs || '.dev_masiniclienti set kmint=:1 where id_masiniclient=:2' using pnKmInt, pnIdMC; end; ``` **Observații critice (post-clarificare Marius 2026-04-11):** - **Cele două INSERT-uri sunt pattern de inheritance, nu side effects**: - Step 1 = INSERT în `NOM_LUCRARI` (parent, base ROA ERP) — creează header-ul generic al comenzii (numele care va fi vizibil în ACT/RUL la facturare) - Step 2 = INSERT în `DEV_ORDL` (child, extensie ROAAUTO) — creează extensia auto legată prin `id_lucrare` - Ambele sunt **esențiale**. Fără step 1, `dev_ordl` e orphan FK violation. - **Side effect real** (step 3): UPDATE pe `dev_masiniclienti.kmint` — actualizează odometrul mașinii clientului pentru a reflecta ultima intrare în service. Nu e parte din creare, e sincronizare colaterală. Poate fi omis în prototype. - **Dependency pe `pack_sesiune.dev_idLucrare`** — după step 1, trigger-ul pe `nom_lucrari` (probabil `TRG_NOM_LUCRARI_BEFOINS`) populează `pack_sesiune.dev_idLucrare := :new.id_lucrare`. Step 2 citește acest state session pentru a completa `id_lucrare` în `dev_ordl`. **Pattern-ul vine din ROA ERP-ul mainframe-era**, unde session state era modul standard de comunicare între trigger și procedură. **Nu e bug, e convenție istorică.** - **Pentru roa2web bypass e trivial**: folosim `RETURNING id_lucrare INTO v_local` după INSERT-ul pe `nom_lucrari` — trigger-ul încă populează `pack_sesiune.dev_idLucrare` (dacă există în MARIUSM_AUTO), dar noi îl ignorăm și citim direct prin RETURNING clause. Standard Oracle, zero dependency. Confirmat prin pattern-ul identic la `dev_ordl` (`TRG_DEV_ORDL_BEFOINS` la triggere.sql:1165-1172 — `SEQ_DEV_ORDL.NEXTVAL INTO :new.id_ordl` + `pack_sesiune.dev_idOrdl := :new.id_ordl`). - `datai` și `dataoraad` sunt ambele `sysdate` local — nu primite ca param. ### 4.2. Versiunea PRODUCȚIE: `pack_auto.dev_adauga_lucrare` (17 IN + 1 OUT) **Sursa:** `Programe/oproceduri_devize.prg:147-148` — doar CALL-ul VFP. Body-ul **NU** e în `Scripturi_instalare/packages.sql` — pachetul `pack_auto` a fost adăugat după install. Body-ul real trăiește doar în DB-ul MARIUS-ului. **Call-ul din VFP:** ```sql begin pack_auto.dev_adauga_lucrare( ?gcS, ?gnAn, ?gnLuna, ?gnIdUtil, ?pcNr, ?pnIdInsp, ?pnIdAsig, ?pcNrDosar, ?pnIdMC, ?pnKmInt, ?pnOreFct, to_date(?, 'DD/MM/YYYY'), ?pntipcom, ?pcSirIDOperatiiClient, ?pcObservatii, ?pcDefectiuni, ?pnIdPartRef, ?@pnIdOrdl ); end; ``` **5 params adăugați în v2** față de v1: - `pcNrDosar` — nr dosar daună (pentru garanție cu asigurator) - `pnOreFct` — estimare ore manoperă la intrare - `pcSirIDOperatiiClient` — listă operații pre-selectate de client (CSV de IDs) - `pcObservatii` / `pcDefectiuni` — notes structurate - `pnIdPartRef` — partener referent **Sursa body-ului real în MARIUSM_AUTO** — de extras în săpt 3 cu: ```sql SELECT text FROM all_source WHERE owner='MARIUSM_AUTO' AND name='PACK_AUTO' AND type='PACKAGE BODY' ORDER BY line; ``` ### 4.3. Implicații pentru prototype — trei opțiuni | # | Strategie | Pro | Contra | |---|---|---|---| | **1** | Reuse `pack_auto.dev_adauga_lucrare` v2 direct (17 params, majoritatea defaults hardcodate în Python) | Hedge max: dovedește reuse pachet producție inclusiv side-effects. Template deliverable max value. | Depinde de `pack_sesiune.dev_idLucrare` care nu e inițializat în sesiunea roa2web. Risc că pică la primul call pentru context lipsă. | | **2** | Reuse `pack_devize.dev_adauga_lucrare` v1 (12 params, body vizibil în sursă) | Știi exact ce face SP-ul (body în `packages.sql`). 5 params mai puțin. | Același bug `pack_sesiune`. 12 params sunt încă mult pentru 2h/săpt. | | **3** | **SP nou minimal** `SP_CREEAZA_COMANDA_PROTOTIP` cu INSERT direct în `dev_ordl` cu câmpurile minime + `returning id_ordl` | Control total. Zero dependențe. Simplu. Testable. Hypothesis #1 probată la fel de bine. | Bypass-uie business logic. Template deliverable e "SP simplu", nu "reuse pachet legacy". Hedge slăbit puțin. | **Recomandare actualizată (după descoperirea `pack_sesiune`):** **Opțiunea 3** (SP nou minimal) e acum **recomandarea principală**. Motivul: `pack_sesiune` introduce un coupling invizibil cu session state VFP care ar sabota prototype-ul la prima tentativă — iar ipoteza #1 (Python+oracledb apelează PL/SQL cu OUT params) e probată la fel de bine de un SP simplu ca de unul complex. Reuse-ul production-logic rămâne pentru phase 2. **Hedge-ul rămâne valabil**: template-ul deliverable poate documenta ambele pattern-uri ("pentru SP-uri simple: pattern X; pentru SP-uri legacy cu `pack_sesiune`: investigă în phase 2 cum să inițializezi session state în Python"). **Decision point săpt 3/4**: verifică body-ul `pack_auto.dev_adauga_lucrare` în MARIUSM_AUTO. Dacă e refactored fără `pack_sesiune`, revin-o la opțiunea 1. Altfel, opțiunea 3. **SP minimal propus (opțiunea 3) — corectat pentru inheritance pattern:** ```sql CREATE OR REPLACE PROCEDURE MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP( p_id_tip IN NUMBER, -- FK dev_tip_deviz.id_tip (1-7) p_id_masiniclient IN NUMBER, -- FK dev_masiniclienti.id_masiniclient p_kmint IN NUMBER, -- km la bord p_termen IN DATE, -- termen execuție p_id_util IN NUMBER, -- user creator p_nr_comanda IN VARCHAR2, -- generat în Python cu prefix (G/R/P/PR/C) p_id_ordl OUT NUMBER, -- id-ul din dev_ordl (pentru UI) p_numar_out OUT VARCHAR2 -- ecou al nr_comanda (simetrie API) ) AS v_id_lucrare NUMBER; -- local, bypass pack_sesiune.dev_idLucrare v_dataora DATE := SYSDATE; BEGIN -- 1. INSERT parent: nom_lucrari (header generic vizibil în ACT/RUL la facturare) INSERT INTO MARIUSM_AUTO.nom_lucrari (nrord, id_mod) VALUES (p_nr_comanda, 1200) RETURNING id_lucrare INTO v_id_lucrare; -- ^ RETURNING bypasses dependency on pack_sesiune.dev_idLucrare -- ^ trigger TRG_NOM_LUCRARI_BEFOINS still fires + populates session var, -- but we ignore it and use our local v_id_lucrare instead -- 2. INSERT child: dev_ordl (extensia auto, FK la nom_lucrari prin id_lucrare) INSERT INTO MARIUSM_AUTO.dev_ordl (an, luna, id_inspector, id_lucrare, datai, id_util_ad, id_masiniclient, id_asigurator, id_tip, kmint, termen, dataoraad) VALUES (EXTRACT(YEAR FROM v_dataora), EXTRACT(MONTH FROM v_dataora), 0, -- id_inspector = 0 (nu folosim inspector în prototype) v_id_lucrare, -- FK la nom_lucrari v_dataora, -- datai p_id_util, p_id_masiniclient, 0, -- id_asigurator = 0 (nu folosim asigurator) p_id_tip, p_kmint, p_termen, v_dataora) -- dataoraad RETURNING id_ordl INTO p_id_ordl; -- Step 3 (UPDATE dev_masiniclienti.kmint) SKIP — side effect opțional -- pentru prototype. Dacă vrem să-l includem, adăugăm aici: -- UPDATE dev_masiniclienti SET kmint = p_kmint -- WHERE id_masiniclient = p_id_masiniclient; p_numar_out := p_nr_comanda; END; / ``` **~40 linii**, două INSERT-uri în ordinea FK-ului parent→child, RETURNING pentru chaining, zero dependency pe `pack_sesiune`. Testabil din SQL Developer: ```sql DECLARE v_id NUMBER; v_num VARCHAR2(100); BEGIN MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP( p_id_tip => 3, -- Regie p_id_masiniclient => 1, -- prima mașină client existentă p_kmint => 150000, p_termen => SYSDATE + 10, p_id_util => 1, -- user test p_nr_comanda => 'R' || TO_CHAR(MARIUSM_AUTO.SEQ_NRORD.NEXTVAL), p_id_ordl => v_id, p_numar_out => v_num ); DBMS_OUTPUT.PUT_LINE('id_ordl: ' || v_id || ', nr: ' || v_num); ROLLBACK; -- pentru test, nu commit END; / ``` **Avantaj**: exact pattern-ul pe care îl va folosi Python (`callproc` cu OUT params + manual commit). Dovedește ipoteza #1 pe un SP realist care atinge DOUĂ tabele în ordine corectă, nu pe un `test_out` trivial. --- ## 5. `tip_comanda` — enum real extras din DDL + seed **Sursa primară:** `Scripturi_instalare/tabele.sql:763-794` (DDL) + `Scripturi_instalare/initializari.sql:199-208` (seed INSERT). **Tabela reală: `DEV_TIP_DEVIZ`** (nu `dev_tip_comenzi` — user a corectat, dar ground truth din scripturile de instalare zice `dev_tip_deviz`; **confirmă în săpt 3 care e numele în MARIUSM_AUTO** — poate au redenumit-o). ### DDL ```sql create table DEV_TIP_DEVIZ ( ID_TIP NUMBER(5) not null, -- PK, auto-generat din SEQ_DEV_TIP_DEVIZ DENUMIRE VARCHAR2(50) not null, -- Label afișat în dropdown STERS NUMBER(1) default 0 not null -- Soft delete flag ); alter table DEV_TIP_DEVIZ add constraint PK_TIP_DEVIZ primary key (ID_TIP); ``` **Notă:** `update_devize.prg:424` selectează `id_tip, denumire, inch_validare from dev_tip_deviz` — coloana `inch_validare` **NU** e în DDL-ul din `tabele.sql`, deci a fost adăugată post-install printr-o migrație. Așteaptă-te la diferențe între schema "curată" și MARIUSM_AUTO real. ### FK în `DEV_ORDL` Linia 203 din `packages.sql` arată coloana folosită pe tabela de comandă: ```sql insert into .dev_ordl (an, luna, id_inspector, id_lucrare, datai, id_util_ad, id_masiniclient, id_asigurator, id_tip, kmint, termen, dataoraad) values (...) returning id_ordl into pnIdOrdl ``` Coloana este **`id_tip`** (nu `tip_comanda`). Numele `tip_comanda` apare doar în view-ul `vcomenzi` ca alias denormalizat pentru `denumire` din JOIN-ul cu `dev_tip_deviz`. ### Seed values (install-time, din `initializari.sql:199-208`) | ID_TIP | DENUMIRE | Prefix pe `nr_comanda` (din `oproceduri_devize.prg:109-120`) | |---|---|---| | 1 | **POST GARANTIE** | *(niciun prefix)* | | 2 | **GARANTIE** | **G** | | 3 | **REGIE** | **R** | | 4 | **PREGATIRE** | **P** | | 5 | **REGIE 2** | *(niciun prefix — skipped în switch)* | **IDs 6 și 7** (cu prefix `PR`, respectiv `C`) **NU sunt în seed-ul de install** — au fost adăugate în producție prin `INSERT INTO dev_tip_deviz` (sau prin UI-ul VFP de admin). Denumirea lor o știe Marius — de confirmat în săpt 3. ### Verificare în săpt 3 ```sql -- Lista completă curentă din MARIUSM_AUTO SELECT id_tip, denumire, sters FROM MARIUSM_AUTO.DEV_TIP_DEVIZ ORDER BY id_tip; -- Verifică dacă există alias-ul 'dev_tip_comenzi' ca synonym sau view SELECT object_name, object_type FROM all_objects WHERE owner='MARIUSM_AUTO' AND UPPER(object_name) LIKE '%TIP%COM%'; ``` ### Pentru prototype (decision) `ComandaNoua.vue` are nevoie de un dropdown cu 4 opțiuni. **Hardcodarea în Vue** e OK pentru prototype (scope wall: nu există endpoint `/tipuri-comanda`). Recomandare valori: - `{id: 1, label: 'Post Garanție'}` - `{id: 2, label: 'Garanție'}` - `{id: 3, label: 'Regie'}` - `{id: 4, label: 'Pregatire'}` - `{id: 5, label: 'Regie 2'}` - `{id: 6, label: 'Productie'}` - `{id: 7, label: 'Constatare'}` Skip ID-ul 5 (REGIE 2, probabil deprecated). --- ## 6. Label-uri Romanian pentru formulare **Extrase din context VFP** (nume variabile + procese). Aceste label-uri le folosești în `ComandaNoua.vue`: | Câmp UI | Label Romanian | Corespondent VFP | |---|---|---| | Tip comandă | **Tip comandă** | `tip_comanda` / combobox în `frm_gencom` | | Client | **Client** | `nume` (denormalizat) / `id_codclient` | | Mașină | **Mașină** (sau **Număr înmatriculare**) | `nrinmat` / `id_masina` | | Operații solicitate | **Operații solicitate** | `pcSirIDOperatiiClient` | | Km la intrare | **Km la bord** | `pnKmInt` (în VFP se afișează "kmint") | | Ore manoperă estimate | **Ore manoperă** | `pnOreFct` | | Termen execuție | **Termen execuție** (default = `today + gnTermenZileService`) | `pdTermen` | | Observații | **Observații** | `pcObservatii` | | Defecțiuni | **Defecțiuni** | `pcDefectiuni` | | Nr. dosar daună | **Nr. dosar** (doar dacă tip=garanție/asigurare) | `pcNrDosar` | **Pentru MVP-ul prototype-ului (4 câmpuri)**: păstrează doar primele 4 din tabel (tip / client / mașină / operații). Restul trec în plan ca TODO-phase2 sau se afișează cu valori default hardcodate. **Toast-uri (Romanian, convenție ROA2WEB din `ReceiptCreateUnifiedView.vue`):** - Success: `summary="Comandă creată"`, `detail="Nr ${nr_comanda}"` (ex: "Nr G12345") - Business error: `summary="Validare"`, `detail=` - Infra error: `summary="Eroare conexiune"` (503) / `"Eroare internă"` (500) --- ## 7. Funcții PL/SQL utile găsite în VFP source Din grep `pack_auto\.` și `pack_comenzi\.` pe tot repo-ul: | Funcție/Proc | Scop | Relevantă pentru prototype? | |---|---|---| | `pack_auto.dev_adauga_lucrare` | Creează comandă (17 params) | **DA** — SP-ul principal | | `pack_auto.dev_adauga_oper_fact` | Adaugă operații pe comandă pentru facturare | NU — post-facturare | | `pack_auto.dev_distribuie_timp_n` | Distribuie timp pe norme | NU | | `pack_auto.citeste_discount_contract` | Citește discount-uri contract | NU | | `pack_auto.actualizeaza_deviz` | Updatează deviz | NU | | `pack_auto.getOptiuneInchidere(n)` | Citește opțiune închidere | NU | | `pack_auto.set_perioada_raport` | Setează perioadă raport | NU | | `pack_comenzi.extrage_optiuni(varvalue, id_sectie)` | Citește opțiuni pe secție | **Poate** — pentru `tip_comanda` default | | `pack_comenzi.genereaza_nr_lucrare` | Generează nr. lucrare | **Poate** — alternativ la prefix hardcodat | | `pack_comenzi.sectii_utilizator(id_util, id_sucursala)` | Secții accesibile utilizatorului | **Poate** — pentru multi-section support phase 2 | **Pattern observat**: `{call pack_auto.proc(?param, ?@out_param)}` pentru apeluri cu OUT. Confirmă că oracledb async cu OUT params e un pattern deja stabilit în stack-ul VFP → Oracle. --- ## 8. Next steps — săpt 3 task list (actualizat) În loc de task-ul vag "deschide VFP producție și caută fluxul de creare comandă": - [ ] Clonează `gitea.romfast.ro/romfast/vfp_roaauto` local (dacă nu e clonat) - [ ] Conectează-te la `10.0.20.121/ROA` ca `ROA_WEB` (sau alt user cu acces la `all_objects` pe MARIUSM_AUTO) - [ ] Rulează și salvează în `week3-verification.sql`: ```sql -- Verifică existența pachetului pack_auto SELECT object_name, object_type, status FROM all_objects WHERE owner='MARIUSM_AUTO' AND object_name IN ('PACK_AUTO','PACK_COMENZI'); -- Verifică coloanele din comenzi (confirmă schema de mai sus) SELECT column_name, data_type, data_length, nullable FROM all_tab_columns WHERE owner='MARIUSM_AUTO' AND table_name='COMENZI' ORDER BY column_id; -- Găsește tabela/nomenclatorul pentru tip_comanda SELECT table_name FROM all_tables WHERE owner='MARIUSM_AUTO' AND UPPER(table_name) LIKE '%TIP%COM%'; -- Lista procedurilor din pack_auto (pentru a decide opțiunea 1 vs 3) SELECT procedure_name, overload FROM all_procedures WHERE owner='MARIUSM_AUTO' AND object_name='PACK_AUTO' ORDER BY procedure_name; ``` - [ ] Decide: opțiunea 1 (reuse `dev_adauga_lucrare`), 2 (wrapper), sau 3 (INSERT direct) - [ ] Confirmă denumirile pentru `tip_comanda` = 4, 6, 7 - [ ] Completează secțiunea 5 și 6 de mai sus cu valorile confirmate - [ ] Commit pe branch `feat/service-auto` cu mesaj `docs(service-auto): confirm VFP audit against real MARIUSM_AUTO schema` --- ## 9. Ce NU am găsit încă (gaps pentru săpt 3) - **Forma UI reală** — `frm_gencom` e definită într-un `.vcx` (VFP binary class file), nu grep-abil direct. Pentru layout-ul real și ordinea câmpurilor în UI-ul VFP, fie deschid VFP-ul (nu în scope), fie Marius trimite un screenshot în săpt 3. - **Default values** — care sunt valorile default în `frm_gencom`? `pdTermen` are `DATE() + gnTermenZileService` (default 10 zile) — asta e relevant. Restul defaults trebuie verificate. - **Validările client-side** — VFP face probabil validări în `frm_gencom.valid()`. Pentru prototype, planul deja spune "no client-side validation" — nu e gap real. - **Permission model** — `gcAcces=[1;2;3;4;]` apare în `onom_comenzi.prg:14` — sugerează un sistem de ACL cu 4 nivele. Irelevant pentru prototype (1 user), dar de notat pentru TODO-phase2. --- **END OF DRAFT** — să fie revăzut și completat în săpt 3, 2026-05-05 → 2026-05-09.