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

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

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

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

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

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

581 lines
25 KiB
Plaintext

* test_s5b_proforma.prg
* Headless: S5b in frm_facturare_articole2 (COMUN\clase\ofacturare.vc2).
* M1 - rutarea proformei: verificata STATIC (FILETOSTR + AT pe textul din arbore, fara Oracle,
* fara dialog) - Case poDate.eProforma = 1 e LITERALMENTE prima ramura din Do Case-ul lui
* do_scrie_factura (inaintea Case poDate.Tip = 4 si Case Inlist(poDate.Tip,3,21,25,28,42,47),
* ramurile Rol A / S4-4), iar apelul din acea ramura foloseste pack_facturare.scrie_proforma(
* cu toti cei 16 parametri reali (nu scrie_proforma_old, semnatura veche cu 5). A fost scoasa
* temporar, gresit banuita drept cauza a unui blocaj vfp9.exe - repusa dupa ce o rulare fara ea
* a reprodus identic blocajul (deci FILETOSTR nu era cauza). O rulare reala care ar emite o
* proforma la Oracle ar consuma un numar de document in MARIUSM_AUTO - datorie deschisa (vezi
* docs\raport_s5b_implementare.md).
* Logare DIAG: AfLog scrie si inchide fisierul la fiecare apel (flush per linie), deci un kill in
* mijlocul unei proceduri lasa in log ultima linie reala executata - folosita ca sa localizeze
* blocajul la instructiune, nu doar la procedura.
* M2 - marcheaza_linii_proforma: sentinela -1000/gestionabil=0 aplicata la salvare, pe toate
* liniile din crsfactura, cu restaurarea pozitiei curente (Recno).
* M3 - do_schimba_tipdoc: garda care blocheaza comutarea PROFORMA -> alt tip cat timp crsfactura
* are linii; sensurile FACTURA -> PROFORMA si "fara linii" raman libere.
*
* Proiectare (v2, dupa incidentul cu dialogul modal real din prima rulare):
* - poDate.eProforma se seteaza DIRECT, niciodata prin poDate.nIdTipDoc = 23 sau prin comutarea
* efectiva a tipului (nici la Createobject, nici prin do_schimba_tipdoc). Formularul se
* instantiaza mereu ca FACTURA (nIdTipDoc = 5, tip cu plaje de serii garantat in MARIUSM_AUTO).
* - do_schimba_tipdoc() se cheama DOAR in cazuri unde garda opreste executia inainte de
* alege_tipdoc/schimba_tipdoc (deci inainte de reincarcarea seriilor), sau unde tipul TINTA e
* FACTURA (are plaje). Sensul care ar comuta efectiv catre PROFORMA (fara plaje in acest mediu)
* NU se ruleaza - vezi TestGardaSensLiber.
* - Sonda RanduriSerii() (SQLEXEC direct pe verifica_cursor_serii, fara alocare) verifica plajele
* disponibile INAINTE de orice caz care ar putea comuta efectiv catre un tip nou.
*
* PLASA ANTI-MODAL, v3 - istoric complet in docs\raport_s5b_implementare.md:
* v1 (incident #2 initial): mock_amessagebox.prg incarcat o singura data la inceput, "verde" fara
* sa fi fost dovedit activ.
* v2: auto-proba prin SET PROCEDURE ADDITIVE + apel de proba - ea insasi auto-anulanta (detecta
* pierderea precedentei CHEMAND amessagebox(), exact apelul riscant). Inlocuita cu FUNCTION
* amessagebox definita DIRECT in acest .prg, pe baza experimentului A (precedenta .prg curent
* peste SET PROCEDURE - CONFIRMATA, dar testata doar pentru apel DIRECT din .prg).
* v3 (actuala): experimentul F a aratat ca precedenta din A NU se mosteneste in interiorul unei
* metode compilate SEPARAT (aici: do_schimba_tipdoc, metoda din ofacturare.vcx) - un apel
* amessagebox() facut din interiorul acelei metode NU foloseste FUNCTION amessagebox de mai jos,
* cade prin SET PROCEDURE chain. Deci FUNCTION amessagebox locala protejeaza doar apelurile
* DIRECTE din acest script (ex. proba din experimente); pentru apelul real din do_schimba_tipdoc
* e nevoie SI de reincarcarea `SET PROCEDURE TO mock_amessagebox.prg ADDITIVE` chiar inainte de
* fiecare apel riscant (SET PROCEDURE nu executa nimic, deci nu are cum sa deschida un dialog -
* spre deosebire de v2, unde proba insasi executa amessagebox()). Asta era, de fapt, mecanismul
* CORECT descris in incidentul #2 original din sarcina - confirmat acum experimental, nu doar
* presupus. NEVERIFICAT LA RULARE (nicio lansare disponibila dupa experimentul F) - apelurile
* TestGardaBlocheaza/TestGardaFaraLinii/TestGardaSensLiber raman comentate in lista principala.
*
* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\test_s5b_proforma.prg"
* Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s5b_proforma.log
* Mediu: ROA_CENTRAL / MARIUSM_AUTO; seriile de facturi (tipdoc 5) sunt pe utilizator -> gnIdUtil = 8.
SET SAFETY OFF
SET TALK OFF
SET NOTIFY OFF
PUBLIC gcLog, gnFail, gnPass, gnSarit, gcCaz
gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s5b_proforma.log"
IF !DIRECTORY("D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out")
MD "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out"
ENDIF
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
gnFail = 0
gnPass = 0
gnSarit = 0
gcCaz = ""
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
DO AfLog WITH "FAIL: conexiune Oracle esuata"
DO Final
ENDIF
* fara asta, un lacat Oracle blocheaza rularea la infinit, invizibil in log (tipar confirmat in test_s3b_emitere_paritate_2.prg)
SQLSETPROP(gnHandle, "QueryTimeOut", 45)
IF TYPE('goExecutor.nHandle') = 'N' AND goExecutor.nHandle > 0 AND goExecutor.nHandle <> gnHandle
SQLSETPROP(goExecutor.nHandle, "QueryTimeOut", 45)
ENDIF
* FUNCTION amessagebox e definita mai jos, in acest .prg - vezi PLASA ANTI-MODAL, v2, in antet
PUBLIC gcMockUltimMesaj, gnMockUltimTip
gcMockUltimMesaj = ""
gnMockUltimTip = 0
IF !actualizeaza_optiuni_program()
DO AfLog WITH "FAIL: actualizeaza_optiuni_program()"
DO Final
ENDIF
gnIdUtil = 8
goExecutor.oExecuta([begin pack_sesiune.set_Id_Util(?gnIdUtil); end;])
DO AfLog WITH "ENV OK"
* gridextras.vcx e referit din ofacturare.vcx cu cale relativa (..\utile\gridextras), rezolvabila doar din exe/IDE
SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras" ADDITIVE
PRIVATE poDate, poGeneratorNumere
poGeneratorNumere = CREATEOBJECT("oGeneratorNumere")
gnScadereStoc = 0
IF USED('crscursuri')
USE IN crscursuri
ENDIF
CREATE CURSOR crscursuri (curs N(12,4), nume_val C(10), multiplicator N(6))
DO creeaza_facturacrs WITH 'crsfactura'
* grd_factura.cGestiune e legat la crsFactura.gestiune, camp inexistent in creeaza_facturacrs (nume_gestiune)
SELECT *, CAST(NULL AS C(100)) AS gestiune FROM crsfactura INTO CURSOR crsfact_tmp READWRITE
USE IN crsfactura
SELECT * FROM crsfact_tmp INTO CURSOR crsfactura READWRITE
USE IN crsfact_tmp
* sonda plaje - fara alocare, doar SQLEXEC direct pe verifica_cursor_serii (vezi RanduriSerii)
PUBLIC glFacturaAreplaje, glProformaAreplaje
LOCAL lnRandFactura, lnRandProforma
lnRandFactura = RanduriSerii(5)
lnRandProforma = RanduriSerii(23)
glFacturaAreplaje = (lnRandFactura > 0)
glProformaAreplaje = (lnRandProforma > 0)
DO AfLog WITH "pre-proba plaje: tip 5(FACTURA) randuri=" + TRANSFORM(lnRandFactura) + ;
" tip 23(PROFORMA) randuri=" + TRANSFORM(lnRandProforma) + ;
" -> PROFORMA " + IIF(glProformaAreplaje, "probabil", "NEPROBABIL in acest mediu")
DO TestRutareProformaOrdine
DO TestMarcheazaLiniiProforma
DO TestMarcheazaLiniiProformaGol
* Experimentul D (coordonator): instrumenteaza operanzii conditiei gardei M3, FARA sa cheme
* do_schimba_tipdoc() - zero risc. TestGardaBlocheaza/TestGardaFaraLinii/TestGardaSensLiber raman
* comentate pentru aceasta rulare de diagnostic; se repun dupa ce D da raspunsul.
DO TestD_OperandGarda
* DO TestGardaBlocheaza
* DO TestGardaFaraLinii
* DO TestGardaSensLiber
DO Final
*----------------------------------------------------------------------------------------
PROCEDURE TestRutareProformaOrdine
LOCAL lcTxt, lcWindow, lnPosMark, lnPosDoCase, lnPosProforma, lnPosTip4, lnPosInlist, ;
lnPosPrimulCase, lcApel, laMarkeri[16], lnI, llToti16
gcCaz = "[M1 static: ordinea Do Case + forma apelului scrie_proforma] "
DO AfLog WITH "DIAG M1: start"
lcTxt = FILETOSTR("D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare.vc2")
DO AfLog WITH "DIAG M1: FILETOSTR OK, len=" + TRANSFORM(LEN(lcTxt))
IF EMPTY(lcTxt)
DO Assert WITH .F., "FILETOSTR ofacturare.vc2 a esuat/gol"
RETURN
ENDIF
* Thisform.marcheaza_linii_proforma() apare o singura data in tot fisierul (metoda noua, doar in
* frm_facturare_articole2) - ancoreaza fereastra de cautare exact pe ramura noua din do_scrie_factura
lnPosMark = AT("Thisform.marcheaza_linii_proforma()", lcTxt)
DO Assert WITH lnPosMark > 0, "Thisform.marcheaza_linii_proforma() apelat din do_scrie_factura"
IF lnPosMark = 0
RETURN
ENDIF
lcWindow = SUBSTR(lcTxt, MAX(lnPosMark - 300, 1), 5000)
lnPosDoCase = AT("Do Case", lcWindow)
lnPosProforma = AT("Case poDate.eProforma = 1", lcWindow)
lnPosTip4 = AT("Case poDate.Tip = 4", lcWindow)
lnPosInlist = AT("Case Inlist(poDate.Tip,3,21,25,28,42,47)", lcWindow)
DO Assert WITH lnPosDoCase > 0 AND lnPosProforma > 0 AND lnPosTip4 > 0 AND lnPosInlist > 0, ;
"toate reperele gasite: DoCase=" + TRANSFORM(lnPosDoCase) + " eProforma=" + TRANSFORM(lnPosProforma) + ;
" Tip4=" + TRANSFORM(lnPosTip4) + " Inlist=" + TRANSFORM(lnPosInlist)
IF lnPosDoCase = 0 OR lnPosProforma = 0 OR lnPosTip4 = 0 OR lnPosInlist = 0
RETURN
ENDIF
DO Assert WITH lnPosDoCase < lnPosProforma AND lnPosProforma < lnPosTip4 AND lnPosTip4 < lnPosInlist, ;
"ordine: Do Case < Case eProforma=1 < Case Tip=4 < Case Inlist(3,21,25,28,42,47)"
* Case eProforma=1 trebuie sa fie LITERALMENTE prima ramura - primul "Case " gasit dupa "Do Case"
* e chiar ea, nu doar "undeva inaintea" ramurilor S4-4 (Rol A) - o proforma tip 3/4 nu poate cadea
* pe ramura Rol A si sa ceara confirmarea "aviz de retur"
lnPosPrimulCase = AT("Case ", SUBSTR(lcWindow, lnPosDoCase + 7)) + lnPosDoCase + 7 - 1
DO Assert WITH lnPosPrimulCase == lnPosProforma, ;
"Case eProforma=1 e prima ramura din Do Case (primul Case dupa Do Case), pozitie prim Case=" + ;
TRANSFORM(lnPosPrimulCase) + " pozitie eProforma=" + TRANSFORM(lnPosProforma)
* forma apelului: pack_facturare.scrie_proforma cu 16 parametri (nu scrie_proforma_old cu 5)
lcApel = SUBSTR(lcWindow, lnPosProforma, lnPosTip4 - lnPosProforma)
DO Assert WITH "pack_facturare.scrie_proforma(" $ lcApel, "apelul contine pack_facturare.scrie_proforma("
DO Assert WITH !("scrie_proforma_old" $ lcApel), "apelul NU foloseste scrie_proforma_old (semnatura veche, 5 parametri)"
laMarkeri[1] = "pnTotalFtva"
laMarkeri[2] = "pnTotalTva"
laMarkeri[3] = "pnDiscount"
laMarkeri[4] = "serie_chit"
laMarkeri[5] = "nr_incasare"
laMarkeri[6] = "lcListaIncasare"
laMarkeri[7] = "id_delegat"
laMarkeri[8] = "id_masina"
laMarkeri[9] = "id_facturare"
laMarkeri[10] = "nListareDetaliata"
laMarkeri[11] = "dataora_exp"
laMarkeri[12] = "id_agent"
laMarkeri[13] = "text_aditional"
laMarkeri[14] = "discount_evidentiat"
laMarkeri[15] = "pnParametruAditional"
laMarkeri[16] = "nid_vanzare"
llToti16 = .T.
FOR lnI = 1 TO 16
IF !(laMarkeri[lnI] $ lcApel)
llToti16 = .F.
DO AfLog WITH " lipseste parametrul [" + laMarkeri[lnI] + "] din apelul scrie_proforma"
ENDIF
ENDFOR
DO Assert WITH llToti16, "toti cei 16 parametri ai scrie_proforma prezenti in apel (semnatura reala, nu cea veche cu 5)"
DO AfLog WITH "DIAG M1: done"
ENDPROC
PROCEDURE TestMarcheazaLiniiProforma
LOCAL loNou, lnRecnoInitial
gcCaz = "[M2 marcheaza_linii_proforma cu linii] "
SELECT crsfactura
ZAP
APPEND BLANK
REPLACE denumire WITH "art1", gestionabil WITH 1, id_gestiune WITH 77
APPEND BLANK
REPLACE denumire WITH "art2", gestionabil WITH 1, id_gestiune WITH 77
APPEND BLANK
REPLACE denumire WITH "art3", gestionabil WITH 1, id_gestiune WITH 77
GO 2 IN crsfactura
lnRecnoInitial = RECNO('crsfactura')
DO AfLog WITH "DIAG M2: crsfactura populat cu 3 randuri, Recno initial=" + TRANSFORM(lnRecnoInitial)
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27001, 1)
DO AfLog WITH "DIAG M2: poDate = Createobject(oDateFactura) OK"
poDate.nIdTipDoc = 5
DO AfLog WITH "DIAG M2: poDate.nIdTipDoc = 5 OK"
poGeneratorNumere.ResetNumere()
DO AfLog WITH "DIAG M2: poGeneratorNumere.ResetNumere() OK"
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(5)
DO AfLog WITH "DIAG M2: creeaza_cursor_serii(5) OK, rezultat=" + TRANSFORM(poDate.rezultat_serii)
DO AfLog WITH "DIAG M2: inainte de Createobject frm_facturare_articole2"
loNou = CREATEOBJECT('frm_facturare_articole2')
DO AfLog WITH "DIAG M2: Createobject frm_facturare_articole2 OK, vartype=" + VARTYPE(loNou)
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
loNou.marcheaza_linii_proforma()
DO AfLog WITH "DIAG M2: marcheaza_linii_proforma() OK"
LOCAL lnRecnoDupa
lnRecnoDupa = RECNO('crsfactura')
DO AfLog WITH "DIAG M2: Recno('crsfactura') OK, dupa=" + TRANSFORM(lnRecnoDupa)
DO Assert WITH lnRecnoDupa == lnRecnoInitial, "Recno restaurat, initial=" + TRANSFORM(lnRecnoInitial) + " dupa=" + TRANSFORM(lnRecnoDupa)
DO AfLog WITH "DIAG M2: Assert Recno OK"
SELECT crsfactura
LOCAL llToateMarcate
llToateMarcate = .T.
SCAN
IF gestionabil <> 0 OR id_gestiune <> -1000
llToateMarcate = .F.
ENDIF
ENDSCAN
DO AfLog WITH "DIAG M2: SCAN OK, llToateMarcate=" + TRANSFORM(llToateMarcate)
DO Assert WITH llToateMarcate, "toate liniile gestionabil=0 si id_gestiune=-1000"
GO m.lnRecnoDupa IN crsfactura
DO AfLog WITH "DIAG M2: GO OK"
loNou.Release()
DO AfLog WITH "DIAG M2: loNou.Release() OK"
ENDIF
RELEASE loNou
DO AfLog WITH "DIAG M2: RELEASE loNou OK, rezultat_serii=" + TRANSFORM(poDate.rezultat_serii)
IF poDate.rezultat_serii <> 0
poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
DO AfLog WITH "DIAG M2: dezaloca_numar OK"
ENDIF
DO AfLog WITH "DIAG M2: TestMarcheazaLiniiProforma TERMINAT"
ENDPROC
PROCEDURE TestMarcheazaLiniiProformaGol
LOCAL loNou
gcCaz = "[M2 marcheaza_linii_proforma pe crsfactura gol] "
DO AfLog WITH "DIAG: intrat in TestMarcheazaLiniiProformaGol"
SELECT crsfactura
ZAP
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27005, 1)
poDate.nIdTipDoc = 5
poGeneratorNumere.ResetNumere()
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(5)
loNou = CREATEOBJECT('frm_facturare_articole2')
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
LOCAL llEroare
llEroare = .F.
TRY
loNou.marcheaza_linii_proforma()
CATCH
llEroare = .T.
ENDTRY
DO Assert WITH !llEroare, "marcheaza_linii_proforma nu arunca eroare pe crsfactura gol"
loNou.Release()
ENDIF
RELEASE loNou
IF poDate.rezultat_serii <> 0
poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
ENDIF
ENDPROC
* Experimentul D (coordonator): reproduce exact contextul lui TestGardaBlocheaza (a treia
* instantiere a formularului, aceleasi valori) dar NU cheama do_schimba_tipdoc() - doar logheaza
* fiecare operand al conditiei gardei (ofacturare.vc2:19788) separat, plus conditia evaluata in
* test. Zero risc: nu se atinge nicio metoda de productie care ar putea deschide un dialog sau
* reincarca serii.
PROCEDURE TestD_OperandGarda
LOCAL loNou, lcValoare, lcValoareUpper, lnReccount, lnEProforma, llConditie
gcCaz = "[D operanzi garda, fara do_schimba_tipdoc] "
DO AfLog WITH "DIAG D: intrat in TestD_OperandGarda"
SELECT crsfactura
ZAP
APPEND BLANK
REPLACE denumire WITH "art1"
DO AfLog WITH "DIAG D: crsfactura populat cu 1 rand"
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27010, 1)
poDate.nIdTipDoc = 5
poGeneratorNumere.ResetNumere()
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(5)
DO AfLog WITH "DIAG D: creeaza_cursor_serii(5) OK, rezultat=" + TRANSFORM(poDate.rezultat_serii)
loNou = CREATEOBJECT('frm_facturare_articole2')
DO AfLog WITH "DIAG D: Createobject frm_facturare_articole2 OK, vartype=" + VARTYPE(loNou)
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
poDate.eProforma = 1
loNou.clb_fdoc.cboFdoc.Value = "FACTURA"
DO AfLog WITH "DIAG D: proprietati setate (eProforma=1, cboFdoc.Value=FACTURA)"
lcValoare = loNou.clb_fdoc.cboFdoc.Value
lcValoareUpper = UPPER(lcValoare)
lnReccount = RECCOUNT('crsfactura')
lnEProforma = poDate.eProforma
llConditie = (lnEProforma = 1 AND lcValoareUpper <> "PROFORMA" AND lnReccount > 0)
DO AfLog WITH "DIAG D: cboFdoc.Value=[" + lcValoare + "] (lungime=" + TRANSFORM(LEN(lcValoare)) + ")"
DO AfLog WITH "DIAG D: UPPER(cboFdoc.Value)=[" + lcValoareUpper + "]"
DO AfLog WITH "DIAG D: poDate.eProforma=" + TRANSFORM(lnEProforma)
DO AfLog WITH "DIAG D: Reccount('crsfactura')=" + TRANSFORM(lnReccount)
DO AfLog WITH "DIAG D: CONDITIA GARDEI (eProforma=1 AND Upper(Value)<>PROFORMA AND Reccount>0) = " + TRANSFORM(llConditie)
IF llConditie
DO AfLog WITH "DIAG D: VERDICT: garda S-AR FI DECLANSAT (blocheaza) - do_schimba_tipdoc ar fi intrat pe ramura sigura"
ELSE
DO AfLog WITH "DIAG D: VERDICT: garda NU s-ar fi declansat - do_schimba_tipdoc ar fi CAZUT PRIN ea, spre alege_tipdoc/schimba_tipdoc"
ENDIF
* nu se cheama do_schimba_tipdoc() - experimentul D se opreste aici, deliberat
loNou.Release()
DO AfLog WITH "DIAG D: loNou.Release() OK"
ENDIF
RELEASE loNou
IF poDate.rezultat_serii <> 0
poGeneratorNumere.dezaloca_numar(5)
DO AfLog WITH "DIAG D: dezaloca_numar OK"
ENDIF
DO AfLog WITH "DIAG D: TestD_OperandGarda TERMINAT"
ENDPROC
PROCEDURE TestGardaBlocheaza
LOCAL loNou
gcCaz = "[M3 garda blocheaza PROFORMA->FACTURA cu linii] "
DO AfLog WITH "DIAG: intrat in TestGardaBlocheaza"
SELECT crsfactura
ZAP
APPEND BLANK
REPLACE denumire WITH "art1"
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27002, 1)
poDate.nIdTipDoc = 5 && FACTURA la instantiere - are plaje, sigur
poGeneratorNumere.ResetNumere()
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(5)
DO AfLog WITH "DIAG: TestGardaBlocheaza - creeaza_cursor_serii(5) OK, rezultat=" + TRANSFORM(poDate.rezultat_serii)
loNou = CREATEOBJECT('frm_facturare_articole2')
DO AfLog WITH "DIAG: TestGardaBlocheaza - Createobject frm_facturare_articole2 OK"
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
* eProforma setat DIRECT dupa instantiere - nu prin nIdTipDoc, nu comuta efectiv tipul
poDate.eProforma = 1
loNou.clb_fdoc.cboFdoc.Value = "FACTURA"
gcMockUltimMesaj = ""
* FUNCTION amessagebox locala (mai jos in acest .prg) NU protejeaza acest apel - experimentul F
* a demonstrat ca precedenta unei functii definite in .prg-ul curent NU se mosteneste in
* interiorul unei metode compilate separat (aici: do_schimba_tipdoc, metoda din ofacturare.vcx).
* Reincarcarea mock_amessagebox.prg chiar inainte de apel (fara nicio proba prin executie -
* SET PROCEDURE nu executa nimic, deci nu are cum sa deschida un dialog) e mecanismul corect
* pentru un apel facut din interiorul unei metode de clasa.
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
loNou.do_schimba_tipdoc()
DO AfLog WITH "DIAG: TestGardaBlocheaza - do_schimba_tipdoc() OK"
DO Assert WITH poDate.nIdTipDoc == 5, "poDate.nIdTipDoc neschimbat, ramas=" + TRANSFORM(poDate.nIdTipDoc)
DO Assert WITH "Stergeti articolele" $ gcMockUltimMesaj, "mesajul de refuz s-a declansat, primit=[" + gcMockUltimMesaj + "]"
DO Assert WITH UPPER(loNou.clb_fdoc.cboFdoc.Value) == "PROFORMA", "cboFdoc.Value readus pe PROFORMA, e=" + TRANSFORM(loNou.clb_fdoc.cboFdoc.Value)
loNou.Release()
DO AfLog WITH "DIAG: TestGardaBlocheaza - loNou.Release() OK"
ENDIF
RELEASE loNou
IF poDate.rezultat_serii <> 0
poGeneratorNumere.dezaloca_numar(5)
DO AfLog WITH "DIAG: TestGardaBlocheaza - dezaloca_numar OK"
ENDIF
DO AfLog WITH "DIAG: TestGardaBlocheaza TERMINAT"
ENDPROC
PROCEDURE TestGardaFaraLinii
LOCAL loNou
gcCaz = "[M3 garda nu blocheaza fara linii, tinta FACTURA] "
DO AfLog WITH "DIAG: intrat in TestGardaFaraLinii"
IF !glFacturaAreplaje
DO AfLog WITH "SARIT - " + gcCaz + "nu exista plaje de serii pentru tipul FACTURA in acest mediu"
gnSarit = gnSarit + 1
RETURN
ENDIF
SELECT crsfactura
ZAP
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27003, 1)
poDate.nIdTipDoc = 5 && FACTURA la instantiere
poGeneratorNumere.ResetNumere()
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(5)
DO AfLog WITH "DIAG: TestGardaFaraLinii - creeaza_cursor_serii(5) OK, rezultat=" + TRANSFORM(poDate.rezultat_serii)
loNou = CREATEOBJECT('frm_facturare_articole2')
DO AfLog WITH "DIAG: TestGardaFaraLinii - Createobject frm_facturare_articole2 OK"
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
* eProforma fortat direct la 1, dar tinta ramane FACTURA (are plaje) si crsfactura e gol
poDate.eProforma = 1
loNou.clb_fdoc.cboFdoc.Value = "FACTURA"
gcMockUltimMesaj = ""
* vezi TestGardaBlocheaza - reincarcare inainte de apel, mecanismul corect pentru un apel
* facut din interiorul unei metode de clasa (experimentul F)
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
loNou.do_schimba_tipdoc()
DO AfLog WITH "DIAG: TestGardaFaraLinii - do_schimba_tipdoc() OK"
DO Assert WITH !("Stergeti articolele" $ gcMockUltimMesaj), "fara dialog de refuz cand crsfactura e gol, primit=[" + gcMockUltimMesaj + "]"
loNou.Release()
DO AfLog WITH "DIAG: TestGardaFaraLinii - loNou.Release() OK"
ENDIF
RELEASE loNou
IF poDate.rezultat_serii <> 0
poGeneratorNumere.dezaloca_numar(5)
DO AfLog WITH "DIAG: TestGardaFaraLinii - dezaloca_numar OK"
ENDIF
DO AfLog WITH "DIAG: TestGardaFaraLinii TERMINAT"
ENDPROC
PROCEDURE TestGardaSensLiber
LOCAL loNou, llConditieGarda
gcCaz = "[M3 sensul liber FACTURA->PROFORMA cu linii] "
* Nesigur de rulat: ar comuta efectiv catre PROFORMA, ceea ce ar cere plaje de serii pentru
* tipul de document 23 - PROFORMA, absente in MARIUSM_AUTO (confirmat de sonda de mai sus).
* Nu se cheama do_schimba_tipdoc() aici. Se evalueaza static conditia gardei: cu eProforma=0
* (pornind ca FACTURA) garda nu trebuie sa opreasca trecerea, indiferent daca exista linii.
DO AfLog WITH "SARIT (rulare reala) - " + gcCaz + "nu exista plaje de serii pentru tipul PROFORMA in acest mediu; se evalueaza static conditia gardei"
gnSarit = gnSarit + 1
SELECT crsfactura
ZAP
APPEND BLANK
REPLACE denumire WITH "art1"
APPEND BLANK
REPLACE denumire WITH "art2"
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", 27004, 1)
poDate.nIdTipDoc = 5 && FACTURA
loNou = CREATEOBJECT('frm_facturare_articole2')
IF VARTYPE(loNou) <> 'O'
DO Assert WITH .F., "Createobject frm_facturare_articole2"
ELSE
DO Assert WITH poDate.eProforma == 0, "precontitie eProforma=0 dupa nIdTipDoc=5"
loNou.clb_fdoc.cboFdoc.Value = "PROFORMA"
* conditia gardei din do_schimba_tipdoc (ofacturare.vc2) evaluata direct, fara sa se cheme metoda
llConditieGarda = (poDate.eProforma = 1 AND UPPER(loNou.clb_fdoc.cboFdoc.Value) <> "PROFORMA" AND RECCOUNT('crsfactura') > 0)
DO Assert WITH !llConditieGarda, "conditia gardei e falsa cand eProforma=0 (sensul liber FACTURA->PROFORMA nu e blocat)"
loNou.Release()
ENDIF
RELEASE loNou
ENDPROC
* cate randuri de plaja intoarce verifica_cursor_serii pentru un tip de document, fara sa aloce
FUNCTION RanduriSerii
LPARAMETERS tnIdTipDoc
LOCAL lnOk, lnRanduri, lcSql
LOCAL ARRAY laErr[1]
PRIVATE pnIdTipDoc, pnRezultat
pnIdTipDoc = tnIdTipDoc
pnRezultat = 0
lnRanduri = -1
lcSql = "{call " + gcS + ".pack_serii_numere.verifica_cursor_serii(?pnIdTipDoc,?gnIdUtil,?gnIdSucursala,?@pnRezultat)}"
lnOk = SQLEXEC(gnHandle, lcSql, "crsprobapl")
IF lnOk > 0
lnRanduri = RECCOUNT("crsprobapl")
USE IN (SELECT("crsprobapl"))
ELSE
AERROR(laErr)
DO AfLog WITH "pre-proba plaje tip " + TRANSFORM(tnIdTipDoc) + " ESEC: " + TRANSFORM(laErr[2])
ENDIF
RETURN lnRanduri
ENDFUNC
* FUNCTION amessagebox definita AICI, in .prg-ul care se executa acum - confirmat experimental
* (experimentul A, docs\raport_s5b_implementare.md) ca o procedura/functie din PRG-ul curent are
* precedenta NECONDITIONATA fata de orice SET PROCEDURE ... ADDITIVE, deci apelul nu poate rezolva
* niciodata catre amessagebox() real din COMUN\programe\oproceduri_comune.prg. Corp copiat identic
* din mock_amessagebox.prg (aceeasi semantica: gcMockUltimMesaj/gnMockUltimTip pentru asertii pe
* textul dialogului, gnMockRaspuns/gnMockRaspunsTotal pentru raspunsuri configurabile per caz).
FUNCTION amessagebox
LPARAMETERS tcMessage, tnDialogBoxType, tcTitle, tcFont, tnTimeOut, tnTimeoutValue
LOCAL lnRaspuns
IF TYPE('gnMockRaspunsTotal') = 'N' AND 'Actualizati totalul facturii' $ tcMessage
lnRaspuns = gnMockRaspunsTotal
ELSE
lnRaspuns = IIF(TYPE('gnMockRaspuns') = 'N', gnMockRaspuns, 6)
ENDIF
IF TYPE('gcMockUltimMesaj') = 'C'
gcMockUltimMesaj = TRANSFORM(tcMessage)
gnMockUltimTip = IIF(TYPE('tnDialogBoxType') = 'N', tnDialogBoxType, 0)
ENDIF
RETURN lnRaspuns
ENDFUNC
PROCEDURE Assert
LPARAMETERS tlCond, tcMsg
IF tlCond
gnPass = gnPass + 1
ELSE
gnFail = gnFail + 1
DO AfLog WITH "FAIL: " + gcCaz + tcMsg
ENDIF
ENDPROC
PROCEDURE AfLog
LPARAMETERS tcMsg
STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
ENDPROC
PROCEDURE AfErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
gnFail = gnFail + 1
DO AfLog WITH "ERROR " + gcCaz + TRANSFORM(tnErr) + " [" + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
ENDPROC
PROCEDURE Final
DO AfLog WITH "TOTAL pass=" + TRANSFORM(gnPass) + " fail=" + TRANSFORM(gnFail) + " sarit=" + TRANSFORM(gnSarit)
DO AfLog WITH "END " + TTOC(DATETIME())
QUIT
ENDPROC