sync SVN r18016: editare articole in factura de vanzare, precizie pret achizitie
ROAFACTURARE 2.11.15 (r18015): programe/ofacturare_editare.prg, programe/ofacturare_stoc.prg. docs: conventia de encoding .sc2/.vc2 corectata la cp1250; cercetarile trans-proiect mutate din ROAFACTURARE in docs/cercetare (r18014); actualizari reguli_lucru, oracle_export, flux-editare-vfp-text, scripturi-migrare-db, flux-modificare-stergere-nota-jurnal, todos. .gitignore: watchdog_out si PNG-urile din rularile headless (r18008). Text FoxBin2Prg regenerat: clase/comun.vc2, ferestre/frm_import_note_facturi_clienti.sc2, ferestre/frm_initializare_facturi_balanta.sc2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AV7dQbTLAqvrtQbH7zxXxw
This commit is contained in:
164
docs/cercetare/rec_view_articole_vanzare.md
Normal file
164
docs/cercetare/rec_view_articole_vanzare.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Proiectare view Oracle pentru liniile de articole ale unei vanzari (VVANZARI_ARTICOLE)
|
||||
|
||||
Cercetare + proiectare, read-only pe baza. Decizia lui Marius (08.08.2026): view dedicat, varianta B
|
||||
din `rec_review_ancorare_s4.md` (respinsa atunci doar pentru ca insemna migrare de schema - acum
|
||||
aprobata). Inlocuieste lista de 20 coloane + join pe 4 tabele din `IncarcaArticoleFactura`
|
||||
(`COMUN\programe\ofacturare_editare.prg:201-208`).
|
||||
|
||||
## A. Precoditia VERSIUNE
|
||||
|
||||
`MARIUSM_AUTO` e la zi **pentru schema firmei (`ff_`)** pe orice ar putea atinge `VANZARI_DETALII`/
|
||||
facturare: toate scripturile `ff_` din 2015 incoace apar in `VERSIUNE`, inclusiv cele mai recente
|
||||
patru (`ff_2026_08_06_09/10/11/12`, comanda/contract, `PACK_FACTURARE`, `FACT_VFACTURI`,
|
||||
`VANZARI_BACKFILL`). Diferenta gasita fata de `SCRIPTURI_CLAR` (452 de fisiere, din care 14 `ff_`)
|
||||
e integral din 2009-2014 (dinainte de generalizarea `UpdateVersiune`) plus scripturi de diagnostic
|
||||
fara prefix de tracking (`DIAG_SPATIU_*`, ad-hoc-uri fara nume standard) - niciunul din ele nu
|
||||
atinge `VANZARI`/`VANZARI_DETALII`/facturare. Verdict: **precoditia trece**, sursa `MARIUSM_AUTO` e
|
||||
de incredere pentru acest DDL.
|
||||
|
||||
## B. Ce exista deja - niciun candidat direct refolosibil, dar un precedent util
|
||||
|
||||
Cautat in `all_views` (MARIUSM_AUTO) orice view pe `VANZARI_DETALII`/liniile unei vanzari:
|
||||
`VVANZARI_DETALII`, `VVANZARI_DETALII_TOT`, `FACT_VFACTURI_DETALII` sunt cele relevante.
|
||||
|
||||
- **`FACT_VFACTURI_DETALII`** (exportat integral) e cel mai apropiat candidat structural - selecteaza
|
||||
direct din `vanzari_detalii`, cu join-uri catre `nom_articole`/`nom_gestiuni`/`nom_valute` ca in
|
||||
proiectarea de mai jos. **Nu e reutilizabil ca atare**: `pret` si `discount_unitar` sunt
|
||||
RECALCULATE la cursul valutar curent (`ROUND(NVL(g.curs,1)*NVL(a.pret,0)/NVL(g.multiplicator,1),
|
||||
pack_sesiune.getoptiunefirma('PPRETV'))`, apel de functie PL/SQL per coloana per rand), construit
|
||||
pentru **afisare/tiparire** facturi, nu pentru editare. Pagina de editare (#6) trebuie sa lucreze
|
||||
pe valorile RAW stocate, ca la salvare (S5) sa scrie inapoi exact ce a citit - un `pret` deja
|
||||
convertit ar strica exact acest contract. Confirma insa tiparul de join corect (articol/gestiune/
|
||||
valuta) si ca genul asta de view exista deja in familia `FACT_*` pentru alt scop.
|
||||
- **`VVANZARI_DETALII`/`VVANZARI_DETALII_TOT`**: alt scop (afisare generica vanzari + utilizatori +
|
||||
politici de pret), nu au `pret_cu_tva`, `cont`, `id_valuta`, `id_gestiune`, `taxcode`, `lot` -
|
||||
nepotrivite.
|
||||
|
||||
Niciunul nu inlocuieste nevoia unui view nou - se continua cu proiectarea.
|
||||
|
||||
## C. Numele: `VVANZARI_ARTICOLE`
|
||||
|
||||
Verificat liber in `all_objects` (MARIUSM_AUTO). 17 caractere, sub limita de 30 (Oracle 10.2).
|
||||
|
||||
**Criteriul lui Marius (08.08.2026)**: numele trebuie sa pastreze prefixul familiei de vanzari,
|
||||
`vvanzari_*`, pentru ca el se uita la view-uri **alfabetic** si vrea sa vada dintr-o privire ca tine
|
||||
de vanzari. La o listare alfabetica: `VVANZARI_ARTICOLE`, `VVANZARI_DETALII`,
|
||||
`VVANZARI_DETALII_TOT`, `VVANZARI_TOT`.
|
||||
|
||||
Numele analog conventiei surorilor de pe acelasi formular (`vact_tot`, `vrul_tot`,
|
||||
`vrul_obinv_tot`) ar fi fost `vvanzari_detalii_tot`, dar e **deja ocupat** (alt view, B mai sus).
|
||||
|
||||
Numele de lucru din prima varianta a fost `VVD_TOT` (`v` + abreviere + `_tot`, aliniat cu aliasul
|
||||
VFP `tvd`), respins de Marius pe criteriul de mai sus: nu se citea ca facand parte din familie si
|
||||
cadea in alta parte a listei alfabetice.
|
||||
|
||||
## D. Coloanele - RAW, fara filtru STERS in view
|
||||
|
||||
Cele 20 de coloane consumate azi + **`id_vanzare` adaugat**: lista din
|
||||
`ofacturare_editare.prg:201-203` filtreaza pe `vd.id_vanzare` dar nu-l intoarce niciodata ca si
|
||||
coloana - omisiune reala, semnalata in misiune, acum corectata in view.
|
||||
|
||||
- **Fara conversie valutara, fara valori calculate** (spre deosebire de `FACT_VFACTURI_DETALII`) -
|
||||
editarea scrie inapoi exact ce citeste.
|
||||
- **`STERS` ramane in view ca si coloana, dar FARA filtru `WHERE sters=0` in definitie** - acelasi
|
||||
tipar ca `VACT_TOT`/`VRUL_TOT`/`VRUL_OBINV_TOT` (niciunul nu filtreaza `sters` in view, apelantul
|
||||
o face explicit). Apelantul de azi (`IncarcaArticoleFactura`) deja are `WHERE ... vd.sters = 0` -
|
||||
ramane neschimbat, doar `FROM vanzari_detalii vd ... WHERE vd.id_vanzare=... AND vd.sters=0` devine
|
||||
`FROM vvanzari_articole vd WHERE vd.id_vanzare=... AND vd.sters=0`.
|
||||
|
||||
## E. Ce s-a respins: valorile calculate `CALCULEAZA_TOTAL_FARA_TVA_FACT`/`_TVA_FACT`
|
||||
|
||||
Ambele sunt functii **in `PACK_FACTURARE`**, semnatura `(V_PRET, V_DIFERENTA, V_CURS,
|
||||
V_DISCOUNT_UNITAR, V_DISCOUNT_EVIDENTIAT, V_CANTITATE, V_PRET_CU_TVA, V_PROC_TVAV) RETURN NUMBER` -
|
||||
strict `NUMBER`, deci **apelabile din SQL** (confirmat prin `all_arguments`, fara tip PL/SQL-only).
|
||||
Exista precedent local pentru functii de pachet apelate per-rand intr-un view din aceeasi familie
|
||||
(`VRUL_TOT` cheama `PACK_SESIUNE.SUMA_RON` pe aproape fiecare coloana numerica), deci performanta nu
|
||||
e un argument respingator prin ea insasi pe un view filtrat pe `id_vanzare` (cateva linii/factura).
|
||||
|
||||
**Respins totusi, pentru acum**:
|
||||
1. `V_DISCOUNT_EVIDENTIAT` **nu e coloana pe `VANZARI_DETALII`** - e pe antet (`VANZARI.
|
||||
DISCOUNT_EVIDENTIAT`, confirmat in `all_tab_columns`). A include totalul calculat per linie ar
|
||||
cere fie un join suplimentar la `VANZARI` (umfla view-ul cu o dependenta noua doar pentru un
|
||||
parametru), fie parametrul trimis din VFP - oricum, in afara scopului Rundei 1 (doar afisare).
|
||||
2. Runda 1 (deja implementata si testata, `docs\progres.md`) **nu consuma** aceste valori - grid-ul
|
||||
e readonly, fara subtotal calculat.
|
||||
3. Nevoia reala apare la S4b/Runda 4 (`plan_06_s4_proiectare.md`, C.1-C.3) - dar acolo e vorba de
|
||||
**totalul pe DOCUMENT** (suma peste toate liniile), comparat cu `ACT`/`RUL`, nu de o coloana pe
|
||||
fiecare rand din grid. O interogare de agregare separata (sau o functie Oracle dedicata) e o
|
||||
potrivire mai buna pentru "totalul de control" decat 2 coloane calculate in view-ul de grid.
|
||||
4. **Costul amanarii e mic**: extinderea unui VIEW (`CREATE OR REPLACE`) nu e o migrare de schema in
|
||||
sensul de risc/coordonare al unei modificari de tabela - se poate adauga oricand printr-un script
|
||||
nou, fara sa afecteze datele sau consumatorii existenti ai coloanelor deja definite. Deci nu e
|
||||
nevoie sa se "prevada" acum ca sa se evite un al doilea script peste o saptamana.
|
||||
|
||||
**Recomandare pentru Runda 4**: cand S4b ajunge la implementare, se adauga fie doua coloane noi in
|
||||
`VVANZARI_ARTICOLE` (dupa un join la `VANZARI` pentru `DISCOUNT_EVIDENTIAT`), fie - preferabil - o interogare
|
||||
de agregare separata in Oracle care calculeaza direct SUMA pe document, fara sa treaca prin grid.
|
||||
Decizia ramane a lui Marius/sesiunii care implementeaza S4b, pe baza planului deja scris in
|
||||
`plan_06_s4_proiectare.md` C.1.
|
||||
|
||||
## F. Validare pe cele doua cazuri de regresie
|
||||
|
||||
Rulat direct ca `SELECT` (fara `CREATE VIEW`), corpul propus vs. interogarea de azi din
|
||||
`IncarcaArticoleFactura`, pe `MARIUSM_AUTO`:
|
||||
|
||||
- **`id_vanzare = 1050`** (`cod=1140888`, `tip=1`): **4 randuri**, valori identice rand-cu-rand intre
|
||||
interogarea veche si corpul noului view (`id_vanzare_det` 1584-1587). Coincide cu baza de regresie
|
||||
din `docs\progres.md`.
|
||||
- **`id_vanzare = 1047`** (`cod=1140885`, `tip=-12`): **2 randuri** (1578, 1579), identice intre cele
|
||||
doua interogari.
|
||||
|
||||
Ambele cazuri: zero divergenta, inclusiv pe coloanele cu `NULL` (ex. `id_gestiune`/`nume_gestiune`
|
||||
pe liniile nestocate din `id_vanzare=1047`).
|
||||
|
||||
## G. Numele coloanelor la iesire
|
||||
|
||||
Fara alias-uri noi - toate coloanele pastreaza numele lor de baza din tabelele sursa (Oracle
|
||||
foloseste automat numele coloanei cand nu exista `AS`):
|
||||
|
||||
```
|
||||
ID_VANZARE, ID_VANZARE_DET, ID_ARTICOL, CANTITATE, PRET, PRET_CU_TVA, PROC_TVAV, DISCOUNT_UNITAR,
|
||||
ID_GESTIUNE, CONT, ID_VALUTA, ID_JTVA_COLOANA, SERIE, EXPLICATIE, TAXCODE, LOT, STERS,
|
||||
DENUMIRE, CODMAT, NUME_GESTIUNE, NUME_VAL
|
||||
```
|
||||
|
||||
**Zero schimbari fata de azi** pentru `ControlSource`-urile existente ale `grdArticoleFactura`
|
||||
(`tvd.denumire`, `tvd.codmat`, etc.) - toate numele coincid cu ce se foloseste azi. Singura
|
||||
schimbare vizibila e coloana noua `tvd.id_vanzare`, disponibila dar neconsumata inca de grid.
|
||||
|
||||
## H. Numerotare script
|
||||
|
||||
`SCRIPTURI_CLAR\2026\08\` exista deja, ultimul numar folosit azi (08.08.2026, la momentul
|
||||
verificarii) e **niciunul** - nu exista fisiere `_2026_08_08_` in director (ultimele sunt din
|
||||
06.08.2026, `NN` pana la 12). **`NN=01` e liber pentru 08.08.2026**, comun tuturor prefixelor -
|
||||
de reverificat la momentul aplicarii, pentru ca sesiunea are mai multi agenti activi in paralel azi
|
||||
care ar putea consuma acelasi numar inaintea acestui script.
|
||||
|
||||
Nume final propus: **`ff_2026_08_08_01_COMUN_VVANZARI_ARTICOLE.sql`** - scriptul livrat foloseste deja acest
|
||||
nume in `exec pack_migrare.UpdateVersiune(...)`; daca sesiunea principala aloca alt `NN`, fisierul
|
||||
**si** acel apel trebuie schimbate impreuna (altfel `VERSIUNE` inregistreaza un nume care nu exista
|
||||
pe disc).
|
||||
|
||||
## I. Format script
|
||||
|
||||
`CREATE OR REPLACE VIEW` (fara `FORCE`) - verificat pe modelul cel mai recent din `SCRIPTURI_CLAR`
|
||||
(`ff_2026_08_06_11_COMUN_FACT_VFACTURI.sql`, care creeaza doua view-uri fara `FORCE`); `FORCE` nu e
|
||||
necesar oricum, toate tabelele sursa (`VANZARI_DETALII`, `NOM_ARTICOLE`, `NOM_GESTIUNI`,
|
||||
`NOM_VALUTE`) exista deja. CRLF verificat byte-safe dupa scriere (44 CRLF, 0 LF singur). Fara `;` in
|
||||
comentarii inaintea instructiunii. Se incheie cu `UpdateVersiune` + `commit`.
|
||||
|
||||
## Livrabil
|
||||
|
||||
`D:\ROA\ROAFACTURARE\docs\cercetare\ff_view_articole_vanzare.sql` - scriptul complet, **neaplicat**.
|
||||
|
||||
## Ce trebuie schimbat in VFP ca urmare (doar cand se aplica scriptul)
|
||||
|
||||
1. `COMUN\programe\ofacturare_editare.prg:201-208` (`IncarcaArticoleFactura`): inlocuieste
|
||||
`FROM vanzari_detalii vd LEFT JOIN nom_articole na ... LEFT JOIN nom_gestiuni ng ... LEFT JOIN
|
||||
nom_valute nv ...` cu `FROM vvanzari_articole vd`, pastrand neschimbat `WHERE vd.id_vanzare = ... AND
|
||||
vd.sters = 0` si toata lista de coloane din `SELECT` (numele raman identice).
|
||||
2. Fallback-ul `CREATE CURSOR tvd (...)` (`:214-216`) si duplicatul din `omodificari.vc2` (~14076,
|
||||
semnalate deja ca duplicare in `rec_review_ancorare_s4.md`) **nu se ating** de aceasta schimbare -
|
||||
raman neschimbate structural, doar sursa `SELECT`-ului se simplifica.
|
||||
3. **Opional**, daca se doreste sa se profite de coloana noua `id_vanzare`: nu e necesar niciun
|
||||
consum imediat in VFP - grid-ul nu are nevoie de ea (id-ul e deja cunoscut din parametrul functiei).
|
||||
Reference in New Issue
Block a user