376 lines
16 KiB
Plaintext
376 lines
16 KiB
Plaintext
* test_todo21_e2e_verificare.prg
|
|
* TODO #21 - test END-TO-END al verificarii codurilor fiscale.
|
|
*
|
|
* Spre deosebire de celelalte teste (care instantiaza direct frm_verificare_parteneri), acesta
|
|
* intra prin punctul de intrare REAL folosit de toti apelantii - verificare_parteneri()
|
|
* (COMUN\programe\oproceduri_comune.prg:4525) - cu lista in formatul sir
|
|
* "cod***denumire***atribut***ales***id_part***data|...", si merge pana la capat:
|
|
* sir -> crsXMLParteneriVerificare -> crsVerificareParteneri -> formular modal ->
|
|
* Activate -> do_verifica -> serviciul web ANAF REAL -> perioade + atentie -> cursor final.
|
|
*
|
|
* Formularul se deschide cu Show(1) (modal), deci headless-ul s-ar agata. Deblocarea se face cu
|
|
* un obiect Timer independent (clasa tmrE2EDeblocare, la finalul fisierului), care asteapta ca
|
|
* verificarea sa PORNEASCA (lblVerifica.Visible = .T., pus la inceputul lui do_verifica) si abia
|
|
* apoi ca ea sa se TERMINE (lblVerifica.Visible = .F., pus la final), inainte sa dea Release.
|
|
* Fara cele doua faze, timer-ul ar putea elibera formularul in mijlocul verificarii - do_verifica
|
|
* apeleaza Inkey(1), moment in care evenimentele de timer chiar se executa.
|
|
*
|
|
* Cursorul se pastreaza dupa inchidere (tlDontCloseCursor = .T.), iar asertiunile se fac pe el.
|
|
*
|
|
* Datele de test: coduri fiscale REALE alese dinamic din istoric_coduri_fiscale si un partener
|
|
* REAL din nom_parteneri (id_part nenul), plus un cod invalid fabricat si un duplicat - nimic
|
|
* hardcodat, deci testul nu depinde de starea unei anumite firme.
|
|
*
|
|
* Nu scrie nimic in Oracle (doar SELECT-uri) si nu modifica nomenclatorul.
|
|
*
|
|
* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\todo21\test_todo21_e2e_verificare.prg"
|
|
* Verdict in log: TOTAL OK / TOTAL FAIL: n pas(i).
|
|
|
|
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\todo21\test_todo21_e2e_verificare_log.txt"
|
|
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
|
|
|
|
PUBLIC gnEsecuri
|
|
gnEsecuri = 0
|
|
|
|
ON ERROR DO PrErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
|
ON SHUTDOWN QUIT
|
|
|
|
PUBLIC gcMockUltimMesaj, gnMockUltimTip, gnMockRaspuns
|
|
gcMockUltimMesaj = ''
|
|
gnMockUltimTip = 0
|
|
gnMockRaspuns = 6
|
|
|
|
PUBLIC goTmrE2E, gnE2EFazaTimer, gnE2ETicks, glE2EEliberat
|
|
gnE2EFazaTimer = 0
|
|
gnE2ETicks = 0
|
|
glE2EEliberat = .F.
|
|
|
|
TRY
|
|
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
|
|
DO PrLog WITH 'mock-uri incarcate'
|
|
|
|
DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
|
IF gnHandle <= 0
|
|
DO PrLog WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')'
|
|
gnEsecuri = gnEsecuri + 1
|
|
DO PrLog WITH 'TOTAL FAIL: ' + TRANSFORM(gnEsecuri) + ' pas(i)'
|
|
QUIT
|
|
ENDIF
|
|
DO PrLog WITH 'mediu OK, schema=' + gcS
|
|
|
|
*=====================================================================
|
|
* Date de test reale, alese dinamic
|
|
*=====================================================================
|
|
LOCAL lcSql, lcCod1, lcCod2
|
|
TEXT TO lcSql NOSHOW
|
|
select cod_fiscal_n from (
|
|
select cod_fiscal_n from istoric_coduri_fiscale
|
|
where cod_fiscal_n is not null and data_inceput_scptva is not null
|
|
order by dataorav_anaf desc) where rownum <= 2
|
|
ENDTEXT
|
|
lcCod1 = ''
|
|
lcCod2 = ''
|
|
IF goExecutor.oExecuta(lcSql, 'crsE1') AND USED('crsE1') AND RECCOUNT('crsE1') > 0
|
|
SELECT crsE1
|
|
GO TOP
|
|
lcCod1 = ALLTRIM(TRANSFORM(NVL(crsE1.cod_fiscal_n, 0)))
|
|
IF RECCOUNT('crsE1') > 1
|
|
SKIP
|
|
lcCod2 = ALLTRIM(TRANSFORM(NVL(crsE1.cod_fiscal_n, 0)))
|
|
ENDIF
|
|
ENDIF
|
|
USE IN (SELECT('crsE1'))
|
|
|
|
LOCAL lnIdPart, lcCodPart, lcDenPart
|
|
TEXT TO lcSql NOSHOW
|
|
select id_part, cod_fiscal, denumire from (
|
|
select id_part, cod_fiscal, denumire from nom_parteneri
|
|
where nvl(inactiv,0) = 0 and nvl(sters,0) = 0 and not cod_fiscal is null
|
|
order by id_part desc) where rownum <= 1
|
|
ENDTEXT
|
|
lnIdPart = 0
|
|
lcCodPart = ''
|
|
lcDenPart = ''
|
|
IF goExecutor.oExecuta(lcSql, 'crsE2') AND USED('crsE2') AND RECCOUNT('crsE2') > 0
|
|
lnIdPart = NVL(crsE2.id_part, 0)
|
|
lcCodPart = ALLTRIM(NVL(crsE2.cod_fiscal, ''))
|
|
lcDenPart = ALLTRIM(NVL(crsE2.denumire, ''))
|
|
ENDIF
|
|
USE IN (SELECT('crsE2'))
|
|
|
|
DO PrLog WITH 'coduri ANAF de test: [' + lcCod1 + '] [' + lcCod2 + ']; partener: id_part=' + ;
|
|
TRANSFORM(lnIdPart) + ' cod=[' + lcCodPart + ']'
|
|
|
|
IF EMPTY(lcCod1) OR lnIdPart = 0
|
|
DO PrLog WITH 'FAIL: nu s-au gasit date de test in Oracle'
|
|
gnEsecuri = gnEsecuri + 1
|
|
DO PrLog WITH 'TOTAL FAIL: ' + TRANSFORM(gnEsecuri) + ' pas(i)'
|
|
QUIT
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* Lista de intrare, construita EXACT ca la apelantii reali (D394, jurnale TVA): un cursor cu
|
|
* id_part / cod_fiscal / denumire / atribut_fiscal / ales / data, trecut prin Cursortoxml
|
|
* (vezi Clase/ovanzcump.vc2:19608-19618).
|
|
* 5 randuri: cod real 1 de doua ori (-> DUPLICAT), cod real 2, partener real cu id_part,
|
|
* cod fabricat invalid (-> INVALID).
|
|
*=====================================================================
|
|
LOCAL lcLista, ldData
|
|
ldData = DATE(YEAR(DATE()), MONTH(DATE()), 1)
|
|
CREATE CURSOR crsE2ELista (id_part N(16), cod_fiscal C(30), denumire C(100), atribut_fiscal C(2), ;
|
|
ales L, IsCIF L, Data D)
|
|
INSERT INTO crsE2ELista VALUES (0, lcCod1, 'E2E DUPLICAT A', 'RO', .F., .T., ldData)
|
|
INSERT INTO crsE2ELista VALUES (0, lcCod1, 'E2E DUPLICAT B', 'RO', .F., .T., ldData)
|
|
IF !EMPTY(lcCod2)
|
|
INSERT INTO crsE2ELista VALUES (0, lcCod2, 'E2E COD ANAF 2', 'RO', .F., .T., ldData)
|
|
ENDIF
|
|
INSERT INTO crsE2ELista VALUES (lnIdPart, lcCodPart, lcDenPart, ;
|
|
IIF(LEFT(UPPER(lcCodPart), 2) == 'RO', 'RO', ' '), .F., .T., ldData)
|
|
INSERT INTO crsE2ELista VALUES (0, '123', 'E2E COD INVALID', 'RO', .F., .T., ldData)
|
|
lcLista = ''
|
|
CURSORTOXML('crsE2ELista', 'lcLista', 1, 0, 0, '1')
|
|
USE IN (SELECT('crsE2ELista'))
|
|
|
|
*=====================================================================
|
|
* Timer de deblocare + apelul REAL (modal)
|
|
*=====================================================================
|
|
goTmrE2E = CREATEOBJECT('tmrE2EDeblocare')
|
|
goTmrE2E.Enabled = .T.
|
|
|
|
LOCAL lcCursor, ltStart
|
|
ltStart = DATETIME()
|
|
DO PrLog WITH 'apelez verificare_parteneri (modal) ...'
|
|
lcCursor = verificare_parteneri(m.lcLista, .T., .T., .F., .T., .T., .F., .T.)
|
|
goTmrE2E.Enabled = .F.
|
|
DO PrLog WITH 'verificare_parteneri s-a intors dupa ' + TRANSFORM(INT(DATETIME() - ltStart)) + ;
|
|
' s, cursor=[' + TRANSFORM(lcCursor) + '], timer: faza=' + TRANSFORM(gnE2EFazaTimer) + ;
|
|
' ticks=' + TRANSFORM(gnE2ETicks) + ' eliberat=' + TRANSFORM(glE2EEliberat)
|
|
|
|
*=====================================================================
|
|
* E1: cursorul supravietuieste (tlDontCloseCursor = .T.) si are toate randurile
|
|
*=====================================================================
|
|
LOCAL lnAsteptate
|
|
lnAsteptate = IIF(EMPTY(lcCod2), 4, 5)
|
|
IF USED('crsVerificareParteneri') AND RECCOUNT('crsVerificareParteneri') = lnAsteptate
|
|
DO PrLog WITH 'OK E1: cursorul crsVerificareParteneri a ramas deschis, ' + ;
|
|
TRANSFORM(lnAsteptate) + ' randuri'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E1: cursor deschis=' + TRANSFORM(USED('crsVerificareParteneri')) + ;
|
|
' randuri=' + TRANSFORM(IIF(USED('crsVerificareParteneri'), RECCOUNT('crsVerificareParteneri'), -1)) + ;
|
|
' asteptat ' + TRANSFORM(lnAsteptate)
|
|
gnEsecuri = gnEsecuri + 1
|
|
DO PrLog WITH 'TOTAL FAIL: ' + TRANSFORM(gnEsecuri) + ' pas(i)'
|
|
QUIT
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E2: id_part si data au traversat parsarea sirului (fix-ul C4 din TODO 21)
|
|
*=====================================================================
|
|
SELECT crsVerificareParteneri
|
|
LOCATE FOR ALLTRIM(NVL(denumire, '')) == lcDenPart
|
|
IF FOUND() AND NVL(crsVerificareParteneri.id_part, 0) = lnIdPart AND crsVerificareParteneri.Data = ldData
|
|
DO PrLog WITH 'OK E2: id_part=' + TRANSFORM(lnIdPart) + ' si data=' + DTOC(ldData) + ' au ajuns in cursor'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E2: id_part=' + TRANSFORM(IIF(FOUND(), NVL(crsVerificareParteneri.id_part, 0), -1)) + ;
|
|
' data=' + IIF(FOUND(), DTOC(crsVerificareParteneri.Data), '?') + ' asteptat ' + ;
|
|
TRANSFORM(lnIdPart) + ' / ' + DTOC(ldData)
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E3: codul invalid e marcat Valid = .F. si primeste eticheta INVALID
|
|
*=====================================================================
|
|
SELECT crsVerificareParteneri
|
|
LOCATE FOR ALLTRIM(NVL(denumire, '')) == 'E2E COD INVALID'
|
|
IF FOUND() AND NVL(crsVerificareParteneri.Valid, .T.) = .F. AND 'INVALID' $ crsVerificareParteneri.atentie
|
|
DO PrLog WITH 'OK E3: cod invalid -> Valid=.F., atentie=[' + ALLTRIM(crsVerificareParteneri.atentie) + ']'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E3: cod invalid -> Valid=' + TRANSFORM(IIF(FOUND(), crsVerificareParteneri.Valid, .NULL.)) + ;
|
|
' atentie=[' + IIF(FOUND(), ALLTRIM(crsVerificareParteneri.atentie), '?') + ']'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E4: cele doua randuri cu acelasi cod fiscal sunt marcate DUPLICAT
|
|
*=====================================================================
|
|
LOCAL lnDupl
|
|
SELECT crsVerificareParteneri
|
|
COUNT FOR ALLTRIM(NVL(cod_fiscal, '')) == lcCod1 AND 'DUPLICAT' $ atentie TO lnDupl
|
|
IF lnDupl = 2
|
|
DO PrLog WITH 'OK E4: ambele randuri cu codul ' + lcCod1 + ' au eticheta DUPLICAT'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E4: randuri DUPLICAT pentru ' + lcCod1 + ' = ' + TRANSFORM(lnDupl) + ' (asteptat 2)'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E5: ANAF a raspuns pe traseul real - cel putin un rand cu firma completata
|
|
* si cel putin o perioada de TVA completata (coloanele noi din TODO 21)
|
|
*=====================================================================
|
|
LOCAL lnCuFirma, lnCuPerioada
|
|
SELECT crsVerificareParteneri
|
|
COUNT FOR !EMPTY(NVL(firma, '')) TO lnCuFirma
|
|
COUNT FOR !EMPTY(NVL(data_inceput_scptva, {})) OR !EMPTY(NVL(data_inceput_tvainc, {})) ;
|
|
OR !EMPTY(NVL(data_inactivare, {})) TO lnCuPerioada
|
|
IF lnCuFirma > 0 AND lnCuPerioada > 0
|
|
DO PrLog WITH 'OK E5: ANAF a raspuns real - ' + TRANSFORM(lnCuFirma) + ' rand(uri) cu firma, ' + ;
|
|
TRANSFORM(lnCuPerioada) + ' cu perioade completate'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E5: firma=' + TRANSFORM(lnCuFirma) + ' perioade=' + TRANSFORM(lnCuPerioada) + ' (asteptat > 0)'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E6: textul venit de la ANAF nu contine '?' (decodarea UTF-8 prin
|
|
* AnafDecodeResponseText - COMUN\programe\validare.prg)
|
|
*=====================================================================
|
|
LOCAL lnSemn, lcExemplu
|
|
lnSemn = 0
|
|
lcExemplu = ''
|
|
SELECT crsVerificareParteneri
|
|
SCAN FOR !EMPTY(NVL(firma, ''))
|
|
IF '?' $ NVL(firma, '') OR '?' $ NVL(adresa, '') OR '?' $ NVL(stare, '') OR '?' $ NVL(judet, '')
|
|
lnSemn = lnSemn + 1
|
|
lcExemplu = ALLTRIM(NVL(firma, '')) + ' / ' + ALLTRIM(NVL(adresa, ''))
|
|
ENDIF
|
|
ENDSCAN
|
|
IF lnSemn = 0
|
|
DO PrLog WITH 'OK E6: niciun "?" in textele ANAF (firma/adresa/judet/stare)'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E6: ' + TRANSFORM(lnSemn) + ' rand(uri) cu "?" in text, ex: [' + lcExemplu + ']'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E7: atentie contine numai etichetele definite, in ordinea gravitatii,
|
|
* si nu are text trunchiat (regresie: concatenarea pe camp padded)
|
|
*=====================================================================
|
|
LOCAL lcAtn, llOrdineOK, lnPozI, lnPozD, lnPozN, lnPozR, llRauOK
|
|
llOrdineOK = .T.
|
|
llRauOK = .T.
|
|
SELECT crsVerificareParteneri
|
|
SCAN
|
|
lcAtn = ALLTRIM(NVL(atentie, ''))
|
|
IF EMPTY(lcAtn)
|
|
LOOP
|
|
ENDIF
|
|
*-- fara spatii duble (semn ca s-a concatenat peste padding)
|
|
IF ' ' $ lcAtn
|
|
llRauOK = .F.
|
|
DO PrLog WITH ' atentie cu spatii duble pe randul ' + TRANSFORM(RECNO()) + ': [' + lcAtn + ']'
|
|
ENDIF
|
|
lnPozI = AT('INVALID', lcAtn)
|
|
lnPozD = AT('DUPLICAT', lcAtn)
|
|
lnPozN = AT('INACTIV', lcAtn)
|
|
lnPozR = AT('FARA RO', lcAtn)
|
|
IF (lnPozI > 0 AND lnPozD > 0 AND lnPozI > lnPozD) OR ;
|
|
(lnPozD > 0 AND lnPozN > 0 AND lnPozD > lnPozN) OR ;
|
|
(lnPozN > 0 AND lnPozR > 0 AND lnPozN > lnPozR)
|
|
llOrdineOK = .F.
|
|
DO PrLog WITH ' ordine gresita in atentie pe randul ' + TRANSFORM(RECNO()) + ': [' + lcAtn + ']'
|
|
ENDIF
|
|
ENDSCAN
|
|
IF llOrdineOK AND llRauOK
|
|
DO PrLog WITH 'OK E7: coloana atentie e coerenta (ordine INVALID/DUPLICAT/INACTIV/FARA RO, fara spatii duble)'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E7: coloana atentie incoerenta'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*=====================================================================
|
|
* E8: formularul a fost inchis de timer, nu a ramas deschis
|
|
*=====================================================================
|
|
IF glE2EEliberat AND gnE2EFazaTimer >= 2
|
|
DO PrLog WITH 'OK E8: verificarea a pornit si s-a terminat, formularul a fost eliberat normal'
|
|
ELSE
|
|
DO PrLog WITH 'FAIL E8: faza timer=' + TRANSFORM(gnE2EFazaTimer) + ' eliberat=' + TRANSFORM(glE2EEliberat) + ;
|
|
' (formularul nu a parcurs ciclul complet de verificare)'
|
|
gnEsecuri = gnEsecuri + 1
|
|
ENDIF
|
|
|
|
*-- rezumat pe randuri, pentru diagnostic
|
|
SELECT crsVerificareParteneri
|
|
SCAN
|
|
DO PrLog WITH ' ' + PADR(ALLTRIM(NVL(denumire, '')), 24) + ' cod=' + PADR(ALLTRIM(NVL(cod_fiscal, '')), 14) + ;
|
|
' valid=' + TRANSFORM(NVL(Valid, .NULL.)) + ' dupl=' + TRANSFORM(duplicat) + ;
|
|
' firma=[' + LEFT(ALLTRIM(NVL(firma, '')), 30) + ']' + ' atentie=[' + ALLTRIM(NVL(atentie, '')) + ']'
|
|
ENDSCAN
|
|
|
|
USE IN (SELECT('crsVerificareParteneri'))
|
|
DO PrLog WITH IIF(gnEsecuri = 0, 'TOTAL OK', 'TOTAL FAIL: ' + TRANSFORM(gnEsecuri) + ' pas(i)')
|
|
CATCH TO loEx
|
|
DO PrLog WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure
|
|
DO PrLog WITH 'TOTAL FAIL: exceptie neasteptata'
|
|
ENDTRY
|
|
|
|
QUIT
|
|
|
|
**********************************************************
|
|
PROCEDURE PrLog
|
|
LPARAMETERS tcMsg
|
|
LOCAL lcL
|
|
SET SAFETY OFF
|
|
lcL = IIF(FILE(gcLog), FILETOSTR(gcLog), '')
|
|
STRTOFILE(lcL + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcLog)
|
|
ENDPROC
|
|
|
|
**********************************************************
|
|
PROCEDURE PrErr
|
|
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
|
DO PrLog WITH 'EROARE ' + TRANSFORM(tnErr) + ': ' + TRANSFORM(tcMsg) + ' in ' + ;
|
|
TRANSFORM(tcProg) + ' linia ' + TRANSFORM(tnLine)
|
|
gnEsecuri = gnEsecuri + 1
|
|
DO PrLog WITH 'TOTAL FAIL: eroare neasteptata'
|
|
QUIT
|
|
ENDPROC
|
|
|
|
**********************************************************
|
|
* Deblocarea formularului modal, in doua faze:
|
|
* faza 0 -> asteapta ca do_verifica sa PORNEASCA (lblVerifica.Visible = .T.)
|
|
* faza 1 -> asteapta ca do_verifica sa TERMINE (lblVerifica.Visible = .F.) si da Release
|
|
* Plasa de siguranta: dupa 240 de ticks (~8 minute) elibereaza oricum, ca sa nu agate testul.
|
|
**********************************************************
|
|
DEFINE CLASS tmrE2EDeblocare AS Timer
|
|
Interval = 2000
|
|
Enabled = .F.
|
|
|
|
PROCEDURE Timer
|
|
LOCAL lnI, loF, llVaz
|
|
gnE2ETicks = gnE2ETicks + 1
|
|
IF gnE2ETicks <= 3 OR MOD(gnE2ETicks, 15) = 0
|
|
DO PrLog WITH ' timer tick ' + TRANSFORM(gnE2ETicks) + ' forme=' + TRANSFORM(_SCREEN.FormCount) + ' faza=' + TRANSFORM(gnE2EFazaTimer)
|
|
ENDIF
|
|
FOR lnI = 1 TO _SCREEN.FormCount
|
|
loF = _SCREEN.Forms(lnI)
|
|
IF !PEMSTATUS(loF, 'lblVerifica', 5) OR !PEMSTATUS(loF, 'do_verifica', 5)
|
|
LOOP
|
|
ENDIF
|
|
llVaz = loF.lblVerifica.Visible
|
|
DO CASE
|
|
CASE loF.lAutoverificare OR llVaz
|
|
*-- verificarea nu a pornit inca sau e in curs (lblVerifica vizibil)
|
|
gnE2EFazaTimer = IIF(llVaz, 1, gnE2EFazaTimer)
|
|
CASE gnE2ETicks > 240
|
|
glE2EEliberat = .F.
|
|
loF.Release()
|
|
OTHERWISE
|
|
*-- Activate a rulat (lAutoverificare = .F.) si do_verifica s-a terminat
|
|
gnE2EFazaTimer = 2
|
|
glE2EEliberat = .T.
|
|
loF.Release()
|
|
ENDCASE
|
|
EXIT
|
|
ENDFOR
|
|
ENDPROC
|
|
ENDDEFINE
|