* emite_document_stoc_s93.prg * Reumple rezervorul lui test_s9_3_stergere.prg (candidat eligibil: STERS=0, in luna activa, * fara referinte/urmasi, cu randuri REALE in vact_tot SI vrul_tot). Emite UN document REAL * in MARIUSM_AUTO@ROA_CENTRAL prin fluxul de productie (docs\raport_datoria4_stergere.md). * * Baza: COMUN\utile\Teste\facturare_unificat\test_s3b_emitere_reala.prg (tnTip=22, AVIZ din lista * de preturi, client RAJA id_part=463, forma veche frm_facturare_articole, tip_incasare=1) - * singura combinatie confirmata ca scrie in VANZARI in acest mediu. DOUA modificari fata de acel * fisier, ambele necesare ca sa apara randuri in RUL (nu doar in ACT): * * 1) NU se mai reseteaza gnIdUtil la -3 inainte de cursor_preturi (acolo ramane doar pentru * alocarea numarului). Cu gnIdUtil=8 lista de preturi FACT_VPRETURI_UTILIZATOR intoarce * articole GESTIONABILE cu stoc real (verificat read-only); cu -3 intoarce un singur articol * negestionabil, cantitate 0 - de-asta suita S3b/creeaza_documente_s8 nu producea niciodata * randuri vrul_tot (docs\raport_s13b_fixturi.md ยง6.1). * 2) V_FILTRU_COD = '11.00003' (id_articol=315554536, ACOPERIRE FAR VOLVO FH12) restrange * cursor_preturi la UN singur articol gestionabil cu stoc mare (>11000 bucati la data * scrierii acestui fisier), ca sa nu intre in document toata lista de preturi a utilizatorului 8. * * Rulare: vfp9.exe -A -T "D:\ROA\...\emite_document_stoc_s93.prg" (headless, cateva secunde) * Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\out\emite_document_stoc_s93.log * Rezultat: STRTOFILE cu 'id_vanzare=' la succes, sau 'ESEC' - vezi raportul pentru numerele arse. 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, gnPass, gnFail IF !DIRECTORY("D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\out") MD "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\out" ENDIF gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\out\emite_document_stoc_s93.log" STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLog) gnPass = 0 gnFail = 0 ON ERROR DO EmiteErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() ON SHUTDOWN QUIT TRY SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\achizitie_import\stub_verificare" 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 EmiteLog WITH 'EROARE: conectare Oracle esuata' DO EmiteFinal ENDIF DO EmiteLog WITH 'test_init_env_auto_roafacturare OK, gnHandle=' + TRANSFORM(gnHandle) SQLSETPROP(gnHandle, "QueryTimeOut", 45) SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras" ADDITIVE SET CLASSLIB TO gridextras.vcx ADDITIVE SET CLASSLIB TO _cb_base.vcx ADDITIVE SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\lib_comparatie_documente.prg" ADDITIVE IF !actualizeaza_optiuni_program() DO EmiteLog WITH 'EROARE: actualizeaza_optiuni_program()' DO EmiteFinal ENDIF *-- gnScadereStoc=1 (nu 0, spre deosebire de test_s3b_emitere_reala.prg): cu 0, do_adauga_articol *-- ocoleste mereu do_alege_stoc (ofacturare.vc2:13021), deci ID_GESTIUNE ramane null pe linie si *-- nu apare niciun rand in vrul_tot, indiferent de cantitate/stoc. Cu 1 si UN singur candidat de *-- gestiune (Reccount(crsgestarticol)=1) + tlImplicit=.T., do_alege_stoc(ofacturare.vc2:13478) *-- alege automat gestiunea, FARA sa arate modalul (frm_articol_gest_factura.inainte_de_do_termin *-- se autoconfirma cand nu exista nicio eroare de validare). gnScadereStoc = 1 gnModTotFact = 0 gnFactSeturi = 0 gnListareAvizBonFiscal = 0 gnid_part_casa = 0 gnIdSucursala = 167 goExecutor.oExecuta([begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;]) DO EmiteLog WITH 'optiuni OK gnScadereStoc=' + TRANSFORM(gnScadereStoc) + ' gnIdSucursala=' + TRANSFORM(gnIdSucursala) PUBLIC goDriverAD, glDlgTratatAD, gnTipIncasareCerut, gnNrIncasareCapturat, gcClaseVazute glDlgTratatAD = .F. gnTipIncasareCerut = 1 gnNrIncasareCapturat = 0 gcClaseVazute = ';' goDriverAD = CREATEOBJECT('driverAlteDateEmite') _SCREEN.AddObject('tmrDrvEmite', 'Timer') _SCREEN.tmrDrvEmite.Interval = 200 BINDEVENT(_SCREEN.tmrDrvEmite, 'Timer', goDriverAD, 'Executa') _SCREEN.tmrDrvEmite.Enabled = .T. *-- driverGestArticol: acelasi timer, un al doilea BINDEVENT - conduce modalul per-linie *-- FRM_ARTICOL_GEST_FACTURA (do_alege_stoc, ofacturare.vc2:13518/13526/13540) PUBLIC goDriverGest, glDlgTratatGest, goUltimulFormGest glDlgTratatGest = .F. goUltimulFormGest = .NULL. goDriverGest = CREATEOBJECT('driverGestArticol') BINDEVENT(_SCREEN.tmrDrvEmite, 'Timer', goDriverGest, 'Executa') _SCREEN.Caption = 'emite_document_stoc_s93 - reumplere pool S9-3' LOCAL lnIdVz lnIdVz = CreeazaDocumentStoc() _SCREEN.tmrDrvEmite.Enabled = .F. DO Assert WITH lnIdVz > 0, 'documentul exista in VANZARI (jonctiune serie_act+nract), e=' + TRANSFORM(lnIdVz) IF lnIdVz > 0 DO EmiteLog WITH 'id_vanzare=' + TRANSFORM(lnIdVz) ELSE DO EmiteLog WITH 'ESEC' ENDIF DO EmiteFinal CATCH TO loExc DO EmiteLog WITH 'CATCH TOP-LEVEL ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']' DO EmiteFinal ENDTRY QUIT *================================================================================== PROCEDURE EmiteLog LPARAMETERS tcMsg STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLog, 1) ENDPROC PROCEDURE EmiteErr LPARAMETERS tnErr, tcMsg, tcProg, tnLine DO EmiteLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg ENDPROC PROCEDURE EmiteFinal DO EmiteLog WITH CHR(13)+CHR(10) + 'TOTAL pass=' + TRANSFORM(gnPass) + ' fail=' + TRANSFORM(gnFail) DO EmiteLog WITH 'END ' + TTOC(DATETIME()) QUIT ENDPROC PROCEDURE Assert LPARAMETERS tlCond, tcMsg IF tlCond gnPass = gnPass + 1 DO EmiteLog WITH 'PASS: ' + tcMsg ELSE gnFail = gnFail + 1 DO EmiteLog WITH 'FAIL: ' + tcMsg ENDIF ENDPROC *================================================================================== * CreeazaDocumentStoc: emite un document REAL (tnTip=22, cursor_preturi filtrat pe UN articol * gestionabil cu stoc), tip_incasare=1 (Fara incasare), forma veche. Intoarce id_vanzare (>0 * succes) sau 0. FUNCTION CreeazaDocumentStoc *-- lcFiltruCod PRIVATE, nu LOCAL: goExecutor.oExecute leaga parametrii dupa numele *-- variabilei (ca poDate.* mai jos), deci trebuie vizibila din metoda apelata, nu doar aici. PRIVATE poDate, poGeneratorNumere, poDateGestiuneDest, lcFiltruCod LOCAL lnIdSet, lcSqlCursor, lcCursor, lnSucces, lnIdVanzareRezultat, tnTip, tnIdClient, tnIdDelegat LOCAL lcSerieAlocata, lnNractAlocat lnIdVanzareRezultat = 0 lcSerieAlocata = '' lnNractAlocat = 0 gnNrIncasareCapturat = 0 tnTip = 22 tnIdClient = 463 tnIdDelegat = 256 *-- 4294507796 / MOTOREDUCTOR 20SEC: UN singur lot in gestiunea 1 (Reccount(crsgestarticol)=1, *-- verificat read-only) - conditia lui do_alege_stoc pentru autoselectie fara modal. lcFiltruCod = '0V2549' update_jtva_coloane([JV], [jtva_coloane_temp]) update_saft_taxtable() lnIdSet = 25900 poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip) poGeneratorNumere = CREATEOBJECT("oGeneratorNumere") poDateGestiuneDest = CREATEOBJECT("oDateGestiune") poDate.nIdTipDoc = 6 && AVIZ - plaja globala gnIdUtil = 8 poGeneratorNumere.ResetNumere() poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc) poDate.id_client = tnIdClient poDate.id_delegat = tnIdDelegat poDate.zi_curs = {^2026-08-10} *-- gestiune reala (nu NULL): fara ea cursor_preturi arata articolul gestionabil dar *-- scrierea documentului nu are de unde sa scada stocul - primul document emis (id_vanzare=1474) *-- a iesit cu 0 randuri in vrul_tot desi articolul era gestionabil, cu stoc. poDate.id_gestiune_init = 1 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 ramane 8 (NU -3, spre deosebire de test_s3b_emitere_reala.prg): cu -3 *-- cursor_preturi intoarce un singur articol negestionabil, cantitate 0 - fara asta *-- documentul nu ar avea nicio sansa de rand in RUL. lcSerieAlocata = ALLTRIM(TRANSFORM(NVL(poDate.serie_act, []))) lnNractAlocat = poDate.nract DO EmiteLog WITH 'poDate.nract=' + TRANSFORM(poDate.nract) + ' serie_act=[' + TRANSFORM(NVL(poDate.serie_act,[])) + ']' 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 lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_preturi(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ; [?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala,?lcFiltruCod)}] lcCursor = [crsarticole] lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor) IF lnSucces < 0 DO EmiteLog WITH 'EROARE cursor articole: ' + goExecutor.oPrelucrareEroare() poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) DO CurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF IF RECCOUNT(lcCursor) = 0 DO EmiteLog WITH 'Nu exista articole (Reccount=0) - abandon document' poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc) DO CurataJtva RELEASE poDate, poGeneratorNumere, poDateGestiuneDest RETURN 0 ENDIF DO EmiteLog WITH 'crsarticole Reccount=' + TRANSFORM(RECCOUNT(lcCursor)) SELECT (lcCursor) REPLACE ALL cantitate WITH 1, ; pret_val WITH IIF(tip_valuta = 1, 100, 0), ; pret WITH IIF(tip_valuta = 1, ROUND(100 * IIF(NVL(curs, 0) = 0, 1, curs) / IIF(NVL(multiplicator, 0) = 0, 1, multiplicator), gnPPretV), 100) =TABLEUPDATE(.T., .T., lcCursor) GO TOP 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 PUBLIC goFrmEmite goFrmEmite = CREATEOBJECT('frm_facturare_articole') goFrmEmite.WindowType = 0 goFrmEmite.Show() DOEVENTS FORCE DO EmiteLog WITH 'formular afisat modeless (VECHI frm_facturare_articole)' glDlgTratatGest = .F. goFrmEmite.do_adauga_tot() DOEVENTS FORCE DO EmiteLog WITH 'do_adauga_tot() -> Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ; ' glDlgTratatGest=' + TRANSFORM(glDlgTratatGest) *-- do_initializeaza_articol zeroeste cantitatea la adaugare (ca la tip 1, ofacturare.vc2:13890) - *-- se scrie explicit dupa adaugare, ca in test_s6_1_lista_preturi.prg (SeteazaCantitati): *-- fara asta VANZARI_DETALII.CANTITATE ramane 0 si nu apare niciun rand in vrul_tot. LOCAL loArtCant SELECT crsfactura SCAN REPLACE cantitate WITH 1 SCATTER NAME loArtCant MEMO loArtCant = calculeaza_totaluri(loArtCant) GATHER NAME loArtCant MEMO ENDSCAN DO EmiteLog WITH 'cantitate setata explicit pe crsfactura' goFrmEmite.do_calculeaza_totaluri() DOEVENTS FORCE LOCAL lnScris glDlgTratatAD = .F. gnTipIncasareCerut = 1 lnScris = goFrmEmite.do_termin() LOCAL lnWait lnWait = 0 DO WHILE !glDlgTratatAD AND lnWait < 10 DOEVENTS FORCE lnWait = lnWait + 1 ENDDO DO EmiteLog WITH 'do_termin() -> ' + TRANSFORM(lnScris) + ' poDate.nid_vanzare=' + TRANSFORM(NVL(poDate.nid_vanzare,0)) lnIdVanzareRezultat = CdocGasesteIdVanzare(lcSerieAlocata, lnNractAlocat) IF lnIdVanzareRezultat < 0 lnIdVanzareRezultat = 0 ENDIF DO EmiteLog WITH 'verificare in VANZARI pe ' + lcSerieAlocata + ' ' + TRANSFORM(lnNractAlocat) + ' -> id_vanzare=' + TRANSFORM(lnIdVanzareRezultat) IF TYPE('goFrmEmite') = 'O' AND !ISNULL(goFrmEmite) goFrmEmite.Release() ENDIF goFrmEmite = NULL IF USED('crspolitici') USE IN crspolitici ENDIF IF USED('crscursuri') USE IN crscursuri ENDIF IF USED('crsfactura') USE IN crsfactura ENDIF IF USED('crsarticole') USE IN crsarticole 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 CurataJtva IF USED('jtva_coloane') USE IN jtva_coloane ENDIF IF USED('jtva_coloane_temp') USE IN jtva_coloane_temp ENDIF ENDPROC *================================================================================== *-- driverAlteDateEmite: identic cu driverAlteDateAD din test_s3b_emitere_reala.prg - cauta * FRM_ALTE_DATE prin _SCREEN.Forms si ii seteaza opt_incasat.Value INAINTE de do_termin(). DEFINE CLASS driverAlteDateEmite AS Custom PROCEDURE Executa LOCAL lnI, loForm, llGasit, loMsgForm llGasit = .F. loMsgForm = NULL FOR lnI = 1 TO _SCREEN.FormCount LOCAL lcClasa lcClasa = UPPER(_SCREEN.Forms(lnI).Class) IF lcClasa == 'FRM_ALTE_DATE' loForm = _SCREEN.Forms(lnI) llGasit = .T. ENDIF IF 'MESSAGEBOX_FORM' $ lcClasa loMsgForm = _SCREEN.Forms(lnI) ENDIF IF !(lcClasa $ gcClaseVazute) gcClaseVazute = gcClaseVazute + lcClasa + ';' ENDIF ENDFOR IF !ISNULL(loMsgForm) TRY DO CASE CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdYes', 5) loMsgForm.cmgBotones.cmdYes.Click() CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdOk', 5) loMsgForm.cmgBotones.cmdOk.Click() ENDCASE CATCH TO loExcMsg DO EmiteLog WITH '[diag timer] messagebox_form: CATCH ' + TRANSFORM(loExcMsg.ErrorNo) + ' ' + loExcMsg.Message ENDTRY ENDIF IF glDlgTratatAD OR !llGasit RETURN ENDIF TRY loForm.opt_incasat.Value = gnTipIncasareCerut gnNrIncasareCapturat = poDate.nr_incasare loForm.do_termin() glDlgTratatAD = .T. CATCH TO loExcDrv DO EmiteLog WITH 'driverAlteDateEmite: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ; ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo) glDlgTratatAD = .T. ENDTRY ENDPROC ENDDEFINE *================================================================================== *-- driverGestArticol: acelasi mecanism (poll _SCREEN.Forms + apel direct do_termin(), fara input * real) ca driverAlteDateAD/driverAlteDateEmite, dar pentru FRM_ARTICOL_GEST_FACTURA - modalul * per-linie al lui do_alege_stoc (ofacturare.vc2:13518/13526/13540), aratat neconditionat cand * inainte_de_do_termin() esueaza pe randul curent din crsgestarticol (chiar si pe ramura cu un * singur lot + tlImplicit, ofacturare.vc2:13495-13524, pentru ca poArticol.cantitate a fost deja * zeroit de do_initializeaza_articol - ofacturare.vc2:13922, tip 22 fara opt_facturare 1/2). * Copiaza pe poArticol campurile randului curent din crsgestarticol (ce ar face si navigarea in * grid_gestiuni.AfterRowColChange, ofacturare.vc2:4227-4239) plus o cantitate nenula, apoi cheama * do_termin() direct pe formular. *-- do_adauga_tot() SCANeaza crsarticole (aici 2 randuri, acelasi articol pe doua liste de preturi * ale utilizatorului 8) si cheama do_alege_stoc() o data PE RAND - modalul poate aparea de mai multe * ori, secvential, in aceeasi rulare. De-asta flagul de "tratat" nu e global (ca la frm_alte_date, * aratat o singura data): retine INSTANTA de formular deja tratata (goUltimulFormGest) - o instanta * noua (formular urmator) tot se trateaza, aceeasi instanta nu se retrateaza daca timer-ul mai apuca * un tick inainte sa se inchida. DEFINE CLASS driverGestArticol AS Custom PROCEDURE Executa LOCAL lnI, loForm, llGasit llGasit = .F. FOR lnI = 1 TO _SCREEN.FormCount LOCAL lcClasa lcClasa = UPPER(_SCREEN.Forms(lnI).Class) IF lcClasa == 'FRM_ARTICOL_GEST_FACTURA' loForm = _SCREEN.Forms(lnI) llGasit = .T. ENDIF ENDFOR IF !llGasit OR loForm = goUltimulFormGest RETURN ENDIF TRY SELECT crsgestarticol GO TOP poArticol.cantitate = 1 poArticol.pret_achizitie = Pret poArticol.lot = NVL(lot, []) poArticol.serie = NVL(serie, []) poArticol.id_gestiune = id_gestiune poArticol.Cont = ALLTRIM(Cont) poArticol.id_lucrare_rez = id_lucrare_rez poArticol.id_part_rez = id_part_rez poArticol.pretv_orig = pretv poArticol.id_valuta_d = NVL(id_valuta, 0) poArticol.pretd = pretd DO EmiteLog WITH ' driverGestArticol: id_gestiune=' + TRANSFORM(poArticol.id_gestiune) + ; ' pret_achizitie=' + TRANSFORM(poArticol.pret_achizitie) + ' cantitate=' + TRANSFORM(poArticol.cantitate) loForm.do_termin() glDlgTratatGest = .T. goUltimulFormGest = loForm CATCH TO loExcDrv DO EmiteLog WITH 'driverGestArticol: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ; ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo) glDlgTratatGest = .T. goUltimulFormGest = loForm ENDTRY ENDPROC ENDDEFINE