sync SVN r18218

This commit is contained in:
2026-09-28 16:01:35 +03:00
parent 1255826266
commit e263114bad
9 changed files with 829 additions and 0 deletions

View File

@@ -66,6 +66,27 @@ aprobare. Configurarea e globala, pentru toate proiectele, in `%USERPROFILE%\.co
Se aplica la pornirea serverului (`opencode serve`); un server deja pornit trebuie repornit.
O cerere ramasa in asteptare se aproba prin API: `GET /permission` → `POST /session/:id/permissions/:permissionID` `{"response":"always"}`.
## Flux standard pe o lucrare (plan -> executie -> review -> aprobare)
1. **Plan** (orchestratorul, Opus): `docs\plan_<subiect>.md` exact - pasii, codul de inserat, locul (`fisier:linie`),
pasul 0 = baseline curat (`*.pre_runda1.bak` == `svn cat`), testul cu cazurile lui, verificarile da/nu, livrarea.
Executantul nu redeseneaza; un brief vag produce cod in plus.
2. **Executie**: sesiune opencode noua, `Lane: <x>. Executa EXACT planul din ...`. Livreaza patch + raport + `GATA`.
3. **Verificare orchestrator** (asserturi, nu citire): 0 x `EF BF BD`, CRLF pe toate liniile (numarat cu
`perl -ne '$c++ if /\r\n$/'`; `grep -c $'\r$'` din Git Bash numara gresit), liniile cu octeti
>0x7F identice cu baseline, `git diff --no-index` citit o data fata de plan, testul trecut.
4. **Review**: sesiune opencode NOUA (nu executantul), rol de reviewer, nu modifica cod. Brief
`docs\brief_review_<subiect>.md` cu: intrarile (plan, patch, cod, test), cele 5 verificari - fidelitate fata de plan,
corectitudine pe fluxul real (apelanti, alias selectat, cursoare inchise, NULL, ramurile neatinse raman identice),
conventii (`reguli_lucru.md` 2-3), octeti/CRLF, testul rulat de el -, livrare `docs\review_<subiect>.md` cu
BLOCANT/MAJOR/MINOR + `fisier:linie` + dovada; ce nu poate dovedi marcheaza "ipoteza".
Ultimul mesaj `REVIEW GATA: <n> BLOCANT, <n> MAJOR, <n> MINOR`.
5. BLOCANT/MAJOR -> corectie in sesiunea executantului (sau una noua cu handoff), apoi review din nou.
BLOCANT de doua ori sau verificarea de la 3 pica de doua ori -> escaladare Opus.
6. **Aprobare Marius** pe patch; abia apoi commit.
Prag context per sesiune opencode: ca la subagenti (~200-250k); peste -> abort, handoff pe disc, sesiune noua.
Contextul curent: `input + cache.read` din `info.tokens` al ultimului mesaj (`GET /session/:id/message`).
## Reguli pentru lane-uri
- Sarcina contine numele lane-ului, fisierele exacte si criteriul de terminare.
- Orchestratorul verifica dupa fiecare lane: diff, octeti cp1252, CRLF, teste.

View File

@@ -0,0 +1 @@
D:\ROA\ROACONT\Programe\oproceduri_import.prg

View File

@@ -0,0 +1,9 @@
RUN 28/09/2026 02:34:46 PM fisier=D:\ROA\ROACONT\Programe\oproceduri_import.prg
SET PROCEDURE OK: D:\ROA\ROACONT\Programe\oproceduri_import.prg
PASS A_curier_o_alocare_S :: alocat=.T. nrpoz=1 sursa=S idfact=15634 idpartrand=22423 suma=710.08
PASS B_curier_fara_suma_exacta :: alocat=.F. nrpoz=0
PASS C_curier_doua_facturi_egale :: alocat=.F. nrpoz=0
PASS D_bancar_F_plus_A :: alocat=.T. nrpoz=2 sursa1=F sursa2=A suma=710.08
PASS E_adauga_grup_nume_2cuv :: sqlOk=.T. randuri=0 dubluri=0 ales=0 den=CASA LEI
PASS E_adauga_grup_nume_1cuv :: sqlOk=.T. randuri=0 ales=0 den=ARDAF
=== SUMAR: PASS=6 FAIL=0 ===

View File

@@ -0,0 +1,6 @@
RUN 09/28/26 01:49:20 PM
env init OK (schema MARIUSM_AUTO)
permutari: [TOMESCU GEORGE;GEORGE TOMESCU]
PASS: interogare grup nume OK, randuri=1
id_part=1964 denumire=GEORGE TOMESCU
=== GATA ===

View File

@@ -0,0 +1,53 @@
* mock_cauta_alfa_capture.prg - inlocuieste DOAR PROCEDURE cauta_alfa (COMUN\programe\cauta_alfa.prg,
* linia 16), NU restul lantului (do_cauta/CautPartenerContabilitate/alege_partener raman REALE,
* neatinse) - captureaza starea EXACT in punctul unde codul real ar deschide formularul modal de
* cautare: ASTACKINFO() (cine a apelat - LostFocus/Click/AfterRowColChange), Thisform.LockScreen,
* USED/RECCOUNT('tact'), Grid1.RecordSource. Nu deschide niciun formular - raspunde "Cancel"
* (gnButon=2), exact ca un operator care apasa Renunta, ca sa nu blocheze testul.
* Se incarca PRIMUL (inaintea "SET PROCEDURE TO cauta_alfa ADDITIVE" din test_init_env_auto) - la
* nume duplicat de procedura VFP foloseste fisierul incarcat PRIMUL.
*
* Rezultat expus (citit de testul principal): gnCaptureN (numarul de intrari capturate).
Procedure cauta_alfa
Parameters tcselect,tcfiltru,tcschema,tcorder,tccoloana,tcTitlu,tcTitluColoane, ;
tcNume_Proc,tl_AllInList,tcFiltruOriginal,tcPrimaColoana, tnPornire, tnTipReturn, ;
tcIdColumn, tlDesktop, tcGroup, tcGridDynamicBackColor, tcGridToolTip, tlModParam, tcStringCriterii, ;
tcProceduraVerifica, tcProceduraCopiaza,tcLocate
LOCAL lcStack, lnI, lnN
LOCAL ARRAY laStack[1]
gnCaptureN = gnCaptureN + 1
lnN = ASTACKINFO(laStack)
lcStack = ''
FOR lnI = 1 TO lnN
lcStack = lcStack + ' #' + TRANSFORM(lnI) + ' ' + TRANSFORM(laStack[lnI,3]) + ' linia ' + TRANSFORM(laStack[lnI,6]) + CHR(13) + CHR(10)
ENDFOR
DO HarnessLog WITH '--- CAPTURE #' + TRANSFORM(gnCaptureN) + ' intrare in cauta_alfa (mock) ---'
DO HarnessLog WITH 'ASTACKINFO:' + CHR(13) + CHR(10) + lcStack
DO HarnessLog WITH 'LockScreen=' + TRANSFORM(goFormTest.LockScreen) + ;
' USED(tact)=' + TRANSFORM(USED('tact')) + ' RECCOUNT(tact)=' + TRANSFORM(IIF(USED('tact'),RECCOUNT('tact'),-1)) + ;
' RECNO(tact)=' + TRANSFORM(IIF(USED('tact'),RECNO('tact'),-1)) + ;
' Grid1.RecordSource=[' + goFormTest.Grid1.RecordSource + ']' + ;
' Grid1.Visible=' + TRANSFORM(goFormTest.Grid1.Visible) + ' Thisform.Visible=' + TRANSFORM(goFormTest.Visible)
IF TYPE('gcCaptureSyncStep') = 'N' AND gcCaptureSyncStep > 0
DO HarnessStep WITH gcCaptureSyncStep, 'in interiorul cauta_alfa (mock), captura #' + TRANSFORM(gnCaptureN), 8
ENDIF
*-- raspuns Cancel real (gnButon global, declarat PUBLIC in test_init_env_auto.prg)
gnButon = 2
DO CASE
CASE tnTipReturn = 0
LOCAL loRet
loRet = CREATEOBJECT('Empty')
ADDPROPERTY(loRet, 'id_part', 0)
ADDPROPERTY(loRet, 'tip', 0)
ADDPROPERTY(loRet, 'nume', '')
RETURN loRet
OTHERWISE
RETURN ''
ENDCASE
Endproc && cauta_alfa (mock capturare)

View File

@@ -0,0 +1,78 @@
* probe_env.prg - sonda READ-ONLY: structura vact_tot, un cont cu config_cont_ireg, si test tact minimal.
* Rulare: vfp9.exe -A -T "probe_env.prg"
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcLog
gcLog = "D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\probe_env_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
ON ERROR DO PrE WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT', 2026, 9
IF gnHandle <= 0
DO PrL WITH 'FAIL conectare, gnHandle=' + TRANSFORM(gnHandle)
QUIT
ENDIF
DO PrL WITH 'conectat gnHandle=' + TRANSFORM(gnHandle) + ' gcS=' + gcS + ' gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna)
LOCAL llSucces
llSucces = goExecutor.oExecuta("select * from vact_tot where 1=2", "v_act")
DO PrL WITH 'vact_tot 1=2: succes=' + TRANSFORM(llSucces)
IF llSucces
LOCAL laF[1], lnI, lcCols
lnI = AFIELDS(laF, 'v_act')
lcCols = ''
FOR lnI = 1 TO ALEN(laF,1)
lcCols = lcCols + laF[lnI,1] + '(' + laF[lnI,2] + ') '
ENDFOR
DO PrL WITH 'vact_tot campuri (' + TRANSFORM(ALEN(laF,1)) + '): ' + lcCols
USE IN v_act
ENDIF
llSucces = goExecutor.oExecuta("select cont, count(*) as ncc from config_cont_ireg group by cont order by cont", "cCfg")
IF llSucces
DO PrL WITH 'config_cont_ireg conturi: reccount=' + TRANSFORM(RECCOUNT('cCfg'))
SELECT cCfg
SCAN
DO PrL WITH ' cont=[' + TRANSFORM(cont) + ']'
ENDSCAN
USE IN cCfg
ELSE
DO PrL WITH 'FAIL config_cont_ireg: ' + goExecutor.cEroare
ENDIF
llSucces = goExecutor.oExecuta("select count(*) as n from coresp_tip_cont where cont = '4111'", "cCorp")
IF llSucces
DO PrL WITH 'coresp_tip_cont cont=4111: n=' + TRANSFORM(cCorp.n)
USE IN cCorp
ENDIF
DO PrL WITH 'DONE ' + TTOC(DATETIME())
CATCH TO loEx
DO PrL WITH 'EXCEPTIE ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure
ENDTRY
QUIT
PROCEDURE PrL
LPARAMETERS tcMsg
LOCAL lcL
SET SAFETY OFF
lcL = IIF(FILE(gcLog), FILETOSTR(gcLog), '')
STRTOFILE(lcL + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcLog)
ENDPROC
PROCEDURE PrE
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
DO PrL WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo)
ENDPROC

View File

@@ -0,0 +1,227 @@
* test_grid_albit_stack.prg - dovada prin rulare (nu analiza statica) a CE declanseaza deschiderea
* cautarii partenerului cand se paraseste celula Partener Credit (Grid1.Column10) goala, in
* frm_modific2024 (COMUN\clase\omodificari.vc2:6375), ecranul de verificare dupa import.
* Instrumentare: mock_cauta_alfa_capture.prg inlocuieste cauta_alfa cu o capturare de stare
* (ASTACKINFO/LockScreen/USED/RECCOUNT/RecordSource), fara sa deschida vreun formular - restul
* lantului (do_cauta/CautPartenerContabilitate/alege_partener/LostFocus/AfterRowColChange) e REAL.
* tact e construit din structura REALA de productie (vact_tot -> ales/Cu_tva/tipnota, exact ca in
* Programe\ocont2003.prg::note_fara_predefinire), cu doua randuri: randul 1 cont 4111 (are
* config_cont_ireg+coresp_tip_cont) cu partener CREDIT gol, randul 2 cu partener deja completat.
*
* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\test_grid_albit_stack.prg"
* Iesire: D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\test_grid_albit_stack_log.txt
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir, gnCaptureN, gcCaptureSyncStep, goFormTest
gcSyncDir = 'D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\uisync\'
gcUILog = 'D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\test_grid_albit_stack_log.txt'
STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog)
gnCaptureN = 0
gcCaptureSyncStep = 0
ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
*-- cai complete: la lansare vfp9 -A -T directorul curent NU e cel al scriptului, deci nume goale
*-- de PRG nu se gasesc (era cauza dialogului "Program Error: harnesslog.prg does not exist")
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
*-- mock-ul cauta_alfa TREBUIE incarcat inaintea test_init_env_auto (care face
*-- SET PROCEDURE TO cauta_alfa ADDITIVE) - la nume duplicat VFP tine fisierul incarcat PRIMUL
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\grid_albit\mock_cauta_alfa_capture.prg" ADDITIVE
TRY
DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT', 2026, 9
IF gnHandle <= 0
DO HarnessLog WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')'
DO HarnessDone WITH 'error'
QUIT
ENDIF
DO HarnessLog WITH 'mediu initializat gnHandle=' + TRANSFORM(gnHandle)
DO BuildTact
DO HarnessLog WITH 'tact construit, reccount=' + TRANSFORM(RECCOUNT('tact')) + ' campuri=' + TRANSFORM(FCOUNT('tact'))
DO HarnessLog WITH ' rand1: scc=' + ALLTRIM(tact.scc) + ' partc=[' + ALLTRIM(NVL(tact.partc,'')) + ']'
GO 2 IN tact
DO HarnessLog WITH ' rand2: scc=' + ALLTRIM(tact.scc) + ' partc=[' + ALLTRIM(NVL(tact.partc,'')) + ']'
GO 1 IN tact
SELECT tact
GO TOP
goFormTest = CREATEOBJECT('frm_modific2024', 90023, .T., NULL)
goFormTest.lActivExtrase = .T.
goFormTest.WindowType = 0
goFormTest.Show()
DO HarnessLog WITH 'form afisat: LockScreen=' + TRANSFORM(goFormTest.LockScreen) + ' Grid1.RecordSource=[' + goFormTest.Grid1.RecordSource + '] Grid1.RecordSourceType=' + TRANSFORM(goFormTest.Grid1.RecordSourceType) + ' Visible=' + TRANSFORM(goFormTest.Visible)
*=====================================================================
* SCENARIU A: parasirea celulei Partener Credit (goala) prin LostFocus, urmat de Click pe
* butonul "Partener Credit" - tiparul exact din log.txt (dubla cautare)
*=====================================================================
DO HarnessLog WITH ''
DO HarnessLog WITH '=== SCENARIU A: Column10.Text1.LostFocus (partc gol) apoi Command2.Click ==='
SELECT tact
GO 1
LOCAL lnCapturiA0, lnCapturiA1
lnCapturiA0 = gnCaptureN
DO HarnessLog WITH 'A: inainte - LockScreen=' + TRANSFORM(goFormTest.LockScreen) + ' recno=' + TRANSFORM(RECNO('tact')) + ' partc=[' + ALLTRIM(NVL(tact.partc,'')) + ']'
*-- incearca intai focus REAL (poate declansa evenimente native suplimentare), apoi apelul direct
*-- garanteaza deterministic reproducerea, indiferent daca SetFocus a functionat headless
TRY
goFormTest.Grid1.SetFocus()
goFormTest.Grid1.Column10.Text1.SetFocus()
DO HarnessLog WITH 'A: SetFocus real pe Column10.Text1 - OK, ActiveColumn=' + TRANSFORM(goFormTest.Grid1.ActiveColumn)
CATCH TO loExFocus
DO HarnessLog WITH 'A: SetFocus real a esuat (' + loExFocus.Message + ') - continui cu apelul direct al metodei'
ENDTRY
goFormTest.Grid1.Column10.Text1.LostFocus()
lnCapturiA1 = gnCaptureN
DO HarnessLog WITH 'A1 (LostFocus): capturi noi=' + TRANSFORM(lnCapturiA1 - lnCapturiA0) + ' LockScreen dupa=' + TRANSFORM(goFormTest.LockScreen) + ' partc=[' + ALLTRIM(NVL(tact.partc,'')) + ']'
goFormTest.Command2.Click()
DO HarnessLog WITH 'A2 (Command2.Click): capturi noi=' + TRANSFORM(gnCaptureN - lnCapturiA1) + ' LockScreen dupa=' + TRANSFORM(goFormTest.LockScreen)
DO HarnessLog WITH 'A: TOTAL capturi scenariu=' + TRANSFORM(gnCaptureN - lnCapturiA0) + ' (asteptat 2 daca ipoteza H1 se confirma: LostFocus + Click deschid ambele cautarea)'
*=====================================================================
* SCENARIU B: schimbare de rand, cu randul PARASIT avand partc gol - testeaza (B1) daca un GO
* brut pe cursorul legat declanseaza singur vreun eveniment, si (B2) dansul LockScreen din
* AfterRowColChange (16083-16097) cand randul recalculat (nRecLipsuri) are partc gol
*=====================================================================
DO HarnessLog WITH ''
DO HarnessLog WITH '=== SCENARIU B: schimbare de rand, randul cu partc gol e cel reverificat de AfterRowColChange ==='
SELECT tact
GO 1
LOCAL lnCapturiB0, lnCapturiB1
lnCapturiB0 = gnCaptureN
TRY
goFormTest.Grid1.Column10.Text1.SetFocus()
CATCH TO loExFocus
ENDTRY
GO 2 IN tact
lnCapturiB1 = gnCaptureN
DO HarnessLog WITH 'B1 (GO 2 brut, fara apel explicit): capturi noi=' + TRANSFORM(lnCapturiB1 - lnCapturiB0) + ' LockScreen=' + TRANSFORM(goFormTest.LockScreen)
goFormTest.nRecLipsuri = 1 && "randul parasit" pe care AfterRowColChange il reverifica e randul 1 (partc gol)
goFormTest.cSemnLipsuri = 'FORTAT-DIFERIT-CA-SA-INTRE-PE-RAMURA'
DO HarnessLog WITH 'B2: inainte de AfterRowColChange - LockScreen=' + TRANSFORM(goFormTest.LockScreen) + ' recno curent=' + TRANSFORM(RECNO('tact')) + ' nRecLipsuri=' + TRANSFORM(goFormTest.nRecLipsuri)
goFormTest.Grid1.AfterRowColChange(10)
DO HarnessLog WITH 'B2 (AfterRowColChange explicit): capturi noi=' + TRANSFORM(gnCaptureN - lnCapturiB1) + ' LockScreen dupa=' + TRANSFORM(goFormTest.LockScreen) + ' recno curent=' + TRANSFORM(RECNO('tact'))
DO HarnessLog WITH 'B: TOTAL capturi scenariu=' + TRANSFORM(gnCaptureN - lnCapturiB0)
*=====================================================================
* SCENARIU C: Click direct pe buton, FARA ca focusul sa fi trecut prin celula (fara LostFocus)
*=====================================================================
DO HarnessLog WITH ''
DO HarnessLog WITH '=== SCENARIU C: Command2.Click direct, focus pe alt control (nu in celula Partener Credit) ==='
SELECT tact
GO 1
LOCAL lnCapturiC0
lnCapturiC0 = gnCaptureN
TRY
goFormTest.but_renunt1.SetFocus()
CATCH TO loExFocus
ENDTRY
goFormTest.Command2.Click()
DO HarnessLog WITH 'C (Command2.Click direct): capturi noi=' + TRANSFORM(gnCaptureN - lnCapturiC0) + ' LockScreen dupa=' + TRANSFORM(goFormTest.LockScreen)
DO HarnessLog WITH ''
DO HarnessLog WITH '=== REZULTAT: total capturi cauta_alfa=' + TRANSFORM(gnCaptureN) + ' ==='
DO HarnessDone WITH 'done'
DO HarnessLog WITH 'TOTAL: test terminat fara exceptie'
CATCH TO loEx
DO HarnessLog WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure
DO HarnessDone WITH 'error'
ENDTRY
QUIT
**********************************************************
* tact - structura REALA de productie (vact_tot -> ales/Cu_tva/tipnota), ca in
* Programe\ocont2003.prg::note_fara_predefinire (liniile 1007-1082). Doua randuri: primul cu
* cont 4111 (config_cont_ireg + coresp_tip_cont populate pe schema de test) si partener CREDIT
* gol - tinta bugului; al doilea cu partener deja completat, doar ca sa existe "schimbare de rand".
PROCEDURE BuildTact
LOCAL llSucces
IF USED('tact')
USE IN tact
ENDIF
IF USED('actactan')
USE IN actactan
ENDIF
IF USED('crsJtvaTemp')
USE IN crsJtvaTemp
ENDIF
*-- Init/Load (frm_modific2024) citesc crsJtvaTemp - exact apelul din ocont2003.prg:997
update_jtva_coloane("", "crsJtvaTemp", 1)
llSucces = goExecutor.oExecuta("select * from vact_tot where 1=2", "v_act")
IF !llSucces
DO HarnessLog WITH 'FAIL: vact_tot inaccesibil - ' + goExecutor.cEroare
RETURN .F.
ENDIF
SELECT * FROM v_act INTO CURSOR actactan READWRITE
USE IN v_act
SELECT .F. AS ales, IIF(EMPTY(NVL(a.id_jtva_coloana,0)),0,1) AS Cu_tva, CAST(0 AS N(2)) AS tipnota, a.* FROM actactan a INTO CURSOR tact READWRITE
USE IN actactan
*-- trul/trul_obinv - formularul le foloseste (pgfArticole) chiar daca randurile de tact nu au
*-- rulaje; goale, aceeasi structura ca in ocont2003.prg::note_fara_predefinire (1017-1044)
IF USED('trul')
USE IN trul
ENDIF
llSucces = goExecutor.oExecuta("select * from vrul_tot where 1=2", "v_rul")
IF !llSucces
DO HarnessLog WITH 'FAIL: vrul_tot inaccesibil - ' + goExecutor.cEroare
RETURN .F.
ENDIF
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva FROM v_rul INTO CURSOR trul READWRITE
USE IN v_rul
IF USED('trul_obinv')
USE IN trul_obinv
ENDIF
llSucces = goExecutor.oExecuta("select * from vrul_obinv_tot where 1=2", "v_rul_obinv")
IF !llSucces
DO HarnessLog WITH 'FAIL: vrul_obinv_tot inaccesibil - ' + goExecutor.cEroare
RETURN .F.
ENDIF
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva FROM v_rul_obinv INTO CURSOR trul_obinv READWRITE
USE IN v_rul_obinv
SELECT tact
APPEND BLANK
REPLACE dataireg WITH DATETIME(), dataact WITH DATETIME(), datascad WITH DATETIME() + 30 * 86400
REPLACE id_sucursala WITH NVL(gnIdSucursala, 0), sters WITH 0, an WITH gnAn, luna WITH gnLuna
REPLACE scd WITH '628', scc WITH '4111', partd WITH 'CHELTUIALA TEST', id_partd WITH 0
REPLACE partc WITH '', id_partc WITH 0, suma WITH 100.00, nract WITH 1, cod WITH 1
APPEND BLANK
REPLACE dataireg WITH DATETIME(), dataact WITH DATETIME(), datascad WITH DATETIME() + 30 * 86400
REPLACE id_sucursala WITH NVL(gnIdSucursala, 0), sters WITH 0, an WITH gnAn, luna WITH gnLuna
REPLACE scd WITH '5121', scc WITH '4111', partd WITH '', id_partd WITH 0
REPLACE partc WITH 'PARTENER DEJA ALES', id_partc WITH 1, suma WITH 50.00, nract WITH 2, cod WITH 1
GO TOP
RETURN .T.
ENDPROC
**********************************************************
PROCEDURE PrErrLocal
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
LOCAL lcMsg
lcMsg = 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo)
IF TYPE('gcUILog') = 'C' AND !EMPTY(gcUILog)
SET SAFETY OFF
STRTOFILE(IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + lcMsg + CHR(13) + CHR(10), gcUILog)
ENDIF
ENDPROC

View File

@@ -0,0 +1,365 @@
* test_ramburs_grup_nume.prg
* Test headless pentru alocarea rambursurilor de curier pe grupul de nume (oproceduri_import.prg).
* Construieste manual cursoarele pe care le citeste AlocaFacturiRand si o apeleaza direct, fara UI;
* A-D fara Oracle, E (AdaugaGrupNume) pe MARIUSM_AUTO doar SELECT. Primeste optional calea fisierului
* de testat (pentru baseline vs editat).
*
* Rulare:
* vfp9.exe -A -T "COMUN\utile\Teste\test_ramburs_grup_nume.prg"
* vfp9.exe -A -T "COMUN\utile\Teste\test_ramburs_grup_nume.prg" "<cale\oproceduri_import.prg>"
LPARAMETERS tcFisierImport
LOCAL lcFisierImport
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
* parametrul nu poate fi pasat prin watchdog -> il citesc dintr-un fisier de config opt-in
* (_ramburs_fisier.txt), ca sa pot rula acelasi test pe baseline si pe fisierul editat
PUBLIC gcLogRamburs, gnPass, gnFail, gcFisierImport, gnAn, gnLuna
gcLogRamburs = "D:\ROA\ROACONT\COMUN\utile\Teste\_test_ramburs_out.txt"
IF !EMPTY(tcFisierImport)
gcFisierImport = ALLTRIM(tcFisierImport)
ELSE
IF FILE("D:\ROA\ROACONT\COMUN\utile\Teste\_ramburs_fisier.txt")
gcFisierImport = ALLTRIM(FILETOSTR("D:\ROA\ROACONT\COMUN\utile\Teste\_ramburs_fisier.txt"))
ELSE
gcFisierImport = "D:\ROA\ROACONT\Programe\oproceduri_import.prg"
ENDIF
ENDIF
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnPass = 0
gnFail = 0
* versiunea fisierului testat: daca are parametrul nou tlCurier, apelez cu 5 parametri
* (baseline-ul are 4 - apelul cu 5 da eroarea 94 si ascunde comportamentul real)
PUBLIC glCuCurier
glCuCurier = (ATC("tlCurier", FILETOSTR(gcFisierImport)) > 0)
STRTOFILE("RUN " + TTOC(DATETIME()) + " fisier=" + gcFisierImport + CHR(13)+CHR(10), gcLogRamburs)
ON ERROR DO log_eroare_ramburs WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
* fara Oracle: functiile de alocare nu ating baza; goExecutor exista doar ca sa nu lipseasca simbolul
IF TYPE('goExecutor') = 'U'
PUBLIC goExecutor
goExecutor = CREATEOBJECT('dummy_executor_ramburs')
ENDIF
* regula. ExtractieNumereFacturi foloseste strtranx/GetRegExpAll din regex.prg
SET PROCEDURE TO (ADDBS("D:\ROA\ROACONT\COMUN\programe") + "regex.prg") ADDITIVE
* incarc fisierul testat ca PROCEDURE (functiile AlocaFacturiRand etc. devin apelabile)
SET PROCEDURE TO (gcFisierImport) ADDITIVE
DO log_txt WITH "SET PROCEDURE OK: " + gcFisierImport
DO caz_A
DO caz_B
DO caz_C
DO caz_D
DO caz_E
DO log_txt WITH "=== SUMAR: PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail) + " ==="
QUIT
* apeleaza AlocaFacturiRand cu 4 sau 5 parametri, dupa versiunea fisierului testat
FUNCTION apeleaza_aloca
LPARAMETERS tlCurier
IF glCuCurier
RETURN AlocaFacturiRand("C", "4111", 16117, "TOMONESCU GEORGE", m.tlCurier)
ELSE
RETURN AlocaFacturiRand("C", "4111", 16117, "TOMONESCU GEORGE")
ENDIF
ENDFUNC
* ============================================================
* CAZ A: Tomescu, curier, ales 16117, grup {2156,16117,22423}
* factura 15634 (22423) = 710,08; rand 710,08 -> o singura alocare S, partener mutat pe 22423
PROCEDURE caz_A
DO pregateste_act WITH 710.08, "C"
DO pregateste_solduri
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (16117, "4111", "", 5428, 5428, DATE(2026,4,1), 0, 32.42)
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (22423, "4111", "", 15634, 15634, DATE(2026,9,21), 0, 710.08)
DO pregateste_grup WITH "2156,16117,22423"
DO pregateste_avans
LOCAL llAlocat
llAlocat = apeleaza_aloca(.T.)
LOCAL lnNpoz, lcSursa, lnIdFact, lnIdPartRand, lnSumaAloc
lcSursa = ""
lnIdFact = 0
lnSumaAloc = 0
lnNpoz = 0
SELECT cAlocTemp
COUNT TO lnNpoz
IF lnNpoz > 0
SELECT cAlocTemp
GO TOP
lcSursa = ALLTRIM(csursa)
lnIdFact = id_fact
lnSumaAloc = suma
ENDIF
SELECT cActTemp
lnIdPartRand = NVL(id_partc, 0)
DO verifica WITH "A_curier_o_alocare_S", ;
(m.llAlocat AND m.lnNpoz = 1 AND m.lcSursa = "S" AND m.lnIdFact = 15634 AND m.lnIdPartRand = 22423 AND ABS(m.lnSumaAloc - 710.08) < 0.01), ;
"alocat=" + TRANSFORM(m.llAlocat) + " nrpoz=" + TRANSFORM(m.lnNpoz) + " sursa=" + m.lcSursa + " idfact=" + TRANSFORM(m.lnIdFact) + " idpartrand=" + TRANSFORM(m.lnIdPartRand) + " suma=" + TRANSFORM(m.lnSumaAloc)
ENDPROC
* ============================================================
* CAZ B: curier, nicio factura cu suma exacta in grup (doar 32,42 vechi) -> nimic alocat, rand intreg
PROCEDURE caz_B
DO pregateste_act WITH 710.08, "C"
DO pregateste_solduri
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (16117, "4111", "", 5428, 5428, DATE(2026,4,1), 0, 32.42)
DO pregateste_grup WITH "2156,16117,22423"
DO pregateste_avans
LOCAL llAlocat, lnNpoz
llAlocat = apeleaza_aloca(.T.)
SELECT cAlocTemp
COUNT TO lnNpoz
DO verifica WITH "B_curier_fara_suma_exacta", (NOT m.llAlocat AND m.lnNpoz = 0), ;
"alocat=" + TRANSFORM(m.llAlocat) + " nrpoz=" + TRANSFORM(m.lnNpoz)
ENDPROC
* ============================================================
* CAZ C: curier, doua facturi 150,00 in grup pe parteneri diferiti -> nimic alocat
PROCEDURE caz_C
DO pregateste_act WITH 150.00, "C"
DO pregateste_solduri
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (16117, "4111", "", 7001, 7001, DATE(2026,8,1), 0, 150.00)
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (22423, "4111", "", 7002, 7002, DATE(2026,8,2), 0, 150.00)
DO pregateste_grup WITH "2156,16117,22423"
DO pregateste_avans
LOCAL llAlocat, lnNpoz
llAlocat = apeleaza_aloca(.T.)
SELECT cAlocTemp
COUNT TO lnNpoz
DO verifica WITH "C_curier_doua_facturi_egale", (NOT m.llAlocat AND m.lnNpoz = 0), ;
"alocat=" + TRANSFORM(m.llAlocat) + " nrpoz=" + TRANSFORM(m.lnNpoz)
ENDPROC
* ============================================================
* CAZ D: acelasi ca A, dar import BANCAR (tlFaraFifoAvans = .F.) -> comportamentul vechi F + A
PROCEDURE caz_D
DO pregateste_act WITH 710.08, "C"
DO pregateste_solduri
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (16117, "4111", "", 5428, 5428, DATE(2026,4,1), 0, 32.42)
INSERT INTO cSolduriFact (id_part, Cont, acont, id_fact, nract, dataact, id_valuta, ramas) ;
VALUES (22423, "4111", "", 15634, 15634, DATE(2026,9,21), 0, 710.08)
DO pregateste_grup WITH "2156,16117,22423"
DO pregateste_avans
LOCAL llAlocat, lnNpoz, lcSursa1, lcSursa2, lnSumaTotala
llAlocat = apeleaza_aloca(.F.)
lcSursa1 = ""
lcSursa2 = ""
lnNpoz = 0
lnSumaTotala = 0
SELECT cAlocTemp
COUNT TO lnNpoz
IF lnNpoz >= 1
GO TOP
lcSursa1 = ALLTRIM(csursa)
lnSumaTotala = suma
ENDIF
IF lnNpoz >= 2
SKIP
lcSursa2 = ALLTRIM(csursa)
lnSumaTotala = m.lnSumaTotala + suma
ENDIF
* bancar (ales 16117): F pe 32,42 (5428), apoi avans A pe 419 cu 677,66
DO verifica WITH "D_bancar_F_plus_A", ;
(m.llAlocat AND m.lnNpoz = 2 AND m.lcSursa1 = "F" AND m.lcSursa2 = "A" AND ABS(m.lnSumaTotala - 710.08) < 0.01), ;
"alocat=" + TRANSFORM(m.llAlocat) + " nrpoz=" + TRANSFORM(m.lnNpoz) + " sursa1=" + m.lcSursa1 + " sursa2=" + m.lcSursa2 + " suma=" + TRANSFORM(m.lnSumaTotala)
ENDPROC
* ============================================================
* CAZ E: AdaugaGrupNume pe MARIUSM_AUTO, doar SELECT: un nume din 2 cuvinte si unul dintr-un cuvant
* -> interogarea nu da eroare SQL, cGrupParteneriCui fara dubluri si fara partenerul ales
PROCEDURE caz_E
LOCAL lnIdAles, lcDenAles, llSqlOk, lnNume, lnDistinct, lnAles, lnDup
IF NOT glCuCurier
RETURN
ENDIF
DO (ADDBS("D:\ROA\ROACONT\COMUN\utile\Teste") + "test_init_env_auto.prg") WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO verifica WITH "E_adauga_grup_nume_2cuv", .F., "nu m-am conectat la MARIUSM_AUTO"
RETURN
ENDIF
IF USED('cGrupParteneriCui')
USE IN cGrupParteneriCui
ENDIF
CREATE CURSOR cGrupParteneriCui (id_part_ales N(10), id_part N(10), denumire C(100))
INDEX ON id_part TAG id_part
* nume din 2 cuvinte
lnIdAles = 0
lcDenAles = ""
IF goExecutor.oExecuta([select id_part, denumire from nom_parteneri where sters = 0 and inactiv = 0 and (length(trim(denumire)) - length(replace(trim(denumire), ' ', ''))) = 1 and rownum = 1], "cNumeGrupTest")
SELECT cNumeGrupTest
lnIdAles = id_part
lcDenAles = ALLTRIM(denumire)
USE IN cNumeGrupTest
ENDIF
AdaugaGrupNume(m.lnIdAles, m.lcDenAles)
llSqlOk = sql_verif_grup(m.lcDenAles)
SELECT cGrupParteneriCui
COUNT TO lnNume FOR id_part_ales = m.lnIdAles
COUNT TO lnAles FOR id_part = m.lnIdAles
SELECT DISTINCT id_part FROM cGrupParteneriCui WHERE id_part_ales = m.lnIdAles INTO CURSOR cDistinctGrupa
lnDistinct = RECCOUNT('cDistinctGrupa')
USE IN cDistinctGrupa
lnDup = m.lnNume - m.lnDistinct
DO verifica WITH "E_adauga_grup_nume_2cuv", (m.llSqlOk AND m.lnDup = 0 AND m.lnAles = 0), ;
"sqlOk=" + TRANSFORM(m.llSqlOk) + " randuri=" + TRANSFORM(m.lnNume) + " dubluri=" + TRANSFORM(m.lnDup) + " ales=" + TRANSFORM(m.lnAles) + " den=" + m.lcDenAles
* nume dintr-un singur cuvant (fara permutari)
IF USED('cGrupParteneriCui')
USE IN cGrupParteneriCui
ENDIF
CREATE CURSOR cGrupParteneriCui (id_part_ales N(10), id_part N(10), denumire C(100))
INDEX ON id_part TAG id_part
lnIdAles = 0
lcDenAles = ""
IF goExecutor.oExecuta([select id_part, denumire from nom_parteneri where sters = 0 and inactiv = 0 and (length(trim(denumire)) - length(replace(trim(denumire), ' ', ''))) = 0 and rownum = 1], "cNumeGrupTest")
SELECT cNumeGrupTest
lnIdAles = id_part
lcDenAles = ALLTRIM(denumire)
USE IN cNumeGrupTest
ENDIF
AdaugaGrupNume(m.lnIdAles, m.lcDenAles)
llSqlOk = sql_verif_grup(m.lcDenAles)
SELECT cGrupParteneriCui
COUNT TO lnNume FOR id_part_ales = m.lnIdAles
COUNT TO lnAles FOR id_part = m.lnIdAles
DO verifica WITH "E_adauga_grup_nume_1cuv", (m.llSqlOk AND m.lnAles = 0), ;
"sqlOk=" + TRANSFORM(m.llSqlOk) + " randuri=" + TRANSFORM(m.lnNume) + " ales=" + TRANSFORM(m.lnAles) + " den=" + m.lcDenAles
IF USED('cGrupParteneriCui')
USE IN cGrupParteneriCui
ENDIF
ENDPROC
* Reface SQL-ul construit de AdaugaGrupNume, ca sa dovedeasca faptul ca nu da eroare
FUNCTION sql_verif_grup
LPARAMETERS tcDenumire
LOCAL lcVariante, lcLista, lnI, lcSql, llOk
lcVariante = m.tcDenumire + ';' + GetNamePermutations(m.tcDenumire, .T.)
lcLista = ''
FOR lnI = 1 TO GETWORDCOUNT(m.lcVariante, ';')
lcLista = m.lcLista + IIF(EMPTY(m.lcLista), '', ',') + "'" + STRTRAN(ALLTRIM(GETWORDNUM(m.lcVariante, m.lnI, ';')), "'", "''") + "'"
ENDFOR
lcSql = [select id_part, denumire from nom_parteneri where sters = 0 and inactiv = 0 and trim(upper(denumire)) in (] + m.lcLista + [)]
llOk = goExecutor.oExecuta(m.lcSql, 'cVerifGrup')
IF USED('cVerifGrup')
USE IN cVerifGrup
ENDIF
RETURN m.llOk
ENDFUNC
* ============================================================
* Constructor de cursoare cu structura reala
PROCEDURE pregateste_act
LPARAMETERS tnSuma, tcTip
IF USED('cActTemp')
USE IN cActTemp
ENDIF
CREATE CURSOR cActTemp (nr N(14), Data D, suma N(15,2), suma_val N(15,2), Curs N(15,4), nume_val C(20), id_valuta I, ;
explicatie C(100), iban C(24), denumire C(60), cod_fiscal C(13), tip C(2), tip_2 C(3), documente C(250), comenzi C(250), ;
scd C(4), scc C(4), ascd C(4), ascc C(4), id_partd N(10), id_partc N(10), partd C(100), partc C(100), ;
id_part N(10), partener C(100), id_factd I, id_factc I, pereched N(20), perechec N(20), ;
id_fdoc I, fdoc C(50), listoric L, ngrupa I, npoz I, csursa_f C(1), nordine I)
INSERT INTO cActTemp (suma, tip, scc, id_partc, partc, csursa_f, nordine) ;
VALUES (m.tnSuma, m.tcTip, "4111", 16117, "TOMONESCU GEORGE", "", 100)
GO TOP
ENDPROC
PROCEDURE pregateste_solduri
IF USED('cSolduriFact')
USE IN cSolduriFact
ENDIF
CREATE CURSOR cSolduriFact (id_part N(10), Cont C(4), acont C(20), id_fact I, nract N(20), dataact D, id_valuta I, ramas N(15,2))
INDEX ON id_part TAG id_part
* cAlocTemp se creeaza in CreeazaNote, inainte de apelul alocarii (structura reala)
IF USED('cAlocTemp')
USE IN cAlocTemp
ENDIF
CREATE CURSOR cAlocTemp (nrec I, npoz I, id_fact I, nract N(20), cont C(4) Null, acont C(20) Null, suma N(15,2), csursa C(1))
ENDPROC
PROCEDURE pregateste_grup
LPARAMETERS tcLista
IF USED('cGrupParteneriCui')
USE IN cGrupParteneriCui
ENDIF
CREATE CURSOR cGrupParteneriCui (id_part_ales N(10), id_part N(10), denumire C(100))
INDEX ON id_part TAG id_part
LOCAL lnI, lnId
FOR lnI = 1 TO GETWORDCOUNT(m.tcLista, ",")
lnId = VAL(GETWORDNUM(m.tcLista, m.lnI, ","))
INSERT INTO cGrupParteneriCui (id_part_ales, id_part, denumire) VALUES (16117, m.lnId, "P" + TRANSFORM(m.lnId))
ENDFOR
ENDPROC
PROCEDURE pregateste_avans
IF USED('cAvansExistent')
USE IN cAvansExistent
ENDIF
CREATE CURSOR cAvansExistent (id_part N(10))
INDEX ON id_part TAG id_part
ENDPROC
* ============================================================
PROCEDURE verifica
LPARAMETERS tcLabel, tlOk, tcDetaliu
IF m.tlOk
gnPass = gnPass + 1
DO log_txt WITH "PASS " + m.tcLabel + " :: " + m.tcDetaliu
ELSE
gnFail = gnFail + 1
DO log_txt WITH "FAIL " + m.tcLabel + " :: " + m.tcDetaliu
ENDIF
ENDPROC
PROCEDURE log_txt
LPARAMETERS tcTxt
STRTOFILE(TRANSFORM(m.tcTxt) + CHR(13) + CHR(10), gcLogRamburs, 1)
ENDPROC
PROCEDURE log_eroare_ramburs
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO log_txt WITH " [ON ERROR] " + TRANSFORM(m.tnErr) + " " + TRANSFORM(m.tcMsg) + " in " + TRANSFORM(m.tcProg) + " linia " + TRANSFORM(m.tnLine)
ENDPROC
DEFINE CLASS dummy_executor_ramburs AS Custom
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
RETURN .T.
ENDPROC
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
RETURN 1
ENDPROC
ENDDEFINE

View File

@@ -0,0 +1,69 @@
* test_ramburs_grup_nume_sql.prg
* Proba read-only pe MARIUSM_AUTO pentru interogarea grupului de nume (punctul 1 din brief):
* parteneri activi (sters=0, inactiv=0) cu denumirea exacta in orice permutare, pentru o denumire reala.
* Ruleaza prin watchdog (fara parametri). Nu scrie nimic in Oracle.
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
LOCAL lcLog
lcLog = "D:\ROA\ROACONT\COMUN\utile\Teste\_test_ramburs_sql_out.txt"
STRTOFILE("RUN " + TTOC(DATETIME()) + CHR(13)+CHR(10), lcLog)
ON ERROR DO log_eroare_sql WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
DO (ADDBS("D:\ROA\ROACONT\COMUN\utile\Teste") + "test_init_env_auto.prg") WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO log_sql WITH "FAIL: nu m-am conectat la MARIUSM_AUTO"
QUIT
ENDIF
DO log_sql WITH "env init OK (schema " + gcS + ")"
* aceeasi constructie ca in CreeanaNote: ListaSql(GetNamePermutations(...)) pentru o denumire cu 2 cuvinte
PRIVATE pcDenGrup, pcDenGrupPerm
pcDenGrup = "TOMESCU GEORGE"
pcDenGrupPerm = GetNamePermutations(m.pcDenGrup, .F.)
DO log_sql WITH "permutari: [" + m.pcDenGrupPerm + "]"
LOCAL lcSql, llOk
lcSql = [select id_part, denumire from nom_parteneri where sters = 0 and inactiv = 0 and ] + ;
[(trim(upper(denumire)) = ?pcDenGrup or trim(upper(denumire)) in (] + ListaSql_if(m.pcDenGrupPerm) + [))]
llOk = goExecutor.oExecuta(m.lcSql, 'cGrupNumeTest')
IF m.llOk
SELECT cGrupNumeTest
DO log_sql WITH "PASS: interogare grup nume OK, randuri=" + TRANSFORM(RECCOUNT('cGrupNumeTest'))
SCAN
DO log_sql WITH " id_part=" + TRANSFORM(id_part) + " denumire=" + ALLTRIM(NVL(denumire, ''))
ENDSCAN
USE IN cGrupNumeTest
ELSE
DO log_sql WITH "FAIL: " + goExecutor.cEroare
ENDIF
DO log_sql WITH "=== GATA ==="
QUIT
* ListaSql e in oproceduri_import.prg, dar testul de SQL nu-l incarca; o replic aici identic
FUNCTION ListaSql_if
LPARAMETERS tcLista
LOCAL lnI, lcRezultat, lcItem
lcRezultat = ''
FOR lnI = 1 TO GETWORDCOUNT(m.tcLista, ';')
lcItem = ALLTRIM(GETWORDNUM(m.tcLista, m.lnI, ';'))
IF !EMPTY(m.lcItem)
lcRezultat = m.lcRezultat + IIF(EMPTY(m.lcRezultat), '', ',') + "'" + STRTRAN(m.lcItem, "'", "''") + "'"
ENDIF
ENDFOR
RETURN m.lcRezultat
ENDFUNC
PROCEDURE log_sql
LPARAMETERS tcTxt
STRTOFILE(TRANSFORM(m.tcTxt) + CHR(13) + CHR(10), "D:\ROA\ROACONT\COMUN\utile\Teste\_test_ramburs_sql_out.txt", 1)
ENDPROC
PROCEDURE log_eroare_sql
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO log_sql WITH " [ON ERROR] " + TRANSFORM(m.tnErr) + " " + TRANSFORM(m.tcMsg) + " in " + TRANSFORM(m.tcProg) + " linia " + TRANSFORM(m.tnLine)
ENDPROC