Add real production sources as authoritative reference (supersedes vfp_roaauto/Scripturi_instalare/packages.sql which is for a different product — devize producție, not service auto): - mariusm_ddl_export.sql: 5127 lines DDL from DBMS_METADATA (tables, views, triggers) of MARIUSM_AUTO schema - pack_auto.pck: main business package (17 procedures) - PACK_FACTURARE.pck, PACK_SESIUNE.pck, PACK_CONTAFIN.pck, PACK_COMENZI.pck: dependency packages - export_ddl.sql: SQL export helper using DBMS_METADATA + DBMS_OUTPUT with discovery via ALL_OBJECTS LIKE patterns Rewrite tabele-service-auto.md v3 (~600 lines) fully grounded in production sources. Map all flows end-to-end: - Create (pack_auto.dev_adauga_lucrare) → NOM_LUCRARI + DEV_ORDL - Normare (dev_adauga_operatie) → DEV_OPER + DEV_OPER_MECANICI - Validate ops (dev_valideaza_operatii) → DEV_OPER.VALIDAT - Validate order (dev_valideaza_comanda) → DEV_ORDL.VALIDAT + CALENDAR - Archive (dev_arhiveaza_comanda) → DEV_ORDL.INCHIS_FORTAT - Bonuri consum: generic ROA (ointroduceri.prg tip=3) → RUL.id_lucrare - Facturare: pack_facturare.* + pack_auto.actualizeaza_deviz Key business semantics confirmed by Marius 2026-04-11: - DEV_TIP_DEVIZ.inch_validare = 1 means validation alone closes the order (no closing note). inch_validare = 0 means additional closing required (via invoice for billable types, or 711=332 journal entry for internal types). View AUTO_LISTARE_MAN_TOT_COM has the exact "closed" condition as (validat=1 AND inch_validare=1) OR (facturat=1 AND inch_validare=0). - Live DEV_TIP_DEVIZ values: 1=POST GARANTIE, 2=GARANTIE, 3=REGIE, 4=PREGATIRE, 5=REGIE 2, 6=PRODUCTIE, 7=CONSTATARE. REGIE/PRODUCTIE/ CONSTATARE have inch_validare=1 (internal, closed at validation). - DEV_OPER for service auto contains only manopera (id_norme). The id_articol/id_rul_aux columns exist in DDL for another product that shares the table but are not populated by pack_auto. - Real materials consumed on an order live in RUL tagged by id_lucrare, not in DEV_OPER. DEV_ESTIMARI_REP is a separate pre-sale estimate (both manopera and materiale lines) given to the client, independent of the real manopera (DEV_OPER) and real materials (RUL). Plan Correction 13 (claude-main-design-20260411-rethink.md): - Invalidate Scripturi_instalare references - Confirm NOM_LUCRARI ← DEV_ORDL inheritance pattern - Confirm pack_sesiune.dev_idLucrare/dev_idOrdl populated by triggers - Refine prototype SP (Option 3) template based on real schema - Timeline unchanged, scope wall reconfirmed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 KiB
Tabele + SP-uri Service Auto — MARIUSM_AUTO ground truth (v3)
Status: v3 complet rescris 2026-04-11 pe baza sursă producție.
Surse (toate din
docs/service-auto/):
mariusm_ddl_export.sql— DDL exportat din producție (tabele, views, triggere)pack_auto.pck— pachet principal service autoPACK_FACTURARE.pck— pachet facturarePACK_SESIUNE.pck— session state (dev_idLucrare, dev_idOrdl, getAn/getLuna)PACK_CONTAFIN.pck— financial utilities (getCotaTVAStandard, get_idFact)PACK_COMENZI.pck— pentru ROA ERP base comenzi, NU service autoVersiuni anterioare invalidate:
- v1/v2 a referit
vfp_roaauto/Scripturi_instalare/packages.sql→ acel fișier era pentru alt produs ("devize producție"), NU service auto.- v2 a presupus că tabela e
comenzi/vcomenzi→ view-ulVCOMENZIdin MARIUSM_AUTO nu e pentru service auto (e pentru ROA ERP base, tabela sursăcomenzi+nom_masini+id_codclient+ fieldinternacu valoriINTERNA/EXTERNA/GESTIUNE/SECTIE).- Service auto =
DEV_ORDL+NOM_LUCRARI(pattern de inheritance), cu view-uri dedicate prefixateAUTO_*.
1. Model de entități — ierarhie ROA + extensie ROAAUTO
┌──────────────────────────────────────────────────────────────────────────┐
│ NOM_LUCRARI (ROA ERP base — header generic al oricărei "lucrări"/comenzi) │
│ id_lucrare PK, nrord, id_mod, facturata, id_fact, id_tata │
│ TRIGGER TRG_NOM_LUCRARI_BEFOINS: NEXTVAL → id_lucrare │
│ pack_sesiune.dev_idLucrare := ID │
└────────────────────────────────┬─────────────────────────────────────────┘
│ FK id_lucrare (FK_DEV_ORDL_002)
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ DEV_ORDL (ROAAUTO — extensie service auto) │
│ id_ordl PK, id_lucrare FK, id_tip FK, id_masiniclient FK, │
│ id_inspector, id_asigurator, id_part, id_part_ref, id_agent, │
│ validat, inchis_fortat, proc_tvav, kmint, ore_functionare, │
│ solicitari_client CLOB, observatii, defectiuni, nr_dosar, ... │
│ TRIGGER TRG_DEV_ORDL_BEFOINS: NEXTVAL → id_ordl │
│ pack_sesiune.dev_idOrdl := ID │
└──┬───────────────────────────────────────────────┬───────────────────────┘
│ │
│ FK id_ordl │ id_lucrare (NU FK direct,
▼ │ tag logic prin coloană)
┌─────────────────────────────────────┐ ┌─────────────────────────────┐
│ DEV_OPER │ │ RUL (ROA generic warehouse) │
│ (NUMAI manoperă pentru service auto)│ │ id_rul PK, id_lucrare, │
│ id_oper PK, id_ordl FK, │ │ id_articol, cante, pretv, │
│ id_norme FK → DEV_NOM_NORME, │ │ id_set, id_fact, ... │
│ timpn, pret, validat, │ │ │
│ id_util, dataora, sters, nou │ │ Populat de "Bon consum" │
│ │ │ (ointroduceri.prg tip=3) │
│ Coloane id_articol / id_rul_aux: │ │ cu ID_LUCRARE tag. │
│ EXISTĂ în DDL (pentru alt produs │ └─────────────────────────────┘
│ "producție" care partajează schema),│
│ dar NU sunt populate de service auto│
└────┬────────────────────────────────┘
│ FK id_oper
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ DEV_OPER_MECANICI — distribuția timpului pe mecanici │
│ id_opermecanic PK, id_oper FK, id_mecanic FK, ore │
└──────────────────────────────────────────────────────────────────────────┘
Materialele consumate pe o comandă NU sunt în DEV_OPER. Sunt în RUL (tabela
generică ROA de rulaje / mișcări de stoc), legate de comandă prin coloana RUL.ID_LUCRARE.
Flow-ul e:
- User face "Bon consum" în
ointroduceri.prg(tip=3) → selectează articole din stoc + tag-uiește comandă (id_lucrare) → salvare - Generic ROA warehouse scrie rânduri în
RULcuID_LUCRARE = X,SCD = '3xx',SCC = '6xx'(consum de stoc) - La afișarea devizului și la facturare, materialele se citesc ca
SUM(cante * pretv) FROM RUL WHERE id_lucrare = X
Notă business Marius 2026-04-11: este posibil ca DEV_OPER să fie folosit de alt program
de producție care are și materiale în DEV_OPER (cu id_articol + id_rul_aux populate),
dar pentru service auto ROAAUTO, DEV_OPER conține doar operații de manoperă — fiecare
linie are id_norme non-NULL și id_articol NULL.
Separat, deviz estimativ (pre-sale, ofertă către client):
DEV_ESTIMARI_REP (deviz estimativ — ofertă pentru client înainte de a începe lucrarea)
id_dev_estimare_rep PK, id_lucrare FK,
id_norme (manoperă estimată) SAU id_articol (material estimat),
cantitate, pret, pret_cu_tva, cota_tva, id_sectie, id_valuta, ...
Cele trei flux-uri paralele și independente pe o lucrare (id_lucrare):
| # | Tabel | Ce conține | Când se populează |
|---|---|---|---|
| 1 | DEV_ESTIMARI_REP |
Deviz estimativ (manoperă + materiale estimate) dat ca ofertă clientului | Înainte de a începe lucrarea |
| 2 | DEV_OPER |
Manopera reală executată (doar id_norme, service auto) |
În timpul lucrării |
| 3 | RUL cu id_lucrare |
Materialele reale consumate (bonuri de consum din stoc) | În timpul lucrării |
Nu există sincronizare automată: estimarea e doar o ofertă pre-sale, iar lucrarea reală (manoperă + materiale) poate devia de la ea. Comparațiile estimat vs. real se fac în rapoarte analitice, nu în flux-ul operațional.
2. DEV_ORDL — schema reală producție
Exportat via DBMS_METADATA.GET_DDL pe 2026-04-11 din MARIUSM_AUTO.
37 coloane, FK-uri active:
| Coloană | Tip | Null | Note |
|---|---|---|---|
id_ordl |
NUMBER(10) |
NN | PK, alocat de trigger din SEQ_DEV_ORDL |
luna |
NUMBER(2) |
NN | Luna contabilă (0 default) |
an |
NUMBER(4) |
NN | Anul contabil (0 default) |
id_inspector |
NUMBER(5) |
Y | FK → DEV_NOM_INSPECTORI |
id_lucrare |
NUMBER(10) |
NN | FK → NOM_LUCRARI (FK_DEV_ORDL_002) |
termen |
DATE |
Y | Termen execuție (default SYSDATE + gnTermenZileService, de obicei +10 zile) |
datai |
DATE |
Y | Data intrării |
orai / orae |
NUMBER(5) |
Y | Ora intrare/ieșire |
datae |
DATE |
Y | Data ieșirii |
validat |
NUMBER(1) |
NN | 0/1 |
id_util_ad |
NUMBER(5) |
NN | User creator |
id_util_valid |
NUMBER(5) |
Y | User care a validat |
dataoraad |
DATE |
Y | Audit: momentul creării |
dataoravalid |
DATE |
Y | Audit: momentul validării |
id_utils / dataoras |
Y | Audit: ștergere logică | |
id_masiniclient |
NUMBER(5) |
Y | FK → DEV_MASINICLIENTI |
id_asigurator |
NUMBER(5) |
Y | FK → DEV_NOM_ASIGURATORI |
sters |
NUMBER(1) |
NN | Soft delete |
id_tip |
NUMBER(5) |
NN | FK → DEV_TIP_DEVIZ (default 1) |
inchis_fortat |
NUMBER(1) |
NN | 0/1 — arhivat fără validare |
kmint |
NUMBER(10) |
Y | Km la bord intrare |
nr_dosar |
VARCHAR2(40) |
Y | Nr. dosar daună (pentru garanție asigurator) |
solicitari_client |
CLOB |
Y | Text denormalizat: numele normelor solicitate (agregat prin STRINGAGG din DEV_NOM_NORME la crearea comenzii) |
proc_tvav |
NUMBER(10,4) |
Y | Procent TVA (citit din pack_contafin.getCotaTVAStandard(luna, an) la creare) |
id_part |
NUMBER(10) |
Y | FK → NOM_PARTENERI — clientul direct pe comandă (nu doar prin mașină) |
coada_deviz |
NUMBER(1) |
NN | Flag "în coada devizelor" |
observatii |
VARCHAR2(1000) |
Y | |
data_curs |
DATE |
Y | Pentru comenzi în valută |
in_lucru |
NUMBER(1) |
NN | Flag "comanda în lucru" |
id_valuta_deviz |
NUMBER(10) |
Y | FK → NOM_VALUTE |
facturezmix |
NUMBER(1) |
NN | Flag "facturare mixtă" |
data_in_lucru / dataorainlucru |
DATE |
Y | Audit trecere în lucru |
id_agent |
NUMBER(10) |
Y | FK → NOM_PARTENERI (agent vânzări) |
id_util_inchis / dataorainchis |
Y | Audit "închidere forțată" (arhivare) | |
id_part_ref |
NUMBER(10) |
Y | FK → NOM_PARTENERI (partener referent) |
ore_functionare |
NUMBER(10) |
Y | Pentru vehicule utilitare (ore motor în loc de km) |
defectiuni |
VARCHAR2(200) |
Y |
PK: PK_DEV_ORDL pe id_ordl.
FK active în producție:
FK_DEV_ORDL_001→DEV_NOM_INSPECTORI(id_inspector)ENABLEFK_DEV_ORDL_002→NOM_LUCRARI(id_lucrare)ENABLE ← constraint criticFK_DEV_ORDL_003→NOM_PARTENERI(id_part)ENABLE (client direct)FK_DEV_ORDL_004→NOM_VALUTE(id_valuta)ENABLEFK_DEV_ORDL_005→NOM_PARTENERI(id_agent)ENABLEFK_DEV_ORDL_006→NOM_PARTENERI(id_part_ref)ENABLE
Nu există FK pe id_masiniclient (probabil pentru a permite comenzi pentru mașini
temporare sau fără înmatriculare persistentă).
Coloane AVANS, VALCTVA, TIP_INCAS, ID_CTR, ID_FACT, ID_CONTRACT care apăreau
în v2 DDL NU există în producție reală. Sunt artefacte ale scripturilor de instalare
vechi care au fost abandonate.
3. NOM_LUCRARI — header parent (ROA ERP base)
NOM_LUCRARI (
id_lucrare NUMBER(10) NN PK,
nrord VARCHAR2(50),
sters NUMBER(1) NN default 0,
id_mod NUMBER(20) NN default 0, -- 1200 pentru service auto
inactiv NUMBER(1) NN default 0,
facturata NUMBER(1) NN default 0,
id_tata NUMBER(10), -- parent hierarchy
id_fact NUMBER(20) -- populat la facturare
)
Trigger TRG_NOM_LUCRARI_BEFOINS:
select SEQ_NOM_LUCRARI.NEXTVAL into :new.ID_LUCRARE from dual;
pack_sesiune.dev_idLucrare := :new.id_lucrare; -- <-- session state pentru pack_auto
Implicație pentru roa2web: după INSERT INTO nom_lucrari ... RETURNING id_lucrare INTO v_local,
ai id-ul în două locuri simultan — în v_local (prin RETURNING) și în
pack_sesiune.dev_idLucrare (prin trigger). Poți folosi oricare. pack_auto.dev_adauga_lucrare
folosește intern pack_sesiune.dev_idLucrare pentru step-ul 2 (INSERT în DEV_ORDL).
Trigger TRG_NOM_LUCRARI_BEFOUPD: cheamă pack_audit.verifica_val(...) pentru fiecare
câmp modificat → toate UPDATE-urile pe NOM_LUCRARI sunt audit trail-uite automat
într-un pachet separat pack_audit (nu am încă sursa, nu e în scope imediat).
4. DEV_OPER — liniile de operații manoperă (doar)
Important: pentru service auto ROAAUTO, DEV_OPER conține numai operații de manoperă.
Deși schema fizică are coloanele id_articol, id_rul_aux, id_dev_estimare_rep (probabil
pentru compatibilitate cu alt produs de producție care partajează aceeași tabelă), SP-urile
pack_auto.* pentru service auto nu le populează. Verificare în body-ul dev_adauga_operatie
și dev_adauga_oper_fact: ambele inserează doar id_norme, nu id_articol.
DEV_OPER (
id_oper NUMBER(10) NN PK,
id_ordl NUMBER(10) NN FK → DEV_ORDL,
id_norme NUMBER(10) FK → DEV_NOM_NORME -- SERVICE AUTO: mereu non-NULL
timpn NUMBER(8,3) NN default 0, -- ore manoperă
pret NUMBER(17,4) NN default 0, -- preț oră (lei/oră)
datai DATE NN default SYSDATE,
id_sectie NUMBER(5) FK → NOM_SECTII,
id_util NUMBER(5), -- validator (populat la validare)
dataora DATE, -- momentul validării
id_utili NUMBER(5), -- creator (introducător)
id_utils NUMBER(5), -- user care a șters
dataoras DATE,
sters NUMBER(1) NN default 0,
validat NUMBER(1) NN default 0,
nou NUMBER(1) NN default 0, -- flag heritage-currency RON/ROL
id_fact NUMBER(20) FK → DOCUMENTE -- populat la facturare
-- Coloanele următoare există în DDL dar NU sunt folosite de service auto:
-- id_articol NUMBER(20) FK → NOM_ARTICOLE (pentru alt produs: producție)
-- id_dev_estimare_rep NUMBER(20) FK → DEV_ESTIMARI_REP (pentru alt produs)
-- id_rul_aux NUMBER(20) FK → RUL_AUXILIAR (pentru alt produs)
)
Materialele consumate NU sunt aici. Sunt în RUL.id_lucrare (vezi secțiunea 8
pentru flux-ul de bon consum).
Câmpul nou = flag heritage-currency (RON denominat 2005+ vs vechiul ROL). Setat
automat în SP-uri pe baza comparației lună curentă vs pack_sesiune.GET_ANRON() /
GET_LUNARON(). Pentru orice lucrare modernă (post-2005) → mereu nou = 1. View-urile
AUTO_VOPER conțin un CASE care împarte pret la 10000 pentru valorile ROL vechi.
Artefact istoric, zero impact asupra prototype-ului nou.
Trigger TRG_DEV_OPER_BEFOINS:
select SEQ_dev_oper.NEXTVAL into :new.id_oper from dual;
(Nu populează session state — deosebire față de DEV_ORDL.)
5. DEV_ESTIMARI_REP — deviz estimativ pentru client (pre-sale)
Rol: deviz estimativ pe care service-ul îl oferă clientului înainte ca lucrarea să înceapă — o "ofertă" care conține estimarea de manoperă și materiale pentru o reparație propusă. Este complet separat de lucrarea reală.
DEV_ESTIMARI_REP ≠ DEV_OPER ≠ RUL (id_lucrare)
(deviz estimativ (manopera reală (bonuri consum materiale
către client, cronometrată pe reale pe comandă, din stoc,
manopera + materiale) comandă) din warehouse generic ROA)
Cele trei flux-uri sunt independente:
- DEV_ESTIMARI_REP — înainte de lucrare, utilizatorul face o estimare pentru client cu linii mixte (manoperă estimată + materiale estimate). Clientul primește devizul, decide dacă aprobă lucrarea.
- DEV_OPER — în timpul lucrării, se înregistrează manopera efectiv executată
(doar operații cu
id_norme, timp real, preț manoperă). - RUL cu
id_lucrare— în paralel, bonurile de consum reale scot materiale din stoc tag-uite pe comandă.
Nu există sincronizare automată între estimare și real — un client poate aproba un deviz estimativ de 1000 lei, dar lucrarea reală să se termine la 1200 lei (fie pentru că s-a găsit ceva în plus, fie pentru că au fost piese mai scumpe decât s-a estimat). Comparația real vs. estimat se face probabil la facturare sau în raporte.
Schema: fiecare linie e fie manoperă estimată (id_norme NN) fie material estimat
(id_articol NN):
DEV_ESTIMARI_REP (
id_dev_estimare_rep NUMBER(20) NN PK,
id_lucrare NUMBER(20) NN FK → NOM_LUCRARI,
id_norme NUMBER(20) FK → DEV_NOM_NORME,
id_articol NUMBER(20) FK → NOM_ARTICOLE,
cantitate NUMBER(20,4) NN,
pret NUMBER(20,4) NN default 0,
pret_cu_tva NUMBER(1) NN default 0,
cota_tva NUMBER(10),
id_sectie NUMBER(10) FK → NOM_SECTII,
id_pol NUMBER(20) FK → CRM_POLITICI_PRETURI,
id_dev_estimare_prod NUMBER(20) FK → DEV_ESTIMARI_PRODUSE,
id_articol_grupare NUMBER(20),
cu_pierderi NUMBER(1) NN default 0,
id_valuta NUMBER(10),
semifabricat_ales / semifabricat_id NUMBER(10),
id_util / dataora, id_utils / dataoras, sters
)
View-ul UI: AUTO_VESTIMARI_REP — denormalizează dev_estimari_rep cu dev_nom_norme +
nom_articole, calculează pretftva / pretctva / valftva / valtva / valoare prin
pack_sesiune.calculeaza_pret_* + calculeaza_total_*.
SP-uri pentru estimare (din pack_auto):
adauga_manopera_de(id_lucrare, id_norme, cantitate, pret, pret_cu_tva, cota_tva, id_util)adauga_material_de(id_lucrare, id_articol, cantitate, pret, pret_cu_tva, cota_tva, id_util)modifica_pret_de,modifica_cota_tva_de,modifica_cantitate_de,sterge_articol_de
NOT IN SCOPE pentru prototype — estimarea e un sub-flux pre-sale dedicat.
6. DEV_TIP_DEVIZ — enum tip comandă (cu flag închidere prin validare)
DEV_TIP_DEVIZ (
id_tip NUMBER(5) NN PK,
denumire VARCHAR2(50) NN,
sters NUMBER(1) NN default 0,
inch_validare NUMBER(1) NN default 1 -- 1 = închidere prin validare, 0 = alt mod
)
Coloana inch_validare e cheia pentru a înțelege flux-ul post-validare. Default = 1
(închidere implicită prin validare). Setată per tip-comandă prin
pack_auto.setOptiuneInchidere(v_tip, v_inchidere_validare) și citită prin
pack_auto.getOptiuneInchidere(v_tip) RETURN NUMBER.
Valori live confirmate 2026-04-11 de Marius (SELECT id_tip, denumire, sters, inch_validare FROM MARIUSM_AUTO.DEV_TIP_DEVIZ ORDER BY id_tip):
| id_tip | denumire | prefix | sters | inch_validare | Natura comenzii | Închidere reală |
|---|---|---|---|---|---|---|
| 1 | POST GARANTIE | (fără) | 0 | 0 | Se facturează client direct | prin factură (pack_facturare.*) → facturat=1 |
| 2 | GARANTIE | G | 0 | 0 | Se facturează asigurator prin dosar daună | prin factură → facturat=1 |
| 3 | REGIE | R | 0 | 1 | Auto proprii — NU se facturează | validare directă — validat=1 suficient |
| 4 | PREGATIRE | P | 0 | 0 | Se facturează | prin factură → facturat=1 |
| 5 | REGIE 2 | (fără) | 0 | 0 | Se facturează | prin factură → facturat=1 |
| 6 | PRODUCTIE | PR | 0 | 1 | Producție internă — NU se facturează | validare directă — validat=1 suficient |
| 7 | CONSTATARE | C | 0 | 1 | Doar diagnostic — NU se facturează | validare directă — validat=1 suficient |
Prefixele sunt construite în VFP la oproceduri_devize.prg:108-120 (hardcodate în client,
nu în DB).
Semantica inch_validare (corectată 2026-04-11 după clarificare iterativă Marius):
Flag-ul decide dacă validarea comenzii e suficientă pentru a o considera închisă, sau e necesară încă o notă contabilă suplimentară.
-
inch_validare = 1→ Validarea ESTE închiderea. Comanda se consideră închisă prin simplul fapt căDEV_ORDL.VALIDAT = 1. NU se generează nicio notă contabilă suplimentară. Folosit tipic pentru comenzi interne (REGIE = auto proprii, PRODUCTIE, CONSTATARE) unde nu se facturează nimic și nu se dorește impact contabil la închidere. -
inch_validare = 0→ Validarea NU e închiderea. Comanda rămâne "deschisă" contabil chiar și dupăVALIDAT = 1. E nevoie de o notă contabilă suplimentară pentru a o închide real:- Pentru tipuri facturabile (GARANTIE, POST GARANTIE, PREGATIRE, REGIE 2) → nota
vine prin facturare (
pack_facturare.*), care setează șifacturat = 1pe flux-ul de agregate. - Pentru tipuri nefacturabile (teoretic REGIE/PRODUCTIE dacă ar fi configurate așa) →
se generează o notă contabilă
711 = 332care recunoaște venitul intern și închide stocul "servicii în curs de execuție".
- Pentru tipuri facturabile (GARANTIE, POST GARANTIE, PREGATIRE, REGIE 2) → nota
vine prin facturare (
Dovada în cod — view-urile AUTO_LISTARE_MAN_TOT_COM și AUTO_LISTARE_MAN_TOT_DESF
(mariusm_ddl_export.sql:1795-1800 și :1842-1847) au condiția exactă pentru "comandă
închisă în luna curentă":
WHERE a.sters = 0
AND ( (extract(month from a.dataoravalid) = pack_sesiune.getluna()
AND extract(year from a.dataoravalid) = pack_sesiune.getan()
AND a.validat = 1
AND e.inch_validare = 1) -- inchis prin validare singura
OR
(extract(month from b.dataact) = pack_sesiune.getluna()
AND extract(year from b.dataact) = pack_sesiune.getan()
AND b.facturat = 1
AND e.inch_validare = 0)) -- inchis prin facturare/nota
Cu alte cuvinte, view-ul consideră o comandă "închisă" DOAR dacă:
inch_validare = 1+VALIDAT = 1(calea A: validarea închide) SAUinch_validare = 0+FACTURAT = 1(calea B: trebuie factură/notă de închidere)
Configurare live MARIUSM_AUTO (2026-04-11):
| Tip comandă | Configurare | Efect |
|---|---|---|
| REGIE, PRODUCTIE, CONSTATARE | inch_validare = 1 |
Validarea e închiderea. Zero notă contabilă. |
| POST GARANTIE, GARANTIE, PREGATIRE, REGIE 2 | inch_validare = 0 |
Validarea nu e suficientă. Trebuie factură. |
Marius poate schimba configurarea per tip — ex: dacă schimbă REGIE la inch_validare = 0,
atunci comenzile REGIE nu se mai consideră închise la validare, ci necesită o notă contabilă
711 = 332 suplimentară înainte ca FACTURAT = 1 să apară în agregat.
dev_arhiveaza_comanda este o procedură complet separată (setează INCHIS_FORTAT = 1),
apelată doar pentru a abandona forțat o comandă — nu e legată de inch_validare. Folosit
doar pentru cazuri excepționale (client a renunțat, constatare fără urmare tehnică, etc.).
Implicație pentru prototype (creare only): irelevant pentru scope wall. Critic pentru
phase 2+ când se implementează închiderea comenzii: UI-ul trebuie să știe că validarea
singură NU închide în toate cazurile, și să navigheze la facturare sau notă contabilă de
închidere în funcție de tip.inch_validare.
7. Pachetul principal pack_auto — map procedure → tabel
Map complet (din docs/service-auto/pack_auto.pck):
7.1. Create comandă
| Procedură | Operație |
|---|---|
dev_adauga_lucrare (15 params, overload scurt) |
Wrapper peste versiunea lungă. Apelează versiunea cu 17 params cu defaults pe pnOreFct, pcObservatii, pcDefectiuni. |
dev_adauga_lucrare (17 params, overload lung) |
Flux real: (1) INSERT NOM_LUCRARI(nrord, id_mod=1200); (2) agregă solicitari_client din DEV_NOM_NORME.DENOP pentru id-urile din CSV; (3) INSERT DEV_ORDL cu toate câmpurile; (4) UPDATE DEV_MASINICLIENTI SET kmint, ore_functionare. Verifică mai întâi că NRORD nu e duplicat pe NOM_LUCRARI (aruncă ORA-20000). |
Dependențe runtime ale versiunii lungi:
pack_sesiune.dev_idLucrare— populat deTRG_NOM_LUCRARI_BEFOINS, citit intern la step 3pack_contafin.getCotaTVAStandard(luna, an)— pentruproc_tvav(citit dinCALENDAR/ config lunar)STRINGAGG(DENOP)agregat pesteDEV_NOM_NORME.ID_NORME IN (...)unde...provine din parsarea CSV- (Oracle 19c+ are
STRINGAGGca user-defined aggregate; verifică dacă există în MARIUSM_AUTO)
7.2. Normare operații
| Procedură | Operație |
|---|---|
dev_adauga_operatie(v_gcs, id_sectie, id_ordl, pret, id_util, timpn, id_norme, csv_id_mecanic, an?, luna?) |
(1) Citește DEV_ORDL.VALIDAT → dacă = 1, aruncă ORA-20000 Comanda validata nu se mai poate modifica. (2) INSERT DEV_OPER cu validat=0, nou=1. (3) Sparge csv_id_mecanic pe ; → insert multiplu în DEV_OPER_MECANICI cu ore = timpn / count(mecanici). |
dev_actualizeaza_operatie(v_gcs, camp, valoare_noua, id_oper, luna, an) |
Verifică VALIDAT=0. Actualizează PRET sau TIMPN. Suportă tranziția RON/ROL: dacă DATAI < get_lunaron() și luna-țintă ≥ get_lunaron() atunci valoare_noua * 10000. |
dev_valideaza_operatii(v_gcs, id_ordl, id_util) |
Verifică mai întâi DEV_ORDL.VALIDAT = 0. Setează VALIDAT=1, ID_UTIL, DATAORA=SYSDATE pe toate liniile din DEV_OPER WHERE id_ordl = X AND sters=0 AND validat=0. |
valideaza_operatie(schema, validat, id_oper, id_util) |
Setează manual VALIDAT pe o singură operație. |
sterge_operatie(schema, id_oper, id_util) |
Soft delete: sters=1, dataoras=SYSDATE. |
modifica_sectie(schema, id_sectie, id_oper, id_util) |
UPDATE secție pe operație. |
dev_distribuie_timp_n(v_luna, v_an) |
MERGE peste DEV_OPER_MECANICI: pentru operațiile unde sum(ore_mecanici) <> timpn, redistribuie uniform. Folosit ca housekeeping periodic. |
View-ul UI pentru normare: AUTO_NORMARE_COMENZI — filtrat pe
inchis_fortat = 0 AND validat = 0 (din AUTO_COMENZI_VALIDATE).
7.3. Validare comandă
| Procedură | Operație |
|---|---|
dev_valideaza_comanda(v_gcs, id_ordl, id_util, an?, luna?) |
(1) Verifică DEV_OPER WHERE id_ordl = X AND sters=0 AND validat=0 → dacă există, aruncă ORA-20000 Mai sunt operatii nevalidate. (2) Calculează ldData = SYSDATE sau ultima zi a lunii vechi. (3) Verifică CALENDAR că luna e deschisă. (4) UPDATE DEV_ORDL SET VALIDAT=1, ID_UTIL_VALID, DATAORAVALID=ldData, PROC_TVAV = pack_contafin.getCotaTVAStandard(luna, an). |
dev_invalideaza_comanda(v_gcs, id_ordl, id_utils) |
Reverse: VALIDAT=0, DATAORAVALID=NULL, recalculează PROC_TVAV din luna/an curentă a comenzii. |
dev_arhiveaza_comanda(id_ordl, id_util) |
Alternativă la validare — pentru tipuri cu inch_validare=0. Verifică CALENDAR luna deschisă, setează INCHIS_FORTAT=1, ID_UTIL_INCHIS, DATAORAINCHIS = SYSDATE. |
dev_dezarhiveaza_comanda(id_ordl) |
Reverse: INCHIS_FORTAT=0. |
dev_sterge_comanda(schema, id_util, id_ordl, id_lucrare) |
Verifică că RUL WHERE id_lucrare = X AND sters=0 e gol la sum(cante*pretv). Verifică DEV_OPER WHERE id_ordl = X AND sters=0 = 0. Setează sters=1 pe DEV_ORDL și inactiv=1 pe NOM_LUCRARI. |
View-ul UI: AUTO_VALIDARE_COMENZI — JOIN peste AUTO_COMENZI_VALIDATE +
AUTO_VORDL_MAN (manoperă agregată) + AUTO_VORDL_MAT (materiale agregate) +
AUTO_VORDL_FACTURI (info factură emisă).
Flux de validare condiționat: tipul comenzii (dev_tip_deviz.inch_validare) decide care
dintre dev_valideaza_comanda (dacă inch_validare=1) sau dev_arhiveaza_comanda
(dacă inch_validare=0) se apelează la închiderea comenzii. View-ul AUTO_COMENZI_VALIDATE
are chiar o logică "time-aware": consideră o comandă validată doar dacă dataoravalid
e ≤ luna curentă din pack_sesiune.getluna() + pack_sesiune.getan() * 12. Validările
în viitor apar ca validat=0 în view, ceea ce e intenționat pentru izolare contabilă
pe lună.
7.4. Facturare
| Procedură | Operație |
|---|---|
dev_adauga_oper_fact(schema, id_ordl, id_sectie, id_norme, total_f_tva, timpn, ore, id_util, id_mecanic) |
Folosit pentru tipuri speciale ITP/SPALARE/DIVERSE unde se adaugă o operație "sintetică" direct la facturare. Setează DEV_ORDL.VALIDAT=1 + INSERT în DEV_OPER + DEV_OPER_MECANICI. V_PRET = total_f_tva / timpn (calcul reverse pentru a păstra total exact). |
actualizeaza_deviz(proc_tvav, csv_id_ordl, id_set) |
Apelat la final de facturare. (1) Ia ultimul ID_FACT din ACT WHERE cod = current_cod AND scd NOT LIKE '5%'. (2) UPDATE DEV_ORDL SET PROC_TVAV pentru id-urile din CSV. (3) UPDATE RUL SET ID_FACT = v_id_fact WHERE id_set <> 229 AND id_lucrare IN (...) (index hint IDX_RUL_001). (4) Pentru id_set în (31003-31011), UPDATE și NOM_LUCRARI SET ID_FACT. |
citeste_sume_stornare(csv_id_lucrare, delim, cursor OUT) |
Citește sume storno avans pentru listele CSV de lucrări. |
citeste_date_avans(csv_id_lucrare, delim, cursor OUT) |
Citește avansurile pentru facturare. |
citeste_discount_contract / salveaza_discount_contract |
Citește / salvează discount-uri contract per partener + sucursală. |
Flux facturare real (VFP factureaza_comanda → factureaza_deviz →
pack_facturare.*):
1. [pack_auto.dev_adauga_lucrare] — uneori se creează o comandă ad-hoc pentru facturi
ITP/SPALARE/DIVERSE (altfel se pleacă de la o comandă existentă)
2. User completează date factură (client, valoare, TVA, incasare) în VFP form
3. [lans(lnIdSet, ...)] — VFP generează note contabile pentru factură în cursor actactan
4. [verificare_note_contabile()] — validare locală VFP
5. [pack_auto.dev_adauga_oper_fact] — pentru tipuri ITP/SPALARE/DIVERSE, adaugă operația sintetică
6. [factureaza_deviz]:
a. [pack_facturare.initializeaza_date_factura(...)] → INSERT în VANZARI header (20+ param)
b. pentru fiecare articol în crsvanztemp:
[pack_facturare.adauga_articol_factura_deviz(...)] → INSERT în VANZARI_DETALII
c. [oscrie_in_fisiere(...)] — scrie cursor actactan în ACT (registrul jurnal)
d. [pack_facturare.scrie_in_vanzari(...)] → finalizare VANZARI (incasare, discount, delegat)
apelează în aceeași tranzacție:
[pack_auto.actualizeaza_deviz(proc_tvav, csv_id_ordl, id_set)]
→ UPDATE DEV_ORDL.PROC_TVAV + RUL.ID_FACT + NOM_LUCRARI.ID_FACT (pentru id_set specifice)
e. MERGE INTO vanzari SET id_fact FROM act WHERE cod=v.cod AND scd='4111'
7. COMMIT sau ROLLBACK
Tabele atinse la facturare: VANZARI, VANZARI_DETALII, ACT, DEV_ORDL.PROC_TVAV,
RUL.ID_FACT (pentru materiale consumate), NOM_LUCRARI.ID_FACT, ACT.ID_FACT
(prin pack_facturare). IN SCOPE abia pentru phase 3-4, după ce prototype-ul probează
crearea unei comenzi simple.
7.5. Alte operații
modifica_date_comanda(id_ordl, id_tip, kmint, ore_functionare, id_util)— edit rapidmodifica_tip_comanda(schema, id_tip, id_ordl, id_util)— schimbă tipmodifica_client_comanda(schema, id_ordl, id_masiniclient, id_util)— schimbă mașina
8. Bonuri consum = flow generic ROA, în RUL.id_lucrare
pack_auto nu are nicio procedură pentru bonuri consum. Materialele consumate pe
comandă sunt 100% în tabela generică RUL (rulaje ROA), tag-uite prin
RUL.ID_LUCRARE = X. Flux-ul:
- VFP
ointroduceri.prgcutip=3(BON CONSUM) deschide un form de introducere articole din stoc → user selectează linii + alege comanda (id_lucrare) → salvare. - Generic ROA warehouse SP generează rânduri în
RULcu:ID_LUCRARE = X(tag-ul comenzii)SCD = '3xx'(contul de stoc),SCC = '6xx'sau'332'(contul de destinație)CANTE,PRETV(cantitate + preț unitar)ID_SETcare tipizează operațiunea de stoc
- La afișarea devizului (view-urile
AUTO_VORDL_MAT,AUTO_VALIDARE_COMENZI), materialele se citesc ca agregat dinMV_ORDL_MAT(materialized view pesteRUL) peid_lucrare. - La facturare,
factureaza_devizcitește suma materialelor din cursoareleactactanvanzari(generate delans(lnIdSet...)local în VFP), apoipack_auto.actualizeaza_devizfaceUPDATE RUL SET ID_FACT = :v_id_fact WHERE ID_LUCRARE IN (...) AND ID_SET <> 229— marchează materialele ca facturate.
Impact asupra DEV_OPER: zero. Pentru service auto, DEV_OPER conține doar manoperă;
materialele nu intră în DEV_OPER deloc.
Implicație pentru prototype: Bonul de consum este out of scope. Flux-ul atinge
pachete generice ROA (neauditate) + tabela RUL (nu e în scheme ROAAUTO dedicate). Dacă
phase 2 cere "service auto complet", bonul de consum va fi un sub-modul separat cu propriul
audit asupra pachetului generic ROA pack_intrari_iesiri (sau similar).
Observație specială pentru tipurile nefacturabile (inch_validare = 1 în live MARIUSM_AUTO):
REGIE/PRODUCTIE/CONSTATARE se închid prin simpla validare — zero notă contabilă.
Bonurile de consum materiale rămân în RUL cu ID_FACT = NULL permanent (fără a fi legate
de vreo factură), dar comanda e considerată "închisă" în agregatele de raportare. Impactul
contabil al materialelor consumate pe aceste comenzi se face prin flux-ul generic ROA de
rulaje (stocul e deja scăzut prin scd='3xx', scc='6xx' la momentul bonului de consum).
Dacă Marius ar schimba REGIE la inch_validare = 0 (scenariu teoretic), atunci pentru
a închide o comandă REGIE ar trebui:
- Validare (
VALIDAT = 1) — doar un pas intermediar - O notă contabilă suplimentară
711 = 332(care recunoaște venitul intern aferent materialelor deja consumate) — această notă trebuie să setezefacturat = 1sau un mecanism echivalent ca să apară în agregatele view-ului - Abia atunci view-ul
AUTO_LISTARE_MAN_TOT_COMconsideră comanda "închisă"
Acest scenariu nu e activ în configurarea curentă, dar e permis de schema.
9. View-uri cheie pentru UI service auto
Toate definite în mariusm_ddl_export.sql (secțiunea VIEWS). Cele relevante pentru ecrane:
| View | Rol | JOIN-uri principale |
|---|---|---|
AUTO_COMENZI_VALIDATE |
Base view — "comenzi cu time-aware validat flag" (validat = 1 doar dacă dataoravalid ≤ luna curentă session) |
dev_ordl + syn_utilizatori + nom_lucrari |
AUTO_NORMARE_COMENZI |
Listare comenzi care așteaptă normare operații. Filtru tipic: inchis_fortat=0 AND validat=0 |
auto_comenzi_validate + auto_vordl_facturi + dev_masiniclienti + nom_parteneri + dev_tip_deviz |
AUTO_VALIDARE_COMENZI |
Listare comenzi în curs de validare + manopera/materiale agregate | auto_comenzi_validate + auto_vordl_man + auto_vordl_mat + auto_vordl_facturi + lookup-uri |
AUTO_ORDL_FACTURARE |
Listare comenzi pregătite pentru facturare | dev_ordl + nom_lucrari + dev_masiniclienti + nom_parteneri + dev_nom_masini + dev_nom_marci + dev_nom_asiguratori + dev_nom_inspectori WHERE sters = 0 |
AUTO_VORDL |
Listare completă comandă (toate câmpurile expuse) | ~10 JOIN-uri |
AUTO_VORDL_MAN |
Agregat manoperă pe comandă (sum după pack_sesiune RON/ROL) |
derivat |
AUTO_VORDL_MAT |
Agregat materiale pe comandă — folosește MV_ORDL_MAT (materialized view) cu pack_sesiune currency logic |
MV_ORDL_MAT grupat pe id_lucrare |
AUTO_VORDL_FACTURI |
Facturile emise per id_lucrare |
derivat |
AUTO_VESTIMARI_REP |
Linii estimare pentru un deviz pre-sale | dev_estimari_rep + dev_nom_norme + nom_articole + syn_utilizatori |
AUTO_VOPER |
Liniile de operație cu lookup norme + ansamblu + mașină + secție + mecanic | dev_oper + dev_nom_norme + dev_nom_ansamble + dev_nom_masini + nom_sectii + syn_utilizatori |
AUTO_VOPER_DETALII_M |
Detalii mecanici per operație | dev_oper_mecanici + dev_mecanici + nom_parteneri |
AUTO_VMASINICLIENTI |
Lista mașini + clienți pentru dropdown-uri | dev_masiniclienti + dev_nom_masini + dev_nom_marci + nom_parteneri |
AUTO_VNORME |
Catalog norme manoperă pentru picker | dev_nom_norme + dev_nom_masini + dev_nom_ansamble |
Notă pack_sesiune currency logic: multe view-uri (AUTO_VOPER, AUTO_VORDL_MAT)
conțin CASE WHEN pack_sesiune.getAn()*12 + getLuna() >= GET_ANRON()*12 + GET_LUNARON() THEN ron ELSE rol END.
Acesta e un heritage-currency switch (RON denominat 2005 vs vechiul ROL) — după 2005 toate
înregistrările noi sunt RON, deci în practică întotdeauna se ia branch-ul RON. Pentru
prototype modern, acest CASE e un artefact istoric care nu trebuie replicat — noi inserăm
direct RON fără switch.
10. Flux end-to-end real (VFP → DB)
10.1. Creare comandă
[VFP: frm_gencom] Submit
↓
VFP SQL: begin pack_auto.dev_adauga_lucrare(
gcS, gnAn, gnLuna, gnIdUtil,
pcNr, -- 'G12345' / 'R...'
pnIdInsp,
pnIdAsig, pcNrDosar,
pnIdMC, pnKmInt, pnOreFct,
to_date(pdTermen, 'DD/MM/YYYY'),
pntipcom,
pcSirIDOperatiiClient,
pcObservatii, pcDefectiuni,
pnIdPartRef,
?@pnIdOrdl); end;
↓
PACK_AUTO.DEV_ADAUGA_LUCRARE (overload 17 params):
1. SELECT COUNT(*) FROM NOM_LUCRARI WHERE sters=0 AND nrord=pcNr
→ IF > 0 THEN RAISE ORA-20000 'Mai exista o lucrare...'
2. INSERT INTO NOM_LUCRARI (nrord, id_mod) VALUES (pcNr, 1200)
→ TRG_NOM_LUCRARI_BEFOINS populează :new.id_lucrare din SEQ_NOM_LUCRARI
+ pack_sesiune.dev_idLucrare := :new.id_lucrare
3. IF pcSirIdOperatii IS NOT NULL THEN
SELECT STRINGAGG(DENOP) INTO v_solicitari_client FROM DEV_NOM_NORME
WHERE id_norme IN (<parsed CSV>)
4. INSERT INTO DEV_ORDL (an, luna, id_inspector, id_lucrare, datai,
id_util_ad, id_masiniclient, id_asigurator, id_tip, kmint,
ore_functionare, termen, nr_dosar, dataoraad, solicitari_client,
observatii, defectiuni, proc_tvav, id_part_ref)
VALUES (tnAn, tnLuna, pnIdInsp,
pack_sesiune.dev_idLucrare, -- <-- citit din session state populat la pasul 2
SYSDATE, tnIdUtil, pnIdMC, pnIdAsig, pnTipCom, pnKmInt,
pnOreFct, pdTermen, pcNrDosar, SYSDATE, v_solicitari_client,
pcObservatii, pcDefectiuni,
pack_contafin.getCotaTVAStandard(tnLuna, tnAn),
decode(pnIdPartRef, 0, NULL, pnIdPartRef))
RETURNING id_ordl INTO pnIdOrdl
→ TRG_DEV_ORDL_BEFOINS populează :new.id_ordl din SEQ_DEV_ORDL
+ pack_sesiune.dev_idOrdl := :new.id_ordl
5. UPDATE DEV_MASINICLIENTI SET kmint, ore_functionare WHERE id_masiniclient=pnIdMC
Nu touch-uiește ACT, nici RUL, nici VANZARI. Facturare e un flux separat.
10.2. Normare operații (adaugă manoperă pe o comandă existentă)
[VFP: normare_comanda()] deschide FRM_NOM_COM cu cursor AUTO_NORMARE_COMENZI
↓
User selectează o comandă + alege norme din AUTO_VNORME + alocă mecanici
↓
VFP SQL: begin pack_auto.dev_adauga_operatie(
gcS, pnid_sectie, pnIdOrdl, pnpret, gnIdUtil,
pntimpn, pnid_norme, pcsir_idmecanic); end;
↓
PACK_AUTO.DEV_ADAUGA_OPERATIE:
1. SELECT VALIDAT FROM DEV_ORDL WHERE id_ordl = X
→ IF validat=1 THEN RAISE ORA-20000 'Comanda validata nu mai poate fi modificata'
2. INSERT INTO DEV_OPER (id_ordl, id_sectie, timpn, pret, id_norme,
id_utili, nou, datai, dataora)
VALUES (..., 1, SYSDATE, SYSDATE)
RETURNING id_oper INTO v_id_oper
→ TRG_DEV_OPER_BEFOINS populează :new.id_oper din SEQ_dev_oper
3. PARSE csv_id_mecanic pe ';' → FOR i IN 1..count LOOP
INSERT INTO DEV_OPER_MECANICI (id_oper, id_mecanic, ore)
VALUES (v_id_oper, id_mec_i, timpn / count)
10.3. Validare operații (marchează fiecare operație ca "gata")
[VFP user click "Valideaza operatii"] pe o comandă
↓
VFP SQL: begin pack_auto.dev_valideaza_operatii(gcS, pnIdOrdl, gnIdUtil); end;
↓
PACK_AUTO.DEV_VALIDEAZA_OPERATII:
1. SELECT VALIDAT FROM DEV_ORDL WHERE id_ordl = X
→ IF validat=1 THEN RAISE ORA-20000 'Comanda validata...'
2. UPDATE DEV_OPER SET validat=1, id_util, dataora=SYSDATE
WHERE id_ordl = X AND sters=0 AND validat=0
Alternativ, linie cu linie:
begin pack_auto.dev_valideaza_operatie(gcS, pn_id_oper, gnIdUtil); end;
→ UPDATE DEV_OPER SET VALIDAT=1 WHERE id_oper=X
10.4. Validare comandă (finalizează comanda după ce toate operațiile sunt validate)
[VFP user click "Valideaza comanda"]
↓
VFP SQL: begin pack_auto.dev_valideaza_comanda(gcS, pnIdOrdl, gnIdUtil, an?, luna?); end;
↓
PACK_AUTO.DEV_VALIDEAZA_COMANDA:
1. SELECT COUNT(*) FROM DEV_OPER WHERE id_ordl = X AND sters=0 AND validat=0
→ IF > 0 THEN RAISE ORA-20000 'Mai sunt operatii nevalidate'
2. Calculează ldData: SYSDATE dacă luna curentă = luna_comandă, else LAST_DAY
3. SELECT COUNT(*) FROM CALENDAR WHERE an=.. AND luna=..
→ IF 0 THEN RAISE ORA-20000 'Nu puteti valida deoarece nu este deschisa luna'
4. UPDATE DEV_ORDL SET VALIDAT=1, ID_UTIL_VALID, DATAORAVALID=ldData,
PROC_TVAV = pack_contafin.getCotaTVAStandard(luna, an)
WHERE id_ordl = X
10.5. Închidere forțată (arhivare — pentru tipuri cu inch_validare=0)
[VFP user click "Inchide comanda" pe tip POST_GARANTIE/etc.]
↓
VFP SQL: begin pack_auto.dev_arhiveaza_comanda(pnIdOrdl, gnIdUtil); end;
↓
PACK_AUTO.DEV_ARHIVEAZA_COMANDA:
1. Verifică CALENDAR luna curentă deschisă
2. UPDATE DEV_ORDL SET INCHIS_FORTAT=1, ID_UTIL_INCHIS, DATAORAINCHIS=SYSDATE
10.6. Facturare
Vezi secțiunea 7.4 de mai sus. IN SCOPE abia pentru phase 3-4.
10.7. Bonuri consum
Vezi secțiunea 8. Out of scope — e flux generic ROA.
11. Labelurile UI (Romanian)
| Câmp DB | Label UI (din VFP ground truth) |
|---|---|
id_tip |
Tip comandă |
nrinmat (via masiniclienti) |
Număr înmatriculare / Mașină |
id_part (via masiniclienti.id_partener) |
Client |
solicitari_client (derivat din norme) |
Operații solicitate |
kmint |
Km la bord |
ore_functionare |
Ore funcționare (pt utilitare) |
termen |
Termen execuție |
observatii |
Observații |
defectiuni |
Defecțiuni |
nr_dosar |
Nr. dosar (doar pentru tip=garanție) |
id_inspector |
Inspector |
id_asigurator |
Asigurator |
id_part_ref |
Partener referent |
id_agent |
Agent vânzări |
Toast-uri (convenție ROA2WEB din ReceiptCreateUnifiedView.vue):
- Success:
summary="Comandă creată",detail="Nr ${nr_comanda}" - Business error:
summary="Validare",detail=<mesaj SP după strip prefix ORA-20xxx> - Infra:
summary="Eroare conexiune"(503) /"Eroare internă"(500)
12. Implicații pentru prototype-ul roa2web
12.1. Scope wall reconfirmat
Prototype-ul scrie 1 SP minimal pentru 1 acțiune = creare comandă. Tot restul (normare, validare operații/comandă, arhivare, facturare, bonuri consum, estimare) e out of scope.
12.2. Opțiunea 3 (SP nou minimal) — actualizată
Față de v2, acum știm exact ce face pack_auto.dev_adauga_lucrare versiunea lungă.
Versiunea minimală a SP-ului nostru va:
CREATE OR REPLACE PROCEDURE MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP(
p_id_tip IN NUMBER, -- FK dev_tip_deviz.id_tip
p_id_masiniclient IN NUMBER, -- FK dev_masiniclienti.id_masiniclient
p_kmint IN NUMBER,
p_termen IN DATE,
p_id_util IN NUMBER,
p_nr_comanda IN VARCHAR2, -- generat în Python cu prefix (G/R/P/PR/C)
p_id_ordl OUT NUMBER,
p_numar_out OUT VARCHAR2
) AS
v_id_lucrare NUMBER;
v_nr_existent NUMBER;
v_now DATE := SYSDATE;
BEGIN
-- 1. Duplicate-check (paritate cu pack_auto)
SELECT COUNT(*) INTO v_nr_existent
FROM MARIUSM_AUTO.NOM_LUCRARI
WHERE sters = 0 AND nrord = p_nr_comanda;
IF v_nr_existent > 0 THEN
RAISE_APPLICATION_ERROR(-20001,
'Mai exista o comanda cu numarul ' || p_nr_comanda);
END IF;
-- 2. Parent INSERT (trigger-ul alocă id_lucrare + populează pack_sesiune.dev_idLucrare)
INSERT INTO MARIUSM_AUTO.NOM_LUCRARI (nrord, id_mod)
VALUES (p_nr_comanda, 1200)
RETURNING id_lucrare INTO v_id_lucrare;
-- 3. Child INSERT minimal — doar coloane obligatorii + clientul (prin masiniclient)
INSERT INTO MARIUSM_AUTO.DEV_ORDL (
an, luna,
id_lucrare,
datai, dataoraad,
id_util_ad,
id_masiniclient,
id_tip,
kmint,
termen
) VALUES (
EXTRACT(YEAR FROM v_now), EXTRACT(MONTH FROM v_now),
v_id_lucrare,
v_now, v_now,
p_id_util,
p_id_masiniclient,
p_id_tip,
p_kmint,
p_termen
) RETURNING id_ordl INTO p_id_ordl;
p_numar_out := p_nr_comanda;
END;
/
~30 linii PL/SQL, două INSERT-uri, zero dependency pe pack_contafin / STRINGAGG / pack_sesiune — minim absolut ca să probeze ipoteza #1 (Python + oracledb + OUT params + PL/SQL procedure call pe un INSERT dual cu RETURNING).
Trigger-ele rulează oricum — pack_sesiune.dev_idLucrare și dev_idOrdl vor fi populate, dar nu le citim. E trivial de demonstrat că e safe: pattern-ul Oracle RETURNING INTO e standard.
Coloane SĂRITE pe care SP-ul real le are:
id_inspector,id_asigurator— folosite doar pentru service cu asiguratornr_dosar,pcNrDosar— dosar daunăore_functionare,pnOreFct— pentru utilitaresolicitari_client(agregat din STRINGAGG) — derivat din CSV, dispensabil pentru prototypeobservatii,defectiuni— free text opționalid_part_ref— referentproc_tvav(viapack_contafin.getCotaTVAStandard) — dacă e NOT NULL vor primi default implicit (NULL); dacă schema real e NOT NULL, adăugăm valoarea 19 hardcodat
De verificat în săpt 3: rulează DESC MARIUSM_AUTO.DEV_ORDL sau din mariusm_ddl_export.sql
linia 565 — PROC_TVAV e NUMBER(10,4) nullable, deci OK.
12.3. GRANTS pentru ROA_WEB user
CREATE USER ROA_WEB IDENTIFIED BY "...";
GRANT CONNECT, CREATE SESSION TO ROA_WEB;
GRANT EXECUTE ON MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP TO ROA_WEB;
-- Pentru read-only selectors (ipoteza #3 = grants model funcționează)
GRANT SELECT ON MARIUSM_AUTO.AUTO_VMASINICLIENTI TO ROA_WEB;
GRANT SELECT ON MARIUSM_AUTO.DEV_TIP_DEVIZ TO ROA_WEB;
12.4. Test negativ pentru ipoteza #3
-- Connected as ROA_WEB:
INSERT INTO MARIUSM_AUTO.DEV_ORDL ... ; -- așteptat: ORA-00942
SELECT * FROM MARIUSM_AUTO.DEV_ORDL WHERE ROWNUM < 2; -- așteptat: ORA-00942
EXEC MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP(...); -- așteptat: succes + row inserted
13. Gap-uri rămase (de acoperit după sapt 3)
PACK_SESIUNE.pckcitit — de confirmat cădev_idLucrare,dev_idOrdl,getAn,getLuna,GET_ANRON,GET_LUNARON,get_cod,get_id_utilsunt toate exported și nu ascund ceva surprinzător (nu am citit încă body-ul, doar referințe).PACK_CONTAFIN.pckcitit — de confirmatgetCotaTVAStandard(luna, an)șiget_idFact().PACK_FACTURARE.pckcitit — necesar doar când intrăm în flux-ul de facturare (phase 3-4).DEV_TIP_DEVIZ.inch_validareper rând — rulează query-ul de verificare:SELECT id_tip, denumire, sters, inch_validare FROM MARIUSM_AUTO.DEV_TIP_DEVIZ ORDER BY id_tip;MV_ORDL_MATmaterialized view — de verificat refresh schedule; dacă refresh e "on commit" atunci UPDATE-urile pe RUL sunt imediate în AUTO_VORDL_MAT; dacă e "on demand" cu DBMS_JOB atunci e latency în UI.pack_audit.verifica_val— folosit de toate trigger-ele_BEFOUPD. E dependency ascuns pentru orice UPDATE peNOM_LUCRARI,DEV_ORDL,DEV_OPER, etc. Nu e folosit la INSERT, deci prototype-ul (care doar inserează) nu-l atinge.
14. Referințe
- Ground truth DDL:
docs/service-auto/mariusm_ddl_export.sql(5127 linii) - Pachete production:
pack_auto.pck,PACK_FACTURARE.pck,PACK_SESIUNE.pck,PACK_CONTAFIN.pck,PACK_COMENZI.pck(toate îndocs/service-auto/) - VFP consumer code:
gitea.romfast.ro/romfast/vfp_roaauto/Programe/oproceduri_devize.prg(generare_com,normare_comanda,factureaza_comanda,factureaza_deviz) - Manual utilizator:
docs/service-auto/manual_ROAAUTO.pdf - Plan master:
docs/service-auto/claude-main-design-20260411-rethink.md