Files
comun/utile/Teste/editare_factura/test_writeback_buton1.prg
Marius Mutu 13b4f65723 sync SVN r18004/r18007: #6 editare factura emisa - pagina de articole
ofacturare_editare.prg (nou): helpere comune - garda eFactura, cursoarele
notei si ale rulajelor, randul de vanzare corespunzator notei si liniile de
articole citite din view-ul VVANZARI_ARTICOLE.

omodificari.vc2 (frm_modific2024): pagina noua de articole ale facturii,
deocamdata doar afisare. Apare numai cand ofacturare_editare.prg e
inregistrat si documentul are rand in VANZARI; in ROACONT si ROAGEST, unde
fisierul nu e incarcat, pagina lipseste si registrul jurnal ramane neatins.
Randul de vanzare al notei se cauta pe toate tripletele distincte (nract,
serie_act, dataact) din nota, pentru ca primul rand poate fi o incasare.

ofacturare_comun.vc2 (frm_facturi): do_editare_factura si butonul aferent,
dupa modelul lui do_sterge, cu garzile de luna inchisa, luna curenta,
document sters, referinte si eFactura.

docs: comentariile se scriu strict necesar, si in cod si in scripturile de
migrare - fara referinte la planuri, stories, decizii sau erori, istoricul
doar in antetul fisierului. Plus regula zero (predarea contextului),
capcanele de la testarea headless si completari pe fluxul text -> binar.

utile/Teste: suita de regresie pentru editarea facturii si harness-ul
watchdog (nu sunt in SVN, unde utile/Teste e ignorat). .gitignore ignora si
capturile PNG si watchdog_out/, ramase din rulari.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-08 16:47:24 +03:00

524 lines
23 KiB
Plaintext

* test_writeback_buton1.prg
* Test REAL de write-back pentru ramura buton=1 a lui frm_facturi.do_editare_factura
* (COMUN\clase\ofacturare_comun.vc2:3805-3840) - APROBAT explicit de Marius pe 08.08.2026 sa
* scrie in schema de dev MARIUSM_AUTO@ROA_CENTRAL (nu doar sa citeasca).
*
* Document consumat: cod=1140886, id_vanzare=1048 (factura tip 1, 07-AUG-26, total_cu_tva=302.51,
* 1 linie in VANZARI_DETALII, 5 randuri in ACT, id_set=25010, id_fact=8009658, 1 rand in RUL).
* NU foloseste cod=1140888/1140885 (baze de regresie ale test_incarca_cursoare.prg).
*
* Harness, nu apel direct al metodei: nu instantiaza frm_facturi si NU mai instantiaza
* frm_modific2024 deloc (incercarea initiala s-a blocat la Createobject/Show pe un dialog nativ
* Windows "Open" - cursor/tabela lipsa in acest mediu minimal, capcana j din testare-ui-vfp.md -
* fara legatura cu calea de scriere care se testeaza aici). In loc, harnessul:
* 1) reproduce exact starea de cursoare pe care do_editare_factura o lasa inainte de
* Createobject('frm_modific2024',...) (IncarcaCursoareModificareNota, functia reala din
* ofacturare_editare.prg);
* 2) seteaza buton=1 direct (SARE peste inainte_de_do_termin - vezi ATENTIE mai jos);
* 3) ruleaza LITERAL codul ramurii buton=1 (copiat din ofacturare_comun.vc2:3805-3840).
* Thisform.do_deschide_tranzactie/do_inchide_tranzactie (mostenite nemodificate din _frm_base,
* fara dependinta de vreo clasa de formular anume) sunt reproduse local, INLINE, dupa codul din
* _frm_base.vc2:252-302 - ocolesc si instantierea unui _frmbase generic, ca sa nu riste acelasi
* fel de blocaj vazut la frm_modific2024.
*
* ATENTIE - ce NU acopera acest test: validarea din inainte_de_do_termin
* (omodificari.vc2:13357-13549 - verificare_note_contabile, echilibru 4426-4428,
* VerificaAvertizareExigibilizareTVA) si comportamentul real al formularului la butonul
* "Terminat". Testul demonstreaza ca LANTUL DE SCRIERE merge, nu ca utilizatorul ajunge la el
* prin UI - cele doua nu trebuie confundate la interpretarea rezultatului.
*
* Mediu: test_init_env_auto.prg (bootstrap ROACONT, conexiune reala MARIUSM_AUTO) - acelasi mediu
* folosit deja cu succes de test_incarca_cursoare.prg si test_page3_articole.prg. oscrie_in_fisiere.prg
* e incarcat explicit din COMUN-ul ROAFACTURARE (nu cel auto-rezolvat din calea ROACONT) ca sa
* ruleze exact fisierul pe care il ruleaza aplicatia.
*
* Ruleaza 2 treceri pe acelasi document (cod-ul se schimba dupa fiecare salvare, se recitesc din
* VANZARI la fiecare trecere):
* TEST 1 - salvare "goala" (fara nicio modificare in tact) - proba ca lantul chiar scrie.
* TEST 2 - modifica explicatia unui rand ACT inainte de salvare - proba ca modificarea ajunge.
*
* Nu atinge .PJX/.PJT/.exe, nu modifica cod aplicatie. QUIT la final.
SET SAFETY OFF
SET TALK OFF
LOCAL lcLog
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_writeback_buton1_log.txt'
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
PUBLIC gcErrLog
gcErrLog = lcLog
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
*-- mock amessagebox INCARCAT PRIMUL (inaintea lantului din test_init_env_auto, care incarca
*-- amessagebox real) - la nume duplicat de procedura, castiga fisierul cautat PRIMUL (testare-ui-vfp.md, capcana g)
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
QUIT
ENDIF
*-- verificare ca mock-ul chiar umbreste amessebox real (altfel un dialog real ar bloca headless)
LOCAL lnVerifMock
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
STRTOFILE('verificare mock amessagebox = ' + TRANSFORM(lnVerifMock) + ;
IIF(lnVerifMock = 6, ' (OK, mock activ)', ' (ATENTIE: real amessagebox activ, risc de blocaj)') + CHR(13) + CHR(10), lcLog, 1)
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oscrie_in_fisiere.prg ADDITIVE
IF TYPE('gnPC') <> 'N'
PUBLIC gnPC
gnPC = 2
ENDIF
*-- capteaza textul ultimului amessagebox mocked (mock_amessagebox.prg, liniile 13-14/23-26) -
*-- necesar ca sa vedem CE mesaj de eroare arunca oscrie_in_fisiere.prg pe caile de esec
PUBLIC gcMockUltimMesaj, gnMockUltimTip
gcMockUltimMesaj = ''
gnMockUltimTip = 0
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' gcS=' + gcS + CHR(13) + CHR(10), lcLog, 1)
DO test_editare_writeback WITH 1048, .F., 'TEST 1: salvare fara nicio modificare', lcLog
DO test_editare_writeback WITH 1048, .T., 'TEST 2: modificare explicatie pe un rand ACT', lcLog
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
QUIT
*-- executa SELECT-ul agregat prin goExecutor si intoarce lnSucces; NU citi campurile cursorului
*-- decat dupa ce ai verificat lnSucces > 0 (IIF() evalueaza ambele ramuri, ar da eroare pe alias lipsa)
PROCEDURE ExecAgg
LPARAMETERS tcSql, tcCursor
LOCAL lnQ
IF USED(tcCursor)
USE IN (tcCursor)
ENDIF
lnQ = goExecutor.oExecute(tcSql, tcCursor)
RETURN lnQ
ENDPROC
*-- logheaza si RESETEAZA gcMockUltimMesaj/goExecutor.cEroare - reseteaza ca sa nu se confunde
*-- mesajul de la un pas cu mesajul (sau lipsa lui) de la pasul urmator
PROCEDURE LogMockSiEroare
LPARAMETERS tcEticheta, tcLog
STRTOFILE(' [' + tcEticheta + '] gcMockUltimMesaj=[' + ALLTRIM(gcMockUltimMesaj) + '] ' + ;
'goExecutor.cEroare=[' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + ']' + CHR(13) + CHR(10), tcLog, 1)
gcMockUltimMesaj = ''
ENDPROC
*-- reproduce _frm_base.vc2:252-265 (do_deschide_tranzactie) fara sa instantieze niciun formular
PROCEDURE MyDeschideTranzactie
LOCAL llReturn, lnSuccesLocal
IF TYPE('goExecutor') = 'O'
goExecutor.oExecuta([select * from dual])
ENDIF
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 2)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
RETURN llReturn
ENDPROC
*-- reproduce _frm_base.vc2:279-302 (do_inchide_tranzactie) fara sa instantieze niciun formular
PROCEDURE MyInchideTranzactie
LPARAMETERS tnTip
LOCAL llReturn, lnSuccesLocal
IF tnTip = 1
lnSuccesLocal = SQLCOMMIT(gnHandle)
ELSE
lnSuccesLocal = SQLROLLBACK(gnHandle)
ENDIF
IF lnSuccesLocal < 0
llReturn = .F.
ELSE
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 1)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
ENDIF
RETURN llReturn
ENDPROC
PROCEDURE test_editare_writeback
LPARAMETERS tnIdVanzare, tlModificaLinie, tcEticheta, tcLog
*-- pnAn/pnLuna/lnCod/lnIdFact PRIVATE (nu LOCAL), identic cu declararea reala
*-- (ofacturare_comun.vc2:3742) - finalizeaza_modificare_nota le foloseste ca bind-variabile
*-- ?pnLuna/?pnAn in interiorul lui goExecutor.oExecuta, care le cere vizibile PRIVATE pe stiva
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
LOCAL lnSters, llEProforma
LOCAL lnIdSet, lnIdFactD, lnSucces, llGasitRand
LOCAL lcSql, lnQ
LOCAL lnActBeforeCnt, lnActBeforeSuma, lnRulBeforeCnt, lnRulObinvBeforeCnt
LOCAL lnVdCnt, lnVdSumaPret, lnVdSumaPretCuTva
LOCAL lcExplicatieVeche, lcExplicatieNoua
LOCAL lnVzCodBefore, lnVzStersBefore, lnVzTotalFaraTvaBefore, lnVzTotalTvaBefore, lnVzTotalCuTvaBefore, lnVzDiscountBefore
STRTOFILE(CHR(13) + CHR(10) + '========== ' + tcEticheta + ' (id_vanzare=' + TRANSFORM(tnIdVanzare) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
*-- 1) starea curenta din VANZARI (cod-ul se poate schimba fata de trecerea anterioara)
lcSql = [select cod, sters, id_fact, eproforma, total_fara_tva, total_tva, total_cu_tva, discount, ] + ;
[extract(year from data_act) as anact, extract(month from data_act) as lunaact from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecAgg(lcSql, 'v_vanzare_curenta')
IF lnQ <= 0 OR RECCOUNT('v_vanzare_curenta') <> 1
STRTOFILE('FAIL: VANZARI id_vanzare=' + TRANSFORM(tnIdVanzare) + ' - lnQ=' + TRANSFORM(lnQ) + ;
' reccount=' + IIF(lnQ > 0, TRANSFORM(RECCOUNT('v_vanzare_curenta')), '?') + ;
' cEroare=[' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + ']' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
SELECT v_vanzare_curenta
lnCod = cod
lnSters = sters
lnIdFact = id_fact
llEProforma = (eproforma = 1)
pnAn = anact
pnLuna = lunaact
lnVzCodBefore = cod
lnVzStersBefore = sters
lnVzTotalFaraTvaBefore = total_fara_tva
lnVzTotalTvaBefore = total_tva
lnVzTotalCuTvaBefore = total_cu_tva
lnVzDiscountBefore = discount
USE IN v_vanzare_curenta
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCod) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' total_cu_tva=' + TRANSFORM(lnVzTotalCuTvaBefore) + CHR(13) + CHR(10), tcLog, 1)
*-- 2) garzi (replica do_editare_factura, fara UI)
IF lnSters = 1
STRTOFILE(' SKIP: document deja sters' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
IF llEProforma
STRTOFILE(' SKIP: proforma' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
IF (pnAn*12) + pnLuna <> (gnAn*12) + gnLuna
STRTOFILE(' SKIP: nu e luna curenta (document ' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ', curenta ' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna) + ')' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
IF EsteInEFactura(lnIdFact)
STRTOFILE(' SKIP: trimis in eFactura' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
*-- 3) instantaneu INAINTE: ACT / RUL / RUL_OBINV (pe cod-ul curent) + VANZARI_DETALII
lcSql = [select count(*) as cnt, sum(suma) as totsuma from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
lnQ = ExecAgg(lcSql, 'v_act_before')
IF lnQ > 0
lnActBeforeCnt = v_act_before.cnt
lnActBeforeSuma = NVL(v_act_before.totsuma, 0)
USE IN v_act_before
ELSE
lnActBeforeCnt = -1
lnActBeforeSuma = -1
ENDIF
lcSql = [select count(*) as cnt from vrul_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
lnQ = ExecAgg(lcSql, 'v_rul_before')
IF lnQ > 0
lnRulBeforeCnt = v_rul_before.cnt
USE IN v_rul_before
ELSE
lnRulBeforeCnt = -1
ENDIF
lcSql = [select count(*) as cnt from vrul_obinv_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
lnQ = ExecAgg(lcSql, 'v_rulobinv_before')
IF lnQ > 0
lnRulObinvBeforeCnt = v_rulobinv_before.cnt
USE IN v_rulobinv_before
ELSE
lnRulObinvBeforeCnt = -1
ENDIF
lcSql = [select count(*) as cnt, sum(cantitate) as sumcant, sum(pret) as sumpret, sum(pret_cu_tva) as sumpretcutva ] + ;
[from vanzari_detalii where sters = 0 and id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecAgg(lcSql, 'v_vd_before')
IF lnQ > 0
lnVdCnt = v_vd_before.cnt
lnVdSumaPret = NVL(v_vd_before.sumpret, 0)
lnVdSumaPretCuTva = NVL(v_vd_before.sumpretcutva, 0)
USE IN v_vd_before
ELSE
lnVdCnt = -1
lnVdSumaPret = -1
lnVdSumaPretCuTva = -1
ENDIF
STRTOFILE(' INAINTE: ACT cnt=' + TRANSFORM(lnActBeforeCnt) + ' suma=' + TRANSFORM(lnActBeforeSuma) + ;
' RUL cnt=' + TRANSFORM(lnRulBeforeCnt) + ' RUL_OBINV cnt=' + TRANSFORM(lnRulObinvBeforeCnt) + ;
' VANZARI_DETALII cnt=' + TRANSFORM(lnVdCnt) + ' sum(pret)=' + TRANSFORM(lnVdSumaPret) + ' sum(pret_cu_tva)=' + TRANSFORM(lnVdSumaPretCuTva) + CHR(13) + CHR(10), tcLog, 1)
*-- 4) IncarcaCursoareModificareNota (functia reala, ofacturare_editare.prg)
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
STRTOFILE(' FAIL: IncarcaCursoareModificareNota a esuat (eroare Oracle)' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
IF RECCOUNT('actactan') = 0
STRTOFILE(' FAIL: nu exista nota contabila (Reccount(actactan)=0)' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
*-- 5) pozitionare id_fact/id_set/id_factd - copiat identic din do_editare_factura
*-- (ofacturare_comun.vc2:3785-3797; garda id_set scoasa - decizia 24, cod curent nu o mai are)
SELECT actactan
llGasitRand = .F.
IF lnIdFact > 0
LOCATE FOR NVL(id_fact, 0) = lnIdFact
llGasitRand = FOUND()
ENDIF
IF !llGasitRand
GO TOP
lnIdFact = id_fact
ENDIF
lnIdSet = id_set
lnIdFactD = NVL(id_factd, 0)
STRTOFILE(' pozitionare actactan: gasit=' + TRANSFORM(llGasitRand) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
' id_set=' + TRANSFORM(lnIdSet) + ' id_factd=' + TRANSFORM(lnIdFactD) + CHR(13) + CHR(10), tcLog, 1)
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
*-- 6) TEST 2: modifica un camp simplu si verificabil (explicatia) INAINTE de salvare
lcExplicatieVeche = ''
lcExplicatieNoua = ''
IF tlModificaLinie
SELECT tact
LOCATE FOR !EMPTY(ALLTRIM(NVL(explicatia, '')))
IF FOUND()
lcExplicatieVeche = ALLTRIM(explicatia)
lcExplicatieNoua = lcExplicatieVeche + ' (test writeback)'
REPLACE explicatia WITH lcExplicatieNoua
STRTOFILE(' modific tact.explicatia: [' + lcExplicatieVeche + '] -> [' + lcExplicatieNoua + ']' + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' ATENTIE: nu am gasit niciun rand cu explicatia completata, testul nu modifica nimic real' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
ENDIF
*-- 7) frm_modific2024 OCOLIT COMPLET (a blocat Createobject/Show pe dialog nativ "Open" -
*-- vezi antetul fisierului). buton=1 fortat direct - inainte_de_do_termin NU se executa.
buton = 1
STRTOFILE(' frm_modific2024 ocolit: buton=1 fortat direct, inainte_de_do_termin SARIT' + CHR(13) + CHR(10), tcLog, 1)
*-- 8) ramura buton=1 din do_editare_factura (ofacturare_comun.vc2:3805-3840), copiata identic;
*-- Thisform.do_deschide_tranzactie/do_inchide_tranzactie sunt reproduse INLINE mai jos
*-- (MyDeschideTranzactie/MyInchideTranzactie, dupa _frm_base.vc2:252-302) - fara sa instantieze
*-- niciun formular, ca sa nu riste acelasi blocaj vazut la frm_modific2024
lnSucces = 0
TRY
STRTOFILE(' [chk] inainte de MyDeschideTranzactie()' + CHR(13) + CHR(10), tcLog, 1)
IF MyDeschideTranzactie()
STRTOFILE(' [chk] MyDeschideTranzactie() => .T., inainte de OSCRIE_IN_FISIERE(2,...)' + CHR(13) + CHR(10), tcLog, 1)
SELECT actactan
lnSucces = OSCRIE_IN_FISIERE(2, .T., .T.)
STRTOFILE(' [chk] OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
LogMockSiEroare('dupa OSCRIE_IN_FISIERE(2,...)', tcLog)
IF lnSucces > 0
IF USED('actactan')
USE IN actactan
ENDIF
SELECT tact
REPLACE id_jtva_coloana WITH NULL, proc_tva WITH 0 FOR cu_Tva = 0
SELECT * FROM tact INTO CURSOR actactan READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
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
IF USED('rul_temp_obinv')
USE IN rul_temp_obinv
ENDIF
SELECT * FROM trul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
STRTOFILE(' [chk] cursoare rebuild OK, inainte de OSCRIE_IN_FISIERE(0,...)' + CHR(13) + CHR(10), tcLog, 1)
lnSucces = OSCRIE_IN_FISIERE(0, .T., .T.)
STRTOFILE(' [chk] OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
LogMockSiEroare('dupa OSCRIE_IN_FISIERE(0,...)', tcLog)
ENDIF
IF lnSucces > 0
STRTOFILE(' [chk] inainte de pack_contafin.finalizeaza_modificare_nota' + CHR(13) + CHR(10), tcLog, 1)
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,Null,] + ALLTRIM(STR(lnIdSet)) + [,] + ;
ALLTRIM(STR(lnCod)) + [,] + ALLTRIM(STR(lnIdFact)) + [,] + ALLTRIM(STR(lnIdFactD)) + [,?gnIdUtil); end;]
STRTOFILE(' [chk] SQL finalizeaza_modificare_nota = [' + lcSql + ']' + CHR(13) + CHR(10), tcLog, 1)
lnSucces = IIF(goExecutor.oExecuta(lcSql), 1, -1)
STRTOFILE(' [chk] finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
LogMockSiEroare('dupa finalizeaza_modificare_nota', tcLog)
ENDIF
STRTOFILE(' lnSucces dupa lant scriere = ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
STRTOFILE(' [chk] inainte de MyInchideTranzactie' + CHR(13) + CHR(10), tcLog, 1)
IF MyInchideTranzactie(IIF(lnSucces < 0, 2, 1))
STRTOFILE(' tranzactie inchisa cu ' + IIF(lnSucces < 0, 'ROLLBACK', 'COMMIT') + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' FAIL la do_inchide_tranzactie' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
ELSE
STRTOFILE(' FAIL: do_deschide_tranzactie a esuat' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
CATCH TO loExc
STRTOFILE(' EXCEPTIE in lantul de scriere: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + ' -> ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
lnSucces = -99
MyInchideTranzactie(2)
ENDTRY
IF USED('actactan')
USE IN actactan
ENDIF
IF USED('tact')
USE IN tact
ENDIF
IF USED('rul_temp')
USE IN rul_temp
ENDIF
IF USED('trul')
USE IN trul
ENDIF
IF USED('rul_temp_obinv')
USE IN rul_temp_obinv
ENDIF
IF USED('trul_obinv')
USE IN trul_obinv
ENDIF
IF lnSucces <= 0
STRTOFILE(' TEST FAIL - scrierea nu s-a produs (lnSucces=' + TRANSFORM(lnSucces) + '), fara verificari after' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
*-- 9) instantaneu DUPA + verificarile 1-5 cerute
LOCAL lnCodNou, lnVzStersAfter, llV3ok
lcSql = [select cod, sters, id_fact, total_fara_tva, total_tva, total_cu_tva, discount from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecAgg(lcSql, 'v_vanzare_dupa')
IF lnQ <= 0 OR RECCOUNT('v_vanzare_dupa') <> 1
STRTOFILE(' FAIL: VANZARI dupa - nu am gasit exact 1 rand' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
SELECT v_vanzare_dupa
lnCodNou = cod
lnVzStersAfter = sters
llV3ok = (lnCodNou <> lnVzCodBefore) AND (lnVzStersAfter = 0) AND (id_fact == lnIdFact) AND ;
(ABS(total_fara_tva - lnVzTotalFaraTvaBefore) < 0.01) AND (ABS(total_tva - lnVzTotalTvaBefore) < 0.01) AND ;
(ABS(total_cu_tva - lnVzTotalCuTvaBefore) < 0.01) AND (ABS(discount - lnVzDiscountBefore) < 0.01)
STRTOFILE(' [3] VANZARI dupa: cod=' + TRANSFORM(lnCodNou) + ' (era ' + TRANSFORM(lnVzCodBefore) + ') sters=' + TRANSFORM(lnVzStersAfter) + ;
' id_fact=' + TRANSFORM(id_fact) + ' total_cu_tva=' + TRANSFORM(total_cu_tva) + ' -> ' + IIF(llV3ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
USE IN v_vanzare_dupa
*-- [1] ACT: randurile vechi STERS=1 pe cod vechi; randuri noi pe cod nou, acelasi id_fact, aceeasi suma (daca nemodificat)
LOCAL lnActVechiCnt, lnActVechiSumSters, lnActNouCnt, lnActNouSuma, llV1ok
lcSql = [select count(*) as cnt, sum(sters) as sumsters from vact_tot where an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnVzCodBefore)
lnQ = ExecAgg(lcSql, 'v_act_vechi_dupa')
IF lnQ > 0
lnActVechiCnt = v_act_vechi_dupa.cnt
lnActVechiSumSters = NVL(v_act_vechi_dupa.sumsters, 0)
USE IN v_act_vechi_dupa
ELSE
lnActVechiCnt = -1
lnActVechiSumSters = -1
ENDIF
lcSql = [select count(*) as cnt, sum(suma) as totsuma from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou)
lnQ = ExecAgg(lcSql, 'v_act_nou_dupa')
IF lnQ > 0
lnActNouCnt = v_act_nou_dupa.cnt
lnActNouSuma = NVL(v_act_nou_dupa.totsuma, 0)
USE IN v_act_nou_dupa
ELSE
lnActNouCnt = -1
lnActNouSuma = -1
ENDIF
llV1ok = (lnActVechiCnt = lnActBeforeCnt) AND (lnActVechiSumSters = lnActVechiCnt) AND (lnActNouCnt = lnActBeforeCnt) AND ;
(IIF(tlModificaLinie, .T., ABS(lnActNouSuma - lnActBeforeSuma) < 0.01))
STRTOFILE(' [1] ACT: vechi(cod=' + TRANSFORM(lnVzCodBefore) + ') cnt=' + TRANSFORM(lnActVechiCnt) + ' toate sters=' + TRANSFORM(lnActVechiSumSters = lnActVechiCnt) + ;
'; nou(cod=' + TRANSFORM(lnCodNou) + ') cnt=' + TRANSFORM(lnActNouCnt) + ' suma=' + TRANSFORM(lnActNouSuma) + ;
' (era ' + TRANSFORM(lnActBeforeSuma) + ') -> ' + IIF(llV1ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
*-- [2] RUL: acelasi tipar (daca documentul are randuri RUL)
LOCAL lnRulVechiCnt, lnRulVechiSumSters, lnRulNouCnt, llV2ok
lcSql = [select count(*) as cnt, sum(sters) as sumsters from vrul_tot where an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnVzCodBefore)
lnQ = ExecAgg(lcSql, 'v_rul_vechi_dupa')
IF lnQ > 0
lnRulVechiCnt = v_rul_vechi_dupa.cnt
lnRulVechiSumSters = NVL(v_rul_vechi_dupa.sumsters, 0)
USE IN v_rul_vechi_dupa
ELSE
lnRulVechiCnt = -1
lnRulVechiSumSters = -1
ENDIF
lcSql = [select count(*) as cnt from vrul_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou)
lnQ = ExecAgg(lcSql, 'v_rul_nou_dupa')
IF lnQ > 0
lnRulNouCnt = v_rul_nou_dupa.cnt
USE IN v_rul_nou_dupa
ELSE
lnRulNouCnt = -1
ENDIF
llV2ok = (lnRulVechiCnt = lnRulBeforeCnt) AND (lnRulVechiSumSters = lnRulVechiCnt) AND (lnRulNouCnt = lnRulBeforeCnt)
STRTOFILE(' [2] RUL: vechi cnt=' + TRANSFORM(lnRulVechiCnt) + ' toate sters=' + TRANSFORM(lnRulVechiSumSters = lnRulVechiCnt) + ;
'; nou cnt=' + TRANSFORM(lnRulNouCnt) + ' (era ' + TRANSFORM(lnRulBeforeCnt) + ') -> ' + IIF(llV2ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
*-- [4] VANZARI_DETALII: neatins de aceasta cale
LOCAL lnVdCntDupa, lnVdSumaPretDupa, lnVdSumaPretCuTvaDupa, llV4ok
lcSql = [select count(*) as cnt, sum(cantitate) as sumcant, sum(pret) as sumpret, sum(pret_cu_tva) as sumpretcutva ] + ;
[from vanzari_detalii where sters = 0 and id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecAgg(lcSql, 'v_vd_dupa')
IF lnQ > 0
lnVdCntDupa = v_vd_dupa.cnt
lnVdSumaPretDupa = NVL(v_vd_dupa.sumpret, 0)
lnVdSumaPretCuTvaDupa = NVL(v_vd_dupa.sumpretcutva, 0)
USE IN v_vd_dupa
ELSE
lnVdCntDupa = -1
lnVdSumaPretDupa = -1
lnVdSumaPretCuTvaDupa = -1
ENDIF
llV4ok = (lnVdCntDupa = lnVdCnt) AND (ABS(lnVdSumaPretDupa - lnVdSumaPret) < 0.01) AND (ABS(lnVdSumaPretCuTvaDupa - lnVdSumaPretCuTva) < 0.01)
STRTOFILE(' [4] VANZARI_DETALII: cnt=' + TRANSFORM(lnVdCntDupa) + ' (era ' + TRANSFORM(lnVdCnt) + ') sum(pret)=' + TRANSFORM(lnVdSumaPretDupa) + ;
' (era ' + TRANSFORM(lnVdSumaPret) + ') -> ' + IIF(llV4ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
*-- [5] lnSucces>0 pe tot lantul + tranzactia inchisa cu commit (deja logat mai sus, sintetizat aici)
STRTOFILE(' [5] lnSucces final = ' + TRANSFORM(lnSucces) + ' -> ' + IIF(lnSucces > 0, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
*-- verificare suplimentara TEST 2: explicatia modificata ajunge efectiv in ACT pe randul nou
IF tlModificaLinie AND !EMPTY(lcExplicatieNoua)
LOCAL lnExplicatieCnt
lcSql = [select count(*) as cnt from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou) + ;
[ and explicatia = '] + STRTRAN(lcExplicatieNoua, "'", "''") + [']
lnQ = ExecAgg(lcSql, 'v_act_explicatie')
IF lnQ > 0
lnExplicatieCnt = v_act_explicatie.cnt
USE IN v_act_explicatie
ELSE
lnExplicatieCnt = -1
ENDIF
STRTOFILE(' [2b] explicatia modificata ajunge in ACT: cnt=' + TRANSFORM(lnExplicatieCnt) + ' -> ' + IIF(lnExplicatieCnt = 1, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
ENDIF
STRTOFILE(' REZUMAT ' + tcEticheta + ': cod ' + TRANSFORM(lnVzCodBefore) + ' -> ' + TRANSFORM(lnCodNou) + CHR(13) + CHR(10), tcLog, 1)
ENDPROC
PROCEDURE test_error_handler
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC