* test_s8b_rutare_scriere.prg * Proba S8b (docs\propunere_s8b_rutare_scriere.md sectiunea 5): cele 4 rute de scriere la editarea * unui document existent, pe traseul REAL Newobject('frm_facturi') + .do_editare_unificata() + * Thisform.do_scrie_factura() (nu apel direct pe AlegeRutaScriereEditare - proba doar codul, nu * traseul, cf. lectia platita de trei ori in acest plan). * * 4 documente distincte, din setul deja folosit de test_s8_editare_incarcare.prg: * 1047 - caz 1: nimic schimbat -> ruta 0, zero apeluri goExecutor intre deschidere si confirmare * (DEVIZE AUTO, fara delegat - inlocuieste 1113, stricat de un diagnostic anterior) * 1055 - caz 2: antet schimbat (text_aditional) -> ruta 2, UPDATE VANZARI pe id-ul real (defectul * "id_vanzare sentinela" de la S8b, corectat aici) * 1048 - caz 3: explicatie de linie schimbata -> ruta 3, UPDATE VANZARI_DETALII pe linia atinsa * caz 4: cantitate schimbata pe o linie -> ruta 1 (regenerare), implementata (S9/S11/S14): sterge * documentul vechi si reemite unul nou pe acelasi (numar_act, serie_act). Document DEDICAT * (S8B/1, docs\raport_fixtura_1130.md) - nu mai e fix un id, fiindca regenerarea il consuma * (sters=1) la fiecare rulare reusita, deci se cauta la rulare descendentul viu curent prin * (numar_act=1, serie_act='S8B'), robust la orice numar de rerulari. Izolat de orice alt * test - inainte folosea (numar_act=684, serie_act='SSS'), martorul VALUTA folosit cu id * fix (1130) de alte 6 teste din editare_factura; regenerarea periodica de aici il stergea * tacut. docs\raport_fixtura_1130.md. * * Caz 4 regenereaza documentul (ruta 1), dar fara numar nou - reemiterea forteaza acelasi * (numar_act, serie_act). Cazurile 1-3 nu regenereaza; modifica_date_factura/ * modifica_explicatie_articol nu aloca numere (verificat prin snapshot vplaje_numere inainte/dupa). * Contorul de apeluri goExecutor foloseste tiparul deja validat in acest director * (facturare_unificat\mock_cursor_articole.prg: subclasa de oexecutor cu oReal, nu DODEFAULT). SET SAFETY OFF SET TALK OFF PUBLIC gcErrLog gcErrLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s8b_rutare_scriere_log.txt' STRTOFILE('start ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog) ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' IF gnHandle <= 0 STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), gcErrLog, 1) QUIT ENDIF gnIdUtil = 8 *!* --- 'verificare' (Ferestre\verificare.scx, caz 4) foloseste GRID1.Gridextra1 - lipsa din *!* SET PATH/CLASSLIB de test_init_env_auto_roafacturare.prg (nu are nevoie de el in mod normal). *!* Adaugat preventiv, acelasi tipar deja validat in test_s6_3_aviz_retur.prg:102-103 pentru *!* acelasi formular - NU a fost cauza blocajului initial (aceea a fost numele de clasa gresit *!* la detectie, vezi driverVerificareS8b mai jos), dar ramane utila daca gridextra1.setup() *!* (verificare.sc2:1159) ar avea nevoie de resurse din acest folder pe alte date de test --- SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras" ADDITIVE SET CLASSLIB TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras\gridextras.vcx" ADDITIVE PUBLIC gnScadereStoc gnScadereStoc = 0 SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_rutare_scriere.prg ADDITIVE *!* la nume duplicat de procedura castiga PRIMUL fisier din lista SET PROCEDURE, nu ultimul - *!* mock-ul se pune in fata listei existente, altfel amessagebox() real blocheaza headless LOCAL lcProcExistent lcProcExistent = SET("PROCEDURE") SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg", &lcProcExistent PUBLIC gnPass, gnFail, gcMockUltimMesaj, gnMockUltimTip, gnMockRaspuns, gnContorExecutiiS8b gcMockUltimMesaj = '' gnMockUltimTip = 0 gnMockRaspuns = 6 gnPass = 0 gnFail = 0 gnContorExecutiiS8b = 0 *!* --- driver care gaseste fereastra modala frm_facturare_articole2, aplica mutatia specifica *!* cazului, cheama Thisform.do_scrie_factura() si inchide fereastra (acelasi tipar validat in *!* test_s8_editare_incarcare.prg / driverS8p7 - Timer legat de _SCREEN prin Bindevent, viu in *!* interiorul Show()-ului modal, care citeste formularul din colectia Forms) --- *!* Hide(), nu Release() direct: pentru WindowType modal, Show() se intoarce la Hide() (Visible=.F.) *!* la fel de bine ca la Release() (documentat MS: "suspended until the form is either hidden or *!* released") - deblocheaza Show() FARA sa distruga obiectul din Timer; distrugerea reala vine *!* singura, dupa ce Show() revine, cand loForm (local in do_editare_unificata) iese din scop - *!* deci pe stiva do_editare_unificata, nu pe stiva Timer-ului reentrant. PostMessage(WM_CLOSE) *!* incercat prima data a produs "Menu manager internal consistency error" pe cazurile cu scriere *!* reala (2/3/4) - infirmat, vezi docs\raport_reparatie_s8b_rutare_scriere.md PUBLIC goDriverS8b goDriverS8b = Createobject('driverS8bRutare') _SCREEN.AddObject('tmrS8bRutare', 'Timer') _SCREEN.tmrS8bRutare.Interval = 150 BINDEVENT(_SCREEN.tmrS8bRutare, 'Timer', goDriverS8b, 'Executa') _SCREEN.tmrS8bRutare.Enabled = .T. *!* --- al doilea driver/timer, INDEPENDENT de tmrS8bRutare: 'verificare' (Ferestre\verificare.scx, *!* clasa runtime _frmbase - vezi nota de mai jos) se deschide DIN INTERIORUL do_scrie_factura() (ofacturare.vc2:20532), deci *!* pe cand goDriverS8b.lBusy e inca .T. - garda lui de reintrare l-ar impiedica sa trateze un al *!* doilea formular modal aparut in timpul propriei rulari. Timer separat, la fel ca tmrDrv8/ *!* driverAlteDate8 din creeaza_documente_s8.prg, ca sa poata raspunde in timp ce Timer-ul principal *!* e inca "ocupat" mai jos pe stiva. do_termin() (nu Release/Hide direct) - seteaza gnButon=1 *!* (_frm_base.vc2:363-376), aceeasi valoare pre-setata la ofacturare.vc2:20526 pentru traseul de *!* CONFIRMARE (If gnButon=1 la linia 20533 continua scrierea reala - finalizeaza_scriere_verificare/ *!* scrie_factura_avize_retur; orice alta valoare ar sari peste finalizare, netratand cazul ca un *!* utilizator care apasa Terminare/CTRL+F) PUBLIC goDriverVerifS8b, glDlgTratatVerifS8b glDlgTratatVerifS8b = .F. goDriverVerifS8b = Createobject('driverVerificareS8b') _SCREEN.AddObject('tmrVerifS8b', 'Timer') _SCREEN.tmrVerifS8b.Interval = 150 BINDEVENT(_SCREEN.tmrVerifS8b, 'Timer', goDriverVerifS8b, 'Executa') _SCREEN.tmrVerifS8b.Enabled = .T. *!* --- crsfacturi, exact ca in oproceduri_facturare.vizualizare_facturi, pe cele 4 documente --- Private poFacturi poFacturi = Null IF Used('crsfacturi') Use In crsfacturi ENDIF LOCAL lcSchema, lcSelect, lcOrder, lcFiltru lcSchema = ['ales n(1),id_vanzare n(20),id_comanda n(20),dataora t,dataora_exp t,data_act d,data_scad d,sters n(1),dataoras t,numar_act n(14),serie_act c(10),'+] + ; ['tip n(5),id_part n(10),discount n(17,4),disc_fara_tva n(17,4),discount_evidentiat n(1),text_aditional M,facturat n(1),data_facturat t,'+] + ; ['explicatie c(240),altele c(200),client c(100),cod n(20),id_util I,utilizator c(30),utils c(30),utilfact c(30),delegat c(70),'+] + ; ['bidelegat c(30),cnpdelegat c(15),nume_agent c(70),nrinmat c(10),total_fara_tva n(20,4),total_tva n(20,4),total_cu_tva n(20,4),id_gestiune n(10),'+] + ; ['serie_chit c(20),nr_incasare n(10),incasat n(17,4),in_valuta n(1),sucursala c(100),id_ruta n(10),ruta c(100),curs n(20,4),multiplicator n(10),nume_val c(50),'+] + ; ['valuta c(50), id_valuta n(5), valval n(20,4), tvaval n(20,4), totval n(20,4),'+] + ; ['id_delegat n(10),id_agent n(10),id_masina n(10),valoarea N(20,4),nume_gestiune C(50),id_sectie n(5),sectie c(50),id_lucrare n(20), lucrare c(200),'+] + ; ['tip_incasare n(10),afisare_scadenta n(1),id_ordl n(10),tva_incasare n(1),listare_detaliata n(1),'+] + ; ['id_facturare n(10),adresa_facturare c(250),email_facturare c(100),adresa_client c(250),email_client c(100),adresa_beneficiar c(250),email_beneficiar c(100),'+] + ; ['id_beneficiar n(20),beneficiar C(100),tip_factura N(5),ctip_factura C(100), id_ctr N(10), contract C(100),eproforma N(1),tip_saft N(3) null,tip_saftname V(250) null,'+]+; ['id_livrare N(10),adresa_livrare V(250), denumire_adresa_livrare V(100), email_livrare V(100),institutie_publica N(1) null,efactura N(1) null,cod_fiscal C(20),id_fact N(20)'] lcSelect = ['select 0 as ales,id_vanzare,id_comanda,dataora,dataora_exp,data_act,data_scad,sters,dataoras,numar_act,serie_act,'+] + ; ['tip,id_part,discount,disc_fara_tva,discount_evidentiat,text_aditional,facturat,data_facturat,'+] + ; ['explicatie,altele,client,cod,id_util,utilizator,utils,utilfact,delegat,bidelegat,cnpdelegat,'+] + ; ['nume_agent,nrinmat,total_fara_tva,total_tva,total_cu_tva,id_gestiune,serie_chit,nr_incasare,incasat,'+] + ; ['in_valuta,sucursala,id_ruta,ruta,curs,multiplicator,nume_val,'+] + ; ['valuta,id_valuta,valval,tvaval,totval,'+] + ; ['id_delegat,id_agent,id_masina,valoarea,'+] + ; ['nume_gestiune,id_sectie,sectie,id_lucrare,lucrare,tip_incasare,afisare_scadenta,id_ordl,tva_incasare,listare_detaliata,'+] + ; ['id_facturare,adresa_facturare,email_facturare,adresa_client,email_client,adresa_beneficiar,email_beneficiar,'+] + ; ['id_beneficiar, beneficiar, tip_factura, ctip_factura, id_ctr, contract, eproforma,tip_saft,tip_saftname, '+]+; ['id_livrare,adresa_livrare,denumire_adresa_livrare,email_livrare,institutie_publica,efactura,cod_fiscal,id_fact from fact_vfacturi where '] *!* --- caz 4 (cantitate schimbata -> ruta 1 regenerare): document dedicat (S8B/1, docs\ *!* raport_fixtura_1130.md), izolat de orice alt test - regenerarea nu mai consuma un martor *!* partajat. Descendentul viu se gaseste prin (numar_act, serie_act), care ramane FORTAT *!* constant peste regenerari (ForteazaIdFactReemitere, ofacturare_rutare_scriere.prg:506-509), *!* nu prin id_vanzare --- LOCAL lnCaz4IdVanzare, lnSuccesCaz4 lnCaz4IdVanzare = 1720 IF USED('v_caz4_live') USE IN v_caz4_live ENDIF lnSuccesCaz4 = goExecutor.oExecute([select id_vanzare from vanzari where numar_act = 1 and serie_act = 'S8B' and tip = 5 and sters = 0], 'v_caz4_live') goExecutor.oReset() IF lnSuccesCaz4 >= 0 AND USED('v_caz4_live') AND RECCOUNT('v_caz4_live') = 1 lnCaz4IdVanzare = v_caz4_live.id_vanzare ENDIF USE IN v_caz4_live lcOrder = [data_act,numar_act] lcFiltru = [id_vanzare in (1047, 1055, 1048, ] + TRANSFORM(m.lnCaz4IdVanzare) + [)] gencursor('poFacturi', 'crsfacturi', lcSelect, lcFiltru, lcSchema, lcOrder, .F., [], .F., []) poFacturi.ca_baza1.afisare() DO asserteaza WITH 'crsfacturi incarcat cu cele 4 documente reale (rownum=4)', Used('crsfacturi') AND Reccount('crsfacturi') = 4, IIF(Used('crsfacturi'), TRANSFORM(Reccount('crsfacturi')), 'crsfacturi lipsa') *!* ===================================================================================== *!* cele 4 rute, document distinct per caz *!* ===================================================================================== *!* 1047 (DEVIZE AUTO, fara delegat) in loc de 1113 - 1113 a fost stricat de un script de *!* diagnostic anterior din acest bloc (a scris DATA_ACT=01.09.2026 direct, testand daca SQL *!* literal functioneaza), scotandu-l din luna curenta de test; 1047 nu a fost atins de nimic DO VerificaRutaEditare WITH 1047, 1, 'nimic schimbat - ruta 0' DO VerificaRutaEditare WITH 1055, 2, 'antet schimbat (text_aditional) - ruta 2' DO VerificaRutaEditare WITH 1048, 3, 'explicatie linie schimbata - ruta 3' DO VerificaRutaEditare WITH lnCaz4IdVanzare, 4, 'cantitate schimbata - ruta 1 regenerare' _SCREEN.tmrS8bRutare.Enabled = .F. Try _SCREEN.RemoveObject('tmrS8bRutare') Catch Endtry _SCREEN.tmrVerifS8b.Enabled = .F. Try _SCREEN.RemoveObject('tmrVerifS8b') Catch Endtry STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1) STRTOFILE('end ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog, 1) QUIT *!* ===================================================================================== PROCEDURE VerificaRutaEditare LPARAMETERS tnIdVanzare, tnCaz, tcEticheta LOCAL lcPrefix, lnSucces, loFrm LOCAL lcSnapPlajeA, lcSnapPlajeB LOCAL lcTextAditionalVechi, lnCountLiniiA, lnIdVanzareDetPrimaLinie, lnCantitateVeche, lcExplicatieVeche lcPrefix = TRANSFORM(m.tnIdVanzare) + ' [ruta ' + TRANSFORM(m.tnCaz) + ' - ' + m.tcEticheta + ']' gcMockUltimMesaj = '' DO CurataAliasuriReziduale *!* --- G2: nicio ruta din S8b aloca numere - snapshot INAINTE --- IF USED('v_plaje_s8b_a') USE IN v_plaje_s8b_a ENDIF lnSucces = goExecutor.oExecute([select id_plaja, urmval from vplaje_numere order by id_plaja], 'v_plaje_s8b_a') goExecutor.oReset() lcSnapPlajeA = CursorToSnapshot('v_plaje_s8b_a') USE IN v_plaje_s8b_a *!* --- martor antet Oracle, INAINTE --- IF USED('v_antet_s8b_a') USE IN v_antet_s8b_a ENDIF lnSucces = goExecutor.oExecute([select text_aditional from vanzari where id_vanzare = ] + TRANSFORM(m.tnIdVanzare), 'v_antet_s8b_a') goExecutor.oReset() DO asserteaza WITH lcPrefix + ': martor antet Oracle a reusit', lnSucces >= 0 AND USED('v_antet_s8b_a') AND RECCOUNT('v_antet_s8b_a') = 1, TRANSFORM(lnSucces) lcTextAditionalVechi = ALLTRIM(NVL(v_antet_s8b_a.text_aditional,'')) USE IN v_antet_s8b_a *!* --- martor linii Oracle, INAINTE - id_vanzare_det/cantitate/explicatie ale primei linii, *!* aceeasi ordine (id_vanzare_det) ca cea folosita de creeaza_facturacrs/prelucreaza_facturacrs --- IF USED('v_linii_s8b_a') USE IN v_linii_s8b_a ENDIF lnSucces = goExecutor.oExecute([select id_vanzare_det, cantitate, explicatie from vanzari_detalii where id_vanzare = ] + TRANSFORM(m.tnIdVanzare) + [ and sters = 0 order by id_vanzare_det], 'v_linii_s8b_a') goExecutor.oReset() DO asserteaza WITH lcPrefix + ': martor linii Oracle a reusit', lnSucces >= 0 AND USED('v_linii_s8b_a') AND RECCOUNT('v_linii_s8b_a') >= 1, TRANSFORM(lnSucces) lnCountLiniiA = RECCOUNT('v_linii_s8b_a') SELECT v_linii_s8b_a GO TOP lnIdVanzareDetPrimaLinie = id_vanzare_det lnCantitateVeche = cantitate lcExplicatieVeche = ALLTRIM(NVL(explicatie,'')) USE IN v_linii_s8b_a Select crsfacturi loFrm = Newobject('frm_facturi', 'D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare_comun.vcx') DO asserteaza WITH lcPrefix + ': Newobject(frm_facturi) reuseste', VARTYPE(m.loFrm) == 'O', VARTYPE(m.loFrm) IF VARTYPE(m.loFrm) <> 'O' RETURN ENDIF Select crsfacturi Locate For id_vanzare = m.tnIdVanzare DO asserteaza WITH lcPrefix + ': documentul e in crsfacturi', FOUND(), TRANSFORM(FOUND()) IF !FOUND() loFrm.Release() RETURN ENDIF *!* --- driverS8bRutare gaseste formularul, aplica mutatia cazului, cheama do_scrie_factura, *!* inchide formularul --- glDlgTratatVerifS8b = .F. goDriverVerifS8b.cCaleUrmata = '' goDriverS8b.Reseteaza() goDriverS8b.nCaz = m.tnCaz STRTOFILE('MARK ' + lcPrefix + ': inainte de do_editare_unificata' + CHR(13) + CHR(10), gcErrLog, 1) loFrm.do_editare_unificata() STRTOFILE('MARK ' + lcPrefix + ': dupa do_editare_unificata' + CHR(13) + CHR(10), gcErrLog, 1) DO asserteaza WITH lcPrefix + ': formularul s-a deschis (driver a gasit frm_facturare_articole2)', goDriverS8b.lGasit, TRANSFORM(goDriverS8b.lGasit) IF !goDriverS8b.lGasit *!* diagnostic: care garda a respins do_editare_unificata - CU MESAJ (gcMockUltimMesaj) sau *!* silentioasa (garda goala, ex. glLunaInchisa/ReferinteDocumenteNota/EsteInEFactura/DocumentAreUrmasi) STRTOFILE(lcPrefix + ' diagnostic iesire: mesaj=[' + gcMockUltimMesaj + ']' + CHR(13) + CHR(10), gcErrLog, 1) Try loFrm.Release() Catch Endtry DO CurataAliasuriReziduale RETURN ENDIF DO asserteaza WITH lcPrefix + ': fara eroare in driver la mutarea datelor/confirmare - ' + goDriverS8b.cEroare, EMPTY(goDriverS8b.cEroare), goDriverS8b.cEroare DO asserteaza WITH lcPrefix + ': do_scrie_factura a intors un rezultat (fara exceptie)', goDriverS8b.lRezultatCapturat, TRANSFORM(goDriverS8b.lRezultatCapturat) DO asserteaza WITH lcPrefix + ': linia gasita de driver = prima linie din martorul Oracle (ordine id_vanzare_det)', ; VAL(goDriverS8b.cIdTempLinie) == m.lnIdVanzareDetPrimaLinie OR m.tnCaz < 3, TRANSFORM(VAL(goDriverS8b.cIdTempLinie)) Try loFrm.Release() Catch Endtry *!* --- G2: nicio ruta din S8b aloca numere - snapshot DUPA, trebuie identic --- IF USED('v_plaje_s8b_b') USE IN v_plaje_s8b_b ENDIF lnSucces = goExecutor.oExecute([select id_plaja, urmval from vplaje_numere order by id_plaja], 'v_plaje_s8b_b') goExecutor.oReset() lcSnapPlajeB = CursorToSnapshot('v_plaje_s8b_b') USE IN v_plaje_s8b_b DO asserteaza WITH lcPrefix + ': vplaje_numere identic inainte/dupa (niciun numar alocat)', m.lcSnapPlajeA == m.lcSnapPlajeB, '' DO CASE CASE m.tnCaz = 1 *!* --- cazul 1: nimic schimbat - ruta 0, zero apeluri goExecutor intre deschidere si confirmare --- DO asserteaza WITH lcPrefix + ': ruta 0 - do_scrie_factura intoarce .T.', goDriverS8b.lRezultat, TRANSFORM(goDriverS8b.lRezultat) DO asserteaza WITH lcPrefix + ': ruta 0 - zero apeluri catre goExecutor (contor)', goDriverS8b.nContorExecutii == 0, TRANSFORM(goDriverS8b.nContorExecutii) CASE m.tnCaz = 2 *!* --- cazul 2: antet schimbat (text_aditional) - ruta 2, UPDATE VANZARI pe id-ul real --- DO asserteaza WITH lcPrefix + ': ruta 2 - do_scrie_factura intoarce .T.', goDriverS8b.lRezultat, TRANSFORM(goDriverS8b.lRezultat) DO asserteaza WITH lcPrefix + ': ruta 2 - cel putin un apel catre goExecutor', goDriverS8b.nContorExecutii >= 1, TRANSFORM(goDriverS8b.nContorExecutii) LOCAL lcTextAditionalNou, lnCountLiniiB IF USED('v_antet_s8b_b') USE IN v_antet_s8b_b ENDIF lnSucces = goExecutor.oExecute([select text_aditional from vanzari where id_vanzare = ] + TRANSFORM(m.tnIdVanzare), 'v_antet_s8b_b') goExecutor.oReset() lcTextAditionalNou = ALLTRIM(NVL(v_antet_s8b_b.text_aditional,'')) USE IN v_antet_s8b_b DO asserteaza WITH lcPrefix + ': VANZARI.TEXT_ADITIONAL = valoarea noua (UPDATE a atins randul real, nu sentinela)', ; m.lcTextAditionalNou == ALLTRIM(goDriverS8b.cValoareNoua), m.lcTextAditionalNou DO asserteaza WITH lcPrefix + ': VANZARI.TEXT_ADITIONAL s-a schimbat fata de vechea valoare', !(m.lcTextAditionalNou == m.lcTextAditionalVechi), m.lcTextAditionalVechi IF USED('v_linii_s8b_b') USE IN v_linii_s8b_b ENDIF lnSucces = goExecutor.oExecute([select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(m.tnIdVanzare) + [ and sters = 0], 'v_linii_s8b_b') goExecutor.oReset() lnCountLiniiB = NVL(v_linii_s8b_b.nr,-1) USE IN v_linii_s8b_b DO asserteaza WITH lcPrefix + ': VANZARI_DETALII neatins (ruta 2 nu scrie liniile)', m.lnCountLiniiA == m.lnCountLiniiB, TRANSFORM(m.lnCountLiniiB) CASE m.tnCaz = 3 *!* --- cazul 3: explicatie linie schimbata - ruta 3, VANZARI_DETALII.EXPLICATIE, VANZARI neatins --- DO asserteaza WITH lcPrefix + ': ruta 3 - do_scrie_factura intoarce .T.', goDriverS8b.lRezultat, TRANSFORM(goDriverS8b.lRezultat) DO asserteaza WITH lcPrefix + ': ruta 3 - cel putin un apel catre goExecutor', goDriverS8b.nContorExecutii >= 1, TRANSFORM(goDriverS8b.nContorExecutii) LOCAL lcExplicatieNoua, lcTextAditionalB3 IF USED('v_expl_s8b_b') USE IN v_expl_s8b_b ENDIF lnSucces = goExecutor.oExecute([select explicatie from vanzari_detalii where id_vanzare_det = ] + TRANSFORM(m.lnIdVanzareDetPrimaLinie), 'v_expl_s8b_b') goExecutor.oReset() DO asserteaza WITH lcPrefix + ': martor linie Oracle a reusit', lnSucces >= 0 AND USED('v_expl_s8b_b') AND RECCOUNT('v_expl_s8b_b') = 1, TRANSFORM(lnSucces) lcExplicatieNoua = ALLTRIM(NVL(v_expl_s8b_b.explicatie,'')) USE IN v_expl_s8b_b DO asserteaza WITH lcPrefix + ': VANZARI_DETALII.EXPLICATIE a fost scrisa pe linia atinsa', m.lcExplicatieNoua == ALLTRIM(goDriverS8b.cValoareNoua), m.lcExplicatieNoua DO asserteaza WITH lcPrefix + ': VANZARI_DETALII.EXPLICATIE s-a schimbat fata de vechea valoare', !(m.lcExplicatieNoua == m.lcExplicatieVeche), m.lcExplicatieVeche IF USED('v_antet_s8b_c') USE IN v_antet_s8b_c ENDIF lnSucces = goExecutor.oExecute([select text_aditional from vanzari where id_vanzare = ] + TRANSFORM(m.tnIdVanzare), 'v_antet_s8b_c') goExecutor.oReset() lcTextAditionalB3 = ALLTRIM(NVL(v_antet_s8b_c.text_aditional,'')) USE IN v_antet_s8b_c DO asserteaza WITH lcPrefix + ': VANZARI (antet) neatins (ruta 3 nu scrie antetul)', m.lcTextAditionalB3 == m.lcTextAditionalVechi, m.lcTextAditionalB3 CASE m.tnCaz = 4 *!* --- cazul 4: cantitate schimbata - ruta 1 (regenerare, implementata S9/S11/S14): sterge *!* documentul vechi (sters=1) si reemite unul nou pe acelasi (numar_act, serie_act) - *!* StergeDocumentFacturare + ForteazaIdFactReemitere, ofacturare_rutare_scriere.prg --- DO asserteaza WITH lcPrefix + ': ruta 1 - do_scrie_factura intoarce .T. (regenerare reusita)', goDriverS8b.lRezultat, TRANSFORM(goDriverS8b.lRezultat) DO asserteaza WITH lcPrefix + ': ruta 1 - cel putin un apel catre goExecutor (regenerare reala)', goDriverS8b.nContorExecutii >= 1, TRANSFORM(goDriverS8b.nContorExecutii) LOCAL lnCaz4IdNou, lnCantitateNoua lnCaz4IdNou = 0 IF USED('v_caz4_live_b') USE IN v_caz4_live_b ENDIF lnSucces = goExecutor.oExecute([select id_vanzare from vanzari where numar_act = 1 and serie_act = 'S8B' and tip = 5 and sters = 0], 'v_caz4_live_b') goExecutor.oReset() IF lnSucces >= 0 AND USED('v_caz4_live_b') AND RECCOUNT('v_caz4_live_b') = 1 lnCaz4IdNou = v_caz4_live_b.id_vanzare ENDIF USE IN v_caz4_live_b DO asserteaza WITH lcPrefix + ': ruta 1 - documentul vechi a fost inlocuit cu unul nou (acelasi numar_act/serie_act)', lnCaz4IdNou > 0 AND lnCaz4IdNou <> m.tnIdVanzare, TRANSFORM(lnCaz4IdNou) IF USED('v_vechi_s8b_b') USE IN v_vechi_s8b_b ENDIF lnSucces = goExecutor.oExecute([select sters from vanzari where id_vanzare = ] + TRANSFORM(m.tnIdVanzare), 'v_vechi_s8b_b') goExecutor.oReset() DO asserteaza WITH lcPrefix + ': ruta 1 - documentul vechi e marcat sters', lnSucces >= 0 AND USED('v_vechi_s8b_b') AND RECCOUNT('v_vechi_s8b_b') = 1 AND v_vechi_s8b_b.sters == 1, IIF(USED('v_vechi_s8b_b'), TRANSFORM(NVL(v_vechi_s8b_b.sters,-1)), 'lipsa') USE IN v_vechi_s8b_b IF lnCaz4IdNou > 0 IF USED('v_cant_s8b_b') USE IN v_cant_s8b_b ENDIF lnSucces = goExecutor.oExecute([select cantitate from vanzari_detalii where id_vanzare = ] + TRANSFORM(lnCaz4IdNou) + [ and sters = 0 order by id_vanzare_det], 'v_cant_s8b_b') goExecutor.oReset() lnCantitateNoua = NVL(v_cant_s8b_b.cantitate,-1) USE IN v_cant_s8b_b DO asserteaza WITH lcPrefix + ': ruta 1 - documentul nou preia cantitatea modificata (veche+1)', ROUND(m.lnCantitateNoua,4) == ROUND(m.lnCantitateVeche+1,4), TRANSFORM(m.lnCantitateNoua) ENDIF ENDCASE DO CurataAliasuriReziduale ENDPROC PROCEDURE CurataAliasuriReziduale LOCAL laAlias(1), lnI, lcA laAlias(1) = 'CRSGESTIUNI' DIMENSION laAlias(9) laAlias(2) = 'JTVA_COLOANE' laAlias(3) = 'JTVA_COLOANE_TEMP' laAlias(4) = 'SAFT_TAXTABLE' laAlias(5) = 'CRSCURSURI' laAlias(6) = 'CRSARTICOLE_DOC' laAlias(7) = 'CRSARTICOLE_EDITARE' laAlias(8) = 'V_ANTET_EDITARE' laAlias(9) = 'CRSFACTURA' FOR lnI = 1 TO ALEN(laAlias) lcA = laAlias(lnI) IF Used(m.lcA) Use In (m.lcA) ENDIF ENDFOR ENDPROC PROCEDURE CursorToSnapshot LPARAMETERS tcAlias LOCAL lcResult, lnI lcResult = '' SELECT (m.tcAlias) SCAN FOR lnI = 1 TO FCOUNT() lcResult = lcResult + Transform(Evaluate(Field(m.lnI))) + '|' ENDFOR lcResult = lcResult + Chr(10) ENDSCAN RETURN m.lcResult ENDPROC PROCEDURE asserteaza LPARAMETERS tcNume, tlConditie, tcValoare IF m.tlConditie gnPass = gnPass + 1 STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcErrLog, 1) ELSE gnFail = gnFail + 1 STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + Transform(m.tcValoare) + ')' + CHR(13) + CHR(10), gcErrLog, 1) ENDIF ENDPROC PROCEDURE test_error_handler LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1) ENDPROC *!* --- subclasa de contor pentru oexecutor: acelasi tipar ca facturare_unificat\mock_cursor_articole.prg *!* (oReal, nu DODEFAULT) - numara ORICE apel catre oExecute; oExecuta (mostenita, nesuprascrisa) *!* cheama intern This.oExecute, deci e numarata automat, fara suprascriere separata --- DEFINE CLASS oExecutorContorS8b AS oexecutor oReal = NULL PROCEDURE oExecute LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect LOCAL lnNr, lRetExec gnContorExecutiiS8b = gnContorExecutiiS8b + 1 lnNr = gnContorExecutiiS8b STRTOFILE('MARK oExecute #' + TRANSFORM(m.lnNr) + ': begin ' + LEFT(m.tcSql, 120) + CHR(13) + CHR(10), gcErrLog, 1) IF 'CITESTE_SETARI_DOCUMENT' $ UPPER(m.tcSql) LOCAL lnNivel, lcStack, lcProg lcStack = '' FOR lnNivel = 1 TO 20 lcProg = SYS(16, m.lnNivel) IF EMPTY(m.lcProg) EXIT ENDIF lcStack = lcStack + ' [' + TRANSFORM(m.lnNivel) + '] ' + m.lcProg + CHR(13) + CHR(10) ENDFOR STRTOFILE('MARK oExecute #' + TRANSFORM(m.lnNr) + ': STACK' + CHR(13) + CHR(10) + m.lcStack, gcErrLog, 1) ENDIF TRY lRetExec = This.oReal.oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect) STRTOFILE('MARK oExecute #' + TRANSFORM(m.lnNr) + ': dupa, rezultat=' + TRANSFORM(m.lRetExec) + CHR(13) + CHR(10), gcErrLog, 1) CATCH TO loExcOExecute STRTOFILE('MARK oExecute #' + TRANSFORM(m.lnNr) + ': EROARE ' + TRANSFORM(loExcOExecute.ErrorNo) + ' ' + loExcOExecute.Message + CHR(13) + CHR(10), gcErrLog, 1) THROW ENDTRY RETURN m.lRetExec ENDPROC ENDDEFINE DEFINE CLASS driverS8bRutare AS Custom lBusy = .F. lGasit = .F. nCaz = 0 lRezultat = .F. lRezultatCapturat = .F. nContorExecutii = -1 cEroare = '' cIdTempLinie = '' cValoareNoua = '' PROCEDURE Reseteaza This.lGasit = .F. This.lRezultat = .F. This.lRezultatCapturat = .F. This.nContorExecutii = -1 This.cEroare = '' This.cIdTempLinie = '' This.cValoareNoua = '' ENDPROC PROCEDURE Executa IF This.lBusy OR This.lGasit RETURN ENDIF This.lBusy = .T. TRY LOCAL lnI, loFrm2, loExecutorOriginal, loExecutorContor FOR lnI = 1 TO _SCREEN.FormCount IF Upper(_SCREEN.Forms(m.lnI).Class) == 'FRM_FACTURARE_ARTICOLE2' loFrm2 = _SCREEN.Forms(m.lnI) This.lGasit = .T. DO CASE CASE This.nCaz = 2 *!* antet schimbat - text_aditional, direct pe poDate (Private, viu pe stiva *!* do_editare_unificata -> Show() -> pompa de mesaje -> acest Timer) IF TYPE('poDate') == 'O' This.cValoareNoua = 'S8B TEST ANTET ' + TTOC(DATETIME()) poDate.text_aditional = This.cValoareNoua ELSE This.cEroare = 'poDate nevizibil din driver (caz 2)' ENDIF CASE This.nCaz = 3 IF USED('crsfactura') SELECT crsfactura GO TOP This.cIdTempLinie = TRANSFORM(id_temp) This.cValoareNoua = 'S8B TEST EXPL ' + TTOC(DATETIME()) REPLACE explicatie WITH This.cValoareNoua ELSE This.cEroare = 'crsfactura nedeschis (caz 3)' ENDIF CASE This.nCaz = 4 IF USED('crsfactura') SELECT crsfactura GO TOP This.cIdTempLinie = TRANSFORM(id_temp) REPLACE cantitate WITH cantitate + 1 ELSE This.cEroare = 'crsfactura nedeschis (caz 4)' ENDIF ENDCASE IF EMPTY(This.cEroare) gnContorExecutiiS8b = 0 loExecutorOriginal = goExecutor loExecutorContor = Createobject('oExecutorContorS8b') loExecutorContor.oReal = loExecutorOriginal goExecutor = loExecutorContor STRTOFILE('MARK caz ' + TRANSFORM(This.nCaz) + ': inainte de do_scrie_factura' + CHR(13) + CHR(10), gcErrLog, 1) TRY This.lRezultat = loFrm2.do_scrie_factura() This.lRezultatCapturat = .T. STRTOFILE('MARK caz ' + TRANSFORM(This.nCaz) + ': do_scrie_factura a intors ' + TRANSFORM(This.lRezultat) + CHR(13) + CHR(10), gcErrLog, 1) CATCH TO loExcInterior This.cEroare = 'do_scrie_factura: ' + TRANSFORM(loExcInterior.ErrorNo) + ' ' + loExcInterior.Message ENDTRY goExecutor = loExecutorOriginal This.nContorExecutii = gnContorExecutiiS8b ENDIF *!* Hide(), nu Release() direct din Timer - vezi comentariul de la inceputul fisierului Try loFrm2.Hide() Catch Endtry EXIT ENDIF ENDFOR CATCH TO loExcS8b This.cEroare = 'driver: ' + TRANSFORM(loExcS8b.ErrorNo) + ' ' + loExcS8b.Message STRTOFILE('DRIVER EROARE ' + TRANSFORM(loExcS8b.ErrorNo) + ' ' + loExcS8b.Message + CHR(13) + CHR(10), gcErrLog, 1) FINALLY This.lBusy = .F. ENDTRY ENDPROC ENDDEFINE *!* --- driverVerificareS8b: cauta 'verificare' (Ferestre/verificare.scx, deschis modal DIN *!* INTERIORUL do_scrie_factura la a doua regenerare a documentului caz 4) si apasa Terminare *!* (do_termin) - acelasi tipar validat de driverAlteDate8/tmrDrv8 din creeaza_documente_s8.prg *!* (timer separat, garda de tratare unica prin variabila globala, PEMSTATUS pe un control cunoscut *!* ca test suplimentar fata de simplul nume de clasa). Clasa runtime a formularului e '_FRMBASE' *!* (NU '_frmbase12' din verificare.sc2 - acela e numele sintetizat de FoxBin2Prg pentru textul *!* .sc2, diferit de .Class la rulare; confirmat empiric printr-un heartbeat de diagnostic, scos *!* dupa ce a facut treaba - vezi raportul) --- DEFINE CLASS driverVerificareS8b AS Custom cCaleUrmata = '' PROCEDURE Executa LOCAL lnI, loForm, llGasit llGasit = .F. FOR lnI = 1 TO _SCREEN.FormCount IF UPPER(_SCREEN.Forms(m.lnI).Class) == '_FRMBASE' AND PEMSTATUS(_SCREEN.Forms(m.lnI), 'but_TERMIN1', 5) loForm = _SCREEN.Forms(m.lnI) llGasit = .T. ENDIF ENDFOR IF glDlgTratatVerifS8b OR !llGasit RETURN ENDIF STRTOFILE('MARK driverVerificareS8b: verificare detectat, apas do_termin()' + CHR(13) + CHR(10), gcErrLog, 1) TRY *!* lhide=.T. -> do_termin() cheama Hide(), nu Release() (_frm_base.vc2:363-374) - acelasi *!* motiv ca la loFrm2.Hide() din driverS8bRutare: Release() direct dintr-un Timer nested *!* (acest driver ruleaza in timp ce goDriverS8b.Executa e inca pe stiva, sub do_scrie_factura) *!* a produs "Menu manager internal consistency error" (verificat empiric azi) loForm.lhide = .T. loForm.do_termin() glDlgTratatVerifS8b = .T. *!* Visible=.F. dupa do_termin() = inainte_de_do_termin() (verificare_note_contabile) a *!* trecut si Hide() chiar a rulat (gnButon=1, traseul de confirmare cerut). Visible=.T. = *!* validarea de business a RESPINS confirmarea inainte de gnButon/Hide() *!* (verificare.sc2:1112-1120) - pe datele reale de azi, mesajul e "simboluri analitice *!* necompletate pentru conturile 4111,704" pe documentul curent - o problema reala in *!* datele Oracle de test, nu in driver. FALLBACK: do_renunt() (gnButon=2, validare *!* neconditionata .T. la _frm_base.vc2:489-491) doar ca sa nu ramana testul agatat la *!* nesfarsit - caz4 va inregistra corect un FAIL pe asertiunile de "regenerare confirmata", *!* explicat, nu ascuns (vezi cCaleUrmata mai jos, citit din VerificaRutaEditare) This.cCaleUrmata = 'TERMIN' IF loForm.Visible STRTOFILE('MARK driverVerificareS8b: do_termin() respins de validare business - mesaj=[' + gcMockUltimMesaj + '] - fallback do_renunt()' + CHR(13) + CHR(10), gcErrLog, 1) TRY loForm.do_renunt() This.cCaleUrmata = 'RENUNT_FALLBACK' CATCH TO loExcVerifFallback STRTOFILE('MARK driverVerificareS8b: fallback do_renunt() CATCH ErrorNo=' + TRANSFORM(loExcVerifFallback.ErrorNo) + ' Message=' + loExcVerifFallback.Message + CHR(13) + CHR(10), gcErrLog, 1) This.cCaleUrmata = 'RENUNT_FALLBACK_ESUAT' ENDTRY ENDIF STRTOFILE('MARK driverVerificareS8b: dupa do_termin() Visible=' + TRANSFORM(loForm.Visible) + ' cale=' + This.cCaleUrmata + ' mesaj_mock=[' + gcMockUltimMesaj + ']' + CHR(13) + CHR(10), gcErrLog, 1) CATCH TO loExcVerifS8b STRTOFILE('MARK driverVerificareS8b: CATCH ErrorNo=' + TRANSFORM(loExcVerifS8b.ErrorNo) + ' Message=' + loExcVerifS8b.Message + CHR(13) + CHR(10), gcErrLog, 1) glDlgTratatVerifS8b = .T. ENDTRY ENDPROC ENDDEFINE