13 KiB
Garda "aviz deja facturat" — verificare pe cod
Verificare pe cod, fara nicio modificare de fisier. Sursele citate:
- export pachet:
D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql(mai jos:EXPORT:<linie>); - corpul desfasurat pe DB (
MARIUSM_AUTO@ROA_CENTRAL,all_source), citit ca sa se confirme ca ce e in export e si ce ruleaza (mai jos:DB PACK_FACTURARE:<linie>). Numerotarea difera:sterge_facturaincepe laEXPORT:5432, dar laDB PACK_FACTURARE:4192. Nu exista offset constant; textul insa e identic cuvant cu cuvant pe zona gardelor.
1. Blocheaza garda de azi si un AVIZ care are deja factura generata din el?
DA. Nu e nevoie de nicio garda noua pentru cazul asta — este exact ce testeaza a doua garda din
sterge_factura, prin TIP IN (1, 2).
EXPORT:5464-5476 = DB PACK_FACTURARE:4224-4236:
-- ptr. un aviz normal:
-- verific daca exista facturi sau avize de retur pe avizul resp.
SELECT COUNT(*)
INTO V_NR_AVIZE_FACT
FROM VANZARI_CORESP
WHERE STERS = 0
AND ID_VANZARE_AVIZ = V_ID_VANZARE
AND TIP IN (1, 2);
IF V_NR_AVIZE_FACT > 0 THEN
RAISE_APPLICATION_ERROR(-20000,
'Pe acest aviz s-au emis facturi / aviz de retur. Trebuie sa stergeti mai intai facturile / avizul de retur!');
END IF;
Cheia e semantica lui TIP, citita din singurul scriitor al tabelei, ramura cu ramura
(finalizeaza_factura, EXPORT:14818-14839):
VANZARI_CORESP.TIP |
scris cand | ID_VANZARE_FACT |
ID_VANZARE_AVIZ |
e retur? |
|---|---|---|---|---|
| 1 | ntip = 4 — facturare din aviz (EXPORT:14823-14826) |
factura | avizul-sursa | NU |
| 2 | ntip = 24 — aviz de retur (EXPORT:14828-14830) |
avizul de retur | avizul original | DA |
| 3 | ntip in (8, 9) — factura de retur (EXPORT:14834-14836) |
factura de retur | factura originala | DA |
Deci TIP = 1 este corespondenta aviz -> factura normala, nu retur. Garda de la EXPORT:5473
prinde ambele cazuri; textul mesajului chiar o spune ("s-au emis facturi / aviz de retur").
Formularea din brief ("garda de azi blocheaza documentul care are facturi/avize de retur") vine
dintr-o citire a comentariului -- verific daca exista facturi sau avize de retur in care "de retur"
se distribuie si peste "facturi"; codul zice altceva.
Deci: la ora asta, exact regula ceruta de decizia 50 este deja implementata pentru avize (document cu urmasi = blocat; capatul lantului = liber).
Ce NU citeste garda
VANZARI.FACTURATnu e citit de nicio garda. Pe calea de stergere e doar scris (EXPORT:5504-5510pentruV_TIP = 24,EXPORT:5527-5533pentruV_TIP = 4— resetare la 0 cand dispare factura/avizul de retur), iar la facturare e pus demarcheaza_facturat(EXPORT:15381-15418). NiciunIF/RAISEnu il interogheaza. Semnalul autoritar esteVANZARI_CORESP,FACTURATe derivat redundant.ID_VANZARE_SURSA/ID_VANZARE_DESTnu exista.VANZARI_CORESPare exact 5 coloane (interogare peall_tab_columns):ID_VANZARE_CORESP,ID_VANZARE_FACT,ID_VANZARE_AVIZ,STERS,TIP. NiciVANZARInu are coloane*_SURSA/*_DEST(aceeasi interogare).
2. Exista alte garzi pe calea de stergere / modificare?
2a. Oracle — nu exista alta, dar garda e atinsa pe ambele ramuri de stergere
Interogare pe all_source (owner curent): singurele obiecte care contin VANZARI_CORESP sunt
PACK_FACTURARE (package body) si TRG_VANZARI_CORESP_BEFOINS. Deci nu exista o a doua
garda ascunsa in alt pachet.
Triggerele nu contin garzi (sursa citita integral din all_source):
| trigger | tabela | eveniment | ce face |
|---|---|---|---|
TRG_VANZARI_BEFOUPD |
VANZARI |
UPDATE | 4 apeluri pack_audit.verifica_val (NR_ACT, SERIE_ACT, DATA_ACT, DATA_SCAD) — audit, nu blocare |
TRG_VANZARE_BEFOINS |
VANZARI |
INSERT | — |
TRG_VANZARI_DET_BEFOINS |
VANZARI_DETALII |
INSERT | — |
TRG_VANZARI_CORESP_BEFOINS |
VANZARI_CORESP |
INSERT | doar SEQ_VANZARI_CORESP.nextval |
Punct important de verificat, pentru ca la prima citire pare o portita: in
frm_facturi.do_sterge apelul direct pack_facturare.sterge_factura e comentat pe ramura
documentelor cu note contabile — ofacturare_comun.vc2:4807-4809 (*!* modificare v 2.2.5), iar
ramura activa (:4810-4811) cheama numai pack_contafin.finalizeaza_stergere_nota. Nu e o
portita: lantul se inchide in Oracle.
PACK_CONTAFIN:8322-8326 SELECT COUNT(*) INTO lnEInVanzari FROM vanzari WHERE cod = tnCod;
IF lnEInVanzari > 0 THEN
pack_facturare.sterge_din_vanzari(tnCod, tnAn, tnLuna, tnIdUtil);
PACK_FACTURARE:14996-14998 SELECT ID_VANZARE INTO V_ID_VANZARE FROM VANZARI WHERE COD = V_COD;
pack_facturare.sterge_factura(V_ID_VANZARE, V_LUNA, V_AN, V_ID_UTIL);
Apelantii lui sterge_factura in baza (cautare pe all_source) sunt exact doi:
PACK_FACTURARE.sterge_din_vanzari (DB PACK_FACTURARE:14998) si procedura standalone
STERGE_DOCUMENT (DB STERGE_DOCUMENT:416). Ambele cai trec prin garda.
2b. VFP — pe calea de stergere: nicio garda pe urmasi
frm_facturi.do_sterge (COMUN\clase\ofacturare_comun.vc2:4661-4877) verifica, inainte de apel:
luna inchisa (:4676), sters = 1 (:4689), confirmare (:4694), luna curenta (:4701) si
referinte de incasari/plati (ReferinteDocumenteNota, :4723-4727). Nimic despre FACTURAT,
VANZARI_CORESP sau urmasi — verificarea lantului e delegata integral Oracle-ului.
2c. VFP + Oracle — pe calea de modificare: nicio garda, nici pe urmasi, nici pe lant
frm_facturi.do_modifica (ofacturare_comun.vc2:4541-4640) blocheaza doar doua lucruri
(:4590, :4635):
If poRec.sters = 0 AND NVL(m.pnEFactura,0) = 0
...
amessagebox("Nu puteti face modificari pe inregistrarile sterse sau facturile trimise in eFactura!", 48, "Atentie")
pack_facturare.modifica_date_factura (EXPORT:14439-14509) e un lant de UPDATE-uri fara niciun
IF de validare si fara niciun RAISE_APPLICATION_ERROR. Ceea ce e coerent cu ce modifica azi
(ruta, delegat, agent, masina, dataora exp., text aditional, tip SAFT, eFactura, serie/numar/data act,
data scadenta) — campuri de antet care nu ating lantul aviz -> factura.
3. Concluzia operationala pentru decizia 50 / S7
Regula ceruta de decizia 50 exista deja, si nu are gol pe aviz. sterge_factura implementeaza
azi, in trei garzi consecutive, exact "documentul cu urmasi e blocat, capatul lantului e liber":
| garda | EXPORT |
ce blocheaza |
|---|---|---|
| 1 | 5452-5462 | factura care are facturi de retur peste ea (TIP = 3) |
| 2 | 5466-5476 | aviz care are factura (TIP = 1) sau aviz de retur (TIP = 2) peste el |
| 3 | 5480-5494 | factura din aviz ale carei avize-sursa au primit intre timp aviz de retur |
A treia garda merita subliniata pentru decizia 50: factura din aviz e editabila doar cat timp niciunul dintre avizele ei nu are aviz de retur; nu e "capat de lant" neconditionat.
Deci S7 nu are nevoie de o garda noua ca regula — dar are nevoie de o citire noua a aceleiasi
conditii, ca moment. Garda de azi e in interiorul lui sterge_factura, adica se manifesta ca
ORA-20000 in mijlocul pasului de stergere din regenerare, dupa ce utilizatorul a completat
formularul si dupa ce s-a deschis tranzactia. Pentru un flux de editare asta e o esuare tarzie.
Ce lipseste e un pre-flight read-only, inainte de intrarea in formular, pe exact aceeasi
conditie (fara reimplementarea regulii):
select count(*) from vanzari_coresp
where sters = 0 and id_vanzare_aviz = :id_vanzare and tip in (1, 2, 3)
plus, pentru cazul "factura din aviz", subinterogarea din garda 3 (EXPORT:5480-5488). Garda din
sterge_factura ramane pe loc ca plasa de siguranta — nu se muta, nu se slabeste.
Interogarea se face pe VANZARI_CORESP, nu pe VANZARI.FACTURAT: FACTURAT e un marcaj
redundant, derivat, scris/resetat de marcheaza_facturat / sterge_factura, si necitit de nicio
garda; VANZARI_CORESP e semnalul autoritar.
4. Inventar: ce tipuri de documente-parinte produc urmasi prin VANZARI_CORESP?
Doar trei, toate scrise din acelasi CASE din finalizeaza_factura (EXPORT:14818-14839), prin
singurul scriitor scrie_corespondente_vanzari (EXPORT:15481-15516, singurul INSERT INTO VANZARI_CORESP din tot pachetul — si din toata baza, cf. all_source).
| parinte | urmas | TIP |
de unde vine lista parintilor |
|---|---|---|---|
aviz (VANZARI.TIP in 21, 22, 26, 42) |
factura din aviz (ntip = 4) |
1 | clistaid_avize, setat la EXPORT:7037 in scrie_factura_avize; lista o construieste VFP prin caut_avize, filtrata a.tip in (21,22,26,42) and a.facturat = 0 — COMUN\programe\oproceduri_facturare.prg:2036-2038 |
| aviz | aviz de retur (ntip = 24) |
2 | clistaid |
| factura | factura de retur (ntip in 8, 9) |
3 | clistaid |
Ce NU produce urmasi prin VANZARI_CORESP (deci decizia 50 nu are acoperire acolo prin garda
existenta):
- proforma -> factura. Proforma sta in
VANZARIcuEPROFORMA = 1;finalizeaza_facturanu are ramura care sa scrie corespondenta pentru ea.TIP = 4este o propunere de la S5c, nu cod existent. Mai mult,pack_facturare.sterge_proforma(EXPORT:5610-5635) nu are nicio garda — corpul ei e doar douaUPDATE ... SET STERS = 1peVANZARIsiVANZARI_DETALII. O proforma din care s-a emis factura se poate sterge azi fara niciun avertisment. (Calea VFP:ofacturare_comun.vc2:4707-4719, care iese dindo_stergeinainte de restul verificarilor.) - comanda -> factura. Legatura e
VANZARI.ID_COMANDA+pack_facturare.inchide_comanda(EXPORT:5769), nuVANZARI_CORESP.COMENZInu are coloanaFACTURAT(verificat peall_tab_columns) — flagulfacturatdin grid vine din view-ul de incarcare. Garda exista, dar e in VFP si pe comanda, nu pe factura:COMUN\clase\ocomenzi.vc2:1806-1807la modificare ("Aceasta comanda a fost facturata si nu mai poate fi modificata!") si:2065-2066la stergere. - contract -> factura. Legatura e
VANZARI.ID_CTR+CTR_RATE_FACTURI(atinsa desterge_facturalaEXPORT:5566-5580pentruV_TIP IN (2, 6, 52)); nicio linie inVANZARI_CORESP, nicio garda de tip "are urmasi".
5. Ce am verificat direct vs. ce am dedus
Verificat direct pe cod / pe metadate:
- textul celor trei garzi din
sterge_factura, in export si desfasurat dinall_source(identice); CASE-ul dinfinalizeaza_facturacare da semantica luiTIP, ramura cu ramura;- corpul lui
scrie_corespondente_vanzarisimarcheaza_facturat; - ca
INSERT INTO VANZARI_CORESPexista intr-un singur loc (grep pe export +all_sourcepe toata baza); - sursa integrala a celor 4 triggere de pe
VANZARI/VANZARI_DETALII/VANZARI_CORESP; - lista completa a apelantilor lui
sterge_factura(all_source), inclusiv lantulfinalizeaza_stergere_nota -> sterge_din_vanzari -> sterge_factura; - coloanele reale ale
VANZARI_CORESP,PROFORME, si absenta luiFACTURATdinCOMENZI(all_tab_columns); frm_facturi.do_stergesifrm_facturi.do_modificaintegral, plusmodifica_date_factura;- filtrul
caut_avizedinoproceduri_facturare.prg.
Dedus / cu limite declarate:
- Ca
TIP = 1inseamna "factura normala din aviz" e o deductie din singurul punct de scriere (ntip = 4->scrie_corespondente_vanzari(1)) — solida, dar e deductie, nu o eticheta declarata intr-un nomenclator. - Ca setul tipurilor-parinte pentru
TIP = 1e{21, 22, 26, 42}vine din filtrul VFPcaut_avize, nu dintr-o restrictie in Oracle. Pachetul insereaza oriceID_VANZAREprimit inclistaid_avize, fara filtru pe tip (EXPORT:15494-15504). Alt apelant (alt produs ROA, un import) ar putea introduce alte tipuri. - Nu am verificat daca vreun alt produs ROA (ROACONT / ROAGEST / ...) are o cale proprie de
stergere care ocoleste
sterge_factura. Am verificat doar ca in Oracle nu exista alt apelant si ca in ROAFACTURARE ambele ramuri dindo_stergeajung acolo.
Din date, deci nedovaditor: interogarea pe VANZARI_CORESP din baza de dev arata TIP=1 cu
parinti de tip 21 si 22, TIP=2 cu parinte 22, TIP=3 cu parinte 1 — consistent cu tabelul de mai
sus, dar volumul e de ordinul unitatilor (8 randuri in total). Nu e dovada; concluziile de mai
sus vin din cod.
6. Ce nu s-a putut stabili
Nimic din cele 4 intrebari nu a ramas nedeterminat. Singurul punct pe care l-as lasa explicit
deschis pentru S7 este cel de la §4: golul real nu e pe aviz, e pe proforma —
sterge_proforma nu are absolut nicio garda, iar daca S5c chiar introduce TIP = 4
(proforma -> factura), garda din sterge_factura nu se aplica automat, pentru ca sterge_proforma
e o procedura complet separata care nu o apeleaza.