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
This commit is contained in:
72
utile/Teste/editare_factura/test_incarca_articole_view.prg
Normal file
72
utile/Teste/editare_factura/test_incarca_articole_view.prg
Normal file
@@ -0,0 +1,72 @@
|
||||
* test_incarca_articole_view.prg
|
||||
* Smoke test izolat pentru IncarcaArticoleFactura pe vvanzari_articole (runda 2), inainte de a atinge omodificari.vc2.
|
||||
* Regresie: id_vanzare=1050 (cod=1140888) -> 4 randuri, id_vanzare=1047 (cod=1140885) -> 2 randuri,
|
||||
* coincide cu baza din rec_view_articole_vanzare.md. Verifica si coloana noua tvd.id_vanzare.
|
||||
* Nu atinge Oracle in scriere. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_articole_view_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
DO verifica WITH 1050, 'cod=1140888', lcLog, 4
|
||||
DO verifica WITH 1047, 'cod=1140885', lcLog, 2
|
||||
|
||||
*!* cursorul gol - structura cu 21 de campuri, inclusiv id_vanzare (nou)
|
||||
CreeazaCursorTvdGol()
|
||||
STRTOFILE('--- CreeazaCursorTvdGol ---' + CHR(13) + CHR(10) + ;
|
||||
' Fcount(tvd) = ' + TRANSFORM(FCOUNT('tvd')) + ' (asteptat 21)' + CHR(13) + CHR(10) + ;
|
||||
' are id_vanzare: ' + TRANSFORM(TYPE('tvd.id_vanzare') <> 'U') + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(FCOUNT('tvd') == 21, 'PASS', 'FAIL') + CHR(13) + CHR(10), lcLog, 1)
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE verifica
|
||||
LPARAMETERS tnIdVanzare, tcEticheta, tcLog, tnLiniiAsteptate
|
||||
|
||||
LOCAL lnLinii, lnIdVanzareCol
|
||||
|
||||
IncarcaArticoleFactura(tnIdVanzare)
|
||||
lnLinii = Reccount('tvd')
|
||||
lnIdVanzareCol = -1
|
||||
IF lnLinii > 0
|
||||
SELECT tvd
|
||||
GO TOP
|
||||
lnIdVanzareCol = tvd.id_vanzare
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- id_vanzare=' + TRANSFORM(tnIdVanzare) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tvd) = ' + TRANSFORM(lnLinii) + ' (asteptat ' + TRANSFORM(tnLiniiAsteptate) + ')' + CHR(13) + CHR(10) + ;
|
||||
' tvd.id_vanzare pe primul rand = ' + TRANSFORM(lnIdVanzareCol) + ' (asteptat ' + TRANSFORM(tnIdVanzare) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnLinii == tnLiniiAsteptate AND (lnLinii == 0 OR lnIdVanzareCol == tnIdVanzare), 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
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)
|
||||
ENDPROC
|
||||
141
utile/Teste/editare_factura/test_incarca_cursoare.prg
Normal file
141
utile/Teste/editare_factura/test_incarca_cursoare.prg
Normal file
@@ -0,0 +1,141 @@
|
||||
* test_incarca_cursoare.prg
|
||||
* Verifica IncarcaCursoareModificareNota (COMUN\programe\ofacturare_editare.prg) pe date reale:
|
||||
* cod=1140888 - nota cu rulaje (non-regresie)
|
||||
* cod=1140885 - nota FARA randuri in rul (productie/manopera, fara miscare de stoc)
|
||||
* si pozitionarea in actactan din do_editare_factura (ofacturare_comun.vc2), pe cursoare sintetice.
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_cursoare_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
DO verifica_cod WITH 1140888, 'A (regresie, cu rulaje)', lcLog
|
||||
DO verifica_cod WITH 1140885, 'B (fara randuri in rul)', lcLog
|
||||
DO verifica_pozitionare_actactan WITH 9999995, 'a) nota normala, un singur id_fact pe toate randurile', lcLog, 5000, 5000, 25010, 100, .T.
|
||||
DO verifica_pozitionare_actactan WITH 9999996, 'b) prim rand INCASARE cu id_fact-1, Locate il sare', lcLog, 5000, 5000, 25010, 200, .T.
|
||||
DO verifica_pozitionare_actactan WITH 9999997, 'c) nota fara randul cu id_fact cerut, cade pe Go Top', lcLog, 9999, 7000, 25011, 50, .F.
|
||||
DO verifica_pozitionare_actactan WITH 9999998, 'd) lnIdFact=0 (aviz/transfer), direct Go Top', lcLog, 0, 8000, 25012, 10, .F.
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
* reproduce mecanica pozitionarii din do_editare_factura (ofacturare_comun.vc2): cauta in actactan
|
||||
* randul cu id_fact = lnIdFact (cel citit din crsfacturi/VANZARI.ID_FACT); daca nu-l gaseste (sau
|
||||
* lnIdFact e 0 - avize, transferuri), cade pe Go Top si preia id_fact de acolo. lnIdSet si
|
||||
* lnIdFactD se citesc mereu de pe randul gasit (Locate sau Go Top).
|
||||
PROCEDURE verifica_pozitionare_actactan
|
||||
LPARAMETERS tnCod, tcEticheta, tcLog, tnIdFactIntrare, tnIdFactAsteptat, tnIdSetAsteptat, tnIdFactDAsteptat, tlGasitAsteptat
|
||||
|
||||
LOCAL lnIdFact, lnIdSet, lnIdFactD, llGasitRand, llOk
|
||||
|
||||
CREATE CURSOR actactan (id_fact N(9), id_factd N(9), id_set N(9))
|
||||
DO CASE
|
||||
CASE tnCod = 9999995
|
||||
&& a) nota normala: toate randurile cu acelasi id_fact
|
||||
INSERT INTO actactan VALUES (5000, 100, 25010)
|
||||
INSERT INTO actactan VALUES (5000, 101, 25010)
|
||||
CASE tnCod = 9999996
|
||||
&& b) prim rand INCASARE, id_fact = id_fact-ul facturii - 1
|
||||
INSERT INTO actactan VALUES (4999, 0, 25010)
|
||||
INSERT INTO actactan VALUES (5000, 200, 25010)
|
||||
CASE tnCod = 9999997
|
||||
&& c) nota nu contine id_fact-ul cerut (document vechi)
|
||||
INSERT INTO actactan VALUES (7000, 50, 25011)
|
||||
CASE tnCod = 9999998
|
||||
&& d) aviz/transfer, fara id_fact la intrare
|
||||
INSERT INTO actactan VALUES (8000, 10, 25012)
|
||||
ENDCASE
|
||||
|
||||
lnIdFact = tnIdFactIntrare
|
||||
|
||||
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 = id_factd
|
||||
USE IN actactan
|
||||
|
||||
llOk = (lnIdFact == tnIdFactAsteptat AND lnIdSet == tnIdSetAsteptat AND ;
|
||||
lnIdFactD == tnIdFactDAsteptat AND llGasitRand == tlGasitAsteptat)
|
||||
|
||||
STRTOFILE('--- pozitionare actactan, cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' gasit rand = ' + TRANSFORM(llGasitRand) + ' (asteptat ' + TRANSFORM(tlGasitAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_fact = ' + TRANSFORM(lnIdFact) + ' (asteptat ' + TRANSFORM(tnIdFactAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_set = ' + TRANSFORM(lnIdSet) + ' (asteptat ' + TRANSFORM(tnIdSetAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_factd = ' + TRANSFORM(lnIdFactD) + ' (asteptat ' + TRANSFORM(tnIdFactDAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llOk, 'OK', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE verifica_cod
|
||||
LPARAMETERS tnCod, tcEticheta, tcLog
|
||||
|
||||
LOCAL llOk, lcMsg, lnIdSetDistinct
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, gnAn, gnLuna, .F.)
|
||||
|
||||
lnIdSetDistinct = -1
|
||||
IF Used('actactan') AND Reccount('actactan') > 0
|
||||
SELECT Distinct id_set FROM actactan INTO CURSOR csr_idset_verif_test
|
||||
lnIdSetDistinct = Reccount('csr_idset_verif_test')
|
||||
USE IN csr_idset_verif_test
|
||||
ENDIF
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' Reccount(actactan) = ' + TRANSFORM(IIF(Used('actactan'), Reccount('actactan'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tact) = ' + TRANSFORM(IIF(Used('tact'), Reccount('tact'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' id_set distincte in actactan = ' + TRANSFORM(lnIdSetDistinct) + CHR(13) + CHR(10) + ;
|
||||
' Used(trul) = ' + TRANSFORM(Used('trul')) + ' Reccount(trul) = ' + TRANSFORM(IIF(Used('trul'), Reccount('trul'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' Used(trul_obinv) = ' + TRANSFORM(Used('trul_obinv')) + ' Reccount(trul_obinv) = ' + TRANSFORM(IIF(Used('trul_obinv'), Reccount('trul_obinv'), -1)) + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
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
|
||||
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
|
||||
154
utile/Teste/editare_factura/test_incarca_vanzare_din_nota.prg
Normal file
154
utile/Teste/editare_factura/test_incarca_vanzare_din_nota.prg
Normal file
@@ -0,0 +1,154 @@
|
||||
* test_incarca_vanzare_din_nota.prg
|
||||
* Smoke test izolat pentru IncarcaVanzareDinNota (ofacturare_editare.prg), inainte de a atinge
|
||||
* omodificari.vc2 runda 2. Verifica pe cazurile de regresie ale bugului "Go Top orb pe tact":
|
||||
* cod=1137874/an=2009/luna=8 -> trebuie sa gaseasca id_vanzare=506 (azi, cu Go Top orb, da 0 randuri)
|
||||
* cod=1139934/an=2021/luna=12 -> id_vanzare=882 (coliziune VANZARI.COD deja cunoscuta)
|
||||
* plus regresie pe cazurile vechi: cod=1140888 -> id_vanzare=1050; cod=1125486 -> nu gaseste (tact fara VANZARI)
|
||||
* plus cazul EOF: tact pozitionat deliberat la EOF (ca dupa CalculeazaTotal() din Show()) inainte de
|
||||
* apel - dovedeste ca "cod" se ia din cursorul de triplete (SELECT DISTINCT), nu de pe randul curent
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_vanzare_din_nota_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
DO verifica WITH 1137874, 2009, 8, 'blocant Go Top - prim rand INCASARE', lcLog, .T., 506
|
||||
DO verifica WITH 1139934, 2021, 12, 'coliziune VANZARI.COD', lcLog, .T., 882
|
||||
DO verifica WITH 1140888, (gnAn), (gnLuna), 'regresie runda 1 - factura normala', lcLog, .T., 1050
|
||||
DO verifica WITH 1125486, 2008, 2, 'regresie runda 1 - fara VANZARI', lcLog, .F., 0
|
||||
DO verifica_eof WITH 1137874, 2009, 8, lcLog, 506
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
* pozitioneaza tact deliberat la EOF (Go Bottom + Skip) inainte de IncarcaVanzareDinNota - dovedeste
|
||||
* ca "cod" nu se mai citeste de pe randul curent al aliasului (corectia care a inlocuit Evaluate(alias.cod))
|
||||
PROCEDURE verifica_eof
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcLog, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, llGasit, lnIdVanzare, llEofInainte, llEofDupa
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
llEofInainte = .F.
|
||||
llEofDupa = .F.
|
||||
|
||||
IF llOk AND Used('tact')
|
||||
SELECT tact
|
||||
Go Bottom In tact
|
||||
Skip In tact
|
||||
llEofInainte = Eof('tact')
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
llEofDupa = Eof('tact')
|
||||
IF llGasit
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- EOF pe tact, cod=' + TRANSFORM(tnCod) + ' [pozitionare la EOF inainte de apel] ---' + CHR(13) + CHR(10) + ;
|
||||
' Eof(tact) inainte de apel = ' + TRANSFORM(llEofInainte) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' Eof(tact) dupa apel (pozitia restaurata) = ' + TRANSFORM(llEofDupa) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llEofInainte AND llGasit AND lnIdVanzare == tnIdVanzareAsteptat AND llEofDupa, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
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 Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE verifica
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tlAsteptatGasit, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, llGasit, lnIdVanzare, lcMsg, lnAreaOrigineTest, lcAliasOrigineTest
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
lnAreaOrigineTest = 0
|
||||
lcAliasOrigineTest = ''
|
||||
|
||||
IF llOk AND Used('tact')
|
||||
SELECT tact
|
||||
lnAreaOrigineTest = Select()
|
||||
lcAliasOrigineTest = Alias()
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
IF llGasit
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat ' + TRANSFORM(tlAsteptatGasit) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' workarea restaurata la ' + TRANSFORM(lnAreaOrigineTest) + ': ' + TRANSFORM(Select() == lnAreaOrigineTest) + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit == tlAsteptatGasit AND lnIdVanzare == tnIdVanzareAsteptat AND Select() == lnAreaOrigineTest, 'PASS', 'FAIL') + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
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 Used('tvanz')
|
||||
Use In tvanz
|
||||
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)
|
||||
ENDPROC
|
||||
305
utile/Teste/editare_factura/test_page3_articole.prg
Normal file
305
utile/Teste/editare_factura/test_page3_articole.prg
Normal file
@@ -0,0 +1,305 @@
|
||||
* test_page3_articole.prg
|
||||
* Verifica S4 runda 1+2 (PAGE3, view VVANZARI_ARTICOLE, pozitionare in tact, garda ROACONT/ROAGEST) pe date reale:
|
||||
* - IncarcaVanzareNota/IncarcaArticoleFactura (ofacturare_editare.prg) direct, pe cod=1140888,
|
||||
* cod=1140885 (au rand in VANZARI) si cod=1125486 (nota fara rand in VANZARI)
|
||||
* - cazul de coliziune pe cod: cod=1139934 are 4 randuri VANZARI cu acelasi cod - verifica ca
|
||||
* filtrul compus (cod+nract+serie_act+data_act) gaseste exact randul corect si NU gaseste
|
||||
* nimic pentru un nract fara corespondent (evitarea unei potriviri gresite)
|
||||
* - frm_modific2024 instantiat ca in do_editare_factura (Createobject+Show): PageCount ajunge 3
|
||||
* pe documente cu rand in VANZARI, ramane 2 pe o nota fara VANZARI
|
||||
* - regresie runda 2: cod=1137874/an=2009/luna=8 si cod=1139934/an=2021/luna=12, unde primul
|
||||
* rand din tact e o INCASARE - Go Top orb (runda 1) rata id_vanzare, IncarcaVanzareDinNota il
|
||||
* gaseste prin toate tripletele distincte (nract,serie_act,dataact) din tact
|
||||
* - garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat din SET PROCEDURE, Show() degradeaza
|
||||
* curat la PageCount=2, fara eroare
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_page3_articole_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
*!* OBLIGATORIU: test_init_env_auto:139 face "Set Classlib To omodificari Additive", iar SET PATH
|
||||
*!* e pe D:\ROA\ROACONT\..., deci se incarca copia ROACONT a clasei (alt working copy, fara
|
||||
*!* modificarile noastre). O eliberam si o reincarcam pe cea DE SUB TEST, cu cale completa -
|
||||
*!* altfel Createobject valideaza cu totul alt fisier decat cel editat.
|
||||
RELEASE CLASSLIB omodificari
|
||||
SET CLASSLIB TO D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vcx ADDITIVE
|
||||
|
||||
*!* 1) IncarcaVanzareNota / IncarcaArticoleFactura direct, pe documente reale
|
||||
*!* (gnAn)/(gnLuna) in paranteze = pasare PRIN VALOARE: DO ... WITH paseaza prin REFERINTA, iar o
|
||||
*!* variabila pasata prin referinta devine invizibila sub numele ei propriu in procedura apelata -
|
||||
*!* de acolo venea dialogul nativ "View Parameter: Enter the value for gnAn" (?gnAn din SQL passthrough)
|
||||
DO verifica_vanzare_nota WITH 1140888, (gnAn), (gnLuna), 'A (factura, cu articole)', lcLog, .T., 1050, 1, 4
|
||||
DO verifica_vanzare_nota WITH 1140885, (gnAn), (gnLuna), 'B (aviz/tip -12, cu rand in VANZARI)', lcLog, .T., 1047, -12, -1
|
||||
DO verifica_vanzare_nota WITH 1125486, 2008, 2, 'C (nota fara rand in VANZARI)', lcLog, .F., 0, 0, -1
|
||||
|
||||
*!* 2) cazul de coliziune pe cod=1139934 (4 randuri VANZARI cu acelasi cod) - filtrul compus
|
||||
DO verifica_coliziune_cod WITH lcLog
|
||||
|
||||
*!* 3) frm_modific2024 - PageCount pe factura reala (cod=1140888) si pe nota fara VANZARI (cod=1125486)
|
||||
DO verifica_pagecount_form WITH 1140888, (gnAn), (gnLuna), 'A (factura reala)', lcLog, 3, .T., 1050
|
||||
DO verifica_pagecount_form WITH 1125486, 2008, 2, 'C (nota fara VANZARI)', lcLog, 2, .F., 0
|
||||
|
||||
*!* 4) regresie runda 2 - blocantul "Go Top orb pe tact": prim rand din tact e o INCASARE, cu
|
||||
*!* nract/serie_act/dataact diferite de randul facturii - Go Top orb (runda 1) rata id_vanzare
|
||||
DO verifica_pagecount_form WITH 1137874, 2009, 8, 'D (Go Top orb - blocant runda 2)', lcLog, 3, .T., 506
|
||||
DO verifica_pagecount_form WITH 1139934, 2021, 12, 'E (coliziune cod + Go Top orb)', lcLog, 3, .T., 882
|
||||
|
||||
*!* 5) garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat, Show() nu mai gaseste garda si
|
||||
*!* degradeaza curat la PageCount=2 - ultimul test, elibereaza procedura definitiv pentru restul rularii
|
||||
DO verifica_garda_procedura_lipsa WITH 1140888, (gnAn), (gnLuna), lcLog
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE verifica_vanzare_nota
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tlAsteptatGasit, tnIdVanzareAsteptat, tnTipAsteptat, tnLiniiAsteptate
|
||||
|
||||
LOCAL llOk, lcMsg, llGasit, lnIdVanzare, lnTip, lnLinii, llIdOk, llTipOk, llLiniiOk
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
lnTip = 0
|
||||
lnLinii = -1
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Go Top In tact
|
||||
IncarcaVanzareNota(tact.cod, tact.nract, tact.serie_act, tact.dataact)
|
||||
IF Reccount('tvanz') = 1
|
||||
llGasit = .T.
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
lnTip = tvanz.tip
|
||||
IncarcaArticoleFactura(lnIdVanzare)
|
||||
lnLinii = Reccount('tvd')
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
llIdOk = IIF(tlAsteptatGasit, lnIdVanzare == tnIdVanzareAsteptat, .T.)
|
||||
llTipOk = IIF(tlAsteptatGasit, lnTip == tnTipAsteptat, .T.)
|
||||
llLiniiOk = IIF(tlAsteptatGasit AND tnLiniiAsteptate >= 0, lnLinii == tnLiniiAsteptate, .T.)
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' gasit in vanzari = ' + TRANSFORM(llGasit) + ' (asteptat ' + TRANSFORM(tlAsteptatGasit) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' tip = ' + TRANSFORM(lnTip) + ' (asteptat ' + TRANSFORM(tnTipAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tvd) = ' + TRANSFORM(lnLinii) + ' (asteptat ' + TRANSFORM(tnLiniiAsteptate) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit == tlAsteptatGasit AND llIdOk AND llTipOk AND llLiniiOk, 'PASS', 'FAIL') + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
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 Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
* cod=1139934 are 4 randuri active in VANZARI cu acelasi cod (verificat pe MARIUSM_AUTO):
|
||||
* id_vanzare=882 numar_act=375/SSS, 883=24/PF, 884=25/PF, 885=26/PF - filtrul pe cod singur
|
||||
* ar fi ambiguu; filtrul compus (cod+nract+serie_act+data_act) trebuie sa gaseasca exact
|
||||
* randul cerut si sa NU gaseasca nimic pentru un nract fara corespondent in VANZARI (ACT are
|
||||
* randuri cu nract=13 pe acelasi cod, fara VANZARI corespunzator)
|
||||
PROCEDURE verifica_coliziune_cod
|
||||
LPARAMETERS tcLog
|
||||
|
||||
LOCAL ldDataAct, llOk1, llOk2
|
||||
|
||||
ldDataAct = DATE(2021,12,31)
|
||||
|
||||
IncarcaVanzareNota(1139934, 375, 'SSS', ldDataAct)
|
||||
llOk1 = (Reccount('tvanz') = 1 AND tvanz.id_vanzare == 882)
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
|
||||
IncarcaVanzareNota(1139934, 13, '', ldDataAct)
|
||||
llOk2 = (Reccount('tvanz') = 0)
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- coliziune cod=1139934 (4 randuri VANZARI cu acelasi cod) ---' + CHR(13) + CHR(10) + ;
|
||||
' nract=375/SSS => gaseste id_vanzare=882: ' + IIF(llOk1, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
||||
' nract=13 (fara corespondent) => 0 randuri: ' + IIF(llOk2, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDPROC
|
||||
|
||||
|
||||
* instantiaza frm_modific2024 exact ca in do_editare_factura (ofacturare_comun.vc2:3781-3803):
|
||||
* IncarcaCursoareModificareNota, rebuild tact cu coloana cu_Tva, Createobject+Show; verifica
|
||||
* pgfArticole.PageCount si proprietatile de detectie dupa Show()
|
||||
PROCEDURE verifica_pagecount_form
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tnPageCountAsteptat, tlAreArticoleAsteptat, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, lnIdSet, lnPageCount, llAreArticole, lnIdVanzare, loForm, llIdVanzareOk
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
lnPageCount = -1
|
||||
llAreArticole = .F.
|
||||
lnIdVanzare = 0
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
|
||||
Go Top In tact
|
||||
lnIdSet = tact.id_set
|
||||
|
||||
IF !Used('crsJtvaTemp')
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
ENDIF
|
||||
|
||||
Select tact
|
||||
loForm = Createobject([frm_modific2024], lnIdSet)
|
||||
loForm.WindowType = 0
|
||||
loForm.Show()
|
||||
|
||||
lnPageCount = loForm.pgfArticole.PageCount
|
||||
llAreArticole = loForm.lAreArticoleVanzari
|
||||
lnIdVanzare = loForm.nIdVanzare
|
||||
|
||||
loForm.Release()
|
||||
ENDIF
|
||||
|
||||
llIdVanzareOk = IIF(PCOUNT() >= 9, lnIdVanzare == tnIdVanzareAsteptat, .T.)
|
||||
|
||||
STRTOFILE('--- frm_modific2024, cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' PageCount = ' + TRANSFORM(lnPageCount) + ' (asteptat ' + TRANSFORM(tnPageCountAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' lAreArticoleVanzari = ' + TRANSFORM(llAreArticole) + ' (asteptat ' + TRANSFORM(tlAreArticoleAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' nIdVanzare = ' + TRANSFORM(lnIdVanzare) + IIF(PCOUNT() >= 9, ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')', '') + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnPageCount == tnPageCountAsteptat AND llAreArticole == tlAreArticoleAsteptat AND llIdVanzareOk, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
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 Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
* verifica garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat din SET PROCEDURE, Show()
|
||||
* trebuie sa degradeze curat la PageCount=2, fara eroare - ultimul test din suita, procedura
|
||||
* ramane eliberata pentru restul rularii (QUIT urmeaza imediat)
|
||||
PROCEDURE verifica_garda_procedura_lipsa
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcLog
|
||||
|
||||
LOCAL llOk, lnIdSet, lnPageCount, loForm, lcProcList, lnI, lcFile
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
lnPageCount = -1
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
|
||||
Go Top In tact
|
||||
lnIdSet = tact.id_set
|
||||
|
||||
IF !Used('crsJtvaTemp')
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
ENDIF
|
||||
|
||||
*!* simuleaza ROACONT/ROAGEST: reconstruieste lista de proceduri incarcate, fara ofacturare_editare.prg
|
||||
*!* (VFP nu are un "release" pe un singur fisier din SET PROCEDURE - se inchid toate si se redeschid restul)
|
||||
lcProcList = Set('Procedure')
|
||||
SET PROCEDURE TO
|
||||
FOR lnI = 1 TO GETWORDCOUNT(lcProcList, ',')
|
||||
lcFile = ALLTRIM(GETWORDNUM(lcProcList, lnI, ','))
|
||||
IF !EMPTY(lcFile) AND !("OFACTURARE_EDITARE" $ UPPER(lcFile))
|
||||
SET PROCEDURE TO (lcFile) ADDITIVE
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
Select tact
|
||||
loForm = Createobject([frm_modific2024], lnIdSet)
|
||||
loForm.WindowType = 0
|
||||
loForm.Show()
|
||||
|
||||
lnPageCount = loForm.pgfArticole.PageCount
|
||||
|
||||
loForm.Release()
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- garda ofacturare_editare.prg lipsa, cod=' + TRANSFORM(tnCod) + ' ---' + CHR(13) + CHR(10) + ;
|
||||
' PageCount = ' + TRANSFORM(lnPageCount) + ' (asteptat 2, ca pe ROACONT/ROAGEST)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnPageCount == 2, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
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
|
||||
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
|
||||
40
utile/Teste/editare_factura/test_repro_izolat_gnan.prg
Normal file
40
utile/Teste/editare_factura/test_repro_izolat_gnan.prg
Normal file
@@ -0,0 +1,40 @@
|
||||
* test_repro_izolat_gnan.prg
|
||||
* Experimentul B (cerut de team-lead): reproduce izolat, FARA nimic din S4 - fara
|
||||
* IncarcaCursoareModificareNota, fara frm_modific2024, fara PAGE3. Doar init mediu +
|
||||
* update_jtva_coloane singura. Daca dialogul "View Parameter" apare si aici, blocajul nu are
|
||||
* nicio legatura cu modificarea S4 - e o capcana preexistenta a harness-ului/mediului.
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_repro_izolat_gnan_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_repro_izolat_gnan_errhandler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
STRTOFILE(' TYPE(gnAn)=' + TYPE('gnAn') + ' TRANSFORM(gnAn)=' + TRANSFORM(gnAn) + ;
|
||||
' TYPE(gnLuna)=' + TYPE('gnLuna') + ' TRANSFORM(gnLuna)=' + TRANSFORM(gnLuna) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\updateserver.prg ADDITIVE
|
||||
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
|
||||
STRTOFILE(' dupa update_jtva_coloane: Used(crsJtvaTemp)=' + TRANSFORM(Used('crsJtvaTemp')) + ;
|
||||
' Reccount=' + IIF(Used('crsJtvaTemp'), TRANSFORM(Reccount('crsJtvaTemp')), '(n/a)') + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE test_repro_izolat_gnan_errhandler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
55
utile/Teste/editare_factura/test_scan_workarea.prg
Normal file
55
utile/Teste/editare_factura/test_scan_workarea.prg
Normal file
@@ -0,0 +1,55 @@
|
||||
* test_scan_workarea.prg
|
||||
* Verificare punctuala: IncarcaVanzareDinNota foloseste SCAN...ENDSCAN pe tmp_triplete_pozvanz, iar
|
||||
* corpul buclei (IncarcaVanzareNota) schimba workarea curenta (creeaza/selecteaza tvanz). SCAN in VFP
|
||||
* poate sa nu tolereze schimbarea workareai curente in interiorul buclei (SKIP/EOF() implicit la
|
||||
* ENDSCAN se aplica pe workarea CURENTA, nu neaparat pe cea de la inceputul SCAN). Testul forteaza
|
||||
* explicit cazul cu 2+ triplete unde primul NU se potriveste, ca sa verifice daca a doua iteratie
|
||||
* chiar se executa (nu doar "a mers din intamplare" pe cod=1137874 unde ordinea DISTINCT ar fi putut
|
||||
* pune din start tripletul corect primul).
|
||||
* Nu atinge Oracle in scriere. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_scan_workarea_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
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
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
*!* construieste un cursor "tact" sintetic cu 2 triplete, ordonate explicit ca primul (INCASARE,
|
||||
*!* nract=99999 fara corespondent in VANZARI) sa iasa PRIMUL din SELECT DISTINCT (fara ORDER BY,
|
||||
*!* dar inserat primul si numeric mai mic), iar al doilea sa fie tripletul real (cod=1137874,
|
||||
*!* nract=5, serie=FFFFF, data=27.08.2009) care CHIAR exista in VANZARI (id_vanzare=506)
|
||||
CREATE CURSOR tact (cod I, nract I, serie_act C(20), dataact D, sters I)
|
||||
INSERT INTO tact (cod, nract, serie_act, dataact, sters) VALUES (1137874, 1, '', {}, 0)
|
||||
INSERT INTO tact (cod, nract, serie_act, dataact, sters) VALUES (1137874, 5, 'FFFFF', DATE(2009,8,27), 0)
|
||||
|
||||
LOCAL llGasit, lnIdVanzare
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
lnIdVanzare = IIF(llGasit, tvanz.id_vanzare, -1)
|
||||
|
||||
STRTOFILE('--- SCAN cu workarea schimbata in corp: 2 triplete, primul fara corespondent ---' + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat 506)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit AND lnIdVanzare == 506, 'PASS', 'FAIL') + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
27
utile/Teste/editare_factura/test_set_procedure.prg
Normal file
27
utile/Teste/editare_factura/test_set_procedure.prg
Normal file
@@ -0,0 +1,27 @@
|
||||
* test_set_procedure.prg
|
||||
* Verifica strict formatul intors de SET("PROCEDURE") in VFP9, dupa mai multe
|
||||
* SET PROCEDURE TO ... ADDITIVE succesive, ca sa se stabileasca garda din omodificari.vc2 Show().
|
||||
* Nu atinge Oracle, nu deschide formulare. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_set_procedure_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
STRTOFILE('dupa 1 SET PROCEDURE: [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oproceduri_facturare.prg ADDITIVE
|
||||
STRTOFILE('dupa 2 SET PROCEDURE (alt fisier ADDITIVE): [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_stoc.prg ADDITIVE
|
||||
STRTOFILE('dupa 3 SET PROCEDURE (al treilea fisier ADDITIVE): [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
LOCAL llGasit
|
||||
llGasit = "OFACTURARE_EDITARE" $ UPPER(SET('PROCEDURE'))
|
||||
STRTOFILE('contine OFACTURARE_EDITARE dupa 3 seturi: ' + TRANSFORM(llGasit) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
523
utile/Teste/editare_factura/test_writeback_buton1.prg
Normal file
523
utile/Teste/editare_factura/test_writeback_buton1.prg
Normal file
@@ -0,0 +1,523 @@
|
||||
* 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
|
||||
14
utile/Teste/watchdog_selftest.prg
Normal file
14
utile/Teste/watchdog_selftest.prg
Normal file
@@ -0,0 +1,14 @@
|
||||
* watchdog_selftest.prg - caz banal pentru validarea watchdog_vfp.ps1: afiseaza un MESSAGEBOX
|
||||
* nativ (OK/Cancel) si asteapta. Foloseste doar pentru testarea utilitarului, nu face parte
|
||||
* din nicio suita de regresie.
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_selftest_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
= MESSAGEBOX('Mesaj de test watchdog_vfp.ps1', 1, 'Watchdog selftest')
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
390
utile/Teste/watchdog_vfp.ps1
Normal file
390
utile/Teste/watchdog_vfp.ps1
Normal file
@@ -0,0 +1,390 @@
|
||||
# watchdog_vfp.ps1 - lanseaza un test VFP headless si detecteaza dialoguri native blocante
|
||||
# (mesaje Windows, "View Parameter", erori modale) care nu apar in logul scris de script si
|
||||
# nu sunt prinse de ON ERROR / mock-uri - cazul clasic de proces "agatat" cu CPU~0.
|
||||
#
|
||||
# Ce face: sterge .fxp-ul vechi, lanseaza `vfp9.exe -A -T "<script>"`, apoi polleaza la interval
|
||||
# scurt ferestrele TOP-LEVEL ale procesului (EnumWindows + GetWindowThreadProcessId). Fereastra
|
||||
# principala VFP se identifica prin Process.MainWindowHandle (.NET) - NU dupa numele clasei:
|
||||
# VFP inregistreaza clase diferite prefixate "vfp9..." atat pentru shell-ul principal cat si
|
||||
# pentru dialogurile proprii (ex. "View Parameter"), deci clasificarea pe clasa e nesigura.
|
||||
# Orice fereastra NOUA, diferita de MainWindowHandle, e tratata ca dialog blocant.
|
||||
#
|
||||
# Pentru fiecare dialog detectat: captura PNG (PrintWindow, fallback CopyFromScreen daca iese
|
||||
# neagra) + dump text (titlu, clasa, si textul/clasa fiecarui control copil via WM_GETTEXT - se
|
||||
# citesc controale native Windows chiar daca apartin unui proces strain pe alta arhitectura).
|
||||
#
|
||||
# INTERZIS: watchdog-ul NU are voie sa foloseasca input real de tastatura/mouse (keybd_event,
|
||||
# SetForegroundWindow, SendInput, mouse_event) - masina e PARTAJATA cu utilizatorul, iar un
|
||||
# ESCAPE/click injectat la nivel de sistem ajunge in orice fereastra are focus in acel moment,
|
||||
# nu neaparat in dialogul tintit (verificat: a ajuns in IDE-ul VFP al utilizatorului aflat in
|
||||
# lucru in paralel, intrerupandu-l). -AutoDismiss foloseste STRICT mesaje Windows tintite pe
|
||||
# handle-ul dialogului: buton copil cu text Cancel/Anulare/Renunta -> BM_CLICK; altfel
|
||||
# WM_COMMAND IDCANCEL -> ESCAPE ca mesaj (WM_KEYDOWN/WM_KEYUP, nu input real) -> WM_CLOSE, in
|
||||
# ordine, primul care inchide fereastra castiga. Dialogurile proprii VFP owner-drawn (ex.
|
||||
# "View Parameter" - butoanele sunt desenate, nu HWND-uri reale) pot sa NU raspunda la niciunul -
|
||||
# atunci dismiss-ul ESUEAZA CINSTIT (ramane deschis pana la timeout), nu se cade pe input real.
|
||||
# Captura (PNG+dump text) e intotdeauna de incredere, indiferent de rezultatul dismiss-ului.
|
||||
# Continua polling-ul dupa fiecare dismiss reusit, ca sa prinda si eventuale dialoguri urmatoare
|
||||
# (pana la -MaxDialogs). Fara -AutoDismiss: captureaza primul dialog gasit, apoi opreste
|
||||
# polling-ul (nu-l atinge).
|
||||
#
|
||||
# Procesul e omorat mereu la iesire (finally) - nu ramane niciodata viu.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -ExecutionPolicy Bypass -File watchdog_vfp.ps1 -Script "D:\...\test_x.prg" -AutoDismiss
|
||||
# powershell -ExecutionPolicy Bypass -File watchdog_vfp.ps1 -Script "D:\...\test_x.prg" -TimeoutSec 60 -OutDir "D:\...\out"
|
||||
#
|
||||
# Parametri:
|
||||
# -Script cale completa la .prg de rulat (obligatoriu)
|
||||
# -Vfp cale la vfp9.exe (implicit instalarea standard x86)
|
||||
# -TimeoutSec timeout total de polling (implicit 90)
|
||||
# -OutDir folder pentru PNG-uri + log text (implicit "<folderul scriptului>\watchdog_out")
|
||||
# -AutoDismiss inchide automat dialogurile gasite (Cancel/WM_CLOSE) si continua polling-ul
|
||||
# -MaxDialogs cate dialoguri succesive sa trateze cu -AutoDismiss (implicit 10)
|
||||
#
|
||||
# Iesire: rezumat pe stdout (numar dialoguri, textul fiecaruia, caile PNG, exit code-ul
|
||||
# procesului) + acelasi continut scris in "<Script>_watchdog.log" din -OutDir.
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Script,
|
||||
[string]$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe',
|
||||
[int]$TimeoutSec = 90,
|
||||
[string]$OutDir,
|
||||
[switch]$AutoDismiss,
|
||||
[int]$MaxDialogs = 10
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $Script)) { throw "Nu gasesc scriptul: $Script" }
|
||||
$Script = (Resolve-Path $Script).Path
|
||||
$ScriptDir = [System.IO.Path]::GetDirectoryName($Script)
|
||||
$ScriptBase = [System.IO.Path]::GetFileNameWithoutExtension($Script)
|
||||
if (-not $OutDir) { $OutDir = Join-Path $ScriptDir 'watchdog_out' }
|
||||
if (-not (Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
|
||||
$LogPath = Join-Path $OutDir ($ScriptBase + '_watchdog.log')
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
Add-Type @"
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class WdWin32 {
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool IsWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
|
||||
public static extern IntPtr SendMessageText(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT { public int Left, Top, Right, Bottom; }
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint nFlags);
|
||||
}
|
||||
"@
|
||||
|
||||
$WM_GETTEXT = 0x000D
|
||||
$WM_CLOSE = 0x0010
|
||||
$BM_CLICK = 0x00F5
|
||||
|
||||
function Get-TopWindowsForPid([int]$ProcId) {
|
||||
$result = New-Object System.Collections.Generic.List[IntPtr]
|
||||
$cb = {
|
||||
param($hWnd, $lParam)
|
||||
$owner = 0
|
||||
[void][WdWin32]::GetWindowThreadProcessId($hWnd, [ref]$owner)
|
||||
if ($owner -eq $ProcId -and [WdWin32]::IsWindowVisible($hWnd)) { $result.Add($hWnd) }
|
||||
return $true
|
||||
}
|
||||
[WdWin32]::EnumWindows($cb, [IntPtr]::Zero) | Out-Null
|
||||
return $result
|
||||
}
|
||||
|
||||
function Get-ChildWindowsOf([IntPtr]$hWndParent) {
|
||||
$result = New-Object System.Collections.Generic.List[IntPtr]
|
||||
$cb = {
|
||||
param($hWnd, $lParam)
|
||||
$result.Add($hWnd)
|
||||
return $true
|
||||
}
|
||||
[WdWin32]::EnumChildWindows($hWndParent, $cb, [IntPtr]::Zero) | Out-Null
|
||||
return $result
|
||||
}
|
||||
|
||||
# WM_GETTEXT (nu GetWindowText) - citeste text de la controale ale unui proces strain, indiferent
|
||||
# de arhitectura (32/64 bit); GetWindowText poate esua tacut pe controale custom VFP.
|
||||
function Get-WmText([IntPtr]$hWnd, [int]$MaxLen = 1024) {
|
||||
$sb = New-Object System.Text.StringBuilder $MaxLen
|
||||
[WdWin32]::SendMessageText($hWnd, $WM_GETTEXT, $MaxLen, $sb) | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Get-WinClassName([IntPtr]$hWnd) {
|
||||
$sb = New-Object System.Text.StringBuilder 256
|
||||
[WdWin32]::GetClassName($hWnd, $sb, $sb.Capacity) | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Test-BitmapAllBlack([System.Drawing.Bitmap]$bmp) {
|
||||
$w = $bmp.Width; $h = $bmp.Height
|
||||
if ($w -le 0 -or $h -le 0) { return $true }
|
||||
for ($i = 0; $i -lt 9; $i++) {
|
||||
$x = [Math]::Min($w - 1, [int]($w * (($i % 3) + 0.5) / 3))
|
||||
$y = [Math]::Min($h - 1, [int]($h * ([Math]::Floor($i / 3) + 0.5) / 3))
|
||||
$px = $bmp.GetPixel($x, $y)
|
||||
if ($px.R -ne 0 -or $px.G -ne 0 -or $px.B -ne 0) { return $false }
|
||||
}
|
||||
return $true
|
||||
}
|
||||
|
||||
# PrintWindow direct pe handle; fallback CopyFromScreen daca iese neagra (fereastra themed/GDI+
|
||||
# care nu se randeaza corect prin PrintWindow). Foloseste doar pentru dialoguri surprinse
|
||||
# on-screen - nu se muta off-screen aici (spre deosebire de vfp_ui_harness.ps1), fiindca scopul
|
||||
# e sa surprindem exact dialogul care blocheaza, o singura data.
|
||||
function Save-DialogScreenshot([IntPtr]$hWnd, [string]$Path) {
|
||||
$rect = New-Object WdWin32+RECT
|
||||
[WdWin32]::GetWindowRect($hWnd, [ref]$rect) | Out-Null
|
||||
$w = $rect.Right - $rect.Left
|
||||
$h = $rect.Bottom - $rect.Top
|
||||
if ($w -le 0 -or $h -le 0) { return $false }
|
||||
$bmp = New-Object System.Drawing.Bitmap $w, $h
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$hdc = $g.GetHdc()
|
||||
$ok = [WdWin32]::PrintWindow($hWnd, $hdc, 2)
|
||||
$g.ReleaseHdc($hdc)
|
||||
$g.Dispose()
|
||||
if ((-not $ok) -or (Test-BitmapAllBlack $bmp)) {
|
||||
$bmp.Dispose()
|
||||
$bmp = New-Object System.Drawing.Bitmap $w, $h
|
||||
$g2 = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
try { $g2.CopyFromScreen($rect.Left, $rect.Top, 0, 0, (New-Object System.Drawing.Size $w, $h)) } catch {}
|
||||
$g2.Dispose()
|
||||
}
|
||||
$bmp.Save($Path, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
$bmp.Dispose()
|
||||
return $true
|
||||
}
|
||||
|
||||
function Get-DialogDump([IntPtr]$hWnd, [System.Collections.Generic.List[IntPtr]]$children) {
|
||||
$title = Get-WmText $hWnd
|
||||
$class = Get-WinClassName $hWnd
|
||||
$lines = New-Object System.Collections.Generic.List[string]
|
||||
$lines.Add("dialog hwnd=$hWnd class='$class' title='$title'")
|
||||
foreach ($c in $children) {
|
||||
$ct = (Get-WmText $c 512).Trim()
|
||||
$cc = Get-WinClassName $c
|
||||
if ($ct -or $cc) { $lines.Add(" child hwnd=$c class='$cc' text='$ct'") }
|
||||
}
|
||||
# unary comma obligatoriu: fara ea, un List[string] cu UN SINGUR element (dialog fara copii,
|
||||
# ex. "View Parameter") e "descompus" de PowerShell la scalar string simplu la return, iar
|
||||
# indexarea ulterioara $dumpLines[0] citeste primul CARACTER, nu primul rand - prins la testul
|
||||
# pe test_page3_articole.prg (rezumatul arata titlul "d" in loc de linia intreaga)
|
||||
return , $lines.ToArray()
|
||||
}
|
||||
|
||||
function Find-DismissButton([System.Collections.Generic.List[IntPtr]]$children) {
|
||||
foreach ($c in $children) {
|
||||
if ((Get-WinClassName $c) -ne 'Button') { continue }
|
||||
$txt = ((Get-WmText $c 256) -replace '&', '').Trim()
|
||||
if ($txt -ieq 'Cancel' -or $txt -ieq 'Anulare' -or $txt -ieq 'Renunta' -or $txt -ieq 'Renunță') { return $c }
|
||||
}
|
||||
return [IntPtr]::Zero
|
||||
}
|
||||
|
||||
$WM_COMMAND = 0x0111
|
||||
$WM_KEYDOWN = 0x0100
|
||||
$WM_KEYUP = 0x0101
|
||||
$VK_ESCAPE = 0x1B
|
||||
$IDCANCEL = 2
|
||||
|
||||
# INTERZIS: input real de tastatura/mouse (keybd_event, SetForegroundWindow, SendInput,
|
||||
# mouse_event). Masina e PARTAJATA cu utilizatorul - un ESCAPE injectat la nivel de sistem
|
||||
# ajunge in orice fereastra are focus in acel moment, INDIFERENT carui proces ii apartine
|
||||
# (verificat: a ajuns in IDE-ul VFP al utilizatorului, aflat in lucru in paralel, intrerupandu-l
|
||||
# cu o eroare + "Execution was canceled by the user"). Foloseste STRICT mesaje Windows tintite pe
|
||||
# HANDLE-ul dialogului (PostMessage/SendMessage: WM_COMMAND IDCANCEL, WM_KEYDOWN/WM_KEYUP
|
||||
# VK_ESCAPE, WM_CLOSE, BM_CLICK) - astea nu ating focusul/inputul global, raman izolate la
|
||||
# fereastra tintita. Dialogurile native VFP proprii (ex. "View Parameter") NU au controale copil
|
||||
# reale (owner-drawn) si pot sa NU raspunda la niciunul dintre mesajele de mai jos - in acel caz
|
||||
# dismiss-ul ESUEAZA CINSTIT (dialogul ramane deschis, procesul e omorat la timeout de finally),
|
||||
# nu se cade pe input real. Captura (PNG+dump text) ramane oricum de incredere, indiferent de
|
||||
# rezultatul dismiss-ului.
|
||||
function Dismiss-Dialog([IntPtr]$hWnd, [System.Collections.Generic.List[IntPtr]]$children) {
|
||||
$btn = Find-DismissButton $children
|
||||
if ($btn -ne [IntPtr]::Zero) {
|
||||
[WdWin32]::SendMessage($btn, $BM_CLICK, [IntPtr]::Zero, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'click Cancel/Anulare' }
|
||||
return 'NEREUSIT: BM_CLICK pe Cancel/Anulare nu a inchis dialogul'
|
||||
}
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_COMMAND, [IntPtr]$IDCANCEL, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'WM_COMMAND IDCANCEL' }
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_KEYDOWN, [IntPtr]$VK_ESCAPE, [IntPtr]::Zero) | Out-Null
|
||||
[WdWin32]::SendMessage($hWnd, $WM_KEYUP, [IntPtr]$VK_ESCAPE, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'tasta ESCAPE trimisa cu SendMessage (mesaj, nu input real)' }
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_CLOSE, [IntPtr]::Zero, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'WM_CLOSE' }
|
||||
|
||||
$motiv = if ($children.Count -eq 0) { 'fara controale copil (owner-drawn) si niciun mesaj tintit nu a functionat' } else { 'niciun mesaj tintit (WM_COMMAND/ESCAPE mesaj/WM_CLOSE) nu a functionat' }
|
||||
return "NEREUSIT: dialogul a ramas deschis ($motiv) - fara input real, per regula masinii partajate"
|
||||
}
|
||||
|
||||
# omoara doar vfp9 lansate pe ACEST script (linia de comanda contine calea lui), nu instante straine
|
||||
function Stop-VfpForScript([string]$ScriptPath) {
|
||||
Get-CimInstance Win32_Process -Filter "Name='vfp9.exe'" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
if ($_.CommandLine -and $_.CommandLine.ToLower().Contains($ScriptPath.ToLower())) {
|
||||
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- pregatire ---
|
||||
$Fxp = [System.IO.Path]::ChangeExtension($Script, 'fxp')
|
||||
if (Test-Path $Fxp) { Remove-Item $Fxp -Force }
|
||||
Stop-VfpForScript $Script
|
||||
Start-Sleep -Milliseconds 300
|
||||
|
||||
$log = New-Object System.Collections.Generic.List[string]
|
||||
function Log([string]$s) { Write-Host $s; $log.Add($s) }
|
||||
|
||||
Log "watchdog_vfp: lansez $Vfp -A -T `"$Script`""
|
||||
$proc = Start-Process -FilePath $Vfp -ArgumentList @('-A', '-T', "`"$Script`"") -PassThru
|
||||
|
||||
$dialogs = New-Object System.Collections.Generic.List[object]
|
||||
$exitCode = $null
|
||||
|
||||
try {
|
||||
# Fereastra principala = Process.MainWindowHandle (.NET), latch-uita o singura data. NU se
|
||||
# poate distinge dupa numele clasei: VFP inregistreaza clase diferite prefixate "vfp9..." atat
|
||||
# pentru shell-ul principal ("vfp99400000") CAT SI pentru dialoguri native proprii precum
|
||||
# "View Parameter" ("vfp994000002") - verificat empiric, clasificarea pe clasa a lasat
|
||||
# "View Parameter" nedetectat. MainWindowHandle e acelasi mecanism folosit deja cu succes in
|
||||
# vfp_ui_harness.ps1 (Wait-MainWindowHandle) pentru shell-ul VFP.
|
||||
$mainHwnd = [IntPtr]::Zero
|
||||
$mwDeadline = (Get-Date).AddSeconds(20)
|
||||
while ($mainHwnd -eq [IntPtr]::Zero -and (Get-Date) -lt $mwDeadline) {
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { break }
|
||||
if ($proc.MainWindowHandle -ne [IntPtr]::Zero) { $mainHwnd = $proc.MainWindowHandle }
|
||||
else { Start-Sleep -Milliseconds 200 }
|
||||
}
|
||||
if ($mainHwnd -ne [IntPtr]::Zero) {
|
||||
Log ("fereastra principala VFP: hwnd={0} class='{1}' title='{2}'" -f $mainHwnd, (Get-WinClassName $mainHwnd), (Get-WmText $mainHwnd))
|
||||
} else {
|
||||
Log "ATENTIE: MainWindowHandle nu a aparut in 20s - orice fereastra gasita va fi tratata ca dialog."
|
||||
}
|
||||
|
||||
$knownWindows = New-Object System.Collections.Generic.HashSet[IntPtr]
|
||||
if ($mainHwnd -ne [IntPtr]::Zero) { [void]$knownWindows.Add($mainHwnd) }
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
$stop = $false
|
||||
|
||||
while (-not $stop -and (Get-Date) -lt $deadline) {
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { Log "proces terminat singur (exit code $($proc.ExitCode))"; break }
|
||||
|
||||
# daca MainWindowHandle inca nu era prins, incearca din nou (fereastra principala poate
|
||||
# aparea mai tarziu decat asteptarea initiala de 20s in cazuri lente)
|
||||
if ($mainHwnd -eq [IntPtr]::Zero -and $proc.MainWindowHandle -ne [IntPtr]::Zero) {
|
||||
$mainHwnd = $proc.MainWindowHandle
|
||||
[void]$knownWindows.Add($mainHwnd)
|
||||
Log ("fereastra principala VFP (intarziata): hwnd={0} class='{1}' title='{2}'" -f $mainHwnd, (Get-WinClassName $mainHwnd), (Get-WmText $mainHwnd))
|
||||
}
|
||||
|
||||
$windows = Get-TopWindowsForPid $proc.Id
|
||||
|
||||
foreach ($w in $windows) {
|
||||
if ($knownWindows.Contains($w)) { continue }
|
||||
[void]$knownWindows.Add($w)
|
||||
|
||||
if ($w -eq $mainHwnd) { continue }
|
||||
|
||||
$children = Get-ChildWindowsOf $w
|
||||
$dumpLines = Get-DialogDump $w $children
|
||||
$idx = $dialogs.Count
|
||||
$png = Join-Path $OutDir ("{0}_dialog{1}.png" -f $ScriptBase, $idx)
|
||||
Save-DialogScreenshot $w $png | Out-Null
|
||||
|
||||
Log "=== DIALOG $idx detectat ==="
|
||||
foreach ($l in $dumpLines) { Log $l }
|
||||
Log " screenshot: $png"
|
||||
|
||||
$dismissMethod = $null
|
||||
if ($AutoDismiss) {
|
||||
$dismissMethod = Dismiss-Dialog $w $children
|
||||
Log " dismiss: $dismissMethod"
|
||||
}
|
||||
|
||||
$dialogs.Add([pscustomobject]@{
|
||||
Index = $idx
|
||||
Title = ($dumpLines[0])
|
||||
Png = $png
|
||||
Dismiss = $dismissMethod
|
||||
DumpText = ($dumpLines -join "`r`n")
|
||||
})
|
||||
|
||||
if ($dialogs.Count -ge $MaxDialogs) { Log "MaxDialogs ($MaxDialogs) atins."; $stop = $true; break }
|
||||
if (-not $AutoDismiss) { Log "AutoDismiss oprit - opresc polling-ul dupa primul dialog."; $stop = $true; break }
|
||||
}
|
||||
|
||||
if (-not $stop) { Start-Sleep -Milliseconds 700 }
|
||||
}
|
||||
|
||||
if (-not $proc.HasExited -and (Get-Date) -ge $deadline) {
|
||||
Log "TIMEOUT (${TimeoutSec}s) - procesul e inca viu, il opresc."
|
||||
}
|
||||
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { $exitCode = $proc.ExitCode }
|
||||
}
|
||||
finally {
|
||||
if ($proc -and -not $proc.HasExited) {
|
||||
try { $proc.Kill() } catch {}
|
||||
}
|
||||
Stop-VfpForScript $Script
|
||||
}
|
||||
|
||||
# --- rezumat ---
|
||||
Log ""
|
||||
Log "=== REZUMAT ==="
|
||||
Log ("dialoguri detectate: {0}" -f $dialogs.Count)
|
||||
foreach ($d in $dialogs) {
|
||||
Log (" [{0}] {1}" -f $d.Index, $d.Title)
|
||||
Log (" png: {0}" -f $d.Png)
|
||||
if ($d.Dismiss) { Log (" dismiss: {0}" -f $d.Dismiss) }
|
||||
}
|
||||
Log ("exit code proces: {0}" -f ($(if ($null -ne $exitCode) { $exitCode } else { '(omorat de watchdog, nu s-a terminat singur)' })))
|
||||
Log ("log complet: {0}" -f $LogPath)
|
||||
|
||||
[System.IO.File]::WriteAllLines($LogPath, $log)
|
||||
Reference in New Issue
Block a user