*!* 03.09.2026 *!* marius.mutu *!* AnulareLotEF - anularea in bloc a documentelor generate din importul eFactura: pre-verifica *!* lotul, separa acceptate/refuzate cu motiv, apoi sterge acceptatele intr-o singura tranzactie *!* si reseteaza legatura eFactura Define Class AnulareLotEF As Custom cEroare = '' && mesajul ultimei erori; gol daca ultima operatie a reusit cAvertismentRisc = '' && ce nu poate fi verificat automat (Init) Procedure Init This.cAvertismentRisc = 'Verificarea automata nu poate detecta doua situatii: nota a fost' + ; ' modificata manual dupa import, sau jurnalul de TVA in care intra a fost deja depus.' + ; ' Confirmati anularea doar dupa ce le-ati verificat manual.' Endproc && Init *!* Pre-verifica fiecare id din tcListaIdEfactura (anaf_efactura.id, separate prin virgula) si *!* imparte lotul in acceptate/refuzate cu motiv, fara sa scrie nimic in baza. Lasa deschise *!* CRSACCEPTATE si CRSREFUZATE (id_efactura, id_fact, cod, an, luna, numar_act, furnizor, suma *!* [, motiv]), pentru ecranul de confirmare. La eroare: .F., mesajul in This.cEroare Procedure Verifica Lparameters tcListaIdEfactura Local lcLista, lcSql, lnSucces, llLunaInchisa, lnIdFact, lcMotiv, llAreReferinte, lcSelect This.cEroare = '' lcSelect = Select() This.CreeazaCursoareGoale() lcLista = This.CurataLista(m.tcListaIdEfactura) If Empty(m.lcLista) This.cEroare = 'nu a fost primit niciun id de eFactura valid' Select (m.lcSelect) Return .F. Endif Text To lcSql Textmerge Noshow WITH doc AS ( SELECT a.id_fact, a.cod, a.an, a.luna, ROW_NUMBER() OVER (PARTITION BY a.id_fact ORDER BY a.cod DESC) rn FROM ACT a WHERE a.sters = 0 AND a.id_fact IN (SELECT id_fact FROM ANAF_EFACTURA WHERE id IN (<>) AND NVL(id_fact,0) <> 0) ) SELECT e.id AS id_efactura, NVL(e.id_fact,0) AS id_fact, d.cod, d.an, d.luna, NVL(e.xnumar_act,'') AS numar_act, NVL(e.xfurnizor,'') AS furnizor, NVL(e.xtotal_cu_tva,0) AS suma FROM ANAF_EFACTURA e LEFT JOIN doc d ON (d.id_fact = e.id_fact AND d.rn = 1) WHERE e.id IN (<>) ORDER BY e.id Endtext lnSucces = goExecutor.oExecute(m.lcSql, 'crsCandidatiEF') If m.lnSucces < 0 This.cEroare = Nvl(goExecutor.cEroare, 'eroare necunoscuta la verificarea lotului') Select (m.lcSelect) Return .F. Endif llLunaInchisa = (Type('glLunaInchisa') = 'L' And m.glLunaInchisa) Select crsCandidatiEF Scan lnIdFact = crsCandidatiEF.id_fact lcMotiv = '' Do Case Case Empty(m.lnIdFact) lcMotiv = 'factura nu e importata in contabilitate (id_fact lipseste)' Case Empty(Nvl(crsCandidatiEF.cod, 0)) lcMotiv = 'documentul nu mai exista (a fost deja anulat sau modificat)' Case m.llLunaInchisa lcMotiv = 'luna este inchisa' Otherwise llAreReferinte = ReferinteDocumenteNota(crsCandidatiEF.an, crsCandidatiEF.luna, crsCandidatiEF.cod) If m.llAreReferinte lcMotiv = 'documentul are incasari/plati atasate - anuleaza manual nota ' + Transform(crsCandidatiEF.cod) + ' din registrul jurnal' Endif Endcase If Empty(m.lcMotiv) Insert Into crsAcceptate Values (crsCandidatiEF.id_efactura, crsCandidatiEF.id_fact, crsCandidatiEF.cod, crsCandidatiEF.an, crsCandidatiEF.luna, crsCandidatiEF.numar_act, crsCandidatiEF.furnizor, crsCandidatiEF.suma) Else Insert Into crsRefuzate Values (crsCandidatiEF.id_efactura, crsCandidatiEF.id_fact, Nvl(crsCandidatiEF.cod, 0), Nvl(crsCandidatiEF.an, 0), Nvl(crsCandidatiEF.luna, 0), crsCandidatiEF.numar_act, crsCandidatiEF.furnizor, crsCandidatiEF.suma, m.lcMotiv) Endif Endscan Use In (Select('crsCandidatiEF')) Select (m.lcSelect) Return .T. Endproc && Verifica *!* Scrie in log (goLog) lista completa acceptate+refuzate, inainte de executie si in afara tranzactiei. *!* tcCursorAcceptate/tcCursorRefuzate: implicit CRSACCEPTATE/CRSREFUZATE Procedure Logheaza Lparameters tcCursorAcceptate, tcCursorRefuzate Local lcCursor, lcLog, lcSelect lcSelect = Select() lcLog = 'AnulareLotEF, lot de anulare:' lcCursor = Iif(Empty(m.tcCursorAcceptate), 'crsAcceptate', m.tcCursorAcceptate) If Used(m.lcCursor) Select (m.lcCursor) Scan lcLog = m.lcLog + Chr(13) + Chr(10) + ' ACCEPTAT id_efactura=' + Transform(id_efactura) + ' id_fact=' + Transform(id_fact) + ; ' cod=' + Transform(cod) + ' numar_act=' + Alltrim(Nvl(numar_act, '')) + ' furnizor=' + Alltrim(Nvl(furnizor, '')) + ' suma=' + Transform(suma) Endscan Endif lcCursor = Iif(Empty(m.tcCursorRefuzate), 'crsRefuzate', m.tcCursorRefuzate) If Used(m.lcCursor) Select (m.lcCursor) Scan lcLog = m.lcLog + Chr(13) + Chr(10) + ' REFUZAT id_efactura=' + Transform(id_efactura) + ' id_fact=' + Transform(id_fact) + ; ' cod=' + Transform(cod) + ' numar_act=' + Alltrim(Nvl(numar_act, '')) + ' furnizor=' + Alltrim(Nvl(furnizor, '')) + ' motiv=' + Alltrim(Nvl(motiv, '')) Endscan Endif goLog.Log(m.lcLog, 'AnulareLotEF') Select (m.lcSelect) Endproc && Logheaza *!* Sterge documentele din tcCursorAcceptate (implicit CRSACCEPTATE, lasat de Verifica) intr-o *!* singura tranzactie; la orice eroare face ROLLBACK pe tot lotul. Intoarce numarul de documente *!* sterse, sau 0 la esec (motivul in This.cEroare) Procedure Executa Lparameters tcCursorAcceptate, tcCursorRefuzate Local lcCursor, lnSterse, lcSelect, llSucces, llTranzactieManuala, lcSqlInit, lcSqlSterge Local loEroare As Exception Private pnCod, pnAn, pnLuna, pnIdEfactura, pnIdFact This.cEroare = '' lnSterse = 0 llSucces = .F. llTranzactieManuala = .F. lcSelect = Select() lcCursor = Iif(Empty(m.tcCursorAcceptate), 'crsAcceptate', m.tcCursorAcceptate) This.Logheaza(m.tcCursorAcceptate, m.tcCursorRefuzate) If !Used(m.lcCursor) Or Reccount(m.lcCursor) = 0 Select (m.lcSelect) Return 0 Endif Try If SQLSetprop(gnHandle, 'Transactions', 2) < 0 This.cEroare = 'nu s-a putut porni tranzactia manuala' Else llTranzactieManuala = .T. lcSqlInit = [begin pack_contafin.init_scriere_act_rul_local(?gnIdUtil,?gnAn,?gnLuna, 1,0,?gnIdSucursala); end;] llSucces = (goExecutor.oExecute(m.lcSqlInit) >= 0) If !m.llSucces This.cEroare = Nvl(goExecutor.cEroare, 'eroare necunoscuta la initializarea stergerii') Endif If m.llSucces Select (m.lcCursor) Scan pnCod = cod pnAn = an pnLuna = luna pnIdEfactura = id_efactura pnIdFact = id_fact * pnAn/pnLuna sunt ale documentului (nu gnAn/gnLuna ale sesiunii) - sterge_document(cod) * cu un singur parametru cauta in ACT pe an/luna curente ale sesiunii Oracle si nu ar * gasi nimic pentru un document dintr-o alta perioada, fara sa semnaleze eroare lcSqlSterge = [begin pack_contafin.sterge_document(?pnCod,?pnAn,?pnLuna,?gnIdUtil); end;] llSucces = (goExecutor.oExecute(m.lcSqlSterge) >= 0) If !m.llSucces This.cEroare = Nvl(goExecutor.cEroare, 'eroare necunoscuta la stergerea documentului cod=' + Transform(m.pnCod)) Exit Endif llSucces = ResetEFacturaIdFact(m.pnIdEfactura, m.pnIdFact) If !m.llSucces This.cEroare = 'documentul cod=' + Transform(m.pnCod) + ' a fost sters, dar resetarea legaturii eFactura a esuat' Exit Endif lnSterse = lnSterse + 1 Endscan Endif Endif Catch To loEroare llSucces = .F. This.cEroare = Iif(!Empty(This.cEroare), This.cEroare, loEroare.Message) Finally If m.llTranzactieManuala If m.llSucces goExecutor.oExecute('COMMIT') Else goExecutor.oExecute('ROLLBACK') lnSterse = 0 Endif SQLSetprop(gnHandle, 'Transactions', 1) Endif Endtry Select (m.lcSelect) Return m.lnSterse Endproc && Executa *!* Cursoare goale cu structura finala, folosite si la eroare - ecranul se poate deschide oricum Procedure CreeazaCursoareGoale If Used('crsAcceptate') Use In (Select('crsAcceptate')) Endif Create Cursor crsAcceptate (id_efactura N(20), id_fact N(20), cod N(15), an N(4), luna N(2), numar_act C(30), furnizor C(250), suma N(20,4)) If Used('crsRefuzate') Use In (Select('crsRefuzate')) Endif Create Cursor crsRefuzate (id_efactura N(20), id_fact N(20), cod N(15), an N(4), luna N(2), numar_act C(30), furnizor C(250), suma N(20,4), motiv C(200)) Endproc && CreeazaCursoareGoale *!* Curata tcLista (anaf_efactura.id separate prin virgula) la un sir doar cu intregi valizi, *!* separate prin virgula, gata de interpolat intr-un IN() SQL - elimina orice token nenumeric Procedure CurataLista Lparameters tcLista Local lnN, lnI, lcVal, lcCurata Local Array laId[1] lcCurata = '' lnN = Alines(laId, Nvl(m.tcLista, ''), 0, ',') For lnI = 1 To m.lnN lcVal = Alltrim(laId[m.lnI]) If !Empty(m.lcVal) And Empty(Chrtran(m.lcVal, '0123456789', '')) lcCurata = m.lcCurata + Iif(Empty(m.lcCurata), '', ',') + m.lcVal Endif Endfor Return m.lcCurata Endproc && CurataLista Enddefine