Squash al branch-ului de lucru plan13-s2. Clase: ofacturare (nucleul formularului unificat), ofacturare_comun, ferestre_cere_date, ocomenzi, caut_ora (lista de preturi in combo-urile de cautare), omodificari. Programe: ofacturare impartit - ofacturare_antet, ofacturare_rutare_scriere si ogrid_latimi sunt fisiere noi; oproceduri_facturare primeste discountul pe linie si cota standard de TVA cand articolul nu are cota pe politica. Documentatie: capcana SQLExec no_data_found, conventia de encoding, depanarea testelor VFP si regulile de lucru - conflictele cu modificarile venite din alte proiecte sunt rezolvate pastrand ambele parti. Loguri de rulare a testelor scoase din versionare; testele raman. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
460 lines
19 KiB
Plaintext
460 lines
19 KiB
Plaintext
*!* 01.09.2026
|
|
*!* Biblioteca de comparatie documente v1/v2 (S6-0): fara efecte laterale, doar SELECT, nu emite
|
|
*!* nimic. Compara doua documente identificate prin SERIE_ACT + NRACT (nu ID_FACT - offset
|
|
*!* constant intre ID_FACT si ID_VANZARE, vezi docs\propunere_s6_test_flux_real.md 4.1a) pe
|
|
*!* VANZARI, VANZARI_DETALII, ACT si RUL.
|
|
*!*
|
|
*!* Functii publice (consumate de testele S6-1...S6-5):
|
|
*!* CompDoc(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
*!* ruleaza toate cele patru comparatii de mai jos si intoarce numarul total de esecuri
|
|
*!* CompVanzari(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
*!* antetul (VANZARI): campurile de paritate + totalurile denormalizate, egalitate exacta
|
|
*!* CompVanzariDetalii(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
*!* liniile (VANZARI_DETALII), linie cu linie, sortate dupa id_articol, pret, proc_tvav, plus
|
|
*!* invariantul minim (count, sum(cantitate), sum(cantitate*pret), setul de id_jtva_coloana)
|
|
*!* CompAct(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
*!* multimea de randuri ACT, jonctiune pe serie_act+nract, comparata sortat (nu depinde de
|
|
*!* ordinea de inserare)
|
|
*!* CompRul(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
*!* multimea de randuri RUL; gol pe ambele parti = PASS, dar raportat explicit ca paritate
|
|
*!* vida/neconcludenta (RUL are randuri doar cu gnScadereStoc = 1)
|
|
*!*
|
|
*!* Fiecare functie de mai sus intoarce numarul de esecuri (0 = paritate completa pe campurile
|
|
*!* comparate) si scrie fiecare FAIL/REZUMAT in gcLog daca apelantul l-a definit PUBLIC (conventia
|
|
*!* din acest director); altfel scrie in propriul log implicit (out\lib_comparatie_documente.log).
|
|
*!* Cere conexiune Oracle deja deschisa (goExecutor functional, gnIdUtil setat de apelant) - nu
|
|
*!* deschide conexiune proprie si nu face niciun INSERT/UPDATE/DELETE/DDL.
|
|
*!*
|
|
*!* Incarcare: SET PROCEDURE TO lib_comparatie_documente ADDITIVE (dupa test_init_env_auto_*).
|
|
*!* Restul functiilor (Cdoc*) sunt suportul intern, neconsumat direct de teste.
|
|
|
|
#DEFINE CDOC_LOG_IMPLICIT "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\lib_comparatie_documente.log"
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
FUNCTION CompDoc
|
|
LPARAMETERS tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta
|
|
LOCAL nFail
|
|
tcEticheta = IIF(EMPTY(tcEticheta), '[fara eticheta]', tcEticheta)
|
|
DO CdocLog WITH "===== CompDoc " + tcEticheta + " : " + ALLTRIM(tcSerie1) + " " + TRANSFORM(tnNr1) + ;
|
|
" vs " + ALLTRIM(tcSerie2) + " " + TRANSFORM(tnNr2) + " ====="
|
|
nFail = 0
|
|
nFail = nFail + CompVanzari(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
nFail = nFail + CompVanzariDetalii(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
nFail = nFail + CompAct(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
nFail = nFail + CompRul(tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta)
|
|
DO CdocLog WITH "TOTAL CompDoc " + tcEticheta + " esecuri=" + TRANSFORM(nFail)
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
* VANZARI - antetul, campurile din 5.2 (paritate) + totalurile denormalizate (egalitate exacta)
|
|
FUNCTION CompVanzari
|
|
LPARAMETERS tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta
|
|
LOCAL nId1, nId2, nFail, lcCampuri, lcSql, nCnt
|
|
tcEticheta = IIF(EMPTY(tcEticheta), '[fara eticheta]', tcEticheta)
|
|
nFail = 0
|
|
|
|
nId1 = CdocGasesteIdVanzare(tcSerie1, tnNr1)
|
|
nId2 = CdocGasesteIdVanzare(tcSerie2, tnNr2)
|
|
IF nId1 <= 0 OR nId2 <= 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI: document negasit, serie1=" + ;
|
|
ALLTRIM(TRANSFORM(tcSerie1)) + " nr1=" + TRANSFORM(tnNr1) + " id1=" + TRANSFORM(nId1) + ;
|
|
", serie2=" + ALLTRIM(TRANSFORM(tcSerie2)) + " nr2=" + TRANSFORM(tnNr2) + " id2=" + TRANSFORM(nId2)
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
lcCampuri = "TIP, ID_PART, ID_GESTIUNE, ID_AGENT, ID_SECTIE, ID_SUCURSALA, ID_RUTA, ID_CTR, " + ;
|
|
"ID_COMANDA, ID_DELEGAT, ID_MASINA, IN_VALUTA, ID_VALUTA, CURS, MULTIPLICATOR, DISCOUNT, " + ;
|
|
"DISCOUNT_EVIDENTIAT, DISCOUNT_TVA, TVA_INCASARE, TEXT_ADITIONAL, LISTARE_DETALIATA, " + ;
|
|
"AFISARE_SCADENTA, COEFICIENT_K, TIP_FACTURA, TIP_SAFT, EFACTURA, EPROFORMA, ID_FACTURARE, " + ;
|
|
"ID_BENEFICIAR, NR_PERSOANE, NRINMAT, COD, ID_LUCRARE, ID_PUNCTVANZARE, VALOARE_ACHIZITIE, " + ;
|
|
"DIFTOTFTVA, DIFTOTTVA, COMANDA, CONTRACT, AVIZE, TIP_INCASAT, SERIE_INCASAT, NR_INCASAT, " + ;
|
|
"SUMA_INCASAT, SERIE_ACT, FACTURAT, TOTAL_FARA_TVA, TOTAL_TVA, TOTAL_CU_TVA, VALVAL, TVAVAL, TOTVAL"
|
|
nCnt = OCCURS(",", lcCampuri) + 1
|
|
|
|
lcSql = [select ] + lcCampuri + [ from vanzari where id_vanzare = ] + ALLTRIM(STR(nId1, 20, 0))
|
|
IF goExecutor.oExecute(lcSql, 'crslibv1') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI: select document 1 esuat - " + goExecutor.oPrelucrareEroare()
|
|
RETURN 1
|
|
ENDIF
|
|
lcSql = [select ] + lcCampuri + [ from vanzari where id_vanzare = ] + ALLTRIM(STR(nId2, 20, 0))
|
|
IF goExecutor.oExecute(lcSql, 'crslibv2') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI: select document 2 esuat - " + goExecutor.oPrelucrareEroare()
|
|
DO CdocInchide WITH 'crslibv1'
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
IF !USED('crslibv1') OR RECCOUNT('crslibv1') = 0 OR !USED('crslibv2') OR RECCOUNT('crslibv2') = 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI: unul din documente nu are rand in VANZARI"
|
|
nFail = 1
|
|
ELSE
|
|
nFail = CdocComparaCampuri('crslibv1', 'crslibv2', lcCampuri, tcEticheta, ;
|
|
"VANZARI id1=" + TRANSFORM(nId1) + " id2=" + TRANSFORM(nId2))
|
|
ENDIF
|
|
DO CdocInchide WITH 'crslibv1'
|
|
DO CdocInchide WITH 'crslibv2'
|
|
|
|
DO CdocLog WITH "REZUMAT " + tcEticheta + " VANZARI id1=" + TRANSFORM(nId1) + " id2=" + ;
|
|
TRANSFORM(nId2) + " campuri=" + TRANSFORM(nCnt) + " esecuri=" + TRANSFORM(nFail)
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
* VANZARI_DETALII - linie cu linie (sortate 5.3) + invariantul minim
|
|
FUNCTION CompVanzariDetalii
|
|
LPARAMETERS tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta
|
|
LOCAL nId1, nId2, nFail, lcCampuri, lcSql, nCnt1, nCnt2, i
|
|
tcEticheta = IIF(EMPTY(tcEticheta), '[fara eticheta]', tcEticheta)
|
|
nFail = 0
|
|
nCnt1 = 0
|
|
nCnt2 = 0
|
|
|
|
nId1 = CdocGasesteIdVanzare(tcSerie1, tnNr1)
|
|
nId2 = CdocGasesteIdVanzare(tcSerie2, tnNr2)
|
|
IF nId1 <= 0 OR nId2 <= 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII: document negasit (vezi CompVanzari)"
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
lcCampuri = "ID_ARTICOL, ID_POL, CANTITATE, PRET, PRET_CU_TVA, PROC_TVAV, DISCOUNT_UNITAR, " + ;
|
|
"ID_GESTIUNE, ID_JTVA_COLOANA, ID_JTVA_COLOANA_EX, ID_VALUTA, CONT, EXPLICATIE, SERIE, LOT, " + ;
|
|
"TAXCODE, CUSTODIE, ID_RATA, ID_CTR, ID_VANZARE_SET, PRET_ACHIZITIE, PRETD, ID_VALUTAD, DIFERENTA"
|
|
|
|
lcSql = [select ] + lcCampuri + [ from vanzari_detalii where sters = 0 and id_vanzare = ] + ;
|
|
ALLTRIM(STR(nId1, 20, 0)) + [ order by id_articol, pret, proc_tvav]
|
|
IF goExecutor.oExecute(lcSql, 'crslibd1') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII: select document 1 esuat - " + goExecutor.oPrelucrareEroare()
|
|
RETURN 1
|
|
ENDIF
|
|
lcSql = [select ] + lcCampuri + [ from vanzari_detalii where sters = 0 and id_vanzare = ] + ;
|
|
ALLTRIM(STR(nId2, 20, 0)) + [ order by id_articol, pret, proc_tvav]
|
|
IF goExecutor.oExecute(lcSql, 'crslibd2') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII: select document 2 esuat - " + goExecutor.oPrelucrareEroare()
|
|
DO CdocInchide WITH 'crslibd1'
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
nCnt1 = IIF(USED('crslibd1'), RECCOUNT('crslibd1'), 0)
|
|
nCnt2 = IIF(USED('crslibd2'), RECCOUNT('crslibd2'), 0)
|
|
IF nCnt1 <> nCnt2
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII numar de linii diferit: v1=" + ;
|
|
TRANSFORM(nCnt1) + " v2=" + TRANSFORM(nCnt2)
|
|
ELSE
|
|
FOR i = 1 TO nCnt1
|
|
GO i IN crslibd1
|
|
GO i IN crslibd2
|
|
nFail = nFail + CdocComparaCampuri('crslibd1', 'crslibd2', lcCampuri, tcEticheta, ;
|
|
"VANZARI_DETALII linia " + TRANSFORM(i) + " (sortata)")
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
* invariantul minim din 5.3, chiar cand liniile nu sunt identice camp cu camp
|
|
nFail = nFail + CdocInvariantDetalii('crslibd1', nCnt1, 'crslibd2', nCnt2, tcEticheta)
|
|
|
|
DO CdocInchide WITH 'crslibd1'
|
|
DO CdocInchide WITH 'crslibd2'
|
|
|
|
DO CdocLog WITH "REZUMAT " + tcEticheta + " VANZARI_DETALII id1=" + TRANSFORM(nId1) + " id2=" + ;
|
|
TRANSFORM(nId2) + " linii1=" + TRANSFORM(nCnt1) + " linii2=" + TRANSFORM(nCnt2) + ;
|
|
" esecuri=" + TRANSFORM(nFail)
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
* ACT - multimea de randuri (5.4), jonctiune pe serie_act+nract, comparata sortat
|
|
FUNCTION CompAct
|
|
LPARAMETERS tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta
|
|
LOCAL nFail, lcCampuri, lcOrder, lcSql, nCnt1, nCnt2, i
|
|
tcEticheta = IIF(EMPTY(tcEticheta), '[fara eticheta]', tcEticheta)
|
|
nFail = 0
|
|
nCnt1 = 0
|
|
nCnt2 = 0
|
|
|
|
lcCampuri = "SCD, SCC, SUMA, ID_JTVA_COLOANA, ID_SET, ID_PARTD, ID_PARTC, ID_SECTIE, " + ;
|
|
"ID_VENCHELT, ID_CTR, PROC_TVA, NEIMPOZAB, TAXCODE, EXPLICATIA4"
|
|
lcOrder = " order by " + lcCampuri
|
|
|
|
lcSql = [select ] + lcCampuri + [ from act where sters = 0 and serie_act = '] + ALLTRIM(TRANSFORM(tcSerie1)) + ;
|
|
[' and nract = ] + ALLTRIM(STR(tnNr1, 20, 0)) + lcOrder
|
|
IF goExecutor.oExecute(lcSql, 'crsliba1') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " ACT: select document 1 esuat - " + goExecutor.oPrelucrareEroare()
|
|
RETURN 1
|
|
ENDIF
|
|
lcSql = [select ] + lcCampuri + [ from act where sters = 0 and serie_act = '] + ALLTRIM(TRANSFORM(tcSerie2)) + ;
|
|
[' and nract = ] + ALLTRIM(STR(tnNr2, 20, 0)) + lcOrder
|
|
IF goExecutor.oExecute(lcSql, 'crsliba2') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " ACT: select document 2 esuat - " + goExecutor.oPrelucrareEroare()
|
|
DO CdocInchide WITH 'crsliba1'
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
nCnt1 = IIF(USED('crsliba1'), RECCOUNT('crsliba1'), 0)
|
|
nCnt2 = IIF(USED('crsliba2'), RECCOUNT('crsliba2'), 0)
|
|
IF nCnt1 = 0 OR nCnt2 = 0
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " ACT: unul din documente nu are randuri (v1=" + ;
|
|
TRANSFORM(nCnt1) + " v2=" + TRANSFORM(nCnt2) + ")"
|
|
ELSE
|
|
IF nCnt1 <> nCnt2
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " ACT numar de randuri diferit: v1=" + ;
|
|
TRANSFORM(nCnt1) + " v2=" + TRANSFORM(nCnt2)
|
|
ENDIF
|
|
FOR i = 1 TO MIN(nCnt1, nCnt2)
|
|
GO i IN crsliba1
|
|
GO i IN crsliba2
|
|
nFail = nFail + CdocComparaCampuri('crsliba1', 'crsliba2', lcCampuri, tcEticheta, ;
|
|
"ACT rand " + TRANSFORM(i) + " (sortat)")
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
DO CdocInchide WITH 'crsliba1'
|
|
DO CdocInchide WITH 'crsliba2'
|
|
|
|
DO CdocLog WITH "REZUMAT " + tcEticheta + " ACT randuri1=" + TRANSFORM(nCnt1) + " randuri2=" + ;
|
|
TRANSFORM(nCnt2) + " esecuri=" + TRANSFORM(nFail)
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
* RUL - multimea de randuri (5.5); gol pe ambele parti = PASS, raportat ca paritate vida/neconcludenta
|
|
FUNCTION CompRul
|
|
LPARAMETERS tcSerie1, tnNr1, tcSerie2, tnNr2, tcEticheta
|
|
LOCAL nFail, lcCampuri, lcOrder, lcSql, nCnt1, nCnt2, i
|
|
tcEticheta = IIF(EMPTY(tcEticheta), '[fara eticheta]', tcEticheta)
|
|
nFail = 0
|
|
nCnt1 = 0
|
|
nCnt2 = 0
|
|
|
|
lcCampuri = "ID_ARTICOL, ID_GESTIUNE, ID_GESTIUNEC, CANT, PRET, PRETV, PROC_TVAV, VALOARE, " + ;
|
|
"VALOAREV, VALTVA, VALTVAV, DISCUNITAR, PROC_DISC, ID_TIP_RULAJ, ID_SET, CONT, SERIE, LOT, " + ;
|
|
"TAXCODE, ID_JTVA_COLOANA"
|
|
lcOrder = " order by " + lcCampuri
|
|
|
|
lcSql = [select ] + lcCampuri + [ from rul where sters = 0 and serie_act = '] + ALLTRIM(TRANSFORM(tcSerie1)) + ;
|
|
[' and nract = ] + ALLTRIM(STR(tnNr1, 20, 0)) + lcOrder
|
|
IF goExecutor.oExecute(lcSql, 'crslibr1') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " RUL: select document 1 esuat - " + goExecutor.oPrelucrareEroare()
|
|
RETURN 1
|
|
ENDIF
|
|
lcSql = [select ] + lcCampuri + [ from rul where sters = 0 and serie_act = '] + ALLTRIM(TRANSFORM(tcSerie2)) + ;
|
|
[' and nract = ] + ALLTRIM(STR(tnNr2, 20, 0)) + lcOrder
|
|
IF goExecutor.oExecute(lcSql, 'crslibr2') < 0
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " RUL: select document 2 esuat - " + goExecutor.oPrelucrareEroare()
|
|
DO CdocInchide WITH 'crslibr1'
|
|
RETURN 1
|
|
ENDIF
|
|
|
|
nCnt1 = IIF(USED('crslibr1'), RECCOUNT('crslibr1'), 0)
|
|
nCnt2 = IIF(USED('crslibr2'), RECCOUNT('crslibr2'), 0)
|
|
|
|
IF nCnt1 = 0 AND nCnt2 = 0
|
|
DO CdocLog WITH "PASS " + tcEticheta + " RUL: gol pe ambele parti - paritate VIDA, NECONCLUDENTA " + ;
|
|
"(RUL are randuri doar cu gnScadereStoc = 1)"
|
|
ELSE
|
|
IF nCnt1 = 0 OR nCnt2 = 0
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " RUL: gol doar pe o parte (v1=" + TRANSFORM(nCnt1) + ;
|
|
" v2=" + TRANSFORM(nCnt2) + ") - diferenta reala, nu paritate vida"
|
|
ELSE
|
|
IF nCnt1 <> nCnt2
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " RUL numar de randuri diferit: v1=" + ;
|
|
TRANSFORM(nCnt1) + " v2=" + TRANSFORM(nCnt2)
|
|
ENDIF
|
|
FOR i = 1 TO MIN(nCnt1, nCnt2)
|
|
GO i IN crslibr1
|
|
GO i IN crslibr2
|
|
nFail = nFail + CdocComparaCampuri('crslibr1', 'crslibr2', lcCampuri, tcEticheta, ;
|
|
"RUL rand " + TRANSFORM(i) + " (sortat)")
|
|
ENDFOR
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DO CdocInchide WITH 'crslibr1'
|
|
DO CdocInchide WITH 'crslibr2'
|
|
|
|
DO CdocLog WITH "REZUMAT " + tcEticheta + " RUL randuri1=" + TRANSFORM(nCnt1) + " randuri2=" + ;
|
|
TRANSFORM(nCnt2) + " esecuri=" + TRANSFORM(nFail)
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
*----------------------------------------------------------------------------------------
|
|
* Suport intern - nu se consuma direct din testele S6-1...S6-5
|
|
*----------------------------------------------------------------------------------------
|
|
|
|
* gaseste id_vanzare pornind de la serie_act+numar_act; 0 = negasit, -1 = eroare Oracle
|
|
* ORDER BY id_vanzare DESC: (serie_act,numar_act) nu e garantat unic pe tot istoricul (numere
|
|
* vechi, dinainte de seria de teste, pot coincide) - apelantii cauta mereu documentul scris ACUM,
|
|
* deci cel mai mare id_vanzare e alegerea corecta (descoperit la coliziunea SSS 1001: id_vanzare
|
|
* 451 din 2009 vs. 1623 scris azi de acest test)
|
|
FUNCTION CdocGasesteIdVanzare
|
|
LPARAMETERS tcSerie, tnNr
|
|
LOCAL lcSql
|
|
lcSql = [select id_vanzare as nr from vanzari where sters = 0 and serie_act = '] + ;
|
|
ALLTRIM(TRANSFORM(tcSerie)) + [' and numar_act = ] + ALLTRIM(STR(tnNr, 20, 0)) + ;
|
|
[ order by id_vanzare desc]
|
|
RETURN CdocValoareScalara(lcSql, 'crslibidv')
|
|
ENDFUNC
|
|
|
|
* executa un select ... as nr FROM ... si intoarce prima valoare; -1 = eroare Oracle
|
|
FUNCTION CdocValoareScalara
|
|
LPARAMETERS tcSql, tcCursorTmp
|
|
LOCAL lnRez, lnSucces, lcCur
|
|
lcCur = IIF(EMPTY(tcCursorTmp), 'crslibscalar', tcCursorTmp)
|
|
lnRez = -1
|
|
lnSucces = goExecutor.oExecute(tcSql, lcCur)
|
|
IF lnSucces >= 0 AND USED(lcCur)
|
|
IF RECCOUNT(lcCur) > 0
|
|
SELECT (lcCur)
|
|
GO TOP
|
|
lnRez = NVL(EVALUATE(lcCur + '.nr'), 0)
|
|
ELSE
|
|
lnRez = 0
|
|
ENDIF
|
|
USE IN (lcCur)
|
|
ELSE
|
|
DO CdocLog WITH "SQL ESEC: " + TRANSFORM(goExecutor.oPrelucrareEroare()) + " | " + tcSql
|
|
ENDIF
|
|
RETURN lnRez
|
|
ENDFUNC
|
|
|
|
* egalitate NULL-safe intre doua valori de cursor (numeric, caracter sau logic)
|
|
FUNCTION CdocEgal
|
|
LPARAMETERS tu1, tu2
|
|
IF ISNULL(tu1) AND ISNULL(tu2)
|
|
RETURN .T.
|
|
ENDIF
|
|
IF ISNULL(tu1) OR ISNULL(tu2)
|
|
RETURN .F.
|
|
ENDIF
|
|
IF VARTYPE(tu1) = 'C' OR VARTYPE(tu2) = 'C'
|
|
RETURN ALLTRIM(TRANSFORM(tu1)) == ALLTRIM(TRANSFORM(tu2))
|
|
ENDIF
|
|
RETURN tu1 = tu2
|
|
ENDFUNC
|
|
|
|
* compara toate campurile din tcListaCampuri (lista "camp1, camp2, ...") intre doua alias-uri
|
|
* POZITIONATE deja pe randul de comparat; logheaza fiecare FAIL si intoarce numarul de esecuri.
|
|
* Lista se primeste ca sir, nu ca array: un array trecut ca parametru intre functii isi pierde
|
|
* pentru compilator statutul de array (ambiguitate cu un apel de program), de-aici array-ul local
|
|
* construit chiar in aceasta functie.
|
|
FUNCTION CdocComparaCampuri
|
|
LPARAMETERS tcAlias1, tcAlias2, tcListaCampuri, tcEticheta, tcContext
|
|
LOCAL ARRAY laCampuri[1]
|
|
LOCAL nCnt, nFail, i, lcCamp, lu1, lu2
|
|
nCnt = ALINES(laCampuri, tcListaCampuri, 1, ",")
|
|
nFail = 0
|
|
FOR i = 1 TO nCnt
|
|
lcCamp = laCampuri[i]
|
|
lu1 = EVALUATE(tcAlias1 + '.' + lcCamp)
|
|
lu2 = EVALUATE(tcAlias2 + '.' + lcCamp)
|
|
IF !CdocEgal(lu1, lu2)
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " " + tcContext + " camp=" + lcCamp + ;
|
|
" v1=" + TRANSFORM(lu1) + " v2=" + TRANSFORM(lu2)
|
|
ENDIF
|
|
ENDFOR
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
* invariantul minim de pe VANZARI_DETALII (5.3): count(*), sum(cantitate), sum(cantitate*pret),
|
|
* setul de id_jtva_coloana - valabil chiar cand liniile nu sunt identice camp cu camp
|
|
FUNCTION CdocInvariantDetalii
|
|
LPARAMETERS tcAlias1, tnCnt1, tcAlias2, tnCnt2, tcEticheta
|
|
LOCAL nFail, nSumCant1, nSumCant2, nSumVal1, nSumVal2, lcSet1, lcSet2, lcCod
|
|
nFail = 0
|
|
nSumCant1 = 0
|
|
nSumVal1 = 0
|
|
lcSet1 = ''
|
|
IF USED(tcAlias1) AND tnCnt1 > 0
|
|
SELECT (tcAlias1)
|
|
GO TOP
|
|
SCAN
|
|
nSumCant1 = nSumCant1 + NVL(cantitate, 0)
|
|
nSumVal1 = nSumVal1 + NVL(cantitate, 0) * NVL(pret, 0)
|
|
lcCod = TRANSFORM(NVL(id_jtva_coloana, 0))
|
|
IF !(";" + lcCod + ";" $ ";" + lcSet1)
|
|
lcSet1 = lcSet1 + lcCod + ";"
|
|
ENDIF
|
|
ENDSCAN
|
|
ENDIF
|
|
nSumCant2 = 0
|
|
nSumVal2 = 0
|
|
lcSet2 = ''
|
|
IF USED(tcAlias2) AND tnCnt2 > 0
|
|
SELECT (tcAlias2)
|
|
GO TOP
|
|
SCAN
|
|
nSumCant2 = nSumCant2 + NVL(cantitate, 0)
|
|
nSumVal2 = nSumVal2 + NVL(cantitate, 0) * NVL(pret, 0)
|
|
lcCod = TRANSFORM(NVL(id_jtva_coloana, 0))
|
|
IF !(";" + lcCod + ";" $ ";" + lcSet2)
|
|
lcSet2 = lcSet2 + lcCod + ";"
|
|
ENDIF
|
|
ENDSCAN
|
|
ENDIF
|
|
|
|
IF !CdocEgal(ROUND(nSumCant1, 6), ROUND(nSumCant2, 6))
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII invariant sum(cantitate) diferit: v1=" + ;
|
|
TRANSFORM(nSumCant1) + " v2=" + TRANSFORM(nSumCant2)
|
|
ENDIF
|
|
IF !CdocEgal(ROUND(nSumVal1, 2), ROUND(nSumVal2, 2))
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII invariant sum(cantitate*pret) diferit: v1=" + ;
|
|
TRANSFORM(nSumVal1) + " v2=" + TRANSFORM(nSumVal2)
|
|
ENDIF
|
|
IF !(CdocSortSet(lcSet1) == CdocSortSet(lcSet2))
|
|
nFail = nFail + 1
|
|
DO CdocLog WITH "FAIL " + tcEticheta + " VANZARI_DETALII invariant set id_jtva_coloana diferit: v1=" + ;
|
|
lcSet1 + " v2=" + lcSet2
|
|
ENDIF
|
|
RETURN nFail
|
|
ENDFUNC
|
|
|
|
* normalizeaza un set ";"-delimitat de coduri numerice ca sa nu depinda de ordinea de aparitie
|
|
FUNCTION CdocSortSet
|
|
LPARAMETERS tcSet
|
|
LOCAL ARRAY laSet[1]
|
|
LOCAL nCnt, i, j, lcTmp, lcRez
|
|
nCnt = ALINES(laSet, tcSet, 1, ";")
|
|
IF nCnt = 0
|
|
RETURN ''
|
|
ENDIF
|
|
FOR i = 1 TO nCnt - 1
|
|
FOR j = i + 1 TO nCnt
|
|
IF VAL(laSet[j]) < VAL(laSet[i])
|
|
lcTmp = laSet[i]
|
|
laSet[i] = laSet[j]
|
|
laSet[j] = lcTmp
|
|
ENDIF
|
|
ENDFOR
|
|
ENDFOR
|
|
lcRez = ''
|
|
FOR i = 1 TO nCnt
|
|
lcRez = lcRez + laSet[i] + ";"
|
|
ENDFOR
|
|
RETURN lcRez
|
|
ENDFUNC
|
|
|
|
* elibereaza un alias daca e deschis
|
|
PROCEDURE CdocInchide
|
|
LPARAMETERS tcAlias
|
|
IF USED(tcAlias)
|
|
USE IN (tcAlias)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
* scrie in gcLog (daca apelantul l-a definit PUBLIC) sau in logul implicit al bibliotecii
|
|
PROCEDURE CdocLog
|
|
LPARAMETERS tcMsg
|
|
LOCAL lcLog
|
|
lcLog = IIF(TYPE('gcLog') = 'C' AND !EMPTY(gcLog), gcLog, CDOC_LOG_IMPLICIT)
|
|
IF !DIRECTORY(JUSTPATH(lcLog))
|
|
MD (JUSTPATH(lcLog))
|
|
ENDIF
|
|
STRTOFILE(tcMsg + CHR(13) + CHR(10), lcLog, 1)
|
|
ENDPROC
|