Plan corectat in patru puncte confirmate pe Oracle: - lista de coloane de taxare inversa are 13 termeni, nu 10 (TI19T/TI09T nu exista pe jc2007; expresia din oproceduri_decont.prg:8670 e scrisa peste view-ul VJC2025, cu aliasuri calculate) - tva_incasare nu exista pe jc2007/jv2007; interogarea transei 3 merge pe VJC2025/VJV2025 - kill-switch-ul nu se face in Optiuni_FIRMA/PROGRAM.dbf, ci pe modelul RC_ANAF_VERIF_SELECTIE (INI + optiuni Oracle + intrare de meniu) - oExecute deschide dialog de reconectare cu QUIT pe conexiune cazuta; apelul din transa 3 trebuie sa dezactiveze explicit reconectarea SVN r17910/r17911. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
11 KiB
TRANSA 3 (L3) — cele doua puncte ramase din "Ce ramane neverificat"
Data: 27.07.2026. Read-only (Oracle: doar SELECT; cod: doar citire). Nimic modificat, nimic comis.
Nu ating docs\handoff_transa3_conditii.md (al colegului T3-cond).
VERDICT GENERAL
- Punctul 1 (goExecutor la timeout/conexiune cazuta) — CONTRAZICE PLANUL. Comportamentul implicit
NU e "se sare, cu linie in goLog": pe conexiune cazuta apare mereu un dialog modal blocant, care la
Cancel face
QUIT(inchide toata aplicatia). Pattern-ul defensiv cerut de plan nu are niciun precedent azi in codebase — trebuie construit, nu copiat. - Punctul 2 (linii pe decont) — RAMAS DESCHIS pe cifra exacta, dar decizia arhitecturala a
planului (fara lista
IN(...)) ramane intemeiata independent de cifra. Schema dev nu are volum reprezentativ pentru batch-uri reale de extras/decont.
Punctul 1 — comportamentul goExecutor la timeout / conexiune cazuta
Sursa reala (cautata cu rg --no-ignore... de fapt Grep a gasit-o direct, COMUN nu era exclus in
aceasta sesiune): clasa oexecutor e definita in COMUN\programe\oproceduri_comune.prg:69-547
(NU in anaf_efactura.vc2 — de acolo doar se apeleaza). Instantiata o singura data:
goExecutor = Createobject("oExecutor"), Programe\roacont.prg:588.
Ce intoarce oExecute() la esec
Functie normala, nu arunca eroare VFP. SQLExec() esuat intoarce direct < 0, prins de codul
existent — niciun THROW/ERROR() implicat. Return: CT_INSUCCES (= -1,
COMUN\include\comun.h:10) daca lnSucces < 1, altfel CT_SUCCES (= 1)
(oproceduri_comune.prg:496, Return Iif(lnSucces >= 1, CT_SUCCES, CT_INSUCCES)).
Cursorul de iesire nu se creeaza pe esec (Use-ul din urma nu ruleaza).
oExecuta() (wrapper cu litera mica, folosit in ~jumatate din apeluri) doar impacheteaza
oExecute() si adauga necontitionat amessagebox(This.oPrelucrareEroare(), 16, "Eroare") pe orice
esec (:149-152) — indiferent de parametri. Diferenta fata de oExecute() (raw) e semnificativa
pentru L3.
Urca eroarea la ErrorHandler global? NU, direct — DAR
Nu urca la ON ERROR (nu e o exceptie VFP). Insa exista un dialog modal necontitionat de
tlShowError, la eroare ODBC (lnEroare1 = 1526) cu cod de eroare in lista
12152, 3113, 3114, 12560, 4068, 28, 12 (oproceduri_comune.prg:383) — exact codurile de
conexiune cazuta/protocol (3114 = NOT CONNECTED TO ORACLE, 3113 = end-of-file on communication
channel, 12560 = protocol adapter error):
lnRaspuns = amessagebox('Eroare de conectare.' + ... + 'Doriti reconectare?', 4 + 32, 'Eroare')
(:390) — apare mereu cand llReconnect = .T., chiar daca apelantul a lasat toti parametrii
default. Daca utilizatorul raspunde "Nu" (lnRaspuns <> 6): Quit + Retry (:412-413) —
inchide toata aplicatia, nu doar sare peste verificare.
llReconnect e recalculat la fiecare apel, ignorand orice setare anterioara pe obiect
(:220-224):
If SQLGetprop(lnHandle, "Transactions") = 2 && TRANZACTIE MANUALA
This.lReconnect = .F.
Else
This.lReconnect = .T. && cazul normal, in afara unei tranzactii manuale
Endif
si apoi, daca apelul are sub 8 parametri (cazul general in tot codebase-ul), llReconnect preia
This.lReconnect — deci .T. implicit pentru orice verificare in afara unei tranzactii manuale.
Singurul mod de a opri acest modal e sa dai explicit al 8-lea parametru (tlReconnect = .F.) la
apel — vezi mai jos, nu exista niciun apel asa in tot codebase-ul.
CONTRAZICE PLANUL: cerinta "orice esec (... conexiune cazuta ...) -> se sare, cu linie in
goLog. Niciodata tacut... Esecul nu blocheaza salvarea" (plan, :445-448) nu e comportamentul
implicit pentru exact acest caz (conexiune cazuta). E opusul: un dialog modal blocant, care poate
opri toata aplicatia. Pentru orice ALTA eroare (SQL gresit, tabela inexistenta — ORA-00942,
coloana lipsa — ORA-00904), comportamentul implicit CHIAR e "se sare, log, fara dialog" —
llShowError e .F. implicit si acel dialog nu e conditionat decat de el. Deci planul are dreptate
pentru clasa generala de erori, dar nu pentru "conexiune cazuta" — exact cazul numit explicit in
text.
goLog.Log(...) SE cheama pe toate drumurile de esec (:368-370, :384-387, :422-424) — de
partea asta planul are dreptate necontitionat, indiferent de tipul erorii.
In plus, pe orice esec (lnSucces < 0), independent de parametri, codul posteaza automat eroarea la
endpoint-ul de erori (goMyXMLHTTP.postError(...), :463-471) — un apel HTTP sincron in plus pe
drumul de salvare, la fiecare esec, inclusiv la cele care ar trebui "sarite silentios".
Timeout configurat?
Nu exista niciun SQLSETPROP cu QueryTimeout/ConnectTimeout/WaitTime pe handle-ul Oracle,
nicaieri in oExecutor/oConn (oproceduri_comune.prg:662-731, Connect foloseste doar
Sqlstringconnect(lcString) cu dsn=...;Uid=...;Pwd=..., fara parametri de timeout). Singurul
ConnectTimeout gasit in tot fisierul (:4105-4118) e pentru verificarea HTTP de update-uri, fara
legatura cu conexiunea Oracle. Concluzie: un query care ramane agatat (nu eroare, ci hang) nu are
niciun timeout care sa-l intrerupa — ar bloca formularul la nesfarsit, ceva ce nici planul, nici
codul actual nu adreseaza. De consemnat separat, dincolo de "esec" (eroare) — un hang nu e un esec,
e o blocare fara iesire.
Tiparul de apel defensiv "corect" deja folosit in codebase — NU EXISTA
Am cautat toate apelurile oExecute(/oExecuta( din COMUN si Programe (peste 150) — niciunul nu
trece de 2 parametri (tcSql, tcCursor). Nimeni nu foloseste vreodata parametrii 6-8
(tlShowError, tlQuitOnError, tlReconnect) explicit. Deci pattern-ul "cheama cu
tlReconnect = .F. ca sa eviti dialogul de reconectare" nu are niciun precedent — L3 ar fi
PRIMUL loc din codebase care il foloseste.
Cel mai apropiat precedent (nu perfect, dar cel mai aproape de "se sare fara dialog"):
oproceduri_inchidere.prg:1297:goExecutor.oExecuta(lcSql, "imob_conturi")urmat doar deIf m.llSucces ... Endif— la esec nu se face nimic in plus (daroExecutatot arata singuraamessageboxinterna, deci nu e cu adevarat silentios).- Pattern mai bun de citat ca baza (foloseste
oExecute, nu wrapper-uloExecuta):COMUN\clase\baza.vc2:1807,lnSucces = goExecutor.oExecute(lcSql,lcCursor), fara parametri suplimentari — la 2 parametri,llShowError/llQuitOnErrorraman.F.(fara dialog pe erori generice), darllReconnecttot devine.T.implicit, deci tot apare dialogul de reconectare pe conexiune cazuta.
Recomandare pentru L3 (nu e sarcina mea sa implementez, doar de raportat ca gasire): interogarea
noua trebuie sa apeleze goExecutor.oExecute(...) (NU oExecuta, care are mesaj propriu
necontitionat), cu toti cei 8 parametri, ultimul (tlReconnect) explicit .F., si verificarea
proprie a rezultatului fara niciun amessagebox propriu — un tipar care azi nu exista nicaieri in
cod si trebuie scris de la zero, nu copiat.
Punctul 2 — numarul real de linii pe un decont de curier/procesator
Ce s-a verificat despre sursa datelor
Confirmat din cod (Programe\oproceduri_import.prg:100-264): importul de extrase/deconturi e
strict pe fisier local (Getfile() la :138, parsat client-side in cursoare VFP
C_IMPORT_TEMP -> cActTemp). Oracle NU pastreaza niciun tabel de staging cu "lot de import" si
numar de linii — abia dupa validare, liniile devin note (ACT/ACTACTAN) si se salveaza individual.
Deci nu exista in Oracle o coloana/tabela care sa raspunda direct la intrebare — a trebuit
reconstruita indirect.
nom_fdoc: id_fdoc = 40 = EXTRAS CON (extras cont), id_fdoc = 33 = DECONT (decont
curier/procesator).
Reconstructie indirecta (proxy, nu masuratoare directa)
ACT nu are o coloana de "id lot" — am grupat notele salvate prin apropierea DATAORA (momentul
efectiv al salvarii, cu ora), pe acelasi id_util, cu prag de 10 minute intre randuri consecutive ca
limita de lot. E o aproximare (poate sparge/uni loturi reale), nu o masuratoare exacta din aplicatie.
Rezultate (schema MARIUSM_AUTO, dev):
DECONT(id_fdoc=33): doar 2 randuri in toata baza, un singur lot de 2 linii (25.06.2026). Date insuficiente pentru orice concluzie.EXTRAS CON(id_fdoc=40): 222 randuri, pe 32 zile distincte, din 19.01.2008 pana in 29.05.2026 — 40 loturi estimate. min 1, max 70, medie 5.6, percentila 95 ≈ 10 linii/lot.
CONTRAZICE PLANUL, cu rezerva explicita de mai jos: cifra afirmata in plan ("un extras obisnuit are 300-2000 linii/luna") e cu un ordin de marime peste orice lot gasit in aceasta schema (maximul absolut observat e 70).
De ce nu extrapolez asta la "planul gresit pe cifra": MARIUSM_AUTO e schema de dezvoltare a lui
Marius (confirmat in COMUN\docs\oracle_export.md), nu un client real cu volum de productie. Loturile
gasite arata a teste punctuale facute de-a lungul anilor (o inserare la cateva luni sau ani), nu
activitate de contabilitate lunara reala pe un cont bancar activ. Schema dev NU are date
reprezentative pentru volumul real al unui client — nu pot confirma sau infirma cifra 300-2000 pe
aceasta baza. Ramane RAMAS DESCHIS strict pe cifra exacta.
Corroborare slaba, doar indicativa: fisierul-sablon real din Alte\Extras_de_cont_11634808MT 940.txt (extras MT940 pentru o singura zi, un singur cont) are 11 linii de tranzactie (:61:) pentru
acea zi. Extrapolat naiv la ~20-22 zile lucratoare/luna ar da ~220-240 linii/luna pentru un cont de
activitate medie — aproape de capatul de jos al intervalului din plan (300), dar e un singur esantion
de o zi, pentru o singura firma, nu o distributie.
Ce ramane solid, indiferent de cifra exacta
Decizia arhitecturala a planului de la Pasul 3 ("fara lista IN(...)", :421-431) nu depinde
de cifra 300-2000 ca sa fie corecta: o interogare unica, de lungime fixa, cu intersectia facuta local
in VFP, elimina o clasa intreaga de eroare (ORA-01795, prag 1000) indiferent daca lotul real are
10 sau 2000 de linii — nu exista un prag sub care revenirea la IN(...) ar fi de preferat, pentru
ca varianta cu interogare unica nu are dezavantaj de cost fata de o lista IN mica. Deci verdictul
practic: decizia ramane intemeiata, chiar daca premisa numerica citata in text nu e verificata
(si, pe aceasta schema, pare supraestimata).
Alte observatii utile
oExecuta()(wrapper) vsoExecute()(raw): distinctia conteaza mult pentru L3 si nu era evidenta din plan.oExecutaare propriulamessageboxnecontitionat pe esec — pentru cerinta "niciodata dialog, doar log", trebuie folositoExecute, nuoExecuta.oPrelucrareEroare()(folosit de mesajele proprii de eroare) nu a fost citit in detaliu — nu era necesar pentru cele doua puncte cerute.