#13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2. Cod: clasa noua ofacturare_util (geometrie si utilitare de formular), inrolata in roafacturare.prg; meniul "Facturare (nou)" plat, cu reparatia literalului peste limita VFP de 255 de caractere care impiedica compilarea metodei. Livrare: changelog 2.11.19, marcajul de versiune DB pentru scripturile finale din SCRIPTURI_CLAR\2026\09, inventarul livrarii in docs/livrare_13.md si registrul de erori deschise. Documentatia de lucru a etapei (cercetare, rapoarte, handoff-uri, snapshot-uri de scripturi si backup-uri de rollback) a fost scoasa din arbore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
This commit is contained in:
@@ -1,325 +0,0 @@
|
||||
# Verificare adversariala — golul ntip=4 si "ramurile de aviz" (contabilizeaza_articol)
|
||||
|
||||
Verifica raportul `docs/cercetare/gol_ntip4_factura_din_avize.md`. Rol: incercare de infirmare,
|
||||
nu confirmare. Toate citatele de mai jos sunt re-verificate direct in aceasta runda pe
|
||||
`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql` (17217 linii) si
|
||||
pe `COMUN\clase\ofacturare.vc2` (ambele copii, `frm_facturare_articole` ~13967-14500 si
|
||||
`frm_facturare_articole2` ~18003-18500). Status: **TERMINAT**.
|
||||
|
||||
## Corectie structurala prealabila — cei "3 apelanti" ai `contabilizeaza_articol` sunt gresit numiti
|
||||
|
||||
Toate rapoartele anterioare (`canal_cont_venit_fara_politica.md:67`, `nota_contabila_fara_politica.md:103`,
|
||||
si implicit raportul verificat) numesc cei 3 apelanti interni `scrie_factura2`,
|
||||
**`scrie_factura_avize_retur`**, `scrie_aviz_retur`. **Gresit pentru al doilea.** Verificare directa
|
||||
pe granitele reale (`PROCEDURE ...` / `END ...`):
|
||||
|
||||
```
|
||||
ff_...:6264 PROCEDURE scrie_factura_avize_retur(... ff_...:6657 END scrie_factura_avize_retur;
|
||||
ff_...:6692 PROCEDURE scrie_factura_avize(... ff_...:7058 END scrie_factura_avize;
|
||||
ff_...:7085 PROCEDURE scrie_aviz_retur(... ff_...:7171 END scrie_aviz_retur;
|
||||
```
|
||||
|
||||
Apelul de la `ff_...:6858` (`pack_facturare.contabilizeaza_articol(tab_detalii(i));`, in interiorul
|
||||
`IF articole_aviz(j).custodie = 1 THEN`) cade **intre 6692 si 7058** — deci apartine lui
|
||||
**`scrie_factura_avize`** (fara `_retur`), nu lui `scrie_factura_avize_retur` (care se termina la
|
||||
6657, cu 200+ linii inainte). `scrie_factura_avize_retur` **nu cheama deloc**
|
||||
`contabilizeaza_articol` — corpul ei (6264-6657) insereaza direct in `VANZARI_DETALII_TEMP` din
|
||||
`VANZARI_DETALII` (randurile avizului sursa deja existente), fara sa treaca prin
|
||||
`adauga_articol_factura` sau `contabilizeaza_articol`.
|
||||
|
||||
**De ce conteaza**: `scrie_factura_avize` e exact handler-ul Oracle pentru `ntip=4` ("facturare din
|
||||
aviz") — apelat din VFP la `ofacturare.vc2:14318` (`Case poDate.Tip = 4`). Deci al doilea apel real
|
||||
catre `contabilizeaza_articol` **e in interiorul propriului handler `ntip=4`** (pentru randurile
|
||||
`custodie=1`), nu intr-un flux separat "avize+retur". Cei 3 apelanti reali sunt:
|
||||
|
||||
| Apel | Procedura reala | Cand se ajunge la ea din VFP |
|
||||
|---|---|---|
|
||||
| `ff_...:6141` | `scrie_factura2` | `Case Inlist(poDate.Tip,3,21,25,28,42,47)` sau `Otherwise` (`ofacturare.vc2:14332,14361`, identic la `:18330,18361`) — calea principala pentru aproape toate tipurile, inclusiv avizele |
|
||||
| `ff_...:6858` | `scrie_factura_avize` | `Case poDate.Tip = 4` (`:14301,14318`) — doar pentru randurile `custodie=1` ale unei facturi din aviz |
|
||||
| `ff_...:7140` | `scrie_aviz_retur` | **Niciun apel gasit in `COMUN\` din VFP** (`Grep` pe tot `COMUN` si pe tot proiectul — zero rezultate in cod, doar in rapoarte). Posibil cod mort/apelat din alt produs; nu afecteaza verdictele de mai jos, pentru ca `scrie_factura2` singura e suficienta sa dovedeasca A1a. |
|
||||
|
||||
Corectia nu schimba verdictul general al A1a (avizele *ajung* la `contabilizeaza_articol`), dar
|
||||
schimba **prin ce drum** — relevant pentru oricine ar urma sa scrie cod pe baza acestor rapoarte.
|
||||
|
||||
## A1. Ramurile de AVIZ raman atinse si ramura noua le-ar scrie SCD gresit
|
||||
|
||||
**Verdict: CONFIRMAT, dar mai ingust decat sustine raportul.**
|
||||
|
||||
### A1a. Ajunge `contabilizeaza_articol` sa fie apelata pe un AVIZ?
|
||||
|
||||
**DA, confirmat**, prin `scrie_factura2`. Ruta VFP (`ofacturare.vc2:14282-14389`, identic la
|
||||
`:18enable...`, verificata in ambele copii ale formularului):
|
||||
|
||||
```
|
||||
Case poDate.eProforma = 1 -> scrie_proforma
|
||||
Case poDate.Tip = 4 -> scrie_factura_avize && facturare din aviz
|
||||
Case Inlist(poDate.Tip,3,21,25,28,42,47) -> scrie_factura2 && din comenzi / avize din comenzi
|
||||
Otherwise -> scrie_factura2 && tot restul (incl. 29, 22, 24, 27...)
|
||||
```
|
||||
|
||||
In interiorul `scrie_factura2` (`ff_...:6072-6142`), CASE-ul propriu **intercepteaza unele `ntip`
|
||||
inainte** de a ajunge la `contabilizeaza_articol`:
|
||||
|
||||
```
|
||||
WHEN ntip IN (23,25,30,41) THEN transfera_articol(...) -- NU contabilizeaza_articol
|
||||
WHEN ntip IN (42,47) THEN descarca_gestiune(...) direct -- NU contabilizeaza_articol
|
||||
WHEN ntip IN (2,6,52) AND id_rata<>0 THEN contabilizeaza_rata(...)
|
||||
ELSE contabilizeaza_articol(...) -- aici ajung 28, 29, 21, 22, 24, 27, 3, ...
|
||||
```
|
||||
|
||||
Deci `ntip=28` si `ntip=29` **chiar ajung** la `contabilizeaza_articol` (prin `scrie_factura2`, ramura
|
||||
`ELSE`) — asta confirma miezul A1a. Dar `ntip IN (23,25,30,41,42,47)`, desi trec prin `scrie_factura2`
|
||||
(sunt in lista VFP `Inlist(3,21,25,28,42,47)`), **nu ajung niciodata** la `contabilizeaza_articol` —
|
||||
sunt deviate mai devreme, in CASE-ul propriu al lui `scrie_factura2`, spre `transfera_articol`/
|
||||
`descarca_gestiune`. Vezi corectia la sectiunea 3 (tabelul per-`ntip`).
|
||||
|
||||
### A1b. Poate un articol fara politica sa fie adaugat pe un aviz?
|
||||
|
||||
**DA, confirmat structural**, pe doua cai distincte in `adauga_articol_factura` (`ff_...:5052-5203`):
|
||||
|
||||
- `WHEN ntip IN (3,21,28,42,47)` (`:5053-5078`): cauta in `COMENZI_ELEMENTE` dupa
|
||||
`ID_COMANDA + ID_ARTICOL + PRET` — **fara nicio referinta la `V_ID_POL`** in `WHERE`. Un articol
|
||||
fara politica poate gasi potrivire aici daca exista elementul de comanda corespunzator (comanda +
|
||||
articol + pret identice), indiferent de politica. **Fara handler `EXCEPTION`** — la fel ca ramura
|
||||
`ntip=4`, dar aici absenta handler-ului nu conteaza pentru `id_pol`, pentru ca filtrul nu-l
|
||||
foloseste.
|
||||
- `ELSE` (`:5187-5203`, bucket-ul implicit pentru orice `ntip` neacoperit de ramurile speciale —
|
||||
include `29` si restul avizelor "simple"): **nicio interogare legata de politica** — ia direct
|
||||
`V_PRET_TEMP`/`V_ID_VALUTA_TEMP`/`V_PRETURI_CU_TVA_TEMP`/`V_IN_STOC_TEMP` (valorile deja calculate
|
||||
de VFP), plus o singura `SELECT` pe `JTVA_COLOANE` dupa `V_ID_JTVA_COLOANA` (nimic legat de
|
||||
`id_pol`). **Zero obstacol** pentru un articol fara politica pe aceasta ramura.
|
||||
|
||||
Nu am gasit (si nu am cautat exhaustiv, la fel ca raportul original) formularul VFP concret care ar
|
||||
adauga azi un articol ad-hoc fara politica pe un aviz — premisa ramane, ca si in raportul original,
|
||||
mostenita din proiectul #13 (`canal_cont_venit_fara_politica.md`), nu re-derivata aici. Ce am putut
|
||||
confirma exhaustiv e partea Oracle: **daca** VFP trimite `V_ID_POL=NULL` pe aceste `ntip`, Oracle nu
|
||||
pune nicio piedica.
|
||||
|
||||
### A1c. `SCD` in blocul `:7398-7423` — hardcodat sau derivat?
|
||||
|
||||
Citit integral (`ff_...:7398-7423`), confirmat identic cu citatul raportului, **linie cu linie**:
|
||||
|
||||
```
|
||||
ff_...:7400-7406 WHEN ntip<=20 OR ntip IN (nTipFacturaHotel,nTipFacturaRestaurant,
|
||||
nTipNotaPlata,nTipVanzareRetail,48,49,51,52) THEN
|
||||
V_SCD := crs_rand_articol.scd; -- din politica (NOTE_CONTABILE.SCD)
|
||||
ff_...:7413-7417 WHEN ntip IN (28,29) THEN
|
||||
V_SCD := '461'; -- HARDCODAT, aviz catre clienti debitori
|
||||
ff_...:7418-7422 ELSE
|
||||
V_SCD := '418'; -- HARDCODAT, aviz generic
|
||||
```
|
||||
|
||||
`V_SCC` (linia 7425) vine mereu din `crs_rand_articol.scc` (coloana notei de vanzari), **indiferent
|
||||
de ramura** — CASE-ul de mai sus decide doar `V_SCD`. Confirmat: hardcodarea exista exact cum spune
|
||||
raportul, fara offset de linie.
|
||||
|
||||
**Nuanta importanta, omisa de raport**: proiectarea `canal_cont_venit_fara_politica.md:146` (sursa
|
||||
ramurii noi) **flagheaza deja, printr-o paranteza**, ca "ramurile aviz raman `'418'`/`'461'`, deja
|
||||
hardcodate azi la `ff_...:7415,7420`, independent de politica" — deci designul **e constient** de
|
||||
existenta acestor hardcodari si de faptul ca ar trebui pastrate, dar **nu da structura de cod
|
||||
concreta** (niciun `IF`/`CASE` pe `ntip` in tabelul "Continutul ramurii noi", sectiunea 3) care sa
|
||||
implementeze efectiv acea pastrare. Raportul verificat prezinta acest lucru ca pe o **descoperire
|
||||
noua** ("Gol sora... gasit in aceasta cercetare") — de fapt designul deja stia de riscul general, dar
|
||||
nu-l rezolvase in cod. Concluzia practica ramane aceeasi (ramura noua, asa cum e descrisa azi in
|
||||
proiectare, chiar ar hardcoda `SCD='4111'` fara conditionare pe `ntip` daca ar fi implementata
|
||||
literal dupa tabelul din sectiunea 3), dar caracterizarea "gol nou, neconsemnat" e inexacta.
|
||||
|
||||
### Corectie la tabelul per-`ntip` din raport (sectiunea 3)
|
||||
|
||||
Raportul marcheaza `IN (28,29)` **si** "toate celelalte (`21,22,23,24,25,27,30,41,42,47,...`)" ca
|
||||
"Atinsa: DA". Pe baza rutarii reale prin `scrie_factura2` (A1a de mai sus):
|
||||
|
||||
| `ntip` | Ajunge la `contabilizeaza_articol`? | Motiv |
|
||||
|---|---|---|
|
||||
| `28`, `29` | **DA** | `scrie_factura2` -> `ELSE` -> CASE intern `ntip IN(28,29)` -> `SCD='461'` |
|
||||
| `21`, `22`, `24`, `27`, `3` si alte "otherwise" nespeciale | **DA** (probabil) | cad in `ELSE` al lui `scrie_factura2` -> `ELSE` intern -> `SCD='418'` |
|
||||
| `23`, `25`, `30`, `41` | **NU** | interceptate in `scrie_factura2` de `WHEN ntip IN(23,25,30,41) THEN transfera_articol(...)` — nu ajung niciodata la `contabilizeaza_articol` prin acest apelant |
|
||||
| `42`, `47` | **NU** | interceptate de `WHEN ntip IN(42,47) THEN descarca_gestiune(...) direct` — la fel, nu ajung |
|
||||
|
||||
Golul real e deci mai ingust decat "orice aviz": se limiteaza la avizele care cad in ramura `ELSE` a
|
||||
lui `scrie_factura2` (28, 29, si restul avizelor "simple" neexcluse), nu la `23,25,30,41,42,47`, care
|
||||
sunt structural neatinse de `contabilizeaza_articol` prin singurul apelant confirmat. (Nu exclud ca
|
||||
`scrie_aviz_retur`, al carei apelant VFP nu l-am gasit, sa trateze si aceste `ntip` — dar cum nu exista
|
||||
dovada ca e apelata deloc, nu pot confirma nici infirma pentru ea.)
|
||||
|
||||
## A2. Golul `ntip=46` (`nTipNotaPlata`) — `scrie_nota` sarita azi
|
||||
|
||||
**Verdict: CONFIRMAT.**
|
||||
|
||||
- Constanta: `ff_...:84 nTipNotaPlata VANZARI.TIP%TYPE := 46;` — **exact 46**, verificat direct, nu
|
||||
presupus.
|
||||
- Garda: `ff_...:7441 IF pack_facturare.nTip <> pack_facturare.nTipNotaPlata THEN` — inainte de
|
||||
apelul `scrie_nota` (`:7443-7467`) — citat exact, linie identica cu raportul.
|
||||
- Poate un `ntip=46` sa primeasca un articol fara politica? **DA**, prin acelasi bucket `ELSE`
|
||||
(`ff_...:5187-5203`) al `adauga_articol_factura` verificat la A1b — `nTipNotaPlata` nu e in niciuna
|
||||
din ramurile speciale (`3,21,28,42,47`, `4`, `45`, `V_OPT_FACTURARE=3`), deci cade in `ELSE`, care
|
||||
nu cere `id_pol` deloc.
|
||||
- Ajunge la `contabilizeaza_articol`? **DA** — `ntip=46` nu e proforma, nu e `Tip=4`, nu e in
|
||||
`Inlist(3,21,25,28,42,47)` -> `Otherwise` -> `scrie_factura2` -> nu e in `(23,25,30,41)`/`(42,47)`/
|
||||
`(2,6,52)` -> `ELSE` -> `contabilizeaza_articol`.
|
||||
- Ramura noua (per `canal_cont_venit_fara_politica.md` sectiunea 3, pasul 1 "Apeluri, o singura data
|
||||
fiecare") descrie apelul `scrie_nota` **fara** sa mentioneze garda `ntip<>nTipNotaPlata` — deci, asa
|
||||
cum e scrisa azi proiectarea, ar apela necondiționat `scrie_nota` pentru un document `NotaPlata` cu
|
||||
linie `cont_venit`. Gol real, bine argumentat de raport.
|
||||
|
||||
## A3. `ntip=4` exclus prin `NO_DATA_FOUND` neprins la `adauga_articol_factura`
|
||||
|
||||
**Verdict: CONFIRMAT**, cu toate liniile citate verificate exact, fara offset:
|
||||
|
||||
- `ff_...:5080-5103` — ramura `WHEN ntip=4`, `WHERE A.ID_POL = V_ID_POL` (linia 5096 exact), fara
|
||||
`EXCEPTION`. Confirmat caracter cu caracter identic cu citatul raportului.
|
||||
- Semantica SQL `NULL = NULL` -> `UNKNOWN`, niciodata `TRUE`: standard, corect.
|
||||
- **Ordinea de apel confirmata direct pe VFP**: `do_scrie_articole` (`ofacturare.vc2:13967`) cheama
|
||||
`initializeaza_date_factura` (seteaza `ntip`), apoi in bucla `Scan` peste `crsfactura` cheama
|
||||
`adauga_articol_factura` (`:14069-14091`) pentru fiecare rand — **toate acestea ruleaza inainte** de
|
||||
`Do Case` (`:14282`) care alege `scrie_factura_avize`/`scrie_factura2`/etc. Deci un articol cu
|
||||
`V_ID_POL=NULL` pe `ntip=4` cade la `adauga_articol_factura` **inainte** ca `scrie_factura_avize` sa
|
||||
fie chemata — linia nu ajunge niciodata la `contabilizeaza_articol`. Confirma independent
|
||||
concluzia raportului.
|
||||
- **Semantica VFP `Nvl(Alltrim(Str(poArt.id_pol)),[NULL])`** (`ofacturare.vc2:14072`, identic
|
||||
`:18107`): in Visual FoxPro, `Str()` si `Alltrim()` **propaga `.NULL.`** cand primesc `.NULL.` ca
|
||||
argument (comportament standard, documentat al limbajului — orice functie "null-aware" aplicata pe
|
||||
`.NULL.` intoarce `.NULL.`, nu eroare si nu `"0"`). `Nvl(.NULL., [NULL])` inlocuieste explicit cu
|
||||
literalul caracter `NULL` (4 caractere), care ajunge **necotat** in textul SQL generat (concatenare
|
||||
directa, fara ghilimele in jur) — deci Oracle il interpreteaza ca si cuvantul-cheie `NULL`, nu ca
|
||||
string. Rezultat: `V_ID_POL` ajunge `NULL` in Oracle exact cand `poArt.id_pol` e `.NULL.` in VFP.
|
||||
Verificare bazata pe semantica standard VFP (nu am putut rula VFP live — masina partajata, conform
|
||||
interdictiei) — consistenta si cu tiparul deja folosit identic pentru alti parametri opționali pe
|
||||
acelasi apel (`id_gestiune`, `id_valuta_d`, `id_part_rez` etc., toate cu acelasi `Nvl(Alltrim(Str(...`).
|
||||
- **Neverificat** (nici in raportul original, nici aici): cum ajunge efectiv `poArt.id_pol` sa fie
|
||||
`.NULL.` pentru un articol fara politica — ramane premisa mostenita din proiectul #13, nu
|
||||
re-derivata in aceasta runda.
|
||||
|
||||
## A4. Numerele de linie — offset +17 sau identice?
|
||||
|
||||
**Verdict: NICIUNA din cele doua afirmatii e o regula generala — depinde de setul de citate comparat.**
|
||||
|
||||
- **Pentru citatele proprii ale raportului verificat** (re-testate direct aici): `adauga_articol_factura`
|
||||
header `:4989-5015`, ramura `ntip=4` `:5080-5103`, `contabilizeaza_articol` header `:7173`, CASE
|
||||
`:7398-7423`, hardcode `:7413-7422`, garda `:7441`, `nTipNotaPlata:=46` la `:84` — **toate identice**,
|
||||
zero offset. Raportul are dreptate pentru propriile sale citate.
|
||||
- **Dar exista un offset real, doar ca nu e +17 ci +9**, intre citatele mai vechi din
|
||||
`nota_contabila_fara_politica.md:100-104` (`ff_...:6150`, `:6867`, `:7149` pentru cele 3 apeluri
|
||||
`contabilizeaza_articol`) si pozitiile reale confirmate in aceasta runda pentru **aceleasi** apeluri
|
||||
(`6141`, `6858`, `7140`) — diferenta consecventa de **9 linii**, nu 17, si in directia opusa
|
||||
(citatul vechi e mai mare, nu mai mic).
|
||||
- Concluzia corecta: fisierul `PACK_FACTURARE.sql` a fost re-exportat de mai multe ori pe parcursul
|
||||
proiectului (cod adaugat/sters intre versiuni), asa ca **fiecare set de citate vechi are propriul
|
||||
offset fata de exportul curent — nu exista o constanta universala (nici 0, nici +17, nici +9)**.
|
||||
`handoff_13_formular_unificat.md:190` ("+17") si acest raport ("identic, fara offset") sunt ambele
|
||||
adevarate **doar pentru seturile de citate pe care le-au verificat fiecare** — nu se pot generaliza
|
||||
una peste alta. Disciplina corecta, pe care ambele rapoarte au respectat-o, e re-verificarea directa
|
||||
pe fisierul curent inainte de orice citare — nu presupunerea unui offset fix.
|
||||
|
||||
## Text de plan corectat (sectiunea 4 din raportul verificat, rescris)
|
||||
|
||||
```
|
||||
**Ramura `ntip=4` (facturare din avize, handler real `scrie_factura_avize:6692-7058`, nu
|
||||
`scrie_factura_avize_retur` cum apare gresit in rapoartele anterioare) — exclusa structural, nu
|
||||
necesita cod suplimentar.** `adauga_articol_factura`, ramura `WHEN ntip=4` (`:5080-5103`), cauta
|
||||
randul sursa din `VANZARI_DETALII` prin `A.ID_POL = V_ID_POL`, fara handler de exceptie — cu
|
||||
`V_ID_POL=NULL` (exact cazul liniei fara politica), comparatia nu se poate potrivi niciodata, deci
|
||||
apelul cade cu `ORA-01403` la adaugarea articolului, in bucla `do_scrie_articole` (`ofacturare.vc2:
|
||||
13967-14106`), care ruleaza intotdeauna inaintea `Do Case`-ului (`:14282`) ce ar chema
|
||||
`scrie_factura_avize`. Un articol fara politica nu poate fi, structural, adaugat pe un document
|
||||
`ntip=4`; ramura noua `cont_venit` nu are nimic de tratat aici.
|
||||
|
||||
**Gol confirmat, de acoperit inainte de implementare — mai ingust decat s-a crezut initial**:
|
||||
ramurile de aviz care **efectiv** ajung la `contabilizeaza_articol` prin singurul apelant confirmat
|
||||
functional (`scrie_factura2`, apelat pentru `Inlist(3,21,25,28,42,47)` si pentru toate celelalte
|
||||
tipuri prin `Otherwise`) sunt cele care cad in `ELSE`-ul CASE-ului propriu al `scrie_factura2`:
|
||||
`ntip IN (28,29)` -> `SCD='461'`, restul (`21,22,24,27` si alte "otherwise" avize) -> `SCD='418'`
|
||||
(`:7413-7422`). **`ntip IN (23,25,30,41,42,47)` NU ajung la `contabilizeaza_articol`** prin acest
|
||||
apelant — sunt deviate mai devreme, in `scrie_factura2` insasi, spre `transfera_articol`/
|
||||
`descarca_gestiune`, deci golul nu li se aplica (contabilizeaza_articol si ramura ei noua nu se
|
||||
executa niciodata pentru ele). `adauga_articol_factura` nu cere `id_pol` pentru niciunul din aceste
|
||||
`ntip` (foloseste calea "din comenzi", fara filtru pe `id_pol`, sau calea implicita `ELSE`, fara nicio
|
||||
interogare legata de politica) — deci un articol fara politica poate ajunge pe oricare din avizele
|
||||
`28,29,21,22,24,27` cu `cont_venit` populat. Designul deja semnalase acest risc printr-o paranteza
|
||||
(`canal_cont_venit_fara_politica.md:146`, "ramurile aviz raman 418/461"), dar nu-l implementase: ramura
|
||||
noua trebuie sa aleaga `SCD` in functie de `ntip` (pastrand `'461'` pentru `IN(28,29)`, `'418'` pentru
|
||||
restul avizelor atinse), nu sa hardcodeze `'4111'` necondiționat.
|
||||
|
||||
**Gol confirmat separat**: ramura noua trebuie sa pastreze garda `IF ntip <> nTipNotaPlata` (`ntip=46`,
|
||||
`ff_...:7441`) inainte de a apela `scrie_nota` — azi sarita intentionat pentru documentele de tip
|
||||
"nota de plata", iar un articol fara politica poate fi adaugat si pe acest tip de document
|
||||
(`adauga_articol_factura`, bucket `ELSE`, fara cerinta de `id_pol`).
|
||||
|
||||
**Defensiv (opțional)**: se poate adauga o garda explicita `IF cont_venit IS NOT NULL AND ntip = 4
|
||||
THEN RAISE_APPLICATION_ERROR(...)`, dar e demonstrat redundanta — cazul e deja imposibil pe caile VFP
|
||||
cunoscute, blocat cu doua straturi independente inainte de a ajunge la `contabilizeaza_articol`.
|
||||
```
|
||||
|
||||
## Ce nu s-a putut stabili in aceasta runda (mostenit din raportul original, nu re-rezolvat)
|
||||
|
||||
- Cum ajunge `poArt.id_pol` sa fie `.NULL.` in VFP pentru un articol fara politica pe un aviz —
|
||||
premisa proiectului #13, nu re-derivata.
|
||||
- Cine cheama `scrie_aviz_retur` (daca cineva) — cautare exhaustiva in `COMUN\` si in tot proiectul,
|
||||
zero rezultate; posibil cod mort sau apelat din alt produs al suitei ROA.
|
||||
- Comportamentul exact `goExecutor`/`oPrelucrareEroare()` la o exceptie Oracle neprinsa — nu urmarit
|
||||
in aceasta runda (mostenit ca gol si in raportul original).
|
||||
|
||||
## Handoff
|
||||
|
||||
Verificare incheiata, toate cele 4 afirmatii + corectia structurala preliminara sunt in sectiunile de
|
||||
mai sus. Zero cod atins, zero write-back, doar `SELECT`/`Read`/`Grep` pe SQL si VFP text. Context
|
||||
consumat substantial (citire extinsa pe `ff_...sql` si `ofacturare.vc2`), dar verificarea s-a incheiat
|
||||
inainte de pragul de predare.
|
||||
|
||||
---
|
||||
|
||||
## Propagarea `CONT_VENIT` prin cei trei apelanti — verificare
|
||||
|
||||
Intrebare noua de la team-lead: argumentul central al proiectarii (`canal_cont_venit_fara_politica.md`,
|
||||
sectiunea 1, `:63-69`) — "orice coloana noua pe `VANZARI_DETALII_TEMP` ajunge automat in
|
||||
`detalii_articol`, fara sa atingi cei 3 apelanti, pentru ca fac `SELECT * BULK COLLECT` intr-un
|
||||
`TABLE OF ...%ROWTYPE`" — se bazeaza pe lista de nume deja corectata mai sus. Verificat acum pe
|
||||
numele **reale** ale celor 3 apelanti (`scrie_factura2`, `scrie_factura_avize`, `scrie_aviz_retur`),
|
||||
fiecare citit direct, linie cu linie, in aceasta runda.
|
||||
|
||||
### 1-2. `scrie_factura2` (`:6020-6223`)
|
||||
|
||||
```
|
||||
ff_...:6039-6040 TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
|
||||
tab_detalii tab_detalii_type;
|
||||
ff_...:6063 SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
|
||||
ff_...:6141 pack_facturare.contabilizeaza_articol(tab_detalii(i));
|
||||
```
|
||||
**`SELECT *` intr-un `TABLE OF VANZARI_DETALII_TEMP%ROWTYPE`, confirmat.** `CONT_VENIT` curge automat.
|
||||
|
||||
### 1-2. `scrie_factura_avize` (`:6692-7058`, handler-ul real `ntip=4`)
|
||||
|
||||
```
|
||||
ff_...:6708-6709 TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
|
||||
tab_detalii tab_detalii_type;
|
||||
ff_...:6749 SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
|
||||
ff_...:6858 pack_facturare.contabilizeaza_articol(tab_detalii(i)); -- doar pt. custodie=1
|
||||
```
|
||||
**Acelasi tipar: `SELECT *` in `TABLE OF VANZARI_DETALII_TEMP%ROWTYPE`, confirmat.** Intre populare
|
||||
(`:6749`) si apelul catre `contabilizeaza_articol` (`:6858`), randul `tab_detalii(i)` e modificat doar
|
||||
pe doua campuri (`.cantitate`, `.id_rata`, `:6855-6856`) — `CONT_VENIT` ramane neatins, curge automat.
|
||||
Chiar daca numele apelantului real difera de ce credea proiectarea, **concluzia ei ("nu se ating deloc")
|
||||
ramane corecta pentru acest apelant**, doar numele era gresit.
|
||||
|
||||
### 3. `scrie_aviz_retur` (`:7085-7171`)
|
||||
|
||||
```
|
||||
ff_...:7097-7098 TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
|
||||
tab_detalii tab_detalii_type;
|
||||
ff_...:7106 SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
|
||||
ff_...:7140 pack_facturare.contabilizeaza_articol(tab_detalii(i)); -- doar pt. custodie=0 (ELSE la :7115)
|
||||
```
|
||||
**Acelasi tipar, confirmat.** Nu conteaza ca nu i-am gasit apelant VFP (ramane nedovedit ca se
|
||||
executa vreodata) — *daca* s-ar executa, `CONT_VENIT` ar curge automat si aici, deci nu schimba
|
||||
suprafata diff-ului indiferent de raspuns.
|
||||
|
||||
### Verdict pe argumentul proiectarii
|
||||
|
||||
**Se salveaza.** Toti cei 3 apelanti reali (nu cei numiti gresit in rapoartele anterioare) folosesc
|
||||
identic `SELECT * BULK COLLECT INTO <TABLE OF VANZARI_DETALII_TEMP%ROWTYPE> FROM VANZARI_DETALII_TEMP`
|
||||
— zero lista explicita de coloane, zero `%ROWTYPE` pe alta tabela, zero constructie camp-cu-camp.
|
||||
Concluzia proiectarii ("adaugi coloana pe `VANZARI_DETALII_TEMP`, `contabilizeaza_articol` o vede
|
||||
automat prin toti apelantii, fara sa atingi `scrie_factura2`/`scrie_factura_avize`/`scrie_aviz_retur`")
|
||||
**e corecta ca mecanism**, chiar daca doua din cele trei nume citate pentru ea erau gresite. Corectia
|
||||
de nume nu schimba nimic la suprafata de regresie a schemei — schimba doar la ce trebuie sa te uiti
|
||||
daca vreodata unul dintre cei trei apelanti isi schimba modul de populare a lui `tab_detalii`.
|
||||
Reference in New Issue
Block a user