* test_s3b_emitere_reala.prg * Criteriul 1 de "gata" al S3b, PROBA REALA (nu structurala): emite documente REALE in Oracle * (MARIUSM_AUTO@ROA_CENTRAL, aprobat explicit de Marius) prin fluxul de emitere efectiv, pe * fiecare din cele patru tipuri de incasare (1=Fara incasare, 2=Chitanta, 3=Bon fiscal, 4=POS/Card), * o data pe formularul vechi (frm_facturare_articole) si o data pe cel unificat * (frm_facturare_articole2), si compara randurile persistate in VANZARI dupa commit. * * Sursa documentului e cursor_preturi (lista de preturi, client RAJA id_part=463) cu tnTip=22 - * singura combinatie confirmata prin proba read-only (probe_emitere_reala.prg) ca intoarce articole * in acest mediu; tnTip=5 (FACTURA direct) da Reccount=0. Numerotarea/serie a documentului ramane * cea naturala pentru tnTip=22 (AVIZ, nIdTipDoc=6, plaja globala) - neatinsa, nu conteaza pentru * criteriul de paritate a INCASARII, care e independent de seria documentului. * * Mecanica bazata pe COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg (mediu Oracle real * + clase de productie, dovedit ca emite documente reale pentru tnTip=22): dialogul modal de antet * e inlocuit cu setare directa poDate (ca acolo), iar "Do Form verificare" (ofacturare.vc2:14404 / * :20126) e ocolit cu acelasi stub versionat COMUN\utile\Teste\achizitie_import\stub_verificare\ * (SET PATH cu el primul). * * Diferenta fata de creeaza_documente_s8.prg: al doilea modal (frm_alte_date, doar pe calea veche) * NU e doar "confirmat" - un driver pe Timer ii seteaza opt_incasat.Value la tipul cerut INAINTE * sa-i cheme do_termin(), exact tehnica validata structural in test_s3b_paritate_emitere.prg (setarea * de .Value declanseaza opt_incasat.ProgrammaticChange -> actualizeaza_tipincasare(), cod real). * Pe calea noua nu exista al doilea modal (opt_incasat e inline pe formular): se seteaza direct pe * goFrm inainte de goFrm.do_termin(). * * De ce NU se compara nr_incasare/NR_INCASAT intre vechi si nou (asa cum a facut suita structurala): * acolo numerele erau dezalocate dupa fiecare tip, deci acelasi numar fizic se realoca in faza 2. * Aici documentele raman scrise (nu se dezaloca nimic dupa un commit reusit), deci vechi si nou aloca * NUMERE DIFERITE, consecutive, din aceeasi plaja - egalitatea lor ar fi o eroare, nu o dovada. * Paritatea reala verificata e (a) consistenta interna - VANZARI.NR_INCASAT persistat == poDate.nr_incasare * capturat chiar inainte de scriere, pe fiecare document in parte, si (b) egalitatea intre vechi/nou a * CODULUI de tip (VANZARI.TIP_INCASAT) si a SUMEI (VANZARI.SUMA_INCASAT) - marimi care nu depind de * alocarea secventiala si trebuie sa fie identice daca cele doua cai proceseaza acelasi lcListaIncasare. * * CONSUMA DATE REALE: fiecare pereche (tip, forma) scrie un document nou in VANZARI (client 463), * iar tipurile 2/3/4 aloca si un numar real de chitanta/bon fiscal/pos (serii 16/3/26). Niciun * rollback, nicio stergere - documentele raman in schema, de inspectat de Marius. * * Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\test_s3b_emitere_reala.prg" * Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s3b_emitere_reala.log SET SAFETY OFF SET TALK OFF SET DELETED ON SET EXACT ON SET CENTURY ON SET DATE DMY SET DECIMALS TO 4 SET NULLDISPLAY TO '' CLOSE DATABASES PUBLIC gcLog, gnPass, gnFail gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s3b_emitere_reala.log" STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLog) gnPass = 0 gnFail = 0 ON ERROR DO S3bErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() ON SHUTDOWN QUIT TRY LOCAL lcAppPathLocal, lcSql lcAppPathLocal = "D:\ROA\ROAFACTURARE\" *-- stub_verificare PRIMUL (SET PATH plain, nu ADDITIVE): test_init_env_auto_roafacturare.prg *-- face el insusi SET PATH TO ... ADDITIVE mai jos, care ADAUGA dupa (nu inaintea) intrarilor *-- deja existente - asta pastreaza stub_verificare cu prioritate fata de COMUN\FERESTRE, ca *-- "Do Form verificare" (ofacturare.vc2:14404 / :20126) sa rezolve la stub, nu la formularul real SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\achizitie_import\stub_verificare" *-- mediul REAL, identic cu cel folosit de test_s3b_paritate_emitere.prg (deja dovedit ca *-- instantiaza fara agatare frm_facturare_articole2 - orice reconstructie manuala a acestui *-- mediu s-a dovedit incompleta si a agatat headless in interiorul Init-ului formularului nou, *-- la constructia coloanei Gestiune din grd_factura (vezi raport) DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0 DO S3bLog WITH 'EROARE: conectare Oracle esuata' DO S3bFinal ENDIF DO S3bLog WITH 'test_init_env_auto_roafacturare OK, gnHandle=' + TRANSFORM(gnHandle) *-- fara asta, un lacat Oracle blocheaza rularea la infinit, invizibil in log SQLSETPROP(gnHandle, "QueryTimeOut", 45) *-- clase suplimentare, necesare pentru grd_factura (coloane cu combo pe cursor SQL) SET PATH TO (lcAppPathLocal + "COMUN\utile\gridextras") ADDITIVE SET CLASSLIB TO gridextras.vcx ADDITIVE SET CLASSLIB TO _cb_base.vcx ADDITIVE DO S3bLog WITH 'SET CLASSLIB suplimentar OK' *-- mock amessagebox: la nume duplicat castiga fisierul de proceduri deschis cel mai recent SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE DO S3bLog WITH 'mock_amessagebox OK' *-- CdocGasesteIdVanzare: dovada de scriere pe jonctiunea serie_act + nract SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\lib_comparatie_documente.prg" ADDITIVE *-- initializare REALA a optiunilor de program (tehnica din test_s3b_paritate_emitere.prg) - *-- creeaza dinamic globalele gnXxx/glXxx/gcXxx din tabela OPTIUNI; suprascrise imediat dupa *-- cu valorile care bypaseaza dialogurile per-linie in mediul headless IF !actualizeaza_optiuni_program() DO S3bLog WITH 'EROARE: actualizeaza_optiuni_program()' DO S3bFinal ENDIF gnScadereStoc = 0 gnModTotFact = 0 gnFactSeturi = 0 gnListareAvizBonFiscal = 0 gnid_part_casa = 0 *-- 167: singura sucursala cu plaje pentru chitanta/bon fiscal/pos in acest mediu (16/3/26); *-- verificat READ-ONLY (probe_emitere_reala.prg) ca nu schimba Reccount(cursor_preturi) gnIdSucursala = 167 lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;] goExecutor.oExecuta(lcSql) DO S3bLog WITH 'actualizeaza_optiuni_program OK, gnScadereStoc=' + TRANSFORM(gnScadereStoc) + ' gnIdSucursala=' + TRANSFORM(gnIdSucursala) PUBLIC gcMockUltimMesaj, gnMockUltimTip gcMockUltimMesaj = '' gnMockUltimTip = 0 *----- driver: conduce frm_alte_date (singurul modal ramas, doar pe calea veche) ----- PUBLIC goDriverAD, glDlgTratatAD, gnTipIncasareCerut, gnNrIncasareCapturat, gcClaseVazute glDlgTratatAD = .F. gnTipIncasareCerut = 1 gnNrIncasareCapturat = 0 gcClaseVazute = ';' goDriverAD = CREATEOBJECT('driverAlteDateAD') _SCREEN.AddObject('tmrDrvAD', 'Timer') _SCREEN.tmrDrvAD.Interval = 200 BINDEVENT(_SCREEN.tmrDrvAD, 'Timer', goDriverAD, 'Executa') _SCREEN.tmrDrvAD.Enabled = .T. *-- _SCREEN ramane invizibil (default -A -T), ca in test_s3b_paritate_emitere.prg - un GETFILE() *-- nativ (dialog "Open") aparut la o SET SCREEN VISIBLE = .T. a agatat rularea (vezi raport) _SCREEN.Caption = 'S3b - emitere reala (paritate incasare vechi/nou)' DO S3bLog WITH 'driver+timer pregatiti' *-- pre-proba plajelor 3/16/26 - plasa de siguranta, evita blocaj invizibil daca lipsesc DO S3bLog WITH 'pre-proba plaje: tip3=' + TRANSFORM(RanduriSerii(3)) + ' tip16=' + TRANSFORM(RanduriSerii(16)) + ; ' tip26=' + TRANSFORM(RanduriSerii(26)) *-- stare INAINTE: ultimul NR_INCASAT emis pe fiecare tip de incasare, in TOATA schema DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE INAINTE (MAX(NR_INCASAT) pe tip_incasat, toata schema) =====' DO LogStareMaxIncasat CREATE CURSOR crsRezultate (tip_incasare N(1), forma C(10), id_vanzare N(10), cod N(10), ; serie_act C(10), id_fact N(10), nr_incasare_asteptat N(10), nr_incasat N(10), ; tip_incasat N(10), suma_incasat N(18,2), serie_incasat C(10), total_cu_tva N(18,2)) LOCAL laNumeTip[4] laNumeTip[1] = 'Fara incasare' laNumeTip[2] = 'Chitanta' laNumeTip[3] = 'Bon fiscal' laNumeTip[4] = 'POS Card' *-- FORMA NOUA: BLOCATA in aceasta sesiune (vezi docs\raport_s3b_emitere_reala.md) - *-- frm_facturare_articole2 agata la CREATEOBJECT (Init -> grd_factura.cGestiune.cCboGestiune *-- -> _cb_base.vc2 combosql.Init:589 -> RefreshData(0):826 -> SelectData():832 -> un dialog *-- nativ "Open" real, needeterminat cauzal, indiferent de mediu/tip/vizibilitate _SCREEN). *-- Ramane .F. neconditionat aici; DACA se rezolva blocajul, se schimba in .T. pentru ambele. PUBLIC glIncercaFormaNoua glIncercaFormaNoua = .F. LOCAL lnTip, lnIdVz FOR lnTip = 1 TO 4 DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA VECHE (tnTip=22) =====' lnIdVz = CreeazaDocumentIncasare(lnTip, .F.) DO InregistreazaRezultat WITH lnTip, 'vechi', lnIdVz IF glIncercaFormaNoua DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA NOUA (tnTip=3) =====' lnIdVz = CreeazaDocumentIncasare(lnTip, .T.) DO InregistreazaRezultat WITH lnTip, 'nou', lnIdVz ELSE DO S3bLog WITH ' forma noua SARITA (blocata, vezi raport)' ENDIF ENDFOR DO S3bLog WITH CHR(13)+CHR(10) + '===== COMPARATIE VECHI / NOU, PE TIP =====' DO ComparaRezultate DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE DUPA (MAX(NR_INCASAT) pe tip_incasat, toata schema) =====' DO LogStareMaxIncasat _SCREEN.tmrDrvAD.Enabled = .F. DO S3bFinal CATCH TO loExc DO S3bLog WITH 'CATCH TOP-LEVEL ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']' DO S3bFinal ENDTRY QUIT *================================================================================== PROCEDURE S3bLog LPARAMETERS tcMsg STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLog, 1) ENDPROC PROCEDURE S3bErr LPARAMETERS tnErr, tcMsg, tcProg, tnLine DO S3bLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg ENDPROC PROCEDURE S3bFinal DO S3bLog WITH CHR(13)+CHR(10) + 'TOTAL pass=' + TRANSFORM(gnPass) + ' fail=' + TRANSFORM(gnFail) DO S3bLog WITH 'END ' + TTOC(DATETIME()) QUIT ENDPROC PROCEDURE Assert LPARAMETERS tlCond, tcMsg IF tlCond gnPass = gnPass + 1 DO S3bLog WITH 'PASS: ' + tcMsg ELSE gnFail = gnFail + 1 DO S3bLog WITH 'FAIL: ' + tcMsg ENDIF ENDPROC *-- cate randuri de plaja intoarce verifica_cursor_serii pentru un tip de document, fara sa aloce FUNCTION RanduriSerii LPARAMETERS tnIdTipDoc LOCAL lnOk, lnRanduri, lcSql LOCAL ARRAY laErr[1] PRIVATE pnIdTipDoc, pnRezultat pnIdTipDoc = tnIdTipDoc pnRezultat = 0 lnRanduri = -1 lcSql = "{call " + gcS + ".pack_serii_numere.verifica_cursor_serii(?pnIdTipDoc,?gnIdUtil,?gnIdSucursala,?@pnRezultat)}" lnOk = SQLEXEC(gnHandle, lcSql, "crsprobapl") IF lnOk > 0 lnRanduri = RECCOUNT("crsprobapl") USE IN (SELECT("crsprobapl")) ELSE AERROR(laErr) DO S3bLog WITH 'pre-proba plaje tip ' + TRANSFORM(tnIdTipDoc) + ' ESEC: ' + TRANSFORM(laErr[2]) ENDIF RETURN lnRanduri ENDFUNC PROCEDURE LogStareMaxIncasat LOCAL lnQ lnQ = goExecutor.oExecute([select tip_incasat, max(nr_incasat) as maxnr, count(*) as nr ] + ; [from vanzari where tip_incasat is not null group by tip_incasat order by tip_incasat], 'crsMaxInc') IF lnQ > 0 SELECT crsMaxInc SCAN DO S3bLog WITH ' tip_incasat=' + TRANSFORM(tip_incasat) + ' max(nr_incasat)=' + TRANSFORM(maxnr) + ' nr_documente=' + TRANSFORM(nr) ENDSCAN USE IN crsMaxInc ELSE DO S3bLog WITH ' EROARE citire stare incasat: ' + goExecutor.oPrelucrareEroare() ENDIF ENDPROC *-- citeste randul VANZARI scris pentru id_vanzare si-l adauga in crsRezultate PROCEDURE InregistreazaRezultat LPARAMETERS tnTip, tcForma, tnIdVz DO Assert WITH tnIdVz > 0, '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] documentul exista in VANZARI (jonctiune serie_act+nract), e=' + TRANSFORM(tnIdVz) IF tnIdVz <= 0 DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': documentul NU s-a scris (id_vanzare=0), fara rand in VANZARI' INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, 0) RETURN ENDIF LOCAL lnQ lnQ = goExecutor.oExecute([select id_vanzare, cod, serie_act, nvl(id_fact,0) as id_fact, ] + ; [nvl(nr_incasat,0) as nr_incasat, nvl(tip_incasat,0) as tip_incasat, nvl(suma_incasat,0) as suma_incasat, ] + ; [nvl(serie_incasat,'') as serie_incasat, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVz), 'crsVz1') IF lnQ <= 0 OR RECCOUNT('crsVz1') <> 1 DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': EROARE citire VANZARI id_vanzare=' + TRANSFORM(tnIdVz) INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, tnIdVz) RETURN ENDIF SELECT crsVz1 INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare, cod, serie_act, id_fact, ; nr_incasare_asteptat, nr_incasat, tip_incasat, suma_incasat, serie_incasat, total_cu_tva) ; VALUES (tnTip, tcForma, tnIdVz, crsVz1.cod, NVL(crsVz1.serie_act,''), crsVz1.id_fact, ; gnNrIncasareCapturat, crsVz1.nr_incasat, crsVz1.tip_incasat, crsVz1.suma_incasat, NVL(crsVz1.serie_incasat,''), crsVz1.total_cu_tva) DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': id_vanzare=' + TRANSFORM(tnIdVz) + ' cod=' + TRANSFORM(crsVz1.cod) + ; ' serie_act=' + TRANSFORM(crsVz1.serie_act) + ' id_fact=' + TRANSFORM(crsVz1.id_fact) + ; ' nr_incasat=' + TRANSFORM(crsVz1.nr_incasat) + ' (asteptat ' + TRANSFORM(gnNrIncasareCapturat) + ') tip_incasat=' + TRANSFORM(crsVz1.tip_incasat) + ; ' suma_incasat=' + TRANSFORM(crsVz1.suma_incasat) + ' serie_incasat=[' + TRANSFORM(crsVz1.serie_incasat) + ']' + ; ' total_cu_tva=' + TRANSFORM(crsVz1.total_cu_tva) USE IN crsVz1 DO Assert WITH crsRezultate.nr_incasat = gnNrIncasareCapturat, ; '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] VANZARI.NR_INCASAT persistat (' + TRANSFORM(crsRezultate.nr_incasat) + ; ') == poDate.nr_incasare capturat inainte de scriere (' + TRANSFORM(gnNrIncasareCapturat) + ')' ENDPROC PROCEDURE ComparaRezultate LOCAL lnTip, lnRVechi, lnRNou IF !glIncercaFormaNoua DO S3bLog WITH ' forma noua sarita in aceasta rulare - fara comparatie vechi/nou, doar valorile persistate pe forma veche' RETURN ENDIF FOR lnTip = 1 TO 4 SELECT crsRezultate LOCATE FOR tip_incasare = lnTip AND forma == 'vechi' IF !FOUND() DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand vechi gasit in crsRezultate' LOOP ENDIF lnRVechi = RECNO() LOCATE FOR tip_incasare = lnTip AND forma == 'nou' IF !FOUND() DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand nou gasit in crsRezultate' LOOP ENDIF lnRNou = RECNO() LOCAL lnIdVechi, lnIdNou, lnTipIncVechi, lnTipIncNou, lnSumaVechi, lnSumaNou, lcSerieVechi, lcSerieNou GO lnRVechi IN crsRezultate lnIdVechi = crsRezultate.id_vanzare lnTipIncVechi = crsRezultate.tip_incasat lnSumaVechi = crsRezultate.suma_incasat lcSerieVechi = crsRezultate.serie_incasat GO lnRNou IN crsRezultate lnIdNou = crsRezultate.id_vanzare lnTipIncNou = crsRezultate.tip_incasat lnSumaNou = crsRezultate.suma_incasat lcSerieNou = crsRezultate.serie_incasat IF lnIdVechi <= 0 OR lnIdNou <= 0 DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] ambele documente s-au scris (vechi id_vanzare=' + ; TRANSFORM(lnIdVechi) + ' nou id_vanzare=' + TRANSFORM(lnIdNou) + ')' LOOP ENDIF DO Assert WITH lnTipIncVechi = lnTipIncNou, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.TIP_INCASAT identic (vechi=' + ; TRANSFORM(lnTipIncVechi) + ' nou=' + TRANSFORM(lnTipIncNou) + ')' DO Assert WITH ABS(lnSumaVechi - lnSumaNou) < 0.005, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SUMA_INCASAT identica (vechi=' + ; TRANSFORM(lnSumaVechi) + ' nou=' + TRANSFORM(lnSumaNou) + ')' DO Assert WITH ALLTRIM(lcSerieVechi) == ALLTRIM(lcSerieNou), '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SERIE_INCASAT identica (vechi=[' + ; ALLTRIM(lcSerieVechi) + '] nou=[' + ALLTRIM(lcSerieNou) + '])' ENDFOR ENDPROC *================================================================================== * CreeazaDocumentIncasare: emite un document REAL prin fluxul de productie (tnTip=22, cursor_preturi, * client RAJA id_part=463), aplicand tipul de incasare cerut pe formularul indicat. Intoarce * poDate.nid_vanzare (>0 succes) sau 0 (esec, detaliat in log). gnNrIncasareCapturat e umplut cu * poDate.nr_incasare chiar inainte de do_termin() - marimea persistata se verifica fata de asta. FUNCTION CreeazaDocumentIncasare LPARAMETERS tnTipIncasare, tlFormNou PRIVATE poDate, poGeneratorNumere, poDateGestiuneDest LOCAL lnIdSet, lcSqlCursor, lcCursor, lnSucces, lnIdVanzareRezultat, tnTip, tnIdClient, tnIdDelegat LOCAL lcSerieAlocata, lnNractAlocat lnIdVanzareRezultat = 0 lcSerieAlocata = '' lnNractAlocat = 0 gnNrIncasareCapturat = 0 *-- FORMA VECHE: tnTip=22 (AVIZ din lista de preturi) - calea PROVENITA, curata, fara efecte *-- secundare (nu intra pe ramura "comanda" din do_scrie_factura). opt_incasat traieste pe *-- frm_alte_date (clasa separata), deci nu are restrictia Between(poDate.tip,1,4). *-- FORMA NOUA: are nevoie de tnTip Between(1,4) ca opt_incasat sa existe inline pe formular *-- (ofacturare.vc2:21066) - singurele din acel interval cu date reale in cursor_preturi sunt *-- 3/4 (probe_emitere_reala.prg), dar tnTip=3 declanseaza un MESSAGEBOX_FORM real necunoscut *-- mock-ului ("Doriti sa se inchida comanda?") si formularul nou insusi agata la CREATEOBJECT *-- pe coloana Gestiune a grd_factura (vezi raport) - BLOCAT, nerezolvat in aceasta sesiune. tnTip = IIF(tlFormNou, 3, 22) tnIdClient = 463 tnIdDelegat = 256 update_jtva_coloane([JV], [jtva_coloane_temp]) update_saft_taxtable() lnIdSet = 25000 + tnTip - 1 + gnScadereStoc * 10 poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip) poGeneratorNumere = CREATEOBJECT("oGeneratorNumere") poDateGestiuneDest = CREATEOBJECT("oDateGestiune") IF !tlFormNou poDate.nIdTipDoc = 6 && AVIZ - plaja globala, dovedit (id_vanzare 1061/1062/1063) ENDIF gnIdUtil = 8 poGeneratorNumere.ResetNumere() poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc) poDate.id_client = tnIdClient poDate.id_delegat = tnIdDelegat poDate.zi_curs = {^2026-08-10} IF poDate.rezultat_serii = 3 poDate.serie_act = poGeneratorNumere.getSerieCursor(poDate.nIdTipDoc) ENDIF poDate.nract = poGeneratorNumere.aloca_numar(poDate.nIdTipDoc, NULL) poGeneratorNumere.verifica_numar(poDate.nIdTipDoc, poDate.nract) gnIdUtil = -3 lcSerieAlocata = ALLTRIM(TRANSFORM(NVL(poDate.serie_act, []))) lnNractAlocat = poDate.nract DO S3bLog WITH ' poDate.nract=' + TRANSFORM(poDate.nract) + ' serie_act=[' + TRANSFORM(NVL(poDate.serie_act,[])) + ']' IF poDate.tva_incasare = 0 SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane ELSE SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane ENDIF lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_preturi(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ; [?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala)}] lcCursor = [crsarticole] lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor) IF lnSucces < 0 DO S3bLog WITH ' EROARE cursor articole: ' + goExecutor.oPrelucrareEroare() poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) DO S3bCurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF IF RECCOUNT(lcCursor) = 0 DO S3bLog WITH ' Nu exista articole (Reccount=0) - abandon document' poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) DO S3bCurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF DO S3bLog WITH ' crsarticole Reccount=' + TRANSFORM(RECCOUNT(lcCursor)) *-- Lista de preturi a articolului e in EURO (tip_valuta=1), iar do_scrie_articole *-- trimite pe ramura aceea vpretftva, derivat din pret_val - fortand doar pret, *-- documentul iesea cu VANZARI_DETALII.PRET=0. Se forteaza perechea, coerent cu cursul. SELECT (lcCursor) REPLACE ALL cantitate WITH 1, ; pret_val WITH IIF(tip_valuta = 1, 100, 0), ; pret WITH IIF(tip_valuta = 1, ROUND(100 * IIF(NVL(curs, 0) = 0, 1, curs) / IIF(NVL(multiplicator, 0) = 0, 1, multiplicator), gnPPretV), 100) =TABLEUPDATE(.T., .T., lcCursor) GO TOP creeaza_facturacrs([crsfactura]) IF poDate.in_valuta = 1 SELECT DISTINCT Curs, nume_val, id_valuta, multiplicator FROM (lcCursor) WITH (Buffering = .T.) WHERE tip_valuta = 1 ORDER BY nume_val INTO CURSOR crscursuri SELECT crscursuri poDate.Curs = Curs poDate.multiplicator = multiplicator ELSE citeste_cursuri_zi(poDate.zi_curs) IF RECCOUNT('crscursuri') = 0 USE IN crscursuri ENDIF ENDIF IF TYPE(lcCursor + '.nume_lista_preturi') <> 'U' CREATE CURSOR crspolitici (id_pol N(20), nume_lista_preturi c(100)) SELECT crspolitici INSERT INTO crspolitici(id_pol, nume_lista_preturi) VALUES (-9999, '') INSERT INTO crspolitici(id_pol, nume_lista_preturi) ; SELECT DISTINCT id_pol, nume_lista_preturi FROM (lcCursor) ORDER BY nume_lista_preturi ENDIF *-- formularul, modeless (apel direct de metode) - vechi sau unificat, dupa tlFormNou PUBLIC goFrmS3b IF tlFormNou goFrmS3b = CREATEOBJECT('frm_facturare_articole2') ELSE goFrmS3b = CREATEOBJECT('frm_facturare_articole') ENDIF DO S3bLog WITH ' CREATEOBJECT OK, VARTYPE=' + VARTYPE(goFrmS3b) goFrmS3b.WindowType = 0 DO S3bLog WITH ' WindowType=0 OK' goFrmS3b.Show() DO S3bLog WITH ' Show() OK' DOEVENTS FORCE DO S3bLog WITH ' formular afisat modeless (' + IIF(tlFormNou, 'NOU frm_facturare_articole2', 'VECHI frm_facturare_articole') + ')' goFrmS3b.do_adauga_tot() DOEVENTS FORCE DO S3bLog WITH ' do_adauga_tot() -> Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) goFrmS3b.do_calculeaza_totaluri() DOEVENTS FORCE *-- CONT_VENIT asteptat, derivat exact ca in do_scrie_articole (ofacturare.vc2:14279), citit *-- direct din randul crsfactura pe care do_scrie_articole il va scana LOCAL lcExpContVenit, lnExpIdPol, lnExpIdArticol, lcExpCont, loExecutorReal SELECT crsfactura GO TOP lnExpIdPol = crsfactura.id_pol lnExpIdArticol = crsfactura.id_articol lcExpCont = crsfactura.Cont lcExpContVenit = IIF(EMPTY(NVL(lnExpIdPol, 0)), deriva_cont_venit_fara_pol(lnExpIdArticol, lcExpCont), '') *-- spion pe goExecutor (tehnica SpyS13, probe_s13_toomanycolumns.prg): captureaza SQL-ul real *-- trimis de do_scrie_articole, fara sa-i schimbe comportamentul (DODEFAULT pe PCOUNT) loExecutorReal = goExecutor goExecutor = CREATEOBJECT('SpyContVenit') goExecutor.nHandle = gnHandle LOCAL lnScris IF tlFormNou *-- opt_incasat e inline pe formular - fara al doilea modal goFrmS3b.seteaza_mod_incasare(tnTipIncasare) gnNrIncasareCapturat = poDate.nr_incasare DO S3bLog WITH ' opt_incasat.Value=' + TRANSFORM(tnTipIncasare) + ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ; ' incasat=' + TRANSFORM(poDate.incasat) + ' incasatCARD=' + TRANSFORM(poDate.incasatCARD) lnScris = goFrmS3b.do_termin() ELSE *-- calea veche: al doilea modal (frm_alte_date) e condus de goDriverAD/tmrDrvAD glDlgTratatAD = .F. gnTipIncasareCerut = tnTipIncasare lnScris = goFrmS3b.do_termin() LOCAL lnWait lnWait = 0 DO WHILE !glDlgTratatAD AND lnWait < 10 DOEVENTS FORCE lnWait = lnWait + 1 ENDDO ENDIF DO S3bLog WITH ' do_termin() -> ' + TRANSFORM(lnScris) + ' poDate.nid_vanzare=' + TRANSFORM(NVL(poDate.nid_vanzare,0)) *-- restaureaza goExecutor real si verifica CONT_VENIT trimis de do_scrie_articole LOCAL lcActualContVenit, lcEticheta lcEticheta = '[' + IIF(tlFormNou,'nou','vechi') + ' tip=' + TRANSFORM(tnTipIncasare) + ']' DO Assert WITH goExecutor.cLastArtCall # '', ; lcEticheta + ' do_scrie_articole a trimis adauga_articol_factura (spion pe goExecutor)' IF goExecutor.cLastArtCall # '' lcActualContVenit = ExtrageContVenit(goExecutor.cLastArtCall) DO Assert WITH lcActualContVenit == lcExpContVenit, ; lcEticheta + ' CONT_VENIT trimis de do_scrie_articole = [' + lcExpContVenit + '], obtinut [' + lcActualContVenit + ']' ENDIF goExecutor = loExecutorReal *-- do_termin() intoarce mereu .T. (_frm_base.vc2:363, DoDefault fara RETURN) si nid_vanzare *-- ramane santinela la esec: singura dovada e randul din VANZARI, pe serie_act + nract. lnIdVanzareRezultat = CdocGasesteIdVanzare(lcSerieAlocata, lnNractAlocat) IF lnIdVanzareRezultat < 0 lnIdVanzareRezultat = 0 ENDIF DO S3bLog WITH ' verificare in VANZARI pe ' + lcSerieAlocata + ' ' + TRANSFORM(lnNractAlocat) + ; ' -> id_vanzare=' + TRANSFORM(lnIdVanzareRezultat) IF TYPE('goFrmS3b') = 'O' AND !ISNULL(goFrmS3b) goFrmS3b.Release() ENDIF goFrmS3b = NULL IF USED('crspolitici') USE IN crspolitici ENDIF IF USED('crscursuri') USE IN crscursuri ENDIF IF USED('crsfactura') USE IN crsfactura ENDIF IF USED('crsarticole') USE IN crsarticole ENDIF IF USED('jtva_coloane') USE IN jtva_coloane ENDIF IF USED('jtva_coloane_temp') USE IN jtva_coloane_temp ENDIF RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN lnIdVanzareRezultat ENDFUNC PROCEDURE S3bCurataJtva IF USED('jtva_coloane') USE IN jtva_coloane ENDIF IF USED('jtva_coloane_temp') USE IN jtva_coloane_temp ENDIF ENDPROC *-- extrage parametrul 29 (CONT_VENIT) dintr-un apel capturat pack_facturare.adauga_articol_factura(...); *-- pozitia 28 e mereu literalul NULL, deci pos29 e tot ce urmeaza dupa ultima virgula dinaintea "); end;" FUNCTION ExtrageContVenit LPARAMETERS tcSql LOCAL lnEnd, lcParams, lnComma, lcPos29 lnEnd = AT('); end;', tcSql) IF lnEnd = 0 RETURN '' ENDIF lcParams = LEFT(tcSql, lnEnd - 1) lnComma = RAT(',', lcParams) IF lnComma = 0 RETURN '' ENDIF lcPos29 = SUBSTR(lcParams, lnComma + 1) IF UPPER(lcPos29) == 'NULL' RETURN '' ENDIF RETURN STRTRAN(lcPos29, "'", '') ENDFUNC *================================================================================== *-- SpyContVenit: subclasa a lui oexecutor (tehnica SpyS13 din probe_s13_toomanycolumns.prg) - *-- logheaza in cLastArtCall statementul adauga_articol_factura, apoi executa normal prin *-- DODEFAULT pe PCOUNT (fara sa schimbe comportamentul real) DEFINE CLASS SpyContVenit AS oexecutor cLastArtCall = '' PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect) LOCAL lnPc, lcS, lnRet lnPc = PCOUNT() lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '') IF 'adauga_articol_factura(' $ lcS THIS.cLastArtCall = lcS ENDIF TRY DO CASE CASE lnPc <= 1 lnRet = DODEFAULT(m.tcSql) CASE lnPc = 2 lnRet = DODEFAULT(m.tcSql, m.tcCursor) CASE lnPc = 3 lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress) CASE lnPc = 4 lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress) CASE lnPc = 5 lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle) CASE lnPc = 6 lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError) CASE lnPc = 7 lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError) OTHERWISE lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect) ENDCASE CATCH TO loExSpy lnRet = -1 THIS.cEroare = 'SpyContVenit: ' + TRANSFORM(loExSpy.Message) ENDTRY RETURN lnRet ENDPROC ENDDEFINE *================================================================================== *-- driverAlteDateAD: cauta FRM_ALTE_DATE prin _SCREEN.Forms si ii seteaza opt_incasat.Value la * gnTipIncasareCerut INAINTE de a-i chema .do_termin() - acelasi mecanism ca driverAlteDate8 din * creeaza_documente_s8.prg, cu un singur adaos (selectia tipului de incasare). DEFINE CLASS driverAlteDateAD AS Custom PROCEDURE Executa LOCAL lnI, loForm, llGasit, loMsgForm llGasit = .F. loMsgForm = NULL FOR lnI = 1 TO _SCREEN.FormCount LOCAL lcClasa lcClasa = UPPER(_SCREEN.Forms(lnI).Class) IF lcClasa == 'FRM_ALTE_DATE' loForm = _SCREEN.Forms(lnI) llGasit = .T. ENDIF IF 'MESSAGEBOX_FORM' $ lcClasa loMsgForm = _SCREEN.Forms(lnI) ENDIF IF !(lcClasa $ gcClaseVazute) gcClaseVazute = gcClaseVazute + lcClasa + ';' DO S3bLog WITH ' [diag timer] forma noua vazuta: ' + lcClasa + ' Caption=[' + TRANSFORM(_SCREEN.Forms(lnI).Caption) + ']' ENDIF ENDFOR *-- confirmare reala neacoperita de mock_amessagebox (forma modala messagebox_form) - *-- apasa automat cmdYes/cmdOk, ca in productie la raspuns implicit "Da" IF !ISNULL(loMsgForm) TRY DO CASE CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdYes', 5) DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdYes' loMsgForm.cmgBotones.cmdYes.Click() CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdOk', 5) DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdOk' loMsgForm.cmgBotones.cmdOk.Click() ENDCASE CATCH TO loExcMsg DO S3bLog WITH ' [diag timer] messagebox_form: CATCH ' + TRANSFORM(loExcMsg.ErrorNo) + ' ' + loExcMsg.Message ENDTRY ENDIF IF glDlgTratatAD OR !llGasit RETURN ENDIF LOCAL loAC loAC = loForm.ActiveControl TRY loForm.opt_incasat.Value = gnTipIncasareCerut gnNrIncasareCapturat = poDate.nr_incasare DO S3bLog WITH ' driverAlteDateAD: opt_incasat.Value=' + TRANSFORM(gnTipIncasareCerut) + ; ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ' incasat=' + TRANSFORM(poDate.incasat) + ; ' incasatCARD=' + TRANSFORM(poDate.incasatCARD) loForm.do_termin() glDlgTratatAD = .T. CATCH TO loExcDrv DO S3bLog WITH ' driverAlteDateAD: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ; ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo) glDlgTratatAD = .T. ENDTRY ENDPROC ENDDEFINE