sync SVN r18197

ROAAUTO 2.5.6: Vizualizare comenzi unificata cu Istoric comenzi (filtre si coloane noi), coloane manopera/materiale si total fara/cu TVA in vizualizare comenzi si facturi; versiune_db 2026_09_23_01.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cfkx1QfeDv987o8x1rAtrr
This commit is contained in:
2026-09-23 22:13:59 +03:00
parent c047ff339a
commit 395e51e5bb
12 changed files with 1528 additions and 155 deletions

View File

@@ -3,23 +3,62 @@
Cercetare + plan. Data: 22.09.2026. Dovezile de plan/IO sunt luate pe schema `MARIUSM_AUTO` de pe
`ROA_CENTRAL`.
## 0. Stare — predare către o sesiune nouă
## 0. Stare — 22.09.2026, implementat integral (pașii 1-4 + 6), în așteptare de review
**Acesta este fișierul de implementat.** Planul e la §5, aprobat de Marius pe 22.09.2026.
- **Nimic implementat.** Zero fișiere de cod atinse, zero scripturi rulate pe Oracle, zero commit-uri.
`git status` are doar fișiere noi în `docs/`.
- **Nimic într-o stare periculoasă**: fără editări de binar fără write-back, fără tranzacții deschise,
fără procese rămase vii, fără date de test consumate.
- **Primul pas într-o sesiune nouă**: `git_sync.ps1` (obligatoriu la început de sesiune), apoi §5 pas 1.
- **Decizii deja luate, nu le relua**: §4 varianta 1 (ecranul de comenzi trece pe
`AUTO_ISTORIC_COMENZI`, nu se modifică `AUTO_NORMARE_COMENZI`); manopera se livrează în ambele
forme (deviz + facturat); costul se ia din `RUL.PRET`, nu din `VANZARI_DETALII.PRET_ACHIZITIE`.
- **Interzis**: să atingi `AUTO_NORMARE_COMENZI` (§4); să inserezi coloane noi la mijlocul gridurilor
(§6.1); să rulezi scriptul de bază fără cererea explicită a lui Marius (§5 pas 1); să dai commit
fără ca Marius să vadă întâi diff-ul complet.
- **Rămâne de aflat de la client** (§7.1-7.3): rânduri + timp actual pe luna curentă la baza cea mai
mare, dimensiunile `RUL`/`ACT`/`DEV_OPER`, existența `IDX_RUL_001`. Nu blochează pașii 1-3.
- **Pas 1 — baza de date: SCRIS ȘI RULAT pe `MARIUSM_AUTO` de pe `ROA_CENTRAL`** (aprobat de Marius).
`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_22_01_AUTO.sql`, cu antet de comentarii care
explică ce s-a modificat față de versiunile anterioare ale celor două view-uri.
ASCII, CRLF, se încheie cu `UpdateVersiune` + `commit`.
Dovadă: „View created" ×2, `VERSIUNE` conține `ff_2026_09_22_01_AUTO.sql`, toate cele 5 coloane noi
există în `USER_TAB_COLUMNS`, zero obiecte `AUTO_*` invalide.
**Nepublicat încă** la clienți (`publicare_scripturi.ps1` nu a fost rulat).
- **Pas 2 — cursoarele VFP: FĂCUT.** `Programe/oproceduri_vizualizare.prg` — `vizualizare_comenzi`
trecut pe `auto_istoric_comenzi` (+6 coloane), `vizualizare_facturi` +4 coloane.
- **Pas 3 — gridurile: FĂCUT, cu write-back pe binar.** `Clase/oviz_devize.vc2` — `frm_viz_comenzi`
`ColumnCount` 13→19, `frm_viz_facturi` `ColumnCount` 12→16, coloane noi **la coadă**.
- **Pas 4 — totalurile de sub gridul de facturi: FĂCUT.** 4 containere `clb_tx_simplu` noi
(`Clb_ore_manopera`, `Clb_val_manopera`, `Clb_val_mat_ach`, `Clb_val_mat_vz`) pe două rânduri sub
cele existente, `frm_viz_facturi.Height` 497→560, iar `refreshdata` însumează cele 4 coloane cu
`Nvl(...,0)` și garda `nrcrt=1`.
- **Pas 5 (raportul `rap_facturi_clienti`) — NEFĂCUT**, opțional: `.frx` se editează doar în IDE-ul VFP.
- **Pas 6 — testat pe bază: 7 PASS / 1 FAIL.** Raport: `docs/review/teste_coloane_manopera_piese_viz.md`.
Rularea efectivă a ecranelor în VFP rămâne de făcut (necesită IDE).
- **Necomis.** Diff-ul complet: `docs/review/diff_coloane_manopera_piese_viz.patch`.
### Ce au arătat testele (rezumat)
- **Riscul principal e eliminat**: mutarea sursei ecranului de comenzi **nu schimbă setul de
comenzi afișate** — `AUTO_NORMARE_COMENZI` și `AUTO_ISTORIC_COMENZI` întorc exact aceleași 375 de
`ID_LUCRARE` (0 diferențe în ambele sensuri), iar cu filtrul `gcCondLuna` aplicat, exact aceleași
179 de rânduri. `INCH_VALIDARE` coincide cu `DEV_TIP_DEVIZ` și cu `AUTO_NORMARE_COMENZI`, 0 NULL.
- Cele 4 coloane noi din `AUTO_FACTURI_EMISE` sunt **identice** cu omoloagele din
`AUTO_ISTORIC_COMENZI` pe toate cele 131 de `ID_LUCRARE` comune.
- Garda `id_lucrare > 0` este necesară și funcționează: `RUL` are 6 597 de rânduri cu
`ID_LUCRARE = 0`, iar view-urile nu întorc niciunul.
- **NULL-urile sunt frecvente** (§6.6 de mai jos) — orice sumă/afișare are nevoie de `Nvl`.
- **§3.2 se confirmă pe producție, se infirmă pe dev.** Pe schema de test (`RUL` = 10 374 rânduri)
optimizatorul dez-corelează subinterogările și face `TABLE ACCESS FULL` pe `RUL` — de aici „T8
FAIL". **Pe producția clientului AUTOMOTIVE (`RUL` = 571 508 rânduri) planul folosește
`INDEX RANGE SCAN IDX_RUL_001`**, corelat, exact cum prezicea §3.2; la fel manopera, pe
`IDX_ORDL_00001` + `IDX_OPER_01`. Deci T8 era un artefact al volumului mic.
- ~~Dar apare o problemă mai mare: ecranul întoarce 32 790 de rânduri, +28 % timp~~ — **RETRAS
23.09.2026**, măsurătoare invalidă (lipsea `pack_sesiune.setluna/setan`). Real: **164 de
rânduri, ~3.3 s, +0.4 s de la coloanele noi**. Vezi §7 și `docs/vfp_oracle_pack_sesiune.md`.
- Cost I/O pe schema de test: 642 → 1 207 `consistent gets` (**1.88×**) pentru aceleași 179 de rânduri.
### Ce e de reținut pentru sesiunile următoare
- **Capcană FoxBin2Prg**: blocurile `ADD OBJECT '<grid>.<coloana>.<control>'` trebuie scrise în
**ordine alfabetică** (case-insensitive) în `.vc2`; altfel `txt2vcx.ps1` cade la fidelity-check.
Ordinea canonică se citește din `<staging>\verify\*.vc2` — fișierul acela e chiar editarea ta
rescrisă canonic, deci se poate adopta ca sursă.
- **Decizii deja luate, nu le relua**: §4 varianta 1; manopera în ambele forme (deviz + facturat);
costul din `RUL.PRET`, nu din `VANZARI_DETALII.PRET_ACHIZITIE`.
- **Interzis**: să atingi `AUTO_NORMARE_COMENZI` (§4); coloane noi la mijlocul gridurilor (§6.1);
să publici scriptul la clienți fără cererea explicită a lui Marius; commit fără ca Marius să vadă
diff-ul.
- Conectare la Oracle de dev: vezi `COMUN\docs\conventie_mediu_oracle.md` §4.
- `docs/handoff_comenzi_luna_curenta.md` și `docs/handoff_cost_materiale_manopera.md` sunt predări de
subagenți, integral acoperite de acest document — de ignorat sau de șters.
@@ -343,22 +382,74 @@ din text). La comenzi, `do_listare` (`:15381`) nu atinge gridul — nimic de fă
nefacturate/nevalidate** (`Programe/ovariabile_globale.prg:16`). Asta e sursa reală a comenzilor
„foarte vechi" — dar, cum s-a arătat la 3.2, vechimea nu scumpește subinterogările.
## 7. De verificat înainte de implementare
6. **Planul de execuție măsurat pe `MARIUSM_AUTO` nu spune nimic despre client — și greșește în
ambele sensuri.** Plătită pe 22.09.2026, măsurând aceeași interogare pe dev și pe producția
AUTOMOTIVE:
- pe dev (`RUL` = 10 374 rânduri) optimizatorul **dez-corelează** subinterogările scalare
(unnesting) într-un `GROUP BY` global și face `TABLE ACCESS FULL` pe `RUL` — concluzia ar fi
fost „indexul nu se folosește, e periculos";
- pe producție (`RUL` = 571 508 rânduri) aceeași interogare păstrează subinterogările corelate
și folosește `INDEX RANGE SCAN IDX_RUL_001` — exact invers.
1. **La clientul cu cea mai mare bază**: câte rânduri întoarce azi „Vizualizare comenzi" pe luna
curentă, și cât durează deschiderea acum. Fără numărul ăsta, procentele de la 3.4 nu spun nimic
despre experiența reală.
2. Dimensiunile reale ale `RUL`, `ACT`, `DEV_OPER` la acel client.
3. Există `IDX_RUL_001 (ID_LUCRARE, STERS)` și la client? Aproape sigur da (creat în 2009, folosit
cu hint în `pack_auto` în 2026), dar merită confirmat cu o interogare pe `USER_INDEXES` la
clientul respectiv. Dacă lipsește, ăsta e **singurul** caz în care apare cu adevărat scanarea pe
toată baza de care te temeai — și se rezolvă cu un `CREATE INDEX`, nu cu rescrierea logicii.
4. ~~Poate o lucrare să aibă mai multe `dev_ordl`?~~ **Închis**: Marius a confirmat — o
`NOM_LUCRARI` are exact un `DEV_ORDL`. Deschide varianta 2 ca optimizare ulterioară.
5. ~~„Valoare manoperă" = deviz sau facturat?~~ **Închis**: se livrează amândouă, ca în „Istoric
comenzi" — `VAL_MANOPERA` (din `DEV_OPER`, `timpn*pret`) și `VAL_MANOPERA_FACTURA` (cont 704 din
`ACT`), respectiv `VAL_MATERIALE_VZ` și `VAL_MATERIALE_FACTURA`. La comenzile încă nefacturate
există doar prima; la cele facturate, diferența dintre ele e chiar semnalul util.
Costul subinterogărilor corelate se înmulțește cu numărul de rânduri afișate
(~16 buffer gets/rând), deci și numărul acela trebuie luat de la client.
**Regulă**: orice afirmație despre plan sau cost pentru o interogare cu subinterogări corelate
se verifică pe un client real, nu pe `MARIUSM_AUTO`. Două lucruri trebuie luate de la client,
nu de pe dev: **forma planului** (corelat vs dez-corelat) și **numărul de rânduri returnate**.
7. **`gcCondLuna` nu înseamnă „luna curentă".** Include și comenzile vechi nefacturate
(`inch_validare=0`) sau nevalidate (`inch_validare=1`). La AUTOMOTIVE, luna 10/2025: 107 comenzi
ale lunii + 88 vechi = **195 de rânduri** (164 după filtrul implicit „Active") — deci coada
veche e mică aici, dar numărul trebuie măsurat, nu presupus. **Atenție**: se măsoară doar cu
`pack_sesiune.setluna/setan` inițializate (`docs/vfp_oracle_pack_sesiune.md`); altfel `validat`
iese 0 peste tot și numărul sare la 32 790.
## 7. Verificat pe producție (AUTOMOTIVE, 22-23.09.2026) — închis
Măsurat prin tunel SSH, strict read-only. Detalii și planuri:
`docs/review/teste_coloane_manopera_piese_viz.md`, secțiunea „Teste pe PRODUCTIE".
> **Corectat 23.09.2026.** Măsurătoarea din 22.09 (32 790 rânduri / ~50 s) era **invalidă**:
> rulată din `sqlplus` fără inițializarea lunii de lucru. Vezi
> `docs/vfp_oracle_pack_sesiune.md`. Cifrele de mai jos sunt cele refăcute corect.
1. **Câte rânduri întoarce „Vizualizare comenzi" pe luna curentă și cât durează?**
Cu luna de lucru 10/2025 inițializată (`pack_sesiune.setluna/setan`, exact ce face aplicația la
login): **195 de rânduri** cu filtrul `gcCondLuna` gol, **164** cu filtrul implicit al
formularului (`cbArhivat = "Active"` → `inchis_fortat = 0`, `Clase/oviz_devize.vc2:15630`).
**~3.3 s prin tunel.** Ecranul nu e greu la acest client.
2. **Dimensiunile reale**: `ACT` 833 257, `RUL` 571 508, `DEV_OPER` 137 285, `DEV_ORDL` 38 609.
`RUL` are 215 269 de rânduri cu `ID_LUCRARE = 0` (161 259 cu `STERS = 0`) — garda
`id_lucrare > 0` nu e teoretică, chiar ține la distanță 161 de mii de rânduri.
3. **`IDX_RUL_001` există la client?** **Da**, `NORMAL NONUNIQUE (ID_LUCRARE, STERS)`, și **este
folosit** de planul formei noi. Nu e nevoie de `CREATE INDEX`.
4. ~~Poate o lucrare să aibă mai multe `dev_ordl`?~~ **Închis**: exact unul.
5. ~~„Valoare manoperă" = deviz sau facturat?~~ **Închis**: se livrează amândouă.
### 7.6 Costul măsurat pe producție, pe filtrul real (refăcut 23.09.2026)
Aceeași sesiune, luna de lucru 10/2025 inițializată, filtrul implicit al formularului
(`inchis_fortat = 0`), 164 de rânduri, două rulări fiecare, scăzut overhead-ul de conectare:
| Variantă | timp net |
|---|---|
| fără coloanele noi | 3.3 s |
| cu cele 6 coloane noi | 3.7 s |
| raport | **×1.13 (+0.4 s)** |
Prin tunel SSH; în LAN-ul clientului, mai puțin. Costul scalează cu **numărul de rânduri
afișate** (~16 buffer gets/rând), deci diferența rămâne mică atâta timp cât ecranul întoarce
sute, nu zeci de mii de rânduri.
### 7.7 Ce facem cu asta — decis 23.09.2026
**Nu e nimic de decis.** Problema de performanță (cele 32 790 de rânduri / 50 s) nu există:
era artefactul măsurătorii, nu al datelor. Pe filtrul real ecranul întoarce 164 de rânduri, iar
coloanele noi adaugă ~0.4 s.
Variantele 2 (strângerea filtrului) și 3 (tabelă de totaluri întreținută) **nu se mai justifică**
— nu mai au ce să rezolve. Se merge cu implementarea existentă, la review pe diff.
## 8. Recomandare