Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
14 KiB
Nota contabila pentru articol fara politica de pret (proiect #13)
Cercetare pe cod, fara modificari. Continua raportul anterior
cont_venit_corespondente.md (SCC vine prin lantul
CRM_POLITICI_PRET_ART -> CRM_POLITICI_PRETURI.ID_NOTA -> CRM_NOTE_VANZARI.ID_SET -> NOTE_CONTABILE,
citit de cursor_articol din pack_facturare.contabilizeaza_articol).
Sursa: D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql
(pachet pack_facturare, 17020 linii) si D:\ROA\ROAAUTO\Programe\oproceduri_devize.prg +
D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_31_02_AUTO_PACK_AUTO.sql (pachet pack_auto).
1. Ce face contabilizeaza_articol cand id_pol e NULL/0
Raspuns: ridica exceptia FACT-024 si intreruce functia, inainte sa ajunga la cursorul care citeste SCC. Nu exista o ramura de default si nu se scrie nota cu SCC NULL pentru acest caz.
Corpul complet e la ff_...:7182-7556. Primul lucru pe care il face (inainte de cursor_articol,
inainte de orice scrie_nota) e:
ff_...:7286-7311
BEGIN
SELECT COMPUS, ID_POL_ART
INTO V_COMPUS, V_ID_POL_ART
FROM VCRM_POLITICI_PRET_ART
WHERE ID_ARTICOL = detalii_articol.id_articol
AND ID_POL = detalii_articol.id_pol;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT DENUMIRE INTO lcArticol FROM NOM_ARTICOLE WHERE id_articol = detalii_articol.id_articol;
SELECT NUME_LISTA_PRETURI INTO lcPolitica FROM CRM_POLITICI_PRETURI WHERE id_pol = detalii_articol.id_pol;
RAISE_APPLICATION_ERROR(-20000,
'Articolul ' || detalii_articol.id_articol || '|' || lcArticol ||
' nu este definit in politica de preturi ' ||
detalii_articol.id_pol || '|' || lcPolitica || '! (FACT-024)');
END;
ID_POL = detalii_articol.id_pol cu id_pol NULL nu poate potrivi niciun rand in SQL standard
(X = NULL e necunoscut, nu adevarat) — deci pentru id_pol NULL sau 0 (presupunand ca nu exista
o politica cu ID_POL = 0), SELECT INTO intra mereu pe NO_DATA_FOUND.
Observatie suplimentara, neceruta explicit dar relevanta: in ramura de exceptie, al doilea
SELECT ... INTO lcPolitica FROM CRM_POLITICI_PRETURI WHERE id_pol = detalii_articol.id_pol sufera
de aceeasi problema — cu id_pol NULL, si acest SELECT INTO da tot NO_DATA_FOUND, care nu e
tratat in acest bloc (nu exista un al doilea handler). Deci mesajul FACT-024 "curat" (cu numele
politicii) nu s-ar afisa niciodata pentru cazul id_pol IS NULL — s-ar propaga o exceptie
NO_DATA_FOUND neprinsa din interiorul handler-ului, cu alt mesaj Oracle generic, nu FACT-024 cu
text. Codul articolului (lcArticol) apuca sa fie rezolvat inaintea acestui eșec, deci
identificarea articolului nu s-ar pierde in log/eroare, dar textul final ar fi ORA-01403, nu
mesajul FACT-024 formatat. Pentru id_pol = 0 (nu NULL), daca exista vreo politica cu id 0, acel
SELECT ar reusi si mesajul FACT-024 ar iesi corect.
Cursorul cursor_articol (care citeste SCD/ASCD/SCC/ASCC din NOTE_CONTABILE prin lant) nu se
mai deschide — funcția a ridicat deja exceptia mai sus. Deci intrebarea "cursorul intoarce zero
randuri, ce face codul mai departe" nu se pune in acest caz: nu ajunge acolo.
Concluzie Q1: orice linie de vanzare cu id_pol NULL/0 trimisa la contabilizeaza_articol in
starea actuala a codului arunca o eroare si opreste tranzactia (nu scrie nota cu cont NULL, nu
pune default). Cerinta proiectului #13 ("articol din nomenclator fara politica de pret, pret
tastat manual, pe orice tip de document") ar lovi FACT-024 (sau exceptia neprinsa descrisa mai sus)
daca linia respectiva e trecuta prin acest cod neschimbat.
2. Validare la scrie_nota pentru cont NULL
Raspuns: nu exista. Corpul complet e la ff_...:12338-12570.
- Singura verificare care ar fi atins asta e comentata:
Si oricum verifica
ff_...:12441-12453 /* IF V_SUMA IS NULL THEN RAISE_APPLICATION_ERROR(...) ... END IF;*/V_SUMA(suma calculata), nuV_SCD/V_SCC. INSERT INTO ACT_TEMP (... SCD, ASCD, SCC, ASCC ...)(ff_...:12458-12544) insereaza directV_SCD/V_ASCD/V_SCC/V_ASCCprimite ca parametri, fara niciunNVL/CASE/verificare de NULL pe ele.- Nu exista
NOT NULLverificat in cod pentru aceste coloane in acest fisier (constrangerea ar fi la nivel de DDL al tabeleiACT/ACT_TEMP, care nu face parte din pachetul PL/SQL cercetat — vezi sectiunea Neverificat).
Deci daca cineva ar ocoli blocul de la punctul 1 (de ex. printr-un id_pol care exista in
CRM_POLITICI_PRET_ART dar al carui lant CRM_POLITICI_PRETURI -> CRM_NOTE_VANZARI -> NOTE_CONTABILE
e incomplet, asa incat D.SCC iese NULL din LEFT JOIN), scrie_nota ar scrie nota cu SCC = NULL
fara sa protesteze. Asta e insa un scenariu diferit de "fara politica de pret" (aici politica exista,
dar lantul de sub ea e incomplet) — nu e cazul cerut de proiectul #13 asa cum a fost formulat.
3. Toti apelantii lui contabilizeaza_articol in fisier
Cautare exhaustiva Grep 'contabilizeaza_articol' pe tot fisierul: 3 apeluri (in afara de propria
definitie si un comentariu):
| Linie | Procedura apelanta | Domeniu / flux |
|---|---|---|
ff_...:6150 |
scrie_factura2 (corp ff_...:6029-6272) |
Fluxul principal de scriere — pentru orice document ale carui randuri nu cad in ramurile speciale ale CASE-ului de la ff_...:6081-6151: transfer intre subunitati (ntip IN (23,25,30,41)), factura/aviz custodie (ntip IN (42,47)), rata cu id_rata<>0 (ntip IN (2,6,52)). Toate celelalte tipuri — factura normala (ntip<=20), hotel, restaurant, nota de plata, vanzare retail, tipurile 48/49/51/52, aviz simplu, aviz catre clienti debitori, si aviz retur (tip 24) cand e scris prin scrie_factura2 — ajung la contabilizeaza_articol aici. Aceasta e apelarea "de baza" pe care se sprijina interpretarea corpului functiei facuta la punctul 1 (ramurile CASE din interiorul contabilizeaza_articol, ff_...:7407-7432, mapeaza direct pe tipurile de document tratate de acest apelant). |
ff_...:6867 |
scrie_factura_avize_retur (corp ff_...:6273-6666) |
Flux factura scrisa pe baza de avize + retur simultan. Apelul e in interiorul buclei pe articole_aviz (ff_...:6841-6960 zona), pentru randurile cu custodie = 1 (marfa in custodie ce se descarca din avize). |
ff_...:7149 |
scrie_aviz_retur (corp ff_...:7094-7180) |
Procedura dedicata aviz retur (V_ID_DELEGAT, V_ID_MASINA, ...). Apelul e in ramura ELSE a testului pack_facturare.nfactavizcust = 1 (ff_...:7124-7150) — deci pentru randurile care nu sunt in custodie. |
Concluzie Q3: da, contabilizeaza_articol e apelata pe fluxul principal de facturare
(scrie_factura2, care acopera factura normala si majoritatea celorlalte tipuri de document), nu
doar din scrie_aviz_retur. Raportul anterior lasase asta neverificat; e confirmat aici cu cele 3
puncte de apel gasite si citate mai sus — nu exista un al 4-lea apel in fisier.
4. Precedentul ROAAUTO "Alte servicii" — nu e de fapt un precedent pentru cazul cerut
Asta contrazice premisa din cerere. Firul (crsalteserv -> crsvanztemp -> adauga_articol_factura_deviz)
duce spre un flux care ocoleste complet contabilizeaza_articol, deci nu demonstreaza ce se
intampla in pack_facturare pentru un articol fara politica — demonstreaza doar ca exista un alt
mecanism de contabilizare, in afara pachetului pack_facturare.
Pasii, cu citate:
-
crsalteserv -> crsvanztemp(D:\ROA\ROAAUTO\Programe\oproceduri_devize.prg:1040-1041):Insert Into (lcCursorDeviz)(id_articol,denumire,explicatie,cantitate,um,id_jtva_coloana,proc_Tvav,taxcode,pret,discount_unitar) ; Select id_articol,denumire,"",cantitate,um,CAST(lnIdJTvaColoana as N(6) null) as id_jtva_coloana,CAST(lnProcTvav as N(7,2) null) as proc_tvav,CAST(lnTaxCode as N(6) null) as taxcode,pretftva,0 From crsalteserv Where !Deleted()Nu exista coloana
id_polincrsalteserv, inlcCursorDeviz, sau in cursorulcrsvanztempcreat laoproceduri_devize.prg:1190-1192(schema explicita a cursorului nu includeid_pol). -
crsvanztemp -> adauga_articol_factura_deviz(oproceduri_devize.prg:1240-1257): apelul RPC trimiteid_articol, explicatie, serie, pret_achizitie, pretd, id_valuta_d, pret, id_valuta, curs, multiplicator, proc_tvav, id_jtva_coloana, cantitate, discount_unitar, id_gestiune, cont, pret_cu_tva, NULL, NULL, taxcode— faraid_pol, pentru ca procedura insasi nu are un parametruid_pol. -
Semnatura
adauga_articol_factura_deviz(specff_...:468-488, corpff_...:4675-4745): nu existaV_ID_POL IN NUMBERprintre parametri.INSERT INTO VANZARI_DETALII_TEMPlaff_...:4697-4744nu include coloanaID_POLin lista de coloane inserate — deciID_POLramane pe valoarea implicita a coloanei (probabil NULL; DDL-ul tabelei nu face parte din pachetul cercetat, vezi Neverificat). Asta confirma partea (a) a intrebarii: da, liniile "alte servicii" ajung cuid_polgol inVANZARI_DETALII_TEMP. -
Dar acele randuri nu trec niciodata prin
contabilizeaza_articol. Apelantul dinoproceduri_devize.prgnu cheamascrie_factura2/scrie_factura_avize/scrie_aviz_retur(singurele proceduri care cheamacontabilizeaza_articol, vezi punctul 3). In schimb cheama, in ordine (oproceduri_devize.prg:1211-1310):pack_facturare.initializeaza_date_factura(...)- bucla
pack_facturare.adauga_articol_factura_deviz(...)(doar insert inVANZARI_DETALII_TEMP) - opțional
pack_facturare.scrie_incasari(...)(incasare, nu venit din vanzare) pack_facturare.scrie_in_vanzari(0, ...)(ff_...:13497-13962)pack_auto.actualizeaza_deviz(...)(D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_31_02_AUTO_PACK_AUTO.sql:692-733)
scrie_in_vanzarinu scrie nici o nota contabila de venit. Corpul complet (ff_...:13497-13962) face:INSERT INTO VANZARI(antetul documentului),scrie_cursuri,scrie_seturi, apoiff_...:13714-13766 INSERT /*+ APPEND */ INTO VANZARI_DETALII (..., ID_POL, ...) SELECT ..., ID_POL, ... FROM VANZARI_DETALII_TEMP;(copiaza
ID_POL— care e NULL pentru aceste randuri — direct inVANZARI_DETALII, fara nicio validare), si la final actualizeaza totalurile cache peVANZARI. Nu apare niciun apel catrecontabilizeaza_articol,scrie_nota,cumuleaza_note_actsaufinalizeaza_facturain acest corp (verificat citind procedura cap-coada).pack_auto.actualizeaza_deviz(ff_2026_03_31_02_AUTO_PACK_AUTO.sql:692-733) face doar:SELECT MAX(ID_FACT) INTO lnIdFact FROM ACT WHERE COD = pack_contafin.get_cod() AND SCD NOT LIKE '5%'; UPDATE DEV_ORDL SET PROC_TVAV = ... WHERE ID_ORDL IN (...); UPDATE RUL SET ID_FACT = lnIdFact WHERE ...; UPDATE NOM_LUCRARI SET ID_FACT = lnIdFact WHERE ... (doar pt anumite id_set);Adica presupune ca exista deja un rand in
ACT(nuACT_TEMP) cuSCD NOT LIKE '5%'pentru codul documentului curent, si doar propagaID_FACTgasit acolo spreDEV_ORDL/RUL/NOM_LUCRARI. Nu insereaza el insusi inACTsauNOTE_CONTABILE, si nu contine nicio referinta laSCC,NOTE_CONTABILEsauCRM_POLITICI*(cautat explicit, zero rezultate in acest fisier).
Concluzie Q4, corectand premisa din cerere: liniile "Alte servicii" chiar ajung cu id_pol gol
(confirmat), dar nu demonstreaza ca contabilizeaza_articol tolereaza id_pol gol — pentru ca
nu trec niciodata prin el. Ele demonstreaza doar ca exista deja, pentru fluxul deviz ROAAUTO, o cale
de facturare paralela (scrie_in_vanzari + pack_auto.actualizeaza_deviz) care nu genereaza deloc
nota contabila de venit prin pack_facturare. Daca acele randuri capata totusi un cont de venit in
ACT/NOTE_CONTABILE in productie, mecanismul nu e vizibil in codul cercetat (posibil un
trigger pe tabel, un job batch, sau o scriere manuala/alt modul neexaminat — vezi Neverificat).
Nu se poate folosi acest precedent ca raspuns de fapt la intrebarea 1.
5. Vreun mecanism care sa foloseasca NOM_ARTICOLE.CONT drept cont de venit
Raspuns: NU, in pack_facturare.
Cautat explicit Grep -i 'NOM_ARTICOLE\.CONT' pe intregul fisier
ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql (17020 linii) — zero potriviri. Singurele utilizari
ale NOM_ARTICOLE gasite in contabilizeaza_articol insusi sunt pentru DENUMIRE (mesajul de
eroare FACT-024, ff_...:7295-7298), nu pentru CONT.
crs_rand_articol.scc (folosit ca V_SCC la ff_...:7434) vine exclusiv din
D.SCC din join-ul CRM_POLITICI_PRET_ART -> CRM_POLITICI_PRETURI -> CRM_NOTE_VANZARI -> NOTE_CONTABILE
(ff_...:7261, 7275-7276) — nu exista ramura alternativa care sa substituie NOM_ARTICOLE.CONT
cand politica lipseste. (Raportul anterior confirmase deja separat ca NOM_ARTICOLE.CONT e folosit
doar ca cont de gestiune, transmis catre descarca_gestiune, ff_...:7499.)
Neverificat
- Continutul efectiv al
NOTE_CONTABILE/CRM_POLITICI_PRET_ART(daca exista politici cuID_POL = 0, ce SCC au liniile din productie pentru documente "alte servicii" existente) — necesita interogare pe baza de date, nu doar cod. - Constrangerile DDL ale
VANZARI_DETALII_TEMP.ID_POLsiACT_TEMP.SCC/ACT.SCC(NOT NULL? default?) — scripturile DDL ale acestor tabele nu au fost cautate/citite in aceasta cercetare (am cautat doar in pachetele PL/SQLff_...COMUN_PACK_FACTURARE.sqlsi..._AUTO_PACK_AUTO.sql). - Cine scrie efectiv contul de venit (
ACT/NOTE_CONTABILE) pentru documentele "alte servicii" din ROAAUTO, daca se scrie deloc.pack_auto.actualizeaza_devizpresupune ca exista deja un randACTcuSCD NOT LIKE '5%'pentru codul documentului curent — sursa acelui rand nu a fost gasita inoproceduri_devize.prgsau in corpulscrie_in_vanzari/actualizeaza_devizcercetate. Ar trebui cautat: alte proceduripack_auto(fisierulff_2026_03_31_02_AUTO_PACK_AUTO.sqlare si alte proceduri necercetate aici), triggere peVANZARI/VANZARI_DETALII/ACT, sau apeluri din alte forme VFP (.scx/.vcx) din ROAAUTO care preced acest apel RPC. Nu am cautat exhaustiv triggere in afara folderuluiSCRIPTURI_CLAR\2026(cautare limitata, zero rezultate acolo). - Ce se intampla exact daca
id_pol = 0si exista o politica reala cuID_POL = 0(caz teoretic, neexclus explicit din schema) — ar schimba concluzia de la "eroare neprinsa" la "FACT-024 cu mesaj complet", dar tot ramane o eroare, nu un default silentios.