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>
883 lines
48 KiB
Markdown
883 lines
48 KiB
Markdown
# 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 auto
|
|
> - `PACK_FACTURARE.pck` — pachet facturare
|
|
> - `PACK_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 auto
|
|
>
|
|
> **Versiuni 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-ul `VCOMENZI` din MARIUSM_AUTO
|
|
> **nu e pentru service auto** (e pentru ROA ERP base, tabela sursă `comenzi` + `nom_masini` +
|
|
> `id_codclient` + field `interna` cu valori `INTERNA/EXTERNA/GESTIUNE/SECTIE`).
|
|
> - Service auto = **`DEV_ORDL` + `NOM_LUCRARI`** (pattern de inheritance), cu view-uri
|
|
> dedicate prefixate `AUTO_*`.
|
|
|
|
---
|
|
|
|
## 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:
|
|
|
|
1. User face "Bon consum" în `ointroduceri.prg` (tip=3) → selectează articole din stoc +
|
|
tag-uiește comandă (id_lucrare) → salvare
|
|
2. Generic ROA warehouse scrie rânduri în `RUL` cu `ID_LUCRARE = X`, `SCD = '3xx'`,
|
|
`SCC = '6xx'` (consum de stoc)
|
|
3. 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)` ENABLE
|
|
- `FK_DEV_ORDL_002` → `NOM_LUCRARI(id_lucrare)` **ENABLE** ← constraint critic
|
|
- `FK_DEV_ORDL_003` → `NOM_PARTENERI(id_part)` ENABLE (client direct)
|
|
- `FK_DEV_ORDL_004` → `NOM_VALUTE(id_valuta)` ENABLE
|
|
- `FK_DEV_ORDL_005` → `NOM_PARTENERI(id_agent)` ENABLE
|
|
- `FK_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)
|
|
|
|
```sql
|
|
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`:**
|
|
```sql
|
|
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`.
|
|
|
|
```sql
|
|
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`:**
|
|
```sql
|
|
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**:
|
|
|
|
1. **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.
|
|
2. **DEV_OPER** — în timpul lucrării, se înregistrează manopera efectiv executată
|
|
(doar operații cu `id_norme`, timp real, preț manoperă).
|
|
3. **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):
|
|
|
|
```sql
|
|
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)
|
|
|
|
```sql
|
|
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ă și `facturat = 1` pe flux-ul
|
|
de agregate.
|
|
- Pentru tipuri **nefacturabile** (teoretic REGIE/PRODUCTIE dacă ar fi configurate așa) →
|
|
se generează o notă contabilă `711 = 332` care recunoaște venitul intern și închide
|
|
stocul "servicii în curs de execuție".
|
|
|
|
**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ă":
|
|
|
|
```sql
|
|
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) **SAU**
|
|
- **`inch_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 de `TRG_NOM_LUCRARI_BEFOINS`, citit intern la step 3
|
|
- `pack_contafin.getCotaTVAStandard(luna, an)` — pentru `proc_tvav` (citit din `CALENDAR` / config lunar)
|
|
- `STRINGAGG(DENOP)` agregat peste `DEV_NOM_NORME.ID_NORME IN (...)` unde `...` provine din parsarea CSV
|
|
- (Oracle 19c+ are `STRINGAGG` ca 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 rapid
|
|
- `modifica_tip_comanda(schema, id_tip, id_ordl, id_util)` — schimbă tip
|
|
- `modifica_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:
|
|
|
|
1. VFP `ointroduceri.prg` cu `tip=3` (BON CONSUM) deschide un form de introducere articole
|
|
din stoc → user selectează linii + alege comanda (id_lucrare) → salvare.
|
|
2. Generic ROA warehouse SP generează rânduri în `RUL` cu:
|
|
- `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_SET` care tipizează operațiunea de stoc
|
|
3. **La afișarea devizului** (view-urile `AUTO_VORDL_MAT`, `AUTO_VALIDARE_COMENZI`),
|
|
materialele se citesc ca agregat din `MV_ORDL_MAT` (materialized view peste `RUL`)
|
|
pe `id_lucrare`.
|
|
4. **La facturare**, `factureaza_deviz` citește suma materialelor din cursoarele `actactan`
|
|
+ `vanzari` (generate de `lans(lnIdSet...)` local în VFP), apoi
|
|
`pack_auto.actualizeaza_deviz` face `UPDATE 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:
|
|
1. Validare (`VALIDAT = 1`) — doar un pas intermediar
|
|
2. O notă contabilă suplimentară `711 = 332` (care recunoaște venitul intern aferent
|
|
materialelor deja consumate) — această notă trebuie să seteze `facturat = 1` sau un
|
|
mecanism echivalent ca să apară în agregatele view-ului
|
|
3. Abia atunci view-ul `AUTO_LISTARE_MAN_TOT_COM` consideră 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:
|
|
|
|
```sql
|
|
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 asigurator
|
|
- `nr_dosar`, `pcNrDosar` — dosar daună
|
|
- `ore_functionare`, `pnOreFct` — pentru utilitare
|
|
- `solicitari_client` (agregat din STRINGAGG) — derivat din CSV, dispensabil pentru prototype
|
|
- `observatii`, `defectiuni` — free text opțional
|
|
- `id_part_ref` — referent
|
|
- `proc_tvav` (via `pack_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
|
|
|
|
```sql
|
|
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
|
|
|
|
```sql
|
|
-- 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.pck` citit — de confirmat că `dev_idLucrare`, `dev_idOrdl`, `getAn`, `getLuna`,
|
|
`GET_ANRON`, `GET_LUNARON`, `get_cod`, `get_id_util` sunt toate exported și nu ascund
|
|
ceva surprinzător (nu am citit încă body-ul, doar referințe).
|
|
- `PACK_CONTAFIN.pck` citit — de confirmat `getCotaTVAStandard(luna, an)` și `get_idFact()`.
|
|
- `PACK_FACTURARE.pck` citit — necesar doar când intrăm în flux-ul de facturare (phase 3-4).
|
|
- `DEV_TIP_DEVIZ.inch_validare` per rând — rulează query-ul de verificare:
|
|
```sql
|
|
SELECT id_tip, denumire, sters, inch_validare FROM MARIUSM_AUTO.DEV_TIP_DEVIZ ORDER BY id_tip;
|
|
```
|
|
- `MV_ORDL_MAT` materialized 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 pe `NOM_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 în `docs/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`
|