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:
@@ -678,11 +678,11 @@ DEFINE CLASS pg_meniu_princ AS pg_meniu OF "..\comun\clase\ofundal.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Page2.Cw4.do_actiune
|
||||
DO vizualizare_comenzi IN oproceduri_vizualizare.prg
|
||||
DO vizualizare_comenzi IN oproceduri_vizualizare.prg WITH .F.
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Page2.Cw5.do_actiune
|
||||
DO vizualizare_ist_comenzi IN oproceduri_vizualizare.prg
|
||||
DO vizualizare_comenzi IN oproceduri_vizualizare.prg WITH .T.
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Page2.Cw6.do_actiune
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -232,7 +232,8 @@ Procedure vizualizare_facturi
|
||||
Private pcselect,pcschema,pcfiltru,pcorder,pofacturi,llAfiseaza
|
||||
Store '' To pofacturi
|
||||
pcschema=['NRCRT n(5),ID_LUCRARE N(20),NRORD C(50),DATAI d,NUME c(50),TELEFON C(50),MANOPERA n(20,4),MATERIALE n(20,4),MANOPERA_DEVIZ n(20,4), MATERIALE_DEVIZ n(20,4),'+]+;
|
||||
['ASIGURATOR c(24),INSPECTOR c(24),NR_DOSAR c(40),NRINMAT c(35),NRACT n(14),DATAACT d,VALCTVA n(19,2), ID_PART_REF N(20), PART_REF C(100)']
|
||||
['ASIGURATOR c(24),INSPECTOR c(24),NR_DOSAR c(40),NRINMAT c(35),NRACT n(14),DATAACT d,VALCTVA n(19,2), ID_PART_REF N(20), PART_REF C(100),'+]+;
|
||||
['ORE_MANOPERA n(20,4),VAL_MANOPERA n(20,4),VAL_MATERIALE_ACH n(20,4),VAL_MATERIALE_VZ n(20,4),VALFTVA n(19,2)']
|
||||
pcorder=[a.dataact,a.nract,a.datai,a.nrord]
|
||||
*!* modificare 27.01
|
||||
*!* pcselect=['select row_number() over (partition by a.nrord order by ] + pcorder + [) as nrcrt,'+]+;
|
||||
@@ -241,7 +242,8 @@ pcorder=[a.dataact,a.nract,a.datai,a.nrord]
|
||||
*!* ['from ] + gcS + [.dev_validare_comenzi a '+]+;
|
||||
*!* ['where 1=2']
|
||||
pcselect=['select a.nrcrt,a.id_lucrare,a.nrord,a.datai,a.nume,a.telefon,a.manopera,a.materiale,a.manopera_deviz, a.materiale_deviz, a.asigurator,a.inspector,'+]+;
|
||||
['a.nr_dosar,a.nrinmat,a.nract,a.dataact,a.valctva, a.id_part_ref, a.part_ref '+]+;
|
||||
['a.nr_dosar,a.nrinmat,a.nract,a.dataact,a.valctva, a.id_part_ref, a.part_ref, '+]+;
|
||||
['a.ore_manopera, a.val_manopera, a.val_materiale_ach, a.val_materiale_vz, a.manopera + a.materiale as valftva '+]+;
|
||||
['from auto_facturi_emise a'+]+;
|
||||
['where 1=2']
|
||||
|
||||
@@ -647,17 +649,22 @@ Release pocomenzi
|
||||
Endproc && validare_comenzi
|
||||
*****************************************************************************************
|
||||
Procedure vizualizare_comenzi
|
||||
Lparameters tlIstoric
|
||||
Private pcselect,pcschema,pcfiltru,pcorder,pocomenzi,llAfiseaza
|
||||
Store '' To pocomenzi
|
||||
If Used('crscomenzi')
|
||||
Use In crscomenzi
|
||||
Endif
|
||||
pcschema=['ID_ORDL n(10),ID_LUCRARE n(10),DATAI d,NUME c(50),NRORD c(50),NRINMAT c(35),VALIDAT n(1),ID_TIP N(5),TIP_COMANDA c(50),DATAORAVALID D,'+] +;
|
||||
['FACTURAT n(1),DATAFACT d,NRFACT N(14),PROC_TVAV N(10,4), ID_PART_REF N(20), PART_REF C(100), SERIES V(100), KMINT I, ORE_FUNCTIONARE I']
|
||||
['FACTURAT n(1),DATAFACT d,NRFACT N(14),PROC_TVAV N(10,4), ID_PART_REF N(20), PART_REF C(100), SERIES V(100), KMINT I, ORE_FUNCTIONARE I,'+] +;
|
||||
['ORE_MANOPERA N(20,4),VAL_MANOPERA N(20,4),VAL_MANOPERA_FACTURA N(20,4),VAL_MATERIALE_VZ N(20,4),VAL_MATERIALE_ACH N(20,4),VAL_MATERIALE_FACTURA N(20,4),VALFTVA_FACTURA N(20,4),VALCTVA_FACTURA N(20,4),'+] +;
|
||||
['ASIGURATOR c(40),MARCA c(24),MASINA c(20),INSPECTOR c(40),NR_DOSAR c(40),INCHIS_FORTAT n(1)']
|
||||
|
||||
pcselect=['select a.id_ordl,a.id_lucrare,a.datai,a.nume,a.nrord,a.nrinmat,a.validat,a.id_tip,a.tip_comanda,a.dataoravalid,a.facturat,a.datafact,a.nrfact,a.proc_tvav, a.id_part_ref, a.part_ref, '+]+;
|
||||
[' a.series, a.kmint, a.ore_functionare '+] + ;
|
||||
[' from ] + gcS + [.auto_normare_comenzi a where 1=2']
|
||||
[' a.series, a.kmint, a.ore_functionare, '+] + ;
|
||||
[' a.ore_manopera, a.val_manopera, a.val_manopera_factura, a.val_materiale_vz, a.val_materiale_ach, a.val_materiale_factura, a.val_manopera_factura + a.val_materiale_factura as valftva_factura, a.valctva_factura, '+] + ;
|
||||
[' a.asigurator, a.marca, a.masina, a.inspector, a.nr_dosar, a.inchis_fortat '+] + ;
|
||||
[' from auto_istoric_comenzi a where 1=2']
|
||||
*!* [' from ] + gcS + [.dev_vvalid_comenzi a where 1=2']
|
||||
*!* pcfiltru=[luna=]+Alltrim(Str(gnLuna))+[ and an=]+Alltrim(Str(gnAn))
|
||||
*!* pcfiltru=[(extract(month from datafact) =]+Alltrim(Str(gnLuna))+[ and extract(year from datafact) =]+Alltrim(Str(gnAn))+[) or (datafact is null )]
|
||||
@@ -669,7 +676,7 @@ llAfiseaza=.F.
|
||||
gencursor('pocomenzi','crscomenzi',pcselect,pcfiltru,pcschema,pcorder,llAfiseaza)
|
||||
pocomenzi.ca_baza1.afisare()
|
||||
|
||||
ofrmviz=Createobject('frm_viz_comenzi')
|
||||
ofrmviz=Createobject('frm_viz_comenzi', m.tlIstoric)
|
||||
ofrmviz.Show(1)
|
||||
If Used('crscomenzi')
|
||||
Use In crscomenzi
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
<!--
|
||||
23/09/2026
|
||||
ROAAUTO - 2.5.6
|
||||
|
||||
:,modificare:
|
||||
Vizualizare comenzi si Istoric comenzi folosesc acelasi ecran (filtre noi: asigurator, inspector, nr. dosar, referinta; coloane noi: asigurator, marca, masina, inspector, nr. dosar, arhivat); in Vizualizare comenzi si Vizualizare facturi s-au adaugat coloanele ore/valoare manopera, valoare materiale (achizitie/vanzare) si total fara/cu TVA, cu totaluri in subsolul gridului.
|
||||
-->
|
||||
|
||||
<!--
|
||||
07/08/2026
|
||||
ROAAUTO - 2.5.5
|
||||
|
||||
@@ -19,8 +19,11 @@ jos.
|
||||
|
||||
### Specifice ROAAUTO
|
||||
|
||||
(niciunul încă — primele insight-uri de proiect au fost, până acum, toate transversale și au
|
||||
migrat în `COMUN/docs/`)
|
||||
- [vfp_oracle_pack_sesiune.md](vfp_oracle_pack_sesiune.md) — capcană: view-urile (`AUTO_COMENZI_VALIDATE`, `AUTO_VORDL_FACTURI`) își calculează coloanele după luna de lucru din `PACK_SESIUNE`; o interogare din `sqlplus` fără `setluna/setan` întoarce tăcut alte date decât aplicația
|
||||
- [flux-vizualizare-comenzi.md](flux-vizualizare-comenzi.md) — lanțul ecranului „Vizualizare comenzi": filtru implicit `[1=2]` (cursor gol), filtrul real în `frm_viz_comenzi.do_cauta`; ecranul pereche facturi
|
||||
- [flux-gccondluna.md](flux-gccondluna.md) — `gcCondLuna` nu e „luna calendaristică", ci luna de lucru plus coada de documente vechi neînchise; cele 6 coloane cerute și capcana de măsurare
|
||||
- [vederi-auto-comenzi.md](vederi-auto-comenzi.md) — lanțul de view-uri Oracle din spatele ecranelor de comenzi/facturi: `AUTO_ISTORIC_COMENZI`, `AUTO_COMENZI_VALIDATE`, `AUTO_VORDL_FACTURI`, garzi și indexuri
|
||||
- [tva-valori-manopera-materiale.md](tva-valori-manopera-materiale.md) — cu/fără TVA pe valorile din „Vizualizare comenzi” / „Vizualizare facturi” / facturarea devizelor: devizul și coloanele facturate sunt fără TVA, doar `valctva` e cu TVA
|
||||
|
||||
### Partajate (COMUN/docs/, valabile pe toate proiectele ROA*)
|
||||
|
||||
|
||||
43
docs/flux-gccondluna.md
Normal file
43
docs/flux-gccondluna.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# `gcCondLuna` — filtrul global „luna de lucru"
|
||||
|
||||
## Unde e definit
|
||||
|
||||
- `Programe/ovariabile_globale.prg:16` — `PUBLIC gcCondLuna` (`:1`), construită la pornire din
|
||||
`gnLuna`/`gnAn`. Presupune aliasul `a` pe sursa interogată.
|
||||
|
||||
## Ce înseamnă (formularea de la `:16-18`)
|
||||
|
||||
Rândul intră dacă:
|
||||
|
||||
1. `a.datai` e în luna de lucru (`extract(month)+extract(year)*12 = gnLuna+gnAn*12`), **SAU**
|
||||
2. `a.datai` e mai vechi **ȘI**:
|
||||
- `a.inch_validare = 0` → `a.facturat = 0` sau facturat în luna de lucru (`a.datafact`);
|
||||
- `a.inch_validare = 1` → `a.validat = 0` sau validat în luna de lucru (`a.dataoravalid`).
|
||||
|
||||
Deci **nu** e „luna calendaristică": târăște după ea coada de documente vechi încă neînchise.
|
||||
|
||||
- `inch_validare` vine din `DEV_TIP_DEVIZ` (per tip de document): 0 = se închide prin facturare,
|
||||
1 = se închide prin validare.
|
||||
|
||||
## Consumatori (doar ecrane de vizualizare/validare)
|
||||
|
||||
- `Programe/oproceduri_vizualizare.prg` — `emitere_facturi:64`, `inchidere_regie:131`,
|
||||
`inchidere_productie:198`, `vizualizare_manopera:528`, `validare_comenzi:620`, plus
|
||||
`normare_salarii:394` (suprascris imediat cu `[1=2]` la `:397`, deci inert).
|
||||
- `Programe/oproceduri_devize.prg` — `normare_comanda:236`, `export_comanda_xml:1633`.
|
||||
- `Clase/odevize.vc2` — `do_cauta:1626`, `:5587`.
|
||||
- `Clase/oviz_devize.vc2` — `do_cauta:1331`, `do_factureaza_avans:1581`, `do_factureaza_final:2318`,
|
||||
`do_verifica_part:4486`, `do_cauta:7730`, `:8680`, `:14125`, `frm_viz_comenzi/do_cauta:15333`,
|
||||
`:19074`.
|
||||
- ~19 locuri reale.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Măsurare**: numărul de rânduri depinde de `validat`/`facturat`, coloane calculate de view-uri
|
||||
după **luna de sesiune Oracle**. Fără `pack_sesiune.setluna/setan`, `validat` iese 0 peste tot și
|
||||
filtrul întoarce istoricul. Măsurat AUTOMOTIVE 10/2025: 195 rânduri corect, 32 790 fără sesiune.
|
||||
Vezi `vfp_oracle_pack_sesiune.md`.
|
||||
- **Coloane cerute**: `gcCondLuna` referă `a.datai`, `a.inch_validare`, `a.facturat`, `a.datafact`,
|
||||
`a.validat`, `a.dataoravalid`. Orice sursă nouă pusă sub `gcCondLuna` trebuie să expună toate
|
||||
șase, altfel `ORA-00904` la căutare. `AUTO_ISTORIC_COMENZI` a primit `inch_validare` abia prin
|
||||
`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_22_01_AUTO.sql`.
|
||||
65
docs/flux-vizualizare-comenzi.md
Normal file
65
docs/flux-vizualizare-comenzi.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Flux: ecranul „Vizualizare comenzi" (unificat: luna curenta + istoric)
|
||||
|
||||
## Lanț
|
||||
|
||||
- `Programe/oproceduri_vizualizare.prg:651` `Procedure vizualizare_comenzi` `Lparameters tlIstoric`
|
||||
(`:652`) — **o singura procedura pentru ambele tile-uri**, nu doua separate. `pcschema`/`pcselect`
|
||||
(`:658-667`) pe `auto_istoric_comenzi a`, cu **+6 campuri** fata de forma veche: `asigurator`,
|
||||
`marca`, `masina`, `inspector`, `nr_dosar`, `inchis_fortat`. `pcorder = a.datai,a.nrord` (`:674`).
|
||||
- **Capcană**: `pcfiltru = [1=2]` (`:672`) — cursorul `crscomenzi` se deschide **gol**; gridul se
|
||||
populează abia la căutarea din formular. Neschimbat fata de forma veche.
|
||||
- `gencursor('pocomenzi','crscomenzi',...)` (`:676`) → `pocomenzi.ca_baza1.afisare()` (`:677`) →
|
||||
`Createobject('frm_viz_comenzi', m.tlIstoric)` (`:679`) → `.Show(1)` (`:680`).
|
||||
- Tile-uri (`Clase/ofundal_dev.vc2`): `Page2.Cw4.do_actiune` (`:681`) `DO vizualizare_comenzi ...
|
||||
WITH .F.` (`nid_cw=5`, luna curenta), `Page2.Cw5.do_actiune` (`:685`) `WITH .T.` (`nid_cw=6`,
|
||||
istoric). Drepturile pe cele doua tile-uri raman separate (nid_cw diferit).
|
||||
- Formular: `Clase/oviz_devize.vc2:14503` (`DEFINE CLASS frm_viz_comenzi`). Proprietate `lIstoric`
|
||||
(`*p: listoric`, `:14590`), primita in `Init(tlIstoric)` — controleaza titlul (ISTORIC /
|
||||
VIZUALIZARE COMENZI) si filtrul de mai jos.
|
||||
- `frm_viz_comenzi.do_cauta` (`Clase/oviz_devize.vc2:15667`) — **aici** se bifurca cele doua moduri
|
||||
si se construieste filtrul real:
|
||||
- `lcFiltru = Iif(Thisform.lIstoric, [2=2], gcCondLuna)` (`:15679`) — istoricul vede tot, modul
|
||||
"luna curenta" ramane limitat la `gcCondLuna`;
|
||||
- + filtrele bifate: `ck_datai` (`:15681`), `ck_nrinmat` (`:15685`), `ck_nrord` (`:15689`),
|
||||
`ck_nume` (`:15693`), `ck_asigurator` (`:15697`), `ck_inspector` (`:15701`), `ck_nr_dosar`
|
||||
(`:15705`), `ck_series` (`:15709`), `ck_referinta` (`:15738`) — **ultimii 4 (asigurator,
|
||||
inspector, nr_dosar, referinta) sunt noi**, nu existau in forma veche de "luna curenta";
|
||||
- + `and a.id_tip = ...` dacă s-a ales un tip (`:15713`);
|
||||
- + `and a.validat = 0/1` după `cbValidat` (`:15718-15722`);
|
||||
- + `and a.inchis_fortat = 0/1` după `cbArhivat` (`:15724-15729`);
|
||||
- apoi `Thisform.actualizeaza_grid1(lcFiltru)`.
|
||||
- `actualizeaza_grid1` — pune `pocomenzi.ca_baza1.cfiltru`, reapelă `afisare()`, cu `save_grid` /
|
||||
`restore_grid`.
|
||||
- Coloane noi, adaugate **la coada** grid-ului (`Column22-27`, `:15021-15054`): `cAsigurator`,
|
||||
`cMarca`, `cMasina`, `cInspector`, `cNr_dosar`, `cArhivat` (`IIF(inchis_fortat=1,'Da','Nu')`).
|
||||
- `Cmd_sterge1`/`do_sterge` exista in clasa (`:14858`, `:15982`) dar `Visible = .F.` (`:14865`) —
|
||||
butonul de stergere ramane ascuns, ca in fosta forma de istoric; activarea lui e o decizie
|
||||
separata, netratata de unificare.
|
||||
|
||||
## Capcană: forma unificata e deschisa de `vizualizare_comenzi`, nu de `vizualizare_ist_comenzi`
|
||||
|
||||
`vizualizare_ist_comenzi` (`Programe/oproceduri_vizualizare.prg:445`) si clasa
|
||||
`frm_istoric_comenzi` **raman inca in cod dar nu mai sunt apelate din niciun tile** — cautarea unei
|
||||
proceduri "de istoric" dupa nume duce la codul gresit. Cod mort, de sters.
|
||||
|
||||
## Valorile implicite ale combo-urilor (contează la orice măsurătoare)
|
||||
|
||||
| combo | implicit | efect în `do_cauta` |
|
||||
|---|---|---|
|
||||
| `cbArhivat` | `"Active"` (`Clase/oviz_devize.vc2:14453`) | mereu `and a.inchis_fortat = 0` (`:15726`) |
|
||||
| `cbValidat` | `"<Toate>"` (`:14471`) | nimic |
|
||||
| `cbtip_deviz` | `"<Toate tipurile>"` (`:65`, clasa `ctip_deviz`) | nimic |
|
||||
|
||||
## Ecranul pereche „Vizualizare facturi"
|
||||
|
||||
- `Programe/oproceduri_vizualizare.prg:231` `Procedure vizualizare_facturi` — sursa
|
||||
`auto_facturi_emise a` (`:247`); `pcFiltru = [1=2]` (`:253`), deci din nou cursor gol.
|
||||
- Filtrul real e în `frm_viz_facturi.do_cauta` (`Clase/oviz_devize.vc2:17795`) și **nu** folosește
|
||||
`gcCondLuna` (linia e comentată la `:17800`), ci `extract(month from dataact)=gnLuna` +
|
||||
`extract(year from dataact)=gnAn` (`:17799`) + checkbox-uri; `actualizeaza_grid1` (`:17837`).
|
||||
- Formular: `Clase/oviz_devize.vc2:16936` (`DEFINE CLASS frm_viz_facturi`).
|
||||
|
||||
## Editare de grid
|
||||
|
||||
- Coloane noi **doar la coadă** — preferințele de grid (`gridprefs.tmp` din GridExtras) se aplică
|
||||
pozițional; o coloană inserată la mijloc mută toate preferințele salvate.
|
||||
@@ -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
|
||||
|
||||
|
||||
130
docs/tva-valori-manopera-materiale.md
Normal file
130
docs/tva-valori-manopera-materiale.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Valorile de manoperă / materiale: cu TVA sau fără TVA?
|
||||
|
||||
Read-only, din sursa view-urilor Oracle (`D:\ROA\DATABASE\SCRIPTURI_CLAR\`) + codul VFP.
|
||||
`Clase\oviz_devize.vc2` era editat în paralel — **liniile pot aluneca**, ancorele sigure sunt
|
||||
numele claselor/procedurilor.
|
||||
|
||||
## Răspuns scurt
|
||||
|
||||
- Toate valorile de **deviz** (`val_manopera`, `ore_manopera`, `val_materiale_ach`,
|
||||
`val_materiale_vz`) sunt **FĂRĂ TVA**.
|
||||
- Coloanele **facturate** `val_manopera_factura` / `val_materiale_factura` (și `manopera`,
|
||||
`materiale` din `AUTO_FACTURI_EMISE`) sunt **FĂRĂ TVA** — vin din conturi de venit nete
|
||||
(704, 707/419).
|
||||
- **Doar** `valctva` / `valctva_factura` / „Total facturi (cu TVA)" / „Valoare cu TVA" este
|
||||
**CU TVA** = manoperă + materiale + 4427.
|
||||
|
||||
## Tabel
|
||||
|
||||
| valoare | sursă | cu/fără TVA | formulă | fișier:linie |
|
||||
|---|---|---|---|---|
|
||||
| `ore_manopera` | `DEV_ORDL` ⋈ `DEV_OPER` | n/a (ore) | `sum(b1.timpn)` | `AUTO_ISTORIC_COMENZI` `2026/09/ff_2026_09_22_01_AUTO.sql:55`; `AUTO_FACTURI_EMISE` `:145` |
|
||||
| `val_manopera` | `DEV_OPER.PRET * TIMPN` | **fără TVA** | `sum(round(b1.timpn*b1.pret,2))` | view `2026/09/ff_2026_09_22_01_AUTO.sql:56` / `:146` |
|
||||
| `DEV_OPER.PRET` | scris la facturare din totalul **fără TVA** | **fără TVA** | `V_PRET := tnTotalFTva / tnTimpN` | `PACK_AUTO.dev_adauga_oper_fact` `2026/03/ff_2026_03_31_02_AUTO_PACK_AUTO.sql:392,415`; apelat cu `?pnTotalFTva` din `Programe/oproceduri_devize.prg:801` |
|
||||
| `DEV_OPER.PRET` (adaugare manuală) | `auto_vpreturi.pret` (tarif orar) | **fără TVA** | `Thisform.npret` = `v_preturi.pret` | `Clase/odevize.vc2:947,1082`; `auto_vpreturi` = `dev_nom_preturi` `2013/07/ff_2013_07_24_02_AUTO.sql:930`; DDL fără coloană TVA `Scripturi_instalare/tabele.sql:495` |
|
||||
| `val_materiale_ach` | `RUL.PRET` (cost lot FIFO) | **fără TVA** | `sum(round(pret*cante,2))` | view `2026/09/ff_2026_09_22_01_AUTO.sql:53` / `:143` |
|
||||
| `RUL.PRET` | `STOC.PRET` | **fără TVA** (cost) | `V_PRET := tab_stoc(i).PRET` | `PACK_FACTURARE.descarca_gestiune` `2026/09/ff_2026_09_16_04_COMUN_PACK_FACTURARE.sql:8975` |
|
||||
| `val_materiale_vz` | `RUL.PRETV` (preț vânzare) | **fără TVA** | `sum(round(pretv*cante,2))` | view `2026/09/ff_2026_09_22_01_AUTO.sql:54` / `:144` |
|
||||
| `RUL.PRETV` | `STOC.PRETV`; TVA-ul stă separat în `RUL.TVAV` / `RUL.PRETVTVA` | **fără TVA** | `V_PRETV_ORIG := tab_stoc(i).PRETV`; la insert `PRETV, TVAV, PRETVTVA` | `...COMUN_PACK_FACTURARE.sql:8977` și `:10491-10493` |
|
||||
| `val_manopera_factura` | `AUTO_VORDL_FACTURI.valfactmanopera` = `MV_ORDL_SUME_ACT.manopera_ron/rol` | **fără TVA** | cont **704** | `2025/06/ff_2025_06_30_01_AUTO.sql:9-12`; MV `2013/12/ff_2013_12_09_02_AUTO.sql:50` |
|
||||
| `val_materiale_factura` | `MV_ORDL_SUME_ACT.materiale_ron/rol` | **fără TVA** | cont **707, 419** | `2025/06/ff_2025_06_30_01_AUTO.sql:16-18`; MV `2013/12/ff_2013_12_09_02_AUTO.sql:68` |
|
||||
| `valctva` / `valctva_factura` | `MV_ORDL_SUME_ACT` | **CU TVA** | `manopera + materiale + tva` | `2025/06/ff_2025_06_30_01_AUTO.sql:23-26` |
|
||||
| `...tva_ron` (componenta TVA) | `MV_ORDL_SUME_ACT` | CU TVA | cont **4427 sau 4428** (TVA la încasare) | `2026/09/ff_2026_09_23_01_AUTO.sql`; înainte doar 4427 (`2013/12/ff_2013_12_09_02_AUTO.sql:86`) |
|
||||
| `manopera`, `materiale` (`AUTO_FACTURI_EMISE`) | `MV_ORDL_SUME_ACT` (704 / 707,419) | **fără TVA** | `b.manopera_ron/rol`, `b.materiale_ron/rol` | `2026/09/ff_2026_09_22_01_AUTO.sql:119-132` |
|
||||
| totaluri sub grid „Vizualizare facturi" | `crsfacturi` (`AUTO_FACTURI_EMISE`) | mixt | `clb_valctva`=Sum(valctva) **cu TVA**; `clb_manopera`/`clb_materiale`=Sum(manopera/materiale) WHERE `nrcrt=1` **fără TVA** | `Clase/oviz_devize.vc2` proc `frm_viz_facturi.refreshdata` (~`:17995`) |
|
||||
|
||||
Garda `MV_ORDL_SUME_ACT`: `scd in ('4111','667','482','711','6588')` și
|
||||
`id_set in (31001..31007, 31011..31013)` (`2013/12/ff_2013_12_09_02_AUTO.sql:238-243`), definit
|
||||
ca materialized view *fast refresh on commit* cu fallback pe view (`:39-45`).
|
||||
|
||||
## Observația „Total facturi (cu TVA) = val_manopera_factura + val_materiale_factura"
|
||||
|
||||
**Componentele nu conțin TVA.** `valctva = manopera + materiale + tva_ron`, deci egalitatea cu
|
||||
`manopera + materiale` înseamnă `tva_ron = 0`.
|
||||
|
||||
**Cauza, măsurată pe date: firma are TVA la încasare** (`calendar.tva_incasare = 1`). Pe aceste
|
||||
firme TVA-ul facturii se înregistrează `4111 → 4428` (neexigibil), nu `4111 → 4427`. Până la
|
||||
`ff_2026_09_23_01_AUTO`, `MV_ORDL_SUME_ACT.tva_ron` însuma **doar `scc = '4427'`**, deci ieșea 0,
|
||||
iar coloanele/totalurile „cu TVA" afișau **netul**. Afirmația anterioară din acest doc („eticheta
|
||||
este corectă chiar și atunci") era dedusă doar din sursă și era **greșită**.
|
||||
|
||||
Dovada (`MARIUSM_AUTO`, factura 1159, `id_lucrare` 131): `4428` TVA MANOPERA 147.82 +
|
||||
TVA MATERIALE 180.91 = 328.73 = 21 % din 1 565.37 (manopera 703.89 + materiale 861.48);
|
||||
`tva_ron` era 0. În 2026: 97 linii `4111 → 4427`, 574 linii `4111 → 4428`.
|
||||
|
||||
**Fixul** (`2026/09/ff_2026_09_23_01_AUTO.sql`, aplicat pe `MARIUSM_AUTO`, nepublicat):
|
||||
- `tva_ron`/`tva_rol` (și `cnt_`) însumează `scc in ('4427','4428')`;
|
||||
- liniile `DISCOUNT MANOPERA%` / `DISCOUNT MATERIALE%` cu `scc = '4428'` (TVA-ul discountului)
|
||||
**nu se mai scad din net** — garda era `scc <> '4427'`, deci pe TVA la încasare manopera și
|
||||
materialele ieșeau subevaluate cu TVA-ul discountului (ex. `id_lucrare` 103: manopera 97.58 în
|
||||
loc de 99.58, materiale 234.58 în loc de 240.41).
|
||||
|
||||
**Nu se dublează TVA-ul la încasare**: nota de exigibilizare e `4428 → 4427` (`scd = '4428'`),
|
||||
exclusă de filtrul `scd in ('4111','667','482','711','6588')`. Verificat pe date.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Asimetrie de deduplicare** în `frm_viz_facturi.refreshdata`: `valctva` se însumează pe
|
||||
**toate** rândurile `crsfacturi`, iar `manopera`/`materiale` doar pe `nrcrt=1`. Dacă un `nrord`
|
||||
are >1 rând (mai multe `id_set`/`nact` în `MV_ORDL_SUME_ACT`), totalul „cu TVA" poate fi umflat
|
||||
față de restul coloanelor — nu trage concluzii din diferența dintre totaluri fără verificare.
|
||||
- `proc_tvav` (coloana `DEV_ORDL.PROC_TVAV`, expusă prin `AUTO_COMENZI_VALIDATE` →
|
||||
`AUTO_ISTORIC_COMENZI.proc_tvav`; DDL view `2024/07/ff_2024_07_03_01_AUTO.sql:192`) este
|
||||
**multiplicatorul TVA pe comandă** (`1 + cota/100`). TVA se calculează ca
|
||||
`valoare * (proc_tvav - 1)` (ex. `Clase/oviz_devize.vc2:2355`). Când `proc_tvav = 1`
|
||||
(scutit / taxare inversă), „cu TVA" == „fără TVA". Se stabilește la crearea comenzii și se
|
||||
actualizează la validare/facturare (`Programe/oproceduri_vizualizare.prg:285-288`). **Nu** este
|
||||
o opțiune de firmă.
|
||||
- **Opțiunea „prețuri cu TVA"** există, dar nu e de firmă: `CRM_POLITICI_PRETURI.PRETURI_CU_TVA`
|
||||
(per politică de preț), citită în `COMUN/programe/ofacturare_comun.prg:2425-2431` și
|
||||
`COMUN/clase/ointroduceri.vc2:16270`, propagată pe linii ca `VANZARI_DETALII.PRET_CU_TVA` /
|
||||
`cu_tva` (modulele comenzi/facturare articole). **Nu schimbă cele trei ecrane**: `RUL` ține
|
||||
mereu prețul net (`PRETV`) și cel cu TVA (`PRETVTVA`) în coloane separate, iar veniturile
|
||||
contabile sunt nete. `gnTipPret` nu a fost găsit în cod.
|
||||
- `DEV_OPER.PRET` la corecția unor luni vechi: `pack_devize.dev_actualizeaza_operatie`
|
||||
înmulțește prețul cu `10000` la trecerea ROL→RON (2005), fără legătură cu TVA
|
||||
(`Scripturi_instalare/packages.sql:393-398`).
|
||||
- `MV_ORDL_SUME_ACT` și `AUTO_VORDL_FACTURI` depind de luna de lucru din `PACK_SESIUNE`
|
||||
(`vederi-auto-comenzi.md`, `vfp_oracle_pack_sesiune.md`) — o citire din `sqlplus` fără
|
||||
`setluna/setan` întoarce tăcut alte date.
|
||||
|
||||
## Ecranul „Facturarea devizelor"
|
||||
|
||||
Clasa `frm_emitere_facturi` (`Clase/oviz_devize.vc2:505`), deschisă din
|
||||
`Programe/oproceduri_vizualizare.prg:74` (`emitere_facturi`); procedurile `do_factureaza_avans`
|
||||
(`:1527`) și `do_factureaza_final` (`:2226`). Afișează „Manopera"/„Materiale" (nete), „Avans cu
|
||||
TVA facturat", „Total deviz cu TVA", „Total discount cu TVA", „Total factura", „TVA manopera",
|
||||
„TVA materiale". Manopera facturată se scrie în `DEV_OPER.PRET` ca **total fără TVA / ore**
|
||||
(`Programe/oproceduri_devize.prg:801` → `2026/03/ff_2026_03_31_02_AUTO_PACK_AUTO.sql:415`).
|
||||
Prețul „cu TVA" se calculează separat, la nevoie, cu `pack_sesiune.calculeaza_pret_cu_tva`
|
||||
(ex. `Clase/oviz_devize.vc2:2361`) — folosit la bonul fiscal detaliat, nu în coloanele de deviz.
|
||||
|
||||
## Propunere de etichetare (doar propunere, nu s-a modificat niciun `.vc2`)
|
||||
|
||||
`obiect -> caption propus`
|
||||
|
||||
**frm_viz_comenzi / grdcomenzi** (`Clase/oviz_devize.vc2`)
|
||||
- `cValManopera` -> `Valoare manopera (fara TVA)`
|
||||
- `cValManoperaFactura` -> `Valoare manopera factura (fara TVA)`
|
||||
- `cValMaterialeVz` -> `Valoare materiale vanzare (fara TVA)`
|
||||
- `cValMaterialeAch` -> `Valoare materiale achizitie (fara TVA)`
|
||||
- `cValMaterialeFactura` -> `Valoare materiale factura (fara TVA)`
|
||||
- `cOreManopera` -> neschimbat (ore, fără noțiune de TVA)
|
||||
|
||||
**frm_viz_facturi / grdfacturi + totaluri** (`Clase/oviz_devize.vc2`)
|
||||
- `cManopera` -> `Manopera (fara TVA)`
|
||||
- `cMateriale` -> `Materiale (fara TVA)`
|
||||
- `cValManopera` -> `Valoare manopera (fara TVA)`
|
||||
- `cValMaterialeAch` -> `Valoare materiale achizitie (fara TVA)`
|
||||
- `cValMaterialeVz` -> `Valoare materiale vanzare (fara TVA)`
|
||||
- `clb_manopera` („Manopera fact.") -> `Manopera fact. (fara TVA)`
|
||||
- `clb_materiale` („Materiale fact.") -> `Materiale fact. (fara TVA)`
|
||||
- `clb_val_manopera` („Val. manopera") -> `Val. manopera (fara TVA)`
|
||||
- `clb_val_mat_ach` („Mat. achizitie") -> `Mat. achizitie (fara TVA)`
|
||||
- `clb_val_mat_vz` („Mat. vanzare") -> `Mat. vanzare (fara TVA)`
|
||||
- `cValctva` („Valoare cu TVA") și `clb_valctva` („Total facturi (cu TVA)") -> neschimbate (corecte)
|
||||
|
||||
**frm_emitere_facturi** („Facturarea devizelor", `Clase/oviz_devize.vc2:505`)
|
||||
- „Manopera" / „Materiale" -> `Manopera (fara TVA)` / `Materiale (fara TVA)`
|
||||
- „Total deviz cu TVA", „Avans cu TVA facturat", „Total factura", „TVA manopera",
|
||||
„TVA materiale" -> neschimbate (deja explicite)
|
||||
38
docs/vederi-auto-comenzi.md
Normal file
38
docs/vederi-auto-comenzi.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Vederi Oracle: „Vizualizare comenzi" / „Facturi emise"
|
||||
|
||||
Căile de mai jos sunt relative la `D:\ROA\DATABASE\SCRIPTURI_CLAR\`.
|
||||
|
||||
## Lanțul
|
||||
|
||||
| view | definit în | compus din |
|
||||
|---|---|---|
|
||||
| `AUTO_COMENZI_VALIDATE` | `2024\07\ff_2024_07_03_01_AUTO.sql:181` | `DEV_ORDL a where a.sters = 0` (`:236`) + `SYN_UTILIZATORI` b/d + `NOM_LUCRARI` c |
|
||||
| `AUTO_VORDL_FACTURI` | `2025\06\ff_2025_06_30_01_AUTO.sql:4` | `AUTO_VORDL_FACTURATE` + `MV_ORDL_SUME_ACT` |
|
||||
| `AUTO_ISTORIC_COMENZI` | `2026\09\ff_2026_09_22_01_AUTO.sql:35` | `AUTO_COMENZI_VALIDATE a` + `AUTO_VORDL_FACTURI c` + `DEV_MASINICLIENTI` / `DEV_NOM_MASINI` / `DEV_NOM_MARCI` / `NOM_PARTENERI` / `DEV_NOM_ASIGURATORI` / `DEV_NOM_INSPECTORI` / `DEV_TIP_DEVIZ i` |
|
||||
| `AUTO_FACTURI_EMISE` | `2026\09\ff_2026_09_22_01_AUTO.sql:100` | `AUTO_COMENZI_VALIDATE` + `AUTO_VORDL_FACTURATE` + `MV_ORDL_SUME_ACT` + `AUTO_VORDL_MAN` / `AUTO_VORDL_MAT` |
|
||||
|
||||
## Note
|
||||
|
||||
- `AUTO_COMENZI_VALIDATE`: `validat`, `dataoravalid`, `util_valid`, `dataorainchis`, `util_inchis`
|
||||
sunt **calculate** față de `pack_sesiune.getluna()/getan()` — motivul capcanei din
|
||||
`vfp_oracle_pack_sesiune.md`.
|
||||
- `AUTO_VORDL_FACTURI`: alege coloanele RON vs ROL comparând `pack_sesiune.getan/getluna` cu
|
||||
`get_anron/get_lunaron`; expune `facturat`, `dataact`, `nract`, `valfactmanopera`,
|
||||
`valfactmateriale`, `valctva` (redenumite în `AUTO_ISTORIC_COMENZI` în `datafact`, `nrfact`,
|
||||
`val_manopera_factura`, `val_materiale_factura`, `valctva_factura`).
|
||||
- `AUTO_ISTORIC_COMENZI` primește `i.inch_validare` abia în `ff_2026_09_22_01_AUTO.sql` — cerut de
|
||||
`gcCondLuna` (vezi `flux-gccondluna.md`).
|
||||
- Coloane calculate per rând, prin subinterogări corelate (~16 buffer gets/rând):
|
||||
`val_materiale_ach` / `val_materiale_vz` din `RUL` (`sters=0 and id_lucrare = a.id_lucrare`);
|
||||
`ore_manopera` / `val_manopera` din `DEV_ORDL` + `DEV_OPER`.
|
||||
- **Garda `id_lucrare > 0`** pe `RUL` e obligatorie (`AUTO_FACTURI_EMISE` o are): la AUTOMOTIVE
|
||||
`RUL` are 215 269 rânduri cu `ID_LUCRARE = 0` (161 259 cu `STERS = 0`) — mișcările de stoc
|
||||
obișnuite.
|
||||
- Indexuri de care depind subinterogările: `IDX_RUL_001 (ID_LUCRARE, STERS)`,
|
||||
`IDX_ORDL_00001 (DEV_ORDL.ID_LUCRARE)`, `IDX_OPER_01 (DEV_OPER.ID_ORDL)`.
|
||||
- **Capcană de plan**: pe volum mic (`MARIUSM_AUTO`) optimizatorul de-corelează subinterogările și
|
||||
face `TABLE ACCESS FULL` pe `RUL`; pe volum de producție le păstrează corelate și folosește
|
||||
`IDX_RUL_001`. Nu trage concluzii de plan de pe dev.
|
||||
- `AUTO_NORMARE_COMENZI` **nu se modifică** — e folosit în ~10 alte locuri.
|
||||
- Linia paralelă de produs: `DEVIZE_NORMARE_COMENZI`, `DEVIZE_VALIDARE_COMENZI`, `DEVIZE_VORDL`,
|
||||
cu același tipar.
|
||||
62
docs/vfp_oracle_pack_sesiune.md
Normal file
62
docs/vfp_oracle_pack_sesiune.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Capcană: view-urile ROA depind de `PACK_SESIUNE` (luna de lucru)
|
||||
|
||||
**Orice măsurătoare sau verificare făcută din `sqlplus` / DSN fără inițializarea lunii de lucru
|
||||
întoarce alte date decât aplicația — fără nicio eroare.**
|
||||
|
||||
## Ce se întâmplă
|
||||
|
||||
Mai multe view-uri de bază nu sunt „pure": își calculează coloanele în funcție de starea de
|
||||
sesiune ținută în pachetul `PACK_SESIUNE`, pe care aplicația o setează la login
|
||||
(`setluna`, `setan`, `setanbal`, `setlunabal`, `set_data_init/final`, `set_id_util`, `setschema`).
|
||||
|
||||
Exemplu — `AUTO_COMENZI_VALIDATE` (baza lui `AUTO_ISTORIC_COMENZI`):
|
||||
|
||||
```sql
|
||||
(case when extract(month from a.dataoravalid) + extract(year from a.dataoravalid) * 12
|
||||
<= pack_sesiune.getluna() + pack_sesiune.getan() * 12
|
||||
then 1 else 0 end) as validat
|
||||
```
|
||||
|
||||
Într-o sesiune `sqlplus` proaspătă, `getluna()/getan()` nu sunt setate, comparația e falsă pentru
|
||||
toate rândurile, deci **`validat` iese 0 peste tot** — și la fel `dataoravalid`, `util_valid`,
|
||||
`dataorainchis`, `util_inchis`. Același tipar în `AUTO_VORDL_FACTURI` (alege coloanele RON vs ROL
|
||||
după `getan/getluna` față de `get_anron/get_lunaron`) și în omoloagele `DEVIZE_*`.
|
||||
|
||||
## Cât de mult minte
|
||||
|
||||
Măsurat pe producția AUTOMOTIVE, 23.09.2026, ecranul „Vizualizare comenzi", luna 10/2025:
|
||||
|
||||
| | rânduri întoarse |
|
||||
|---|---|
|
||||
| `sqlplus` fără `pack_sesiune` inițializat | **32 790** (din 2006 încoace) |
|
||||
| cu `setluna(10)/setan(2025)` | **195** (164 cu filtrul implicit „Active") |
|
||||
|
||||
Diferența e ×168. Motivul: `gcCondLuna` (`Programe/ovariabile_globale.prg:16`) păstrează rândurile
|
||||
vechi doar dacă sunt **nevalidate sau nefacturate** — iar fără luna de lucru *totul* pare
|
||||
nevalidat. Din cele 33 704 comenzi ale clientului, 32 744 sunt de fapt validate.
|
||||
|
||||
## Ce se face
|
||||
|
||||
Prima comandă din orice script de diagnostic pe o schemă ROA, imediat după conectare:
|
||||
|
||||
```sql
|
||||
begin
|
||||
<schema>.pack_sesiune.setluna(<luna>);
|
||||
<schema>.pack_sesiune.setan(<an>);
|
||||
end;
|
||||
/
|
||||
```
|
||||
|
||||
(`setluna/setan` sunt setări de sesiune, nu DML — nu încalcă regula „doar SELECT pe producție".)
|
||||
|
||||
Verificare rapidă că sesiunea e inițializată corect, înainte de a crede orice cifră:
|
||||
|
||||
```sql
|
||||
select nvl(validat,0) validat, count(*) from <schema>.auto_comenzi_validate
|
||||
group by nvl(validat,0);
|
||||
```
|
||||
|
||||
Dacă iese **totul pe 0**, sesiunea nu e inițializată — nu interpreta rezultatele.
|
||||
|
||||
Vezi și: `roa-oracle-production-access` (lanțul tunel/TNS/DSN),
|
||||
`COMUN\docs\conexiuni-tunel-ssh-odbc.md`.
|
||||
@@ -1 +1 @@
|
||||
2026_03_31_02
|
||||
2026_09_23_01
|
||||
Reference in New Issue
Block a user