* 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