Files
comun/utile/Teste/editare_factura/test_s11_reparatie_1472.prg
Marius Mutu 8e022d332e #13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2.

Clase: ofacturare (nucleul formularului unificat), ofacturare_comun,
ferestre_cere_date, ocomenzi, caut_ora (lista de preturi in combo-urile de
cautare), omodificari.

Programe: ofacturare impartit - ofacturare_antet, ofacturare_rutare_scriere si
ogrid_latimi sunt fisiere noi; oproceduri_facturare primeste discountul pe linie
si cota standard de TVA cand articolul nu are cota pe politica.

Documentatie: capcana SQLExec no_data_found, conventia de encoding, depanarea
testelor VFP si regulile de lucru - conflictele cu modificarile venite din alte
proiecte sunt rezolvate pastrand ambele parti.

Loguri de rulare a testelor scoase din versionare; testele raman.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
2026-09-09 21:38:25 +03:00

226 lines
9.1 KiB
Plaintext

* test_s11_reparatie_1472.prg
* Proba reparatiei S11 (docs\raport_s11_reparatie_1472.md): confirma ca garda Nvl(...,[NULL])
* aplicata pe poArt.id_articol (ofacturare.vc2:19979) si poArt.id_jtva_coloana (ofacturare.vc2:19994,
* in frm_facturare_articole2.do_scrie_articole) repara EROAREA 1472 pe documentul 630, fara sa
* schimbe lcSql-ul pe randuri fara NULL pe aceste doua campuri (neregresie).
*
* Tipar identic cu test_s11_izolare_camp_1472.prg: mock pe goExecutor, NIMIC scris in Oracle,
* document 630 incarcat REAL (IncarcaAntetFacturaEditare + IncarcaLiniiFacturaEditare), goExecutor
* inlocuit cu mock DOAR dupa incarcare, inaintea do_scrie_articole().
*
* PAS1 (regresia care conta): doc 630 BRUT (id_articol ramane NULL, ca in Oracle) - inainte de
* reparatie VARTYPE(lcSql)='X' (control negativ, citat din
* docs\raport_s11_cauza_1472_camp.md §4 PAS2-brut, nu s-a rerulat). Asteptam acum VARTYPE='C'.
* PAS2 (neregresie, comparatie caracter-cu-caracter): acelasi scenariu ca PAS3 din
* test_s11_izolare_camp_1472.prg (id_articol/id_jtva_coloana normalizate cu NVL(...,0), ca sa
* nu mai fie NULL) - garda noua e un no-op pe valori ne-NULL, deci lcSql trebuie sa fie
* IDENTIC, caracter cu caracter, cu sirul deja capturat inainte de reparatie
* (docs\raport_s11_cauza_1472_camp.md §4 PAS3, citat mai jos ca literal).
LPARAMETERS tnCaz
SET SAFETY OFF
SET TALK OFF
PUBLIC gcErrLog, gnPass, gnFail
PUBLIC poDate
gcErrLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s11_reparatie_1472_log_' + ;
STRTRAN(STRTRAN(STRTRAN(TTOC(DATETIME()), '/', ''), ':', ''), ' ', '_') + '.txt'
STRTOFILE('start ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog)
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDIF
gnIdUtil = 8
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_rutare_scriere.prg ADDITIVE
*!* la nume duplicat de procedura castiga PRIMUL fisier din lista SET PROCEDURE, nu ultimul
LOCAL lcProcExistent
lcProcExistent = SET("PROCEDURE")
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg", &lcProcExistent
LOCAL lcPathVechi, lcPathNou
lcPathVechi = SET("PATH")
lcPathNou = 'D:\ROA\ROAFACTURARE\COMUN\Utile\Teste\achizitie_import\stub_verificare;' + lcPathVechi
SET PATH TO &lcPathNou
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
gnMockRaspuns = 7
gcMockUltimMesaj = ''
gnMockUltimTip = 0
gnPass = 0
gnFail = 0
PUBLIC gcSqlUltim, gcVartypeUltim
gcSqlUltim = ''
gcVartypeUltim = ''
DO ProbaReparatie
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('end ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
*==============================================================================================
PROCEDURE ProbaReparatie
LOCAL lnIdV
lnIdV = 630
LOCAL lnDiscRon, lnDiscVal
lnDiscRon = 0
lnDiscVal = 0
poDate = IncarcaAntetFacturaEditare(lnIdV, @lnDiscRon, @lnDiscVal)
DO asserteaza WITH '0a antetul documentului ' + TRANSFORM(lnIdV) + ' s-a incarcat', VARTYPE(poDate) = 'O', VARTYPE(poDate)
IF VARTYPE(poDate) <> 'O'
RETURN
ENDIF
IncarcaLiniiFacturaEditare(poDate, lnIdV)
DO asserteaza WITH '0b liniile documentului ' + TRANSFORM(lnIdV) + ' s-au incarcat', ;
USED('crsfactura') AND RECCOUNT('crsfactura') > 0, TRANSFORM(IIF(USED('crsfactura'), RECCOUNT('crsfactura'), -1))
IF !USED('crsfactura') OR RECCOUNT('crsfactura') = 0
RETURN
ENDIF
*!* curatare LOCALA (doar in RAM), identica cu test_s11_izolare_camp_1472.prg
SELECT crsfactura
REPLACE ALL explicatie WITH 'test-s11-izolare', serie WITH '', lot WITH '', opt_facturare WITH 0 IN crsfactura
GO TOP IN crsfactura
*!* PAS1: doc 630 BRUT (id_articol ramane NULL) - proba REGRESIEI CARE CONTA
DO RuleazaCuMock WITH 'PAS1-brut-postfix'
DO asserteaza WITH 'PAS1 lcSql BRUT (id_articol NULL, ca in Oracle) e text valid dupa reparatie (VARTYPE C)', gcVartypeUltim = 'C', gcVartypeUltim
IF gcVartypeUltim = 'C'
DO asserteaza WITH 'PAS1 lcSql contine apelul adauga_articol_factura', 'pack_facturare.adauga_articol_factura(' $ gcSqlUltim, gcSqlUltim
ENDIF
*!* PAS2: neregresie - acelasi scenariu ca PAS3 din test_s11_izolare_camp_1472.prg (id_articol,
*!* id_jtva_coloana normalizate cu NVL(...,0)); garda e no-op pe valori ne-NULL, deci lcSql
*!* trebuie sa fie IDENTIC caracter-cu-caracter cu sirul capturat INAINTE de reparatie
*!* (docs\raport_s11_cauza_1472_camp.md §4 PAS3, citat literal, nu recalculat).
SELECT crsfactura
GO TOP IN crsfactura
REPLACE ALL id_articol WITH NVL(id_articol,0), id_jtva_coloana WITH NVL(id_jtva_coloana,0) IN crsfactura
GO TOP IN crsfactura
DO RuleazaCuMock WITH 'PAS2-neregresie-normalizat'
LOCAL lcAsteptatDinRaportInainteDeReparatie
lcAsteptatDinRaportInainteDeReparatie = "begin pack_facturare.adauga_articol_factura(905,0,'','test-s11-izolare',NULL,0,0.0000,NULL,NULL,100.00,0,0,0,1.000,0.00,'',0.000000,1,0,0,0,0.0000,0,134,8,NULL,'',1.1900); end;"
DO asserteaza WITH 'PAS2 lcSql (dupa reparatie, valori ne-NULL) e IDENTIC caracter-cu-caracter cu sirul din raportul dinainte de reparatie', ;
ALLTRIM(gcSqlUltim) == ALLTRIM(lcAsteptatDinRaportInainteDeReparatie), 'CAPTURAT: ' + TRANSFORM(gcSqlUltim)
STRTOFILE('PAS2 --- sirul asteptat (din raport, dinainte de reparatie) ---' + CHR(13) + CHR(10) + lcAsteptatDinRaportInainteDeReparatie + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('PAS2 --- sirul capturat (dupa reparatie) ---' + CHR(13) + CHR(10) + TRANSFORM(gcSqlUltim) + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
*==============================================================================================
* RuleazaCuMock: apeleaza do_scrie_articole() cu goExecutor mockat, intoarce lcSql-ul (sau
* diagnosticul VARTYPE) al APELULUI cu PCOUNT()=1 (adauga_articol_factura din Scan), plus
* rollback pe conexiunea REALA dupa fiecare rulare (tranzactia ramane deschisa pe succes).
*==============================================================================================
PROCEDURE RuleazaCuMock
LPARAMETERS tcPrefix
LOCAL loForm, loMock, loExecutorReal, llReturn
loForm = CREATEOBJECT('frm_facturare_articole2')
IF TYPE('plRegenerareEditare') <> 'U'
RELEASE plRegenerareEditare
ENDIF
loExecutorReal = goExecutor
loMock = CREATEOBJECT('MockGoExecutorS11Reparatie')
goExecutor = loMock
llReturn = loForm.do_scrie_articole()
goExecutor = loExecutorReal
SQLROLLBACK(gnHandle)
SQLSetProp(gnHandle, 'Transactions', 1)
gcSqlUltim = loMock.cSqlArticolCapturat
gcVartypeUltim = loMock.cVartypeArticol
STRTOFILE(tcPrefix + ' do_scrie_articole()=' + TRANSFORM(llReturn) + ' VARTYPE(tcSql pe apelul articol)=' + gcVartypeUltim + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE(tcPrefix + ' --- lcSql capturat (apelul articol) ---' + CHR(13) + CHR(10) + TRANSFORM(gcSqlUltim) + CHR(13) + CHR(10), gcErrLog, 1)
RELEASE loForm
ENDPROC
PROCEDURE asserteaza
LPARAMETERS tcNume, tlConditie, tcValoare
IF m.tlConditie
gnPass = gnPass + 1
STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcErrLog, 1)
ELSE
gnFail = gnFail + 1
STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + TRANSFORM(m.tcValoare) + ')' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
ENDPROC
PROCEDURE test_error_handler
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
IF TYPE('gnHandle') = 'N' AND gnHandle > 0
SQLROLLBACK(gnHandle)
SQLSetProp(gnHandle, 'Transactions', 1)
ENDIF
gnFail = gnFail + 1
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('end (eroare) ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDPROC
*==============================================================================================
* MockGoExecutorS11Reparatie: identic cu MockGoExecutorS11Izolare (test_s11_izolare_camp_1472.prg),
* clasa distincta doar ca sa nu se coliziona cu cea din fisierul de izolare pe acelasi SET PROCEDURE.
*==============================================================================================
DEFINE CLASS MockGoExecutorS11Reparatie AS Custom
cSqlArticolCapturat = ''
cVartypeArticol = ''
nApeluri = 0
cEroare = ''
FUNCTION oExecute(tcSql)
THIS.nApeluri = THIS.nApeluri + 1
LOCAL lcVartype
lcVartype = VARTYPE(m.tcSql)
IF THIS.nApeluri >= 3
THIS.cSqlArticolCapturat = TRANSFORM(m.tcSql)
THIS.cVartypeArticol = m.lcVartype
ENDIF
RETURN 1
ENDFUNC
FUNCTION oExecuta(tcSql, tcCursor)
THIS.nApeluri = THIS.nApeluri + 1
IF VARTYPE(m.tcCursor) = 'C' AND !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (xdummy I)
ENDIF
RETURN .T.
ENDFUNC
FUNCTION oPrelucrareEroare()
RETURN 'MockGoExecutorS11Reparatie: ' + THIS.cEroare
ENDFUNC
ENDDEFINE