caut_partener primeste tlVerificaANAF/tdDataDoc (acelasi bloc ca la caut_parteneri) si citeste
tip_persoana din vnom_parteneri, ca banda de stare sa distinga CNP de CIF, nu dupa lungimea codului.
Apelanti pe documente: factura si partenerul DVI din achizitia de import (data din formular,
dDataAct), furnizorul de la finalizarea NIR-ului (data cade pe poAct.dataact) si schimbarea
furnizorului pe rulaj.
verific_partener si verificare_note_contabile (ooperatii_comune.prg) cer verificarea si cand
completeaza partenerul lipsa pe cont, la salvarea documentului.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
Verificarea "in masa" (VerificaListaCIF ... 'MASA') pica pe ORA-01795 peste 1000
de coduri, iar esecul trimitea tot lotul la ANAF, cu pauze de o secunda la fiecare
100 de coduri. Pe langa asta, fiecare rand servit din cache era salvat inapoi in
istoric si logat separat.
- programe/validare.prg: CitesteIstoricPentruCoduri citeste pe transe de maxim
1000 de coduri legate cu OR in aceeasi interogare (fara obiecte noi in baza,
compatibil cu Oracle 10g); plasa de siguranta cere codurile neacoperite o
singura data, nu cod cu cod; SalveazaIstoricDinCursor sare peste randurile cu
sursa CACHE*; bucla de log per rand devine o singura linie cu totalul.
- clase/overificari.vc2: completarea tabelului de parteneri foloseste index pe
codul normalizat si SEEK in loc de LOCATE cu UDF (era patratic).
- utile/Teste/cache_anaf/: harness-uri de masurare si non-regresie pentru
timpii de mai jos.
Masurat pe MARIUSM_AUTO, cu ANAF blocat: 1000 de coduri 5,1 s -> 0,318 s;
1001 coduri 16,6 s cu ORA-01795 -> 0,553 s fara eroare; 3000 de coduri 1,565 s;
200 de coduri din cache 3,93 s -> 0,05 s, cu 0 randuri noi in istoric;
completarea tabelului pentru 2000 de parteneri 11,97 s -> 0,028 s.
Randurile intoarse si verdictele raman identice.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
Verificarile de partener nu mai depind exclusiv de raspunsul ANAF: se citeste
intai cache-ul din ISTORIC_CODURI_FISCALE (mutat in CONTAFIN_ORACLE), cu
provenienta afisata pe ecrane (sursa / data_sursa) si cu plasa de siguranta
cand ANAF tace. Ordinea cache/ANAF e configurabila; cache-ul expira.
- programe/validare.prg: verificare single si pe loturi peste cache, contract
404 separat de caderea de serviciu, expirarea cache-ului, corectii la
verdictul pe firma si la etichetarea CACHE_INDISP.
- programe/ocautare.prg: plasa de siguranta si banda de provenienta la cautarea
de partener.
- programe/oproceduri_comune.prg: VERIFICA_RTVAI_DATA citeste si cache-ul.
- clase/overificari.vc2: propagarea provenientei in interfata.
- utile/Teste/: harness-uri de testare headless - echivalenta cache/ANAF pe 200
de coduri reale, marginile pe inactiv si TVA la incasare, mock batch ANAF,
baseline D394 si sondele de diagnostic ANAF.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
In import_nota, randul de TVA al DVI-ului pastreaza doc_key-ul facturii-mama.
copiaza_valoare il sarea doar ca tinta, nu si ca sursa, asa ca o trecere prin
celula "Nr" a randului DVI scria numarul vamal peste randurile facturii (B/G/S)
si, la Terminat, in ACT si RUL.nract. Garda e acum in ambele sensuri, pentru
numar, serie, data, fel document si partener; propagarea de partener din
Grid1.cPartC.Text1.Valid a primit aceeasi protectie.
Garzile comparau numele de camp bar, dar ControlSource-ul unei coloane de grid
e calificat la runtime (introdc.nract), deci nu se activau pe drumul din grila.
Teste noi in utile/Teste/achizitie_import.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
- TVA-ul de pe DVI poate avea valuta si curs proprii, diferite de ale facturii
(rand "protejat": rand_dvi/valuta_proprie pe introdc, sparge_tva_protejat).
- Discount financiar pe factura: rand tip_rand='G' (401 = 767), TVA calculat pe
baza diminuata, marfa si preturile articolelor pe valoarea integrala.
- Factura multi-cota: randurile S, G si T se sparg pe cotele articolelor, cu
explicatia TVA din familia coloanei si alinierea T -> S.
- Teste noi in utile/Teste/achizitie_import (discount, DVI, cote, e2e).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
Pe toate cele trei pagini (Facturi emise, Primite, Trimise) doua bife noi, colorate
ca randurile pe care le filtreaza: turcuaz "Cu diferente Reg. TVA" (jtotctva
completat, dar diferenta peste 0,15 lei sau eFactura in valuta) si gri "Lipsa din
Reg. TVA" (jtotctva null). Bifate impreuna se aduna cu OR.
Culorile din grid: gri = nu e in registru, turcuaz = diferenta peste 0,15 lei sau
necalculabila, alb = se potriveste. Expresia DynamicBackColor e sparta in doua
siruri, VFP nu accepta constante peste 255 caractere.
diferenta ramane NULL cand jtotctva e NULL (nu 0 fals), la fel ca la facturile
primite/trimise; jtotctva si diferenta sunt acum nullable in cursorul de facturi
emise.
Corectat lcFiltru3, care se construia din lcFiltru2 si pierdea conditiile paginii.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
Galbenul de la randurile cu diferenta fata de Registrul TVA devine turcoaz in borderou,
ca sa insemne acelasi lucru in ambele ferestre: gri = factura nu e in registru,
turcoaz = e in registru dar valoarea difera cu peste 0.15 lei ori nu se poate compara
(factura in valuta), alb = se potriveste.
Importul preia regulile corectate ieri in borderou: diferenta ramane goala cand factura
nu e in registru sau e in valuta si tine cont de semnul notei de credit, iar jtotctva si
diferenta se declara nullable in cursor (altfel NULL devine 0 si gri-ul nu mai apare).
Pana acum importul colora orice diferenta de un ban si dadea turcoaz fals pe notele de
credit si pe facturile in valuta.
Filtrul initial al cursorului din fereastra de import compara data_act cu un interval
[prima zi a lunii, prima zi a lunii urmatoare) in loc de extract(year/month from data_act),
deci poate folosi IDX_ANAF_EFACTURA_1(FACTURA_EMISA, XDATA_ACT, DATA_RASPUNS). Filtrul
rula la fiecare deschidere a ferestrei, nu era amanat ca la borderou.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
Potrivirea pe numar compara nract cu grupurile de cifre extrase din xnumar_act,
in loc sa aplice un regex peste nract. Predicatul devine sargabil, deci foloseste
IDX_JC2007_003/IDX_JV2007_003 in loc sa scaneze toata luna din jurnal pentru
fiecare factura: borderoul de facturi trimise trece de la 97 de secunde la sub una
(masurat pe o firma cu 6006 facturi si 6466 randuri in jurnal).
Rezerva pe suma egala se pastreaza, dar in view se leaga prin COALESCE, nu prin OR:
se evalueaza doar pentru facturile pe care numarul nu le-a gasit. Legata prin OR,
potrivea nediferentiat orice document cu aceeasi suma la acelasi partener in aceeasi
zi - pana la 49 de documente pentru o factura - si afisa o "Diferenta" gresita.
jcnt si coloana "Pot." se elimina: dupa corectarea potrivirii numarul de documente
potrivite e practic intotdeauna 1, iar starea "nu e in registru" se citeste din
jtotctva IS NULL. jtotctva se declara nullable in cursor, altfel NULL-ul devine 0 si
randurile fara potrivire nu s-ar mai colora.
Pragul de la care un rand devine galben urca de la 0.01 la 0.15 lei: la 0.01 ieseau
841 de randuri galbene din 6006, toate diferente de rotunjire sub 0.11 lei.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
La salvarea notei, VerificaAvertizareExigibilizareTVA (identica in
frm_modific2007 si frm_modific2024) verifica incasarile si platile cu factura
pereche completata si avertizeaza daca vreuna dintre facturile lor cu TVA la
incasare nu are inca nota de TVA exigibilizat.
Candidatii sunt exact cele doua tipare pe care do_adauga_tva_exigibil le trateaza
automat (id_factd > 0 cu scc pe 5xx, id_factc > 0 cu scd pe 5xx); facturile deja
acoperite de o linie tipnota = 1 din nota curenta sunt suprimate. Soldul
neexigibil se citeste dintr-un singur SELECT peste VJC2025/VJV2025, filtrat pe
perioada curenta si pe toate cele 14 coloane de cota.
La "Da" se apeleaza do_adauga_tva_exigibil NEMODIFICAT, marcand temporar `ales`
doar pe liniile candidate si restaurandu-l dupa; programul ramane in formular,
ca notele adaugate sa poata fi verificate. Orice esec (optiune, cursor, SQL)
se logheaza si lasa salvarea sa continue.
Se poate opri din settings.ini [tva] avertizare_exigibilizare=0 sau din optiunea
RC_TVA_AVERT_EXIGIB.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
ct_selectie.Init si ct_selectie_sql.Init apelau do_adauga cu 4 argumente, desi
metoda e declarata cu 6. lcCampId ajungea .F., iar Nvl(.F.,lcCamp) dadea Error 11
la deschiderea oricarui formular de raport generic, urmata de o cascada in
ct_ordonare1._scrollcontainer1.do_adaugaobiect.
ccoloanesuma si cnumecoloanesuma erau stocate cu virgula in formulare, dar codul
le citeste cu "|" (contract documentat in ct_selectie.Init: o coloana poate fi o
expresie de forma round(...,...)). Rezulta SUM(cantitate,valoare_ftva,valoare) si
ORA-00909. Migrate cele 12 valori pe "|"; clistacoloaneordine ramane pe virgula,
asa cum o citeste codul.
Scos SET STEP ON din ct_selectie.do_instructiune_sql si din
frm_date_rapoarte_articole_v.do_cauta - in EXE nu au efect, dar la rularea din
sursa opreau executia in debugger.
Adaugata coloana "Cont" in rapoartele de articole: contul de venit preluat din
nota contabila a politicii de preturi (primul rand dupa ORDINE), cu regula
debit/credit dupa structura notei.
Verificat headless: cele 6 formulare de raport se deschid cu 0 erori (inainte
10/10/14/9/1/9), do_instructiune_sql intoarce .T., iar SQL-ul generat se executa
pe Oracle si returneaza 31 de randuri grupate pe cont.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1J6WjsQn7i7c9uF7VweGc
ocautare.prg - miezul functionalitatii:
- anaf_verif_cautare: verdictul ANAF pe randul curent din formularul de cautare
(label sub grid), la data documentului; discordantele si codurile fiscale invalide
cu rosu; F4 sau click deschide detaliile.
- ANAF_StarePartener, cu cache pe sesiune, excludere parteneri externi si persoane
fizice; ANAF_ValidareCod pentru CIF/CNP.
- ANAF_NivelVerificare: cascada RC_ANAF_VERIF_SELECTIE (kill-switch settings.ini >
optiuni utilizator > optiuni firma > implicit 1), cu cache invalidat la schimbarea
firmei sau utilizatorului; ANAF_ComutaVerificare pentru punctul de meniu.
- Detalii: alegerea variantei corecte de partener din perechea RO / fara RO, cu
discriminator "are documente in perioada"; dupa Da sau Nu se inchide cautarea si
se revine in formular cu partenerul ales (AplicaInlocuirePartenerANAF).
- ANAF_CaData: data documentului poate veni si ca DateTime (tact.dataact).
- Banda proprie sub grid pentru label: formularul creste cu 54, gridul isi pierde
ancorarea de jos si primeste inaltimea din AjusteazaBanda, legata de Resize si
Activate - formularul isi reaseaza gridul dupa Show, deci Activate e momentul util.
validare.prg: ANAF_VerificaCuiSingle, wrapper single-CUI peste serviciul ANAF, cu
data verificarii si o singura eroare logata pe sesiune.
cauta_alfa.prg: hook generic - ataseaza poVerifAlegere pe formularul de cautare
inainte de Show si il detaseaza dupa.
Apelanti opt-in (lVerificaANAF): baza.vc2 (lookup-ul generic de partener din
formularele actbaza/actbaza2007 lansate din meniuri), onote_contabile.vc2 (partener
debit/credit), omodificari.vc2 (do_cauta din cele trei clase de modificare, cu data
notei), ofacturare.vc2 (client, furnizor). Casa/banca ramane in afara: acolo partenerul
se alege pentru imperecherea facturilor.
cauta_alfa_forms.vc2: F4 deschide detaliile, iar terminarea cautarii trece prin
VerificaAlegere.
Teste: suita headless pentru fluxul de verificare (utile/Teste/partener_anaf/), cu
mock pentru apelul ANAF si pentru dialoguri.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019H3r66sVojGhgaKq5niu1u
Debifat = exclus complet din pretul articolului (lei si valuta); procent_lei
ramane 100 pe import, diferenta e absorbita de randul D (recalc_diferente).
Procentele afisate pe randurile neparticipante raman goale. Test nou pe
fluxul real: test_secundara_debifata_pret (15/15 PASS); regresie curata
(test_valuta_dvi_usd 22/22, test_debifare_invaluta 68/68, scenariu complet PASS).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXsyJZBek1e9RvyLAQkoCx
cCurs.Text1.Valid armeaza sincronizarea amanata (repretare articole +
recalc diferente) si propaga cursul principalei in antet (oact.curs,
doar pe randuri in valuta). Teste: pas nou de schimbare curs pe DVI
secundar in test_valuta_dvi_usd (22/22 PASS), regresie
test_debifare_invaluta (68/68) si test_scenariu_dvi_complet PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXsyJZBek1e9RvyLAQkoCx
Rundele 1-7: golire campuri valuta la debifare in_valuta (cu suma_doc_val),
recalcul din curs pe tot documentul (cu refacere suma_doc/suma_doc_val),
spargere document principal in valuta (suma_val doar pe randuri in valuta),
TVA repartizat din baza in valuta pe import, iar la recalculeaza()/procente
per rand sumele in valuta ale documentelor participante aflate in alta
valuta decat a principalei se convertesc prin lei (suma/curs principal),
nu se mai aduna direct la baza in valuta (100 USD nu mai devine 100 EUR).
Teste UI: test_valuta_dvi_usd (scenariu mixt EUR+USD, 8/8 PASS),
test_debifare_invaluta (64/64 PASS), test_repro_valuta_dblclick,
mock_caut_valuta; regresie test_scenariu_dvi_complet PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXsyJZBek1e9RvyLAQkoCx
Nu sunt modificari locale: rulaje.vc2 reflecta binarul actualizat din SVN
(coloane cValoare* + butoane modifica_* pe Page2), iar wincrypt.h e un header
nou versionat in SVN care lipsea din git.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqJ7D5ftMbChDyz5mpVkCd
AnafeFacturaServer.ImportZipLocal (programe/anaf_efactura.prg): dezarhiveaza
arhiva aleasa de utilizator, ia xml-ul facturii (ignora semnatura MFinante),
ParseEFactura, decide FACTURA PRIMITA/TRIMISA dupa codul fiscal al firmei
curente, copiaza arhiva in directorul local de raspunsuri si scrie in Oracle
prin acelasi lant ca descarcarea din SPV (cursor temporar canaf_efactura_temp
+ cUpdateFactura + UpdateDb -> pack_anaf.AdaugaRaspunsFactura si
anaf_efactura_detalii). Fara SQL scris de mana si fara duplicarea maparii de
campuri.
clase/anaf_efactura.vcx (clasa anaf_efactura, metoda citesteraspunsuri):
optiunea 8 in meniul butonului "Raspunsuri" - "Import arhiva zip de pe disc...".
Necesar cand mesajul nu mai e in lista de raspunsuri ANAF (expira dupa 60 zile)
si factura primita nu a ajuns in borderou.
Testare (CENTRAL/MARIUSM_AUTO, ianuarie 2026, 12 PASS / 0 FAIL):
utile/Teste/efactura_import/ - garda pe cod fiscal, import complet cu verificarea
campurilor si a liniilor in anaf_efactura_detalii, factura vizibila in grila reala
"Facturi primite in SPV".
utile/Teste/test_init_env_auto.prg: adauga goFirma.codfiscalfro ca in start_firma
(ostartfirma.prg) - proprietatea nu e coloana in v_firme, iar fara ea orice cod
care o citeste nepazit crapa in mediul headless.
docs/depanare_testare_vfp.md: verificarea de sintaxa prin compilare headless
(config.fpw cu SAFETY=OFF, copie in scratchpad) si capcana literalelor string
mai lungi de 255 de caractere (eroare de compilare, nu de runtime).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqJ7D5ftMbChDyz5mpVkCd