* creeaza_documente_s8.prg * S8 (punct #6, editare factura emisa) - creeaza in MARIUSM_AUTO cele 3 documente lipsa (aviz, * factura din aviz, factura din contract) prin fluxul REAL de emitere (Procedure factureaza, * COMUN\programe\ofacturare.prg:81-560), ca sa poata fi editate ulterior de matricea S8. * * Tehnica: reproduce fidel corpul lui factureaza() pentru fiecare tnTip, cu DOUA inlocuiri, ambele * DOAR de conducere UI (nu de scriere): * 1) dialogul modal de antet (frm_date_aviz / frm_date_factura) - inlocuit cu setare DIRECTA a * proprietatilor poDate (efect identic cu ce ar face operatorul in dialog), ca in precedentul * acceptat test_s5_al_doilea_intrare.prg / test_pret_cu_tva_nivel2.prg. Numarul documentului * (poDate.nract) vine din poGeneratorNumere.creeaza_cursor_serii()+aloca_numar() REAL - acelasi * apel pe care l-ar face controlul clb_serie_act din dialog (serii_numere.vc2:114-136) - nu e * inventat. * 2) al doilea modal inevitabil, frm_alte_date (ofacturare.vc2:14921-14935) - condus cu driverul * validat in test_pret_cu_tva_nivel2.prg (Timer pe _SCREEN + _SCREEN.Forms), care ii apeleaza * direct .do_termin() dupa ce poDate.id_delegat a fost presetat (evita dependenta de * cauta_date_ultima_factura din Init-ul formularului). * Al treilea modal, "Do Form verificare" (ofacturare.vc2:14404, in do_scrie_factura), e evitat prin * SET PATH cu stub_verificare INAINTEA COMUN\FERESTRE (COMUN\utile\Teste\achizitie_import\ * stub_verificare\verificare.sc2 - stub existent, versionat, folosit deja de suitele * achizitie_import\*; Init lui seteaza gnButon=1 si RETURN .F., deci formularul nu se arata deloc). * * Scrierea efectiva ramane 100% in codul de productie: do_adauga_tot() -> do_calculeaza_totaluri() * -> do_termin() -> inainte_de_do_termin() -> do_scrie_factura() -> PACK_FACTURARE (neatins). * * gnScadereStoc = 0 (ca in precedente): do_adauga_articol sare peste dialogul per-linie * frm_articol_factura, nu mai e nevoie de driver pentru el. * * STARE: niciun document nu a fost inca scris cu succes. Rularile s-au oprit in do_termin(), fara * linie de rezultat in log. Capcanele de mediu deja platite, de citit inainte de o reluare: * * 1) Plaja de serii. poGeneratorNumere.creeaza_cursor_serii(nIdTipDoc) + aloca_numar() sunt apeluri * REALE (pack_serii_numere), deci utilizatorul si sucursala din harness trebuie sa se potriveasca * unei plaje active. In MARIUSM_AUTO, pentru FACTURA (nIdTipDoc=5) exista o singura plaja activa * si doar gnIdUtil=8 cu gnIdSucursala=167 o prinde; cu -3 iese ORA-20000 "Nu exista plaje de * serii facturi". Pentru AVIZ (nIdTipDoc=6) merge si gnIdUtil=-3, plajele fiind pe * id_tipentitate=2, care ocoleste verificarea de entitate. Verificabil fara sa consumi numere: * pack_serii_numere.verifica_cursor_serii(5, 8, 167, :prez, :rc) e SELECT pur. * * 2) Alocarea consuma numere ireversibil, chiar daca documentul final nu se scrie: seria SSS/AVIZ a * sarit deja cel putin numerele 11 si 12 in incercari esuate. Nu le socoti pierdute de o rulare noua. * * 3) mock_amessagebox.prg trebuie incarcat ULTIMUL, nu primul (la nume duplicat castiga fisierul * deschis cel mai recent, cum scrie chiar in antetul lui). Aici e incarcat inaintea lui * OPROCEDURI_COMUNE.PRG, deci amessagebox-ul REAL castiga, iar ramura Otherwise a handler-ului de * erori Oracle (oproceduri_comune.prg, ~421-424) deschide un MessageBox nativ care agata procesul * fara sa scrie nimic in log - simptomul observat. Ipoteza netestata inca. * * 4) Cursul EUR lipseste in acest mediu pentru 08-10.08.2026 (ultimul rand CURS pentru id_valuta=2 e * 07.08.2026, fiecare rand valabil o singura zi). Pe calea AVIZ nu s-a declansat - cursor_preturi * a reusit cu Reccount=1. Ramane risc NECONFIRMAT pentru cursor_contract pe id_ctr=235, care are * expunere reala EUR; de verificat prin apel direct, nu prin deductie din alt cod. SET SAFETY OFF SET TALK OFF SET DELETED ON SET EXACT ON SET CENTURY ON SET DATE DMY SET DECIMALS TO 4 SET NULLDISPLAY TO '' CLOSE DATABASES PUBLIC gcLog gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\creeaza_documente_s8_log.txt" STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLog) ON ERROR DO S8Err WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() ON SHUTDOWN QUIT TRY LOCAL gcAppPath, lcPath gcAppPath = "D:\ROA\ROAFACTURARE\" SET DEFAULT TO (gcAppPath) *-- stub_verificare PRIMUL, ca sa castige rezolutia "Do Form verificare" fata de COMUN\FERESTRE lcPath = gcAppPath + 'COMUN\utile\Teste\achizitie_import\stub_verificare;' + ; gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ; gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ; gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ; gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ; gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + ; gcAppPath + 'COMUN\UTILE\CALENDAR;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ; gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ; gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EMAIL;' + ; gcAppPath + 'COMUN\UTILE\NFJSON;' + gcAppPath + 'COMUN\UTILE\NFXML;' + ; ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\] SET PATH TO &lcPath ADDITIVE DO S8Log WITH 'SET PATH OK' *----- CLASE (lista identica cu test_pret_cu_tva_nivel2.prg, deja dovedita) ----- SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE SET CLASSLIB TO registry ADDITIVE SET CLASSLIB TO cauta_alfa_forms ADDITIVE SET CLASSLIB TO ofacturare.vcx ADDITIVE SET CLASSLIB TO ofacturare_comun.vcx ADDITIVE SET CLASSLIB TO accessibility.vcx ADDITIVE SET CLASSLIB TO ocriterii.vcx ADDITIVE SET CLASSLIB TO ctl32_statusbar.vcx ADDITIVE SET CLASSLIB TO ctl32_common.vcx ADDITIVE SET CLASSLIB TO ctl32_structs.vcx ADDITIVE SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE SET CLASSLIB TO DECABAZA ADDITIVE SET CLASSLIB TO onomenclatoare ADDITIVE SET CLASSLIB TO onomenclatoare2 ADDITIVE SET CLASSLIB TO ofacturare_rapoarte ADDITIVE SET CLASSLIB TO orapoarte ADDITIVE SET CLASSLIB TO ferestre_oracle ADDITIVE SET CLASSLIB TO messagebox ADDITIVE SET CLASSLIB TO otoolbar ADDITIVE SET CLASSLIB TO onom_curs ADDITIVE SET CLASSLIB TO comun ADDITIVE SET CLASSLIB TO ferestre_cere_date ADDITIVE SET CLASSLIB TO baza ADDITIVE SET CLASSLIB TO caut ADDITIVE SET CLASSLIB TO ointroduceri ADDITIVE SET CLASSLIB TO serii_numere ADDITIVE SET CLASSLIB TO caut_ora ADDITIVE SET CLASSLIB TO wwdialogs.vcx ADDITIVE SET CLASSLIB TO _calendar.vcx ADDITIVE SET CLASSLIB TO locale ADDITIVE SET CLASSLIB TO overificari ADDITIVE SET CLASSLIB TO ocomenzi ADDITIVE DO S8Log WITH 'SET CLASSLIB OK' *----- PROCEDURI (mock amessagebox PRIMUL) ----- SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" SET PROCEDURE TO proceduri_comune ADDITIVE SET PROCEDURE TO quitapp ADDITIVE SET PROCEDURE TO init_program ADDITIVE SET PROCEDURE TO onomenclatoare.prg ADDITIVE SET PROCEDURE TO onomenclatoare2.prg ADDITIVE SET PROCEDURE TO oproceduri_rapoarte_fact.prg ADDITIVE SET PROCEDURE TO email.prg ADDITIVE SET PROCEDURE TO GENCURSOR.PRG ADDITIVE SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE SET PROCEDURE TO updateserver.PRG ADDITIVE SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE SET PROCEDURE TO ocautare ADDITIVE SET PROCEDURE TO odocumente ADDITIVE SET PROCEDURE TO osecurity ADDITIVE SET PROCEDURE TO acces_meniu ADDITIVE SET PROCEDURE TO wwxmlhttp.prg ADDITIVE SET PROCEDURE TO wwcodeupdate.prg ADDITIVE SET PROCEDURE TO ini.prg ADDITIVE SET PROCEDURE TO cauta_alfa.prg ADDITIVE SET PROCEDURE TO oHeader.prg ADDITIVE SET PROCEDURE TO oproceduri_curs.prg ADDITIVE SET PROCEDURE TO proceduri.prg ADDITIVE SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE SET PROCEDURE TO ofacturare.prg ADDITIVE SET PROCEDURE TO oserii_numere.prg ADDITIVE SET PROCEDURE TO wwutils.prg ADDITIVE SET PROCEDURE TO wwConfig.prg ADDITIVE SET PROCEDURE TO wwApi.prg ADDITIVE SET PROCEDURE TO oexport.prg ADDITIVE SET PROCEDURE TO validare.prg ADDITIVE SET PROCEDURE TO ofacturare_comun.prg ADDITIVE SET PROCEDURE TO ofacturare_stoc.prg ADDITIVE SET PROCEDURE TO pmenu.prg ADDITIVE SET PROCEDURE TO ointroduceri.prg ADDITIVE SET PROCEDURE TO ovariabile_globale.prg ADDITIVE SET PROCEDURE TO ooperatii_comune.prg ADDITIVE SET PROCEDURE TO oproceduri_util.prg ADDITIVE SET PROCEDURE TO filebringer.prg ADDITIVE SET PROCEDURE TO iniacces.prg ADDITIVE SET PROCEDURE TO oupdate.prg ADDITIVE SET PROCEDURE TO procese.prg ADDITIVE SET PROCEDURE TO version.prg ADDITIVE SET PROCEDURE TO wwhttp.prg ADDITIVE SET PROCEDURE TO xmlaccess.prg ADDITIVE SET PROCEDURE TO xmlparser.prg ADDITIVE SET PROCEDURE TO xdate.prg ADDITIVE SET PROCEDURE TO suma_in_vorbe.prg ADDITIVE SET PROCEDURE TO controllerecr ADDITIVE SET PROCEDURE TO regex.prg ADDITIVE DO S8Log WITH 'SET PROCEDURE OK' *----- Globale aplicatie ----- PUBLIC gnPc, gnPVal, gnPcant, gnPPretV, gnScadereStoc, gnMemProcDisc, gl406, gcAcces PUBLIC gnModTotFact, gnRF_FACTURARE_FARA_STOC, gnPPret, gnPPretVal PUBLIC gnFactSeturi, gnCoefKFact, gnListareAvizBonFiscal, gnid_part_casa gnPc = 2 gnPVal = 2 gnPcant = 3 gnPPretV = 4 gnPPret = 4 gnPPretVal = 4 gnScadereStoc = 0 && bypass complet dialogul per-linie (do_adauga_articol) gnMemProcDisc = 0 gl406 = .F. gcAcces = "1;2;3;4;5;6;7;8;" gnModTotFact = 0 gnRF_FACTURARE_FARA_STOC = 0 gnFactSeturi = 0 && nu se factureaza in seturi (nu e cazul S8) gnCoefKFact = 2 && poDate.tip<>48, ramura inactiva - valoare neutra gnListareAvizBonFiscal = 0 gnid_part_casa = 0 && frm_alte_date.Init (ferestre_cere_date.vc2:3165) - fara partener CASA LEI implicit in headless PUBLIC nror(65000) PUBLIC buton, gnButon, pnButon buton = 1 gnButon = 1 pnButon = 1 *----- Conectare Oracle REALA, context ROAFACTURARE (nu ROACONT) ----- PUBLIC gnHandle, goExecutor, goConn, gcS, gcFirma, gcUserName, gnAn, gnLuna, gnIdUtil, ; gnIdFirma, gnIdSucursala, gcNumeProgram, gcAppName, glLunaInchisa, glEMama, goCalendar, goFirma gcNumeProgram = [ROAFACTURARE] gcAppName = [ROAFACTURARE] *-- gnIdUtil=-3 e conventia din restul harnesselor de test (marcaj sintetic in id_util/id_utils), *-- dar SERII_TIPDOC.ID_TIPDOC=5 (FACTURA) are PLAJE_NUMERE scoping per UTILIZATOR *-- (ID_TIPENTITATE=3), fara nicio plaja activa pentru user -3 - verificat prin sqlplus pe *-- MARIUSM_AUTO: PLAJE_NUMERE unde id_tipdoc=5 si id_tipentitate=3 are doar id_entitate in *-- (8,3779,75852,75904,75921); userul 8 are 2 plaje active (id_plaja=10 si 48), fara restrictie *-- de sucursala (id_sucursala NULL) - singurul care acopera atat FACTURA DIN AVIZ cat si FACTURA *-- DIN CONTRACT. AVIZ (tnTip=22) nu e afectat, plaja lui e globala (id_tipentitate=2, *-- id_entitate=0), nu per-utilizator. Insa acelasi gnIdUtil e folosit si de cursor_avize/ *-- cursor_contract/cursor_preturi (vizibilitate documente sursa) - user 8 nu vede AVIZ 1051 nici *-- CONTRACT 235 (create/asociate userului -3), deci gnIdUtil ramane -3 aici (convenția din restul *-- harnesselor, marcaj sintetic in id_util/id_utils) si e comutat LOCAL, doar in jurul apelurilor *-- de alocare numar/serie, in CreeazaDocument (vezi comutarea gnIdUtil=8/-3 mai jos). gnIdUtil = -3 gnIdFirma = 110 gnAn = YEAR(DATE()) gnLuna = MONTH(DATE()) glLunaInchisa = .F. glEMama = .F. gcS = 'MARIUSM_AUTO' gcFirma = gcS gcUserName = gcS goExecutor = CREATEOBJECT('oExecutor') goConn = CREATEOBJECT('oConn') gnHandle = 0 goConn.Connect('CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT') IF gnHandle <= 0 DO S8Log WITH 'EROARE: conectare Oracle esuata' QUIT ENDIF DO S8Log WITH 'Oracle conectat, gnHandle=' + TRANSFORM(gnHandle) LOCAL llSucces goFirma = NULL llSucces = goExecutor.oExecuta("select * from syn_v_nom_firme where schema = ?gcS", "cFirma") IF llSucces SELECT cFirma gnIdFirma = id_firma gnIdSucursala = NULL SCATTER NAME goFirma ENDIF IF USED('cFirma') USE IN cFirma ENDIF goCalendar = NULL llSucces = goExecutor.oExecuta('SELECT anul, luna, tva_incasare FROM calendar WHERE an*12+luna = (select MAX(an*12+luna) FROM calendar)', 'cCalendar') IF llSucces SELECT cCalendar GO TOP gnAn = anul gnLuna = luna SCATTER NAME goCalendar ENDIF IF USED('cCalendar') USE IN cCalendar ENDIF DO S8Log WITH 'gnAn/gnLuna=' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna) CREATE CURSOR dual (dummy c(10)) INSERT INTO dual (dummy) VALUES ("") *-- gcSettingsFile/goApi: cerute de get_ora() (oproceduri_comune.prg) - reproduse din *-- test_init_env_auto.prg:209-230, altfel oDateFactura.Init -> get_ora() cade cu variabila lipsa PUBLIC gcAppPath2, DIRGEN, gcBasePath, gcTempPath, gcGeneralIniFile, gcSettingsFile DIRGEN = [D:\ROA\] gcBasePath = DIRGEN gcGeneralIniFile = DIRGEN + "settings.ini" gcSettingsFile = gcGeneralIniFile IF TYPE('goApi') = 'U' PUBLIC goApi goApi = NEWOBJECT("wwAPI", "wwAPI.prg") ENDIF gcTempPath = ADDBS(SHORTPATH(goApi.GetTempPath())) + gcS + [\] IF !DIRECTORY(gcTempPath) MD (gcTempPath) ENDIF LOCAL lcSql lcSql = [begin pack_sesiune.set_Id_Util(?gnIdUtil); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_sesiune.setluna(?gnLuna); pack_sesiune.setan(?gnAn); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_sesiune.setlunabal(?gnLuna); pack_sesiune.setanbal(?gnAn); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_contafin.SET_DATA_RON(?gcS); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_sesiune.set_data_ron(?gcS); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;] goExecutor.oExecuta(lcSql) lcSql = [begin pack_contafin.set_id_firma(?gnIdFirma); end;] goExecutor.oExecuta(lcSql) DO S8Log WITH 'sesiune Oracle initializata' PUBLIC goApp, goExport goApp = CREATEOBJECT('dummyapp') goExport = CREATEOBJECT('dummyexport') *----- driver: conduce frm_alte_date (singurul modal ramas dupa stub_verificare) ----- PUBLIC goDriver8, glDlgTratat8 glDlgTratat8 = .F. goDriver8 = CREATEOBJECT('driverAlteDate8') _SCREEN.AddObject('tmrDrv8', 'Timer') _SCREEN.tmrDrv8.Interval = 200 BINDEVENT(_SCREEN.tmrDrv8, 'Timer', goDriver8, 'Executa') _SCREEN.tmrDrv8.Enabled = .T. _SCREEN.Visible = .T. _SCREEN.WindowState = 2 _SCREEN.Caption = 'S8 - creare documente (AVIZ / FACTURA DIN AVIZ / FACTURA DIN CONTRACT)' DO S8Log WITH 'driver+timer pregatiti' *====================================================================== * PASUL 1: AVIZ (tnTip=22) din lista de preturi, client RAJA (id_part=463) *====================================================================== LOCAL lnIdVanzareAviz, lnIdVanzareFactAviz, lnIdVanzareFactContract lnIdVanzareAviz = 0 lnIdVanzareFactAviz = 0 lnIdVanzareFactContract = 0 *-- AVIZ id_vanzare=1051 creat cu succes intr-o rulare anterioara (log 10/08/2026 12:01:58, *-- verificat in Oracle: tip=22, id_part=463, numar_act=13, serie_act=SSS, sters=0, id_fact=8009676, *-- 1 rand in VANZARI_DETALII, nefolosit inca de nicio factura) - reutilizat ca sa nu se creeze *-- un AVIZ orfan suplimentar la fiecare rerulare a PAS 2/3. LOCAL llReutilizeazaAviz1051 *-- 1051 are cantitate=0 pe unicul rand (VANZARI_DETALII, articol negestionabil - do_adauga_tot nu *-- a filtrat cantitate=0) - inutil ca sursa pentru FACTURA DIN AVIZ (cursor_avize il exclude). *-- Creeaza un AVIZ NOU, cu fix-ul de cantitate=1 aplicat mai jos (REPLACE ALL cantitate WITH 1). llReutilizeazaAviz1051 = .F. IF llReutilizeazaAviz1051 lnIdVanzareAviz = 1051 DO S8Log WITH CHR(13)+CHR(10) + '===== PAS 1: AVIZ SARIT, reutilizat id_vanzare=1051 (creat intr-o rulare anterioara) =====' ELSE DO S8Log WITH CHR(13)+CHR(10) + '===== PAS 1: AVIZ (tip=22) =====' lnIdVanzareAviz = CreeazaDocument(22, 463, '', 256) DO S8Log WITH 'PAS 1 rezultat: id_vanzare=' + TRANSFORM(lnIdVanzareAviz) ENDIF IF lnIdVanzareAviz > 0 DO S8Log WITH CHR(13)+CHR(10) + '===== PAS 2: FACTURA DIN AVIZ (tip=4), sursa id_vanzare=' + TRANSFORM(lnIdVanzareAviz) + ' =====' lnIdVanzareFactAviz = CreeazaDocument(4, 463, TRANSFORM(lnIdVanzareAviz), 256) DO S8Log WITH 'PAS 2 rezultat: id_vanzare=' + TRANSFORM(lnIdVanzareFactAviz) ELSE DO S8Log WITH 'PAS 2 SARIT: avizul de la pasul 1 nu s-a creat' ENDIF *-- FACTURA DIN CONTRACT id_vanzare=1057 creata cu succes intr-o rulare anterioara (log *-- 10/08/2026 12:28:34) - verificat in Oracle: tip=2, id_part=598, numar_act=14, serie_act=SSS, *-- sters=0, id_fact=8009682, 1 rand in VANZARI_DETALII - reutilizata ca sa nu se creeze un *-- duplicat la fiecare rerulare de debug pt. PAS 2. LOCAL llReutilizeazaFactContract1057 llReutilizeazaFactContract1057 = .T. IF llReutilizeazaFactContract1057 lnIdVanzareFactContract = 1057 DO S8Log WITH CHR(13)+CHR(10) + '===== PAS 3: SARIT, reutilizat id_vanzare=1057 (creat intr-o rulare anterioara) =====' ELSE DO S8Log WITH CHR(13)+CHR(10) + '===== PAS 3: FACTURA DIN CONTRACT (tip=2), id_ctr=235 =====' lnIdVanzareFactContract = CreeazaDocument(2, 598, '235', 256) DO S8Log WITH 'PAS 3 rezultat: id_vanzare=' + TRANSFORM(lnIdVanzareFactContract) ENDIF DO S8Log WITH CHR(13)+CHR(10) + '========== REZUMAT ==========' DO S8Log WITH 'AVIZ (tip=22): id_vanzare=' + TRANSFORM(lnIdVanzareAviz) DO S8Log WITH 'FACTURA DIN AVIZ (tip=4): id_vanzare=' + TRANSFORM(lnIdVanzareFactAviz) DO S8Log WITH 'FACTURA DIN CONTRACT (tip=2): id_vanzare=' + TRANSFORM(lnIdVanzareFactContract) _SCREEN.tmrDrv8.Enabled = .F. DO S8Log WITH 'done ' + TTOC(DATETIME()) CATCH TO loExc DO S8Log WITH 'CATCH TOP-LEVEL ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']' ENDTRY QUIT *================================================================================== PROCEDURE S8Log LPARAMETERS tcMsg LOCAL lcL lcL = IIF(FILE(gcLog), FILETOSTR(gcLog), '') STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcLog) ENDPROC PROCEDURE S8Err LPARAMETERS tnErr, tcMsg, tcProg, tnLine DO S8Log WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg ENDPROC *================================================================================== * CreeazaDocument: reproduce corpul lui Procedure factureaza (ofacturare.prg:81-560) pentru UN * singur tnTip, o singura trecere (fara bucla "continuati?" si fara listare). Intoarce * poDate.nid_vanzare (>0 succes) sau 0 (esec, detaliat in log). FUNCTION CreeazaDocument LPARAMETERS tnTip, tnIdClient, tcListaId, tnIdDelegat PRIVATE poDate, poGeneratorNumere, poDateGestiuneDest, pnTotalDiscountAvize LOCAL lnIdSet, lcSqlCursor, lcCursor, lnSucces, lnIdVanzareRezultat lnIdVanzareRezultat = 0 pnTotalDiscountAvize = 0 update_jtva_coloane([JV], [jtva_coloane_temp]) update_saft_taxtable() lnIdSet = 25000 + tnTip - 1 + gnScadereStoc * 10 poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip) poGeneratorNumere = CREATEOBJECT("oGeneratorNumere") poDateGestiuneDest = CREATEOBJECT("oDateGestiune") DO CASE CASE tnTip < 21 OR INLIST(tnTip, 45, 48, 49, 51, 52) poDate.nIdTipDoc = 5 && FACTURA OTHERWISE poDate.nIdTipDoc = 6 && AVIZ ENDCASE *-- comutare LOCALA gnIdUtil=8 (user cu plaja FACTURA activa) doar pt. alocarea numar/serie - *-- cursor_avize/cursor_contract/cursor_preturi de mai jos au nevoie de gnIdUtil=-3 (vizibilitate *-- AVIZ 1051 / CONTRACT 235, create/asociate userului -3) - vezi comentariul de la initializare. gnIdUtil = 8 poGeneratorNumere.ResetNumere() poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc) DO S8Log WITH ' poDate.nIdTipDoc=' + TRANSFORM(poDate.nIdTipDoc) + ' rezultat_serii=' + TRANSFORM(poDate.rezultat_serii) + ' id_fdoc=' + TRANSFORM(NVL(poDate.id_fdoc,-1)) + ' dataact=' + TRANSFORM(poDate.dataact) + ' datascad=' + TRANSFORM(NVL(poDate.datascad,{})) *-- INLOCUIRE 1: setare directa poDate (echivalent cu ce ar completa operatorul in *-- frm_date_aviz/frm_date_factura), NU prin INSERT. Numarul vine din generatorul real. poDate.id_client = tnIdClient IF !EMPTY(tcListaId) poDate.listaid = tcListaId ENDIF poDate.id_delegat = tnIdDelegat *-- zi_curs: Init() il seteaza = dataact (azi, 10.08.2026), dar in MARIUSM_AUTO nu exista inca *-- curs EUR pentru azi (verificat prin sqlplus) - cursor_preturi/cursor_contract cad pe orice *-- articol/rata in EUR din lista/contract cu eroarea Oracle 20005 "Nu este setat cursul...". *-- Productia trateaza asta cu un dialog editabil (vizualizeaza_curs); headless, folosim ultima *-- zi cu curs EUR real existent in schema (07.08.2026, tot in luna curenta) - camp distinct de *-- dataact/dataireg, nu schimba data documentului. poDate.zi_curs = {^2026-08-07} *-- do_initializeaza din clb_serie_act (serii_numere.vc2:90-109) cheama getSerieCursor() DOAR pe *-- ramura OTHERWISE (rezultat_serii=3, cu serie SI plaja) - pe rezultat_serii=1 (cu serie, fara *-- plaja) serie_act ramane necompletat, de tastat manual de operator (text_simplu1 legat direct *-- pe pcobj.cvariabila). getSerieCursor() nu are garda IsNull() ca aloca_numar() - apelat cand *-- paPlaje(tip,2) e NULL (cazul rezultat=1 din ramura de esec verifica_cursor_serii/verifica_tipdoc) *-- da eroare Oracle reala "Table number is invalid" (Reccount(NULL)). IF poDate.rezultat_serii = 3 poDate.serie_act = poGeneratorNumere.getSerieCursor(poDate.nIdTipDoc) ENDIF poDate.nract = poGeneratorNumere.aloca_numar(poDate.nIdTipDoc, NULL) poGeneratorNumere.verifica_numar(poDate.nIdTipDoc, poDate.nract) gnIdUtil = -3 DO S8Log WITH ' numar alocat: serie_act=[' + TRANSFORM(NVL(poDate.serie_act,[])) + '] nract=' + TRANSFORM(poDate.nract) IF poDate.tva_incasare = 0 SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane ELSE SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane ENDIF *-- cursorul sursa de articole, dupa tnTip (identic cu Do Case din factureaza()) DO CASE CASE tnTip = 2 poDate.id_agent = 0 lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_contract(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ; [?poDate.listaid,?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala,?@poDate.id_agent,?@poDate.nume_agent)}] CASE tnTip = 4 lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_avize(?poDate.listaid,?gnIdUtil,?@pnTotalDiscountAvize)}] OTHERWISE && tnTip = 22 (lista de preturi) lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_preturi(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ; [?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala)}] ENDCASE lcCursor = [crsarticole] lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor) IF lnSucces < 0 DO S8Log WITH ' EROARE cursor articole: ' + goExecutor.oPrelucrareEroare() poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) DO S8CurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF IF RECCOUNT(lcCursor) = 0 AND (!USED(lcCursor+'1') OR (USED(lcCursor+'1') AND RECCOUNT(lcCursor+'1') = 0)) DO S8Log WITH ' Nu exista articole pentru optiunile alese (Reccount=0) - abandon document' poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) IF USED('crsCtrTemp') USE IN crsCtrTemp ENDIF DO S8CurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF DO S8Log WITH ' crsarticole Reccount=' + TRANSFORM(RECCOUNT(lcCursor)) *-- cursor_preturi (lista de preturi, tnTip=22) nu are cantitate implicita - in dialogul real *-- operatorul o tasteaza in grid inainte de "adauga tot". do_adauga_tot (ofacturare.vc2:13181) *-- sare peste articolele gestionabile cu cantitate=0, dar articolul nostru nu e gestionabil, deci *-- s-a adaugat cu cantitate=0 (verificat in Oracle: VANZARI_DETALII.CANTITATE=0 pt. AVIZ 1051) - *-- inutil ca sursa pentru FACTURA DIN AVIZ (cursor_avize exclude liniile cu cantitate ramasa 0). IF tnTip = 22 *-- crsarticole vine cu Buffering optimistic pe rand (3) - REPLACE fara TABLEUPDATE() ramane *-- in bufferul local si e pierdut la urmatoarea citire/mutare de recno (verificat empiric: *-- REPLACE arata cantitate=1 imediat, dar orice citire ulterioara arata iar 0). SELECT (lcCursor) REPLACE ALL cantitate WITH 1 =TABLEUPDATE(.T., .T., lcCursor) GO TOP DO S8Log WITH ' dupa fix cantitate: ' + lcCursor + '.cantitate=' + TRANSFORM(cantitate) ENDIF creeaza_facturacrs([crsfactura]) IF poDate.in_valuta = 1 SELECT DISTINCT Curs, nume_val, id_valuta, multiplicator FROM (lcCursor) WITH (Buffering = .T.) WHERE tip_valuta = 1 ORDER BY nume_val INTO CURSOR crscursuri SELECT crscursuri poDate.Curs = Curs poDate.multiplicator = multiplicator ELSE citeste_cursuri_zi(poDate.zi_curs) IF RECCOUNT('crscursuri') = 0 USE IN crscursuri ENDIF ENDIF IF TYPE(lcCursor + '.nume_lista_preturi') <> 'U' CREATE CURSOR crspolitici (id_pol N(20), nume_lista_preturi c(100)) SELECT crspolitici INSERT INTO crspolitici(id_pol, nume_lista_preturi) VALUES (-9999, '') INSERT INTO crspolitici(id_pol, nume_lista_preturi) ; SELECT DISTINCT id_pol, nume_lista_preturi FROM (lcCursor) ORDER BY nume_lista_preturi ENDIF IF INLIST(tnTip, 2, 6, 26) CREATE CURSOR crscontracte(id_ctr N(20), numar_contract c(100), Data d NULL, numar c(50) NULL) SELECT crscontracte APPEND BLANK REPLACE id_ctr WITH -9999, numar_contract WITH '' IF USED(lcCursor + '1') INSERT INTO crscontracte(id_ctr, numar_contract, Data, numar) ; SELECT DISTINCT id_ctr, numar_contract, Data, numar FROM (lcCursor + [1]) ORDER BY Data, numar ENDIF ENDIF *-- INLOCUIRE 2: frm_facturare_articole modeless (apel direct de metode, ca in *-- test_pret_cu_tva_nivel2.prg:266-272), NU .Show() modal PUBLIC goFrm8 goFrm8 = CREATEOBJECT('frm_facturare_articole') goFrm8.WindowType = 0 goFrm8.Show() DOEVENTS FORCE DO S8Log WITH ' frm_facturare_articole afisat modeless' goFrm8.do_adauga_tot() DOEVENTS FORCE DO S8Log WITH ' do_adauga_tot() -> Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) goFrm8.do_calculeaza_totaluri() DOEVENTS FORCE glDlgTratat8 = .F. LOCAL lnScris lnScris = goFrm8.do_termin() LOCAL lnWait lnWait = 0 DO WHILE !glDlgTratat8 AND lnWait < 10 DOEVENTS FORCE lnWait = lnWait + 1 ENDDO DO S8Log WITH ' do_termin() -> ' + TRANSFORM(lnScris) + ' (frm_alte_date tratat=' + TRANSFORM(glDlgTratat8) + ') poDate.nid_vanzare=' + TRANSFORM(NVL(poDate.nid_vanzare,0)) IF lnScris lnIdVanzareRezultat = NVL(poDate.nid_vanzare, 0) ELSE lnIdVanzareRezultat = 0 ENDIF IF TYPE('goFrm8') = 'O' AND !ISNULL(goFrm8) goFrm8.Release() ENDIF goFrm8 = NULL IF USED('crspolitici') USE IN crspolitici ENDIF IF USED('crscursuri') USE IN crscursuri ENDIF IF USED('crscontracte') USE IN crscontracte ENDIF IF USED('crsCtrTemp') USE IN crsCtrTemp ENDIF IF USED('crsfactura') USE IN crsfactura ENDIF IF USED('crsfacturaset') USE IN crsfacturaset ENDIF IF USED('crsfacturafinala') USE IN crsfacturafinala ENDIF IF USED('crsarticole') USE IN crsarticole ENDIF IF USED('crsarticole1') USE IN crsarticole1 ENDIF IF USED('jtva_coloane') USE IN jtva_coloane ENDIF IF USED('jtva_coloane_temp') USE IN jtva_coloane_temp ENDIF RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN lnIdVanzareRezultat ENDFUNC PROCEDURE S8CurataJtva IF USED('jtva_coloane') USE IN jtva_coloane ENDIF IF USED('jtva_coloane_temp') USE IN jtva_coloane_temp ENDIF ENDPROC *================================================================================== DEFINE CLASS dummyapp AS Custom PROCEDURE ReadIni LPARAMETERS tcSection, tcKey RETURN '' ENDPROC PROCEDURE WriteIni LPARAMETERS tcSection, tcKey, tcValue RETURN .T. ENDPROC ENDDEFINE DEFINE CLASS dummyexport AS Custom PROCEDURE citesteSetareRegistru LPARAMETERS tcCheie RETURN '' ENDPROC ENDDEFINE *-- driverAlteDate8: cauta FRM_ALTE_DATE prin _SCREEN.Forms (mecanism validat, driverdeblocare3 din *-- test_pret_cu_tva_nivel2.prg) si ii apeleaza .do_termin() direct - poDate.id_delegat si *-- poDate.dataora_exp sunt deja setate inainte sa ajunga aici (id_delegat de CreeazaDocument, *-- dataora_exp de frm_facturare_articole.inainte_de_do_termin, ofacturare.vc2:14921, cod neatins) DEFINE CLASS driverAlteDate8 AS Custom PROCEDURE Executa LOCAL lnI, loForm, llGasit llGasit = .F. FOR lnI = 1 TO _SCREEN.FormCount IF UPPER(_SCREEN.Forms(lnI).Class) == 'FRM_ALTE_DATE' loForm = _SCREEN.Forms(lnI) llGasit = .T. ENDIF ENDFOR IF glDlgTratat8 OR !llGasit RETURN ENDIF DO S8Log WITH ' driverAlteDate8: FRM_ALTE_DATE detectat, apas do_termin()' *-- FIX crash dur: citirea lui loForm.ActiveControl AICI, separat, inainte de do_termin(), *-- evita access-violation-ul din inainte_de_do_termin (ferestre_cere_date.vc2:3058, *-- Upper(This.ActiveControl.BaseClass) necondiționat) - confirmat empiric ca elimina crash-ul *-- (fara aceasta atingere prealabila, do_termin() nu mai revine deloc, fara nicio linie de *-- CATCH ulterioara in log). ActiveControl a iesit valid (TEXTBOX/Text_simplu1) chiar si fara *-- SetFocus explicit - simpla accesare a proprietatii inainte de apelul real pare sa *-- sincronizeze starea COM/OLE a formularului aflat inca in Show(1) modal, apelat din Timer. LOCAL loAC loAC = loForm.ActiveControl DO S8Log WITH ' driverAlteDate8: ActiveControl VARTYPE=' + VARTYPE(loAC) + ; IIF(VARTYPE(loAC)='O', ' BaseClass=' + UPPER(loAC.BaseClass) + ' Name=' + loAC.Name, '') TRY loForm.do_termin() glDlgTratat8 = .T. CATCH TO loExcDrv DO S8Log WITH ' driverAlteDate8: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo) glDlgTratat8 = .T. ENDTRY ENDPROC ENDDEFINE