Cercetarile si propunerile rundelor 4-6 pe editarea facturii emise. Starea rundei 6 si ce s-a stabilit intra in progres.md. Nou: docs/conventii_mediu_oracle.md - pe dev/test se lucreaza numai cu ROA_CENTRAL si schemele CONTAFIN_ORACLE si MARIUSM_AUTO; schema ACN nu se foloseste. Scripturile de pachet sunt necalificate, deci schema tinta o decide sirul de conectare, nu fisierul. roafacturare.pj2 regenerat de git_sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gYCNE26G1G7UoGu2ju7aS
7.6 KiB
Cercetare: rulaje (RUL) pe factura emisă din aviz (tip = 4) — test_s8_matrice_surse.prg:308
Verdict
Asserția e greșită pentru tip = 4. Tabela RUL reține exclusiv mișcări pe conturi de stoc
(371 în datele verificate); o factură emisă din aviz nu atinge niciodată contul de stoc — ea doar
transformă creanța provizorie (418) în creanță fermă (4111) și TVA neexigibilă în TVA colectată
(4428→4428) — pentru că marfa a ieșit deja din gestiune la avizul-sursă (tip 22), care e cel ce
scrie rândurile de RUL. Reccount(trul) = 0 pe un document de tip 4 e starea corectă, nu un semn
că editarea a distrus rulaje.
Ce am verificat la sursă (cod + date Oracle)
1. De unde se umple trul
IncarcaCursoareModificareNota (COMUN\programe\ofacturare_editare.prg:35-148) încarcă trul
direct din view-ul vrul_tot, filtrat pe an/luna/cod, fără nicio sinteză sau completare:
COMUN\programe\ofacturare_editare.prg:76
lcSql = [select * from vrul_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul]
Reccount(trul) e deci exact numărul de rânduri deja existente în RUL (server) pentru acel cod
— nu ceva calculat sau garantat nenul de vreo regulă de business în client.
2. Cine scrie rulajele — și diferența pe tip de document
Scrierea efectivă e server-side, în Oracle, PACK_CONTAFIN.SCRIE_IN_RUL (COMUN\docs\PACK_CONTAFIN.pck:1896-2019):
face INSERT INTO RUL (...) SELECT ... FROM RUL_TEMP — deci scrie exact ce a fost pus în
RUL_TEMP de partea VFP, fără vreo ramură condiționată de tipul documentului. Tot ce contează e
dacă RUL_TEMP (populat din trul, deci din vrul_tot deja existent) are rânduri.
Pe partea VFP, calea de editare a facturii (cea exercitată de test, prin frm_facturi.do_editare_factura,
COMUN\clase\ofacturare_comun.vc2:3799-3821) copiază necondiționat trul înapoi în RUL_TEMP și
apelează OSCRIE_IN_FISIERE(0,.T.,.T.) — al treilea parametru (echivalentul lui llRul din editorul
generic) e hardcodat .T., nu depinde de starea inițială:
COMUN\clase\ofacturare_comun.vc2:3811-3821
If Used('rul_temp')
Use In rul_temp
Endif
Select * From trul Into Cursor RUL_TEMP Readwrite
Replace All id_util With gnIdUtil, sters With 0
...
lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)
Deci: dacă trul a fost gol la încărcare (pasul 1), rămâne gol și la scriere — codul conservă
starea, nu o corectează și nu o strică. (Contrast: editorul generic de jurnal contabil,
afisjurcom.do_modifica, COMUN\clase\comun.vc2:2370-2482, are un flag explicit llRul setat doar
dacă Reccount(lcCursor)>0 la încărcarea inițială din vrul_tot — dar calea de factură nu folosește
acest flag deloc, e mereu .T., ceea ce confirmă din nou că absența rândurilor din RUL nu e
tratată ca eroare de nicio ramură a codului.)
Originea rândurilor din RUL e deci strict la crearea/finalizarea notei, nu la editare —
PACK_CONTAFIN.finalizeaza_modificare_nota (apelat și la creare, și la editare) doar re-scrie ce
primește; nu am găsit nicio ramură condiționată de tip/ntip care să decidă "acest tip de
document trebuie să aibă rulaje" — decizia e implicită, dată de ce conturi apar în notă, nu de
tipul documentului.
3. Rolul lui IN_STOC în ActualizeazaVerdictActRul
COMUN\clase\omodificari.vc2:13045-13146. Verdictul ACT/RUL are trei stări, toate informative,
niciodată eroare:
COMUN\clase\omodificari.vc2:13129-13139
DO CASE
CASE !m.llVerdictSigur
lcVerdict = 'Verdict ACT/RUL: nu se aplica (informativ, date de import)'
CASE Abs(This.nTotalActRon - This.nTotalRulRon) <= 0.02
lcVerdict = 'Verdict ACT/RUL: sincronizat (informativ)'
OTHERWISE
lcVerdict = 'Verdict ACT/RUL: divergent (informativ, nu e eroare)'
ENDCASE
in_stoc corectează doar suma comparată (exclude valoarea liniilor nestocate din articolele
facturii, convertită în RON, din totalul RUL — tvd unde Nvl(in_stoc,1) = 0, linia 13111), nu
decide dacă documentul "trebuie" să aibă rulaje. Nu există în această metodă (verificat integral,
liniile 13045-13146, nu doar grep) nicio ramură specifică pentru RUL = 0 pe tip 4 — cazul cade pur
și simplu în "divergent (informativ, nu e eroare)" dacă nTotalActRon <> 0 și nTotalRulRon = 0, ceea
ce confirmă că design-ul acceptă explicit acest caz ca non-eroare.
4. Verificare pe date, read-only, Oracle MARIUSM_AUTO/ROA_CENTRAL
Conectat cu succes (sqlplus.exe, SET TRANSACTION READ ONLY ... ROLLBACK, fișier .sql ASCII,
fără pipe). Cod-urile curente (verificate din VANZARI, nu presupuse):
| id_vanzare | tip | cod (curent) | sters | RUL (cnt activ) | ACT (cnt activ) |
|---|---|---|---|---|---|
| 1048 | 1 | 1140918 | 0 | 1 | 5 |
| 1052 | 22 (aviz) | 1140921 | 0 | 4 | 12 |
| 1054 | 4 (factură din aviz) | 1140923 | 0 | 0 | 2 |
| 1055 | 2 | 1140920 | 0 | 1 | 7 |
id_vanzare = 1054 are cod curent 1140923 (confirmă realocarea din test:
1140910 -> 1140922 -> 1140923, citită direct din VANZARI, nu presupusă).
Detaliu decisiv — conturile efective din ACT/RUL pentru perechea aviz→factură (avizul 1052 e cel
mai probabil sursă a facturii 1054, pe baza secvenței de cod-uri și a fluxului tip 22→tip 4):
ACT pe avizul 1052 (tip 22): scd/scc includ 607/371, 371/378, 378/371, 4428/371, 371/4428, 418/704, 418/4428
RUL pe avizul 1052 (tip 22): 4 rânduri, toate CONT = 371 (cont de stoc)
ACT pe factura 1054 (tip 4): scd/scc = 4111/418 (305 lei) și 4428/4428 (52.93 lei) -- NICIUN cont 371
RUL pe factura 1054 (tip 4): 0 rânduri
Avizul e cel care mișcă efectiv contul de stoc (371) și de aceea are rânduri în RUL (care
urmărește exclusiv cantități pe conturi de stoc — vezi și cant/cante din trul, folosite ca
atare în ActualizeazaVerdictActRul:13102). Factura emisă din acel aviz nu mai atinge 371 deloc —
transformă doar creanța provizorie (418) în creanță fermă (4111) și TVA neexigibilă (4428) în
TVA colectată (4428). N-are, structural, ce rând de stoc să scrie.
Zero tranzacții deschise la final (ROLLBACK executat, SET TRANSACTION READ ONLY respectat pe tot
scriptul).
Ce am dedus (nu verificat direct, dar consistent cu toate dovezile de mai sus)
- Regula generală:
RULse scrie doar pentru documentele/notele care conțin mișcare pe cont de stoc (aviz, NIR, bonuri de consum etc.); facturile "de închidere" (emise din aviz, sau orice document care doar transformă o creanță provizorie într-una fermă) nu vor avea niciodată rânduri înRUL, indiferent câte documente de acest fel verifici — nu e o particularitate a luiid_vanzare = 1054, ci a tipului de operațiune contabilă. - Aserția de la
test_s8_matrice_surse.prg:308(Reccount(trul) > 0obligatoriu după editare) e probabil corectă ca test general "rulajele nu trebuie distruse de editare" pentru documentele care AU avut rulaje înainte de editare, dar e o presupunere greșită aplicată universal — pentru tip 4 (și, prin extensie, orice tip de document care nu atinge cont de stoc) condiția trebuie relaxată la "dacă documentul avea rulaje înainte, tot le are și după" sau pur și simplu exclusă pentru tip = 4.
Fișiere atinse
Niciunul (misiune read-only). Fișiere citite: COMUN\programe\ofacturare_editare.prg,
COMUN\clase\omodificari.vc2, COMUN\clase\comun.vc2, COMUN\clase\ofacturare_comun.vc2,
COMUN\docs\PACK_CONTAFIN.pck. Interogări Oracle read-only pe MARIUSM_AUTO@ROA_CENTRAL, cu
ROLLBACK la final.