Verificarea de duplicate se face document cu document, nu pe primul document din lot

Verificarea folosea o singura data VerificaFactura, pe primul rand din actactan. Daca acel
document exista deja in ROA nu se scria nimic din tot intervalul; daca nu exista, se scria
tot lotul, inclusiv documentele deja importate, care apareau duplicate.

EliminaFacturiDuplicate ia intr-o singura interogare pe (an, luna) documentele existente in
ACT, le pune intr-un cursor indexat pe an+luna+nract+dataact+explicatia5 si scoate din
actactan doar randurile care se potrivesc. VerificaFactura, ramasa fara apelanti, e stearsa.

In modul "Nu scrie note contabile" xls-ul de verificare se genereaza chiar daca actualizarea
partenerilor sau verificarea de duplicate nu a reusit: notele nu ajung oricum in ROA.

Verificat pe ROA_CONPRESS, read-only, pe intrarile din 07/2026: din 152 de randuri raman 15,
toate cele 11 facturi reclamate ca lipsa raman in lot, iar factura 1178734 e scoasa doar pe
30.07 (exista in ROA) si pastrata pe 13.07 (nu exista).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmUPGiStqNKSu4wWq2y77Q
This commit is contained in:
2026-08-21 21:09:26 +03:00
parent 60eae1e490
commit 4c9b6cbddb
6 changed files with 433 additions and 65 deletions

View File

@@ -46,6 +46,7 @@ DEFINE CLASS form1 AS form
*m: creeazanote
*m: disconnectmentor
*m: disconnectroa
*m: eliminafacturiduplicate
*m: exportdate
*m: getidpartener
*m: getidpartenerroa
@@ -53,7 +54,6 @@ DEFINE CLASS form1 AS form
*m: sql_temp_insert
*m: sterge_import
*m: trace
*m: verificafactura
*p: nhandlementor
*p: _memberdata && XML Metadata for customizable properties
*</DefinedPropArrayMethod>
@@ -77,6 +77,7 @@ DEFINE CLASS form1 AS form
<memberdata name="completeazaparteneriroa" display="CompleteazaParteneriROA"/>
<memberdata name="getidpartener" display="GetIdPartener"/>
<memberdata name="getidpartenerroa" display="GetIdPartenerROA"/>
<memberdata name="eliminafacturiduplicate" display="EliminaFacturiDuplicate"/>
</VFPData>
*</PropValue>
@@ -646,12 +647,12 @@ DEFINE CLASS form1 AS form
* VANZARI - nu iau in considerare TipPlata = "MD BUFET"
* Creeaza actactan cu note contabile vanzari
Local lnIdPartCasa, lnIdPartCard, lnSucces, lnIdSet, lnVerificaFacturi
Local lnIdPartCasa, lnIdPartCard, lnSucces, lnIdSet, lnVerificaFacturi, lnSuccesDuplicat
Local lcAcontTVAAchizitie, lcAcontTVAVanzare, lcContTVAAchizitie, lcContTVAVanzare, lcDirImport
Local lcDirOutput, lcExplicatia5, lcFileOutput, ldDataImport, llFacturaDuplicat, llImport, lnAn
Local lcDirOutput, lcExplicatia5, lcFileOutput, ldDataImport, llImport, lnAn
Local lnIdBazaAch0, lnIdBazaAch19, lnIdBazaAch20, lnIdBazaAch24, lnIdBazaAch5, lnIdBazaAch9
Local lnIdFdoc, lnIdFdocBonConsum, lnIdFdocBonFiscal, lnIdFdocFactura, lnIdFdocMonetar, lnIdTVAAch19
Local lnIdTVAAch20, lnIdTVAAch24, lnIdTVAAch5, lnIdTVAAch9, lnLuna, lnTVAIncasare, loRec, lcAcontMf4428
Local lnIdTVAAch20, lnIdTVAAch24, lnIdTVAAch5, lnIdTVAAch9, lnLuna, lnTVAIncasare, lcAcontMf4428
Local lcAContCardRestaurant, lcAContCasaRestaurant, lcAContFacturaCardHotel, lcAContFacturaCasaHotel
Local lcAContFacturaTicheteHotel, lcAContFacturaViramentIntHotel, lcAContTicheteRestaurant
Local lcAcont401, lcAcontCardHotel, lcAcontCasaHotel, lcAcontClientiHotel, lcAcontClientiRestaurant
@@ -1383,24 +1384,28 @@ DEFINE CLASS form1 AS form
UPDATE actactan SET ascd = ALLTRIM(STRTRAN(ascd, CHR(9), '')), ascc = ALLTRIM(STRTRAN(ascc, CHR(9), ''))
USE IN (SELECT('tAct'))
SET STEP ON
llFacturaDuplicat = .F.
* Scot din lot documentele care exista deja in ROA, comparate unul cate unul
lnSuccesDuplicat = CT_SUCCES
If m.lnVerificaFacturi = 1
Select actactan
Go Top
Scatter Name loRec Memo
llFacturaDuplicat = This.VerificaFactura(loRec)
lnSuccesDuplicat = This.EliminaFacturiDuplicate(m.lnIdSet)
Endif
If m.llTest OR !m.llFacturaDuplicat
This.Scrienote()
* In modul de test notele nu ajung in ROA, deci xls-ul de verificare se face si
* atunci cand verificarea de duplicate nu a reusit
If m.llTest Or m.lnSuccesDuplicat = CT_SUCCES
If Reccount('actactan') > 0
This.Scrienote()
Else
This.trace('Toate documentele din interval exista deja in ROA, nu se scrie nimic.')
Endif
Else
lnSucces = CT_INSUCCES
Endif
Endif && m.llImport
Use In (Select('actactan'))
SET STEP ON
If Used('act_test')
lcDirOutput = Addbs(m.lcDirImport)
lcFileOutput = m.lcDirOutput + 'act_test' + Sys(2) + '.xls'
@@ -1437,6 +1442,88 @@ DEFINE CLASS form1 AS form
RETURN m.lnSucces
ENDPROC
PROCEDURE eliminafacturiduplicate
Lparameters tnIdSet
* Scoate din actactan documentele care exista deja in ROA, comparate document cu document
* dupa (an, luna, id_set, nract, dataact, explicatia5).
* Intoarce CT_INSUCCES daca verificarea nu s-a putut face, ca lotul sa nu fie scris nefiltrat.
Private gnAn, gnIdSet, gnLuna
Local lcCheie, lcMesaj, lcSql, lnEliminate, lnRamase, lnSucces, lnTotal
If !Used('actactan') Or Reccount('actactan') = 0
Return CT_SUCCES
Endif
gnIdSet = Evl(m.tnIdSet, 50100)
This.trace('Verificare documente deja existente in ROA')
lnSucces = This.Connectroa()
If m.lnSucces <> CT_SUCCES
Return m.lnSucces
Endif
* Cheia unui document: an + luna + nract + dataact + explicatia5
Create Cursor cFacturiRoa (cheie C(58))
Index On cheie Tag cheie
Select Distinct an, luna From actactan Into Cursor cAnLunaRoa
Select cAnLunaRoa
Scan
gnAn = an
gnLuna = luna
lcSql = [select distinct nract, dataact, explicatia5 from act ] + ;
[where sters = 0 and an = ?gnAn and luna = ?gnLuna and id_set = ?gnIdSet]
lnSucces = goExecutor.oExecute(GetHash('cCursor=>cActRoa??cSql=>' + m.lcSql))
If m.lnSucces <> CT_SUCCES
lcMesaj = goExecutor.cEroare
This.trace(m.lcMesaj)
AMESSAGEBOX(m.lcMesaj, 0 + 48, 'Atentie!')
Exit
Endif
Select cActRoa
Scan
lcCheie = Padl(m.gnAn, 4, '0') + Padl(m.gnLuna, 2, '0') + ;
Padl(Alltrim(Str(Int(Nvl(cActRoa.nract, 0)), 14, 0)), 14, '0') + ;
Dtos(Nvl(cActRoa.dataact, {})) + Padr(Alltrim(Nvl(cActRoa.explicatia5, '')), 30)
Insert Into cFacturiRoa (cheie) Values (m.lcCheie)
Endscan
If Used('cActRoa')
Use In cActRoa
Endif
Select cAnLunaRoa
Endscan
Use In cAnLunaRoa
This.Disconnectroa()
If m.lnSucces <> CT_SUCCES
Use In cFacturiRoa
Return m.lnSucces
Endif
lnTotal = Reccount('actactan')
Select actactan
Delete For Indexseek(Padl(an, 4, '0') + Padl(luna, 2, '0') + ;
Padl(Alltrim(Str(Int(nract), 14, 0)), 14, '0') + ;
Dtos(dataact) + Padr(Alltrim(Nvl(explicatia5, '')), 30), .F., 'cFacturiRoa', 'cheie')
Use In cFacturiRoa
* Rescriu cursorul ca randurile sterse sa dispara fizic, nu doar marcate
Select * From actactan Into Cursor cActRamase
lnRamase = Reccount('cActRamase')
Use In actactan
Select * From cActRamase Into Cursor actactan Readwrite
Use In cActRamase
lnEliminate = m.lnTotal - m.lnRamase
This.trace('Randuri deja existente in ROA, scoase din lot: ' + Transform(m.lnEliminate) + ;
' din ' + Transform(m.lnTotal))
Return CT_SUCCES
ENDPROC
PROCEDURE exportdate
Local laFiles[1], lcDirImport, ldDataImport, lnAn, lnFiles, lnLuna, lnSucces
Local lcFile, lcPrefix, lnFile
@@ -1865,7 +1952,6 @@ DEFINE CLASS form1 AS form
lnAn = Year(m.ldDataImport)
lcDirImport = Addbs(Alltrim(goApp.oSettings.cale_import)) + Alltrim(Str(m.lnAn)) + '\' + Padl(m.lnLuna, 2, '0') + '\'
lnSucces = CT_INSUCCES
SET STEP ON
llTest = (This.chkTest.Value = 1)
If m.llTest
thisform.trace('Salvare note in xls, fara scriere in Registrul Jurnal')
@@ -2241,54 +2327,6 @@ DEFINE CLASS form1 AS form
This.edtInfo.Refresh()
ENDPROC
PROCEDURE verificafactura
Lparameters toRec
Private gnAn, gnIdSucursala, gnIdUtil, gnLuna, gcExplicatia5, gdDataAct, gnIdSet, gnNrAct
Local lcMesaj, lcSql, lnHandle, lnInregistrari, lnSucces
lnInregistrari = 0
lnSucces = This.Connectroa()
If lnSucces = CT_SUCCES
lnHandle = goConn.nHandle
Endif
If lnSucces = CT_SUCCES
gnAn = toRec.an
gnLuna = toRec.luna
gnIdUtil = - 3
gnIdSucursala = Null
gnNrAct = toRec.nract
gdDataAct = toRec.dataact
gnIdSet = toRec.id_set
gcExplicatia5 = Alltrim(toRec.explicatia5)
lcSql = [select COUNT(*) as nr from act where sters = 0 and an = ?gnAn and luna = ?gnLuna and nract = ?gnNrAct and dataact = ?gdDataAct and id_set = ?gnIdSet and explicatia5 = ?gcExplicatia5]
lnSucces = goExecutor.oExecute(GetHash("cCursor=>cInregistrari??cSql=>" + lcSql))
If lnSucces = CT_SUCCES
If !Used('cInregistrari')
lnInregistrari = 1 && daca da eroare, consider duplicat ca sa nu se insereze din greseala
lnSucces = CT_INSUCCES
lcMesaj = 'Nu exista cursorul cInregistrari cu numarul de inregistrari ale facturii!'
This.trace(m.lcMesaj)
Messagebox(m.lcMesaj, 0 + 48, 'Atentie!')
Else
lnInregistrari = cInregistrari.nr
ENDIF
ELSE
lnInregistrari = 1 && daca da eroare, consider duplicat ca sa nu se insereze din greseala
This.trace(goExecutor.cEroare)
Messagebox(goExecutor.cEroare, 0 + 48, 'Atentie!')
ENDIF
USE IN (SELECT('cInregistrari'))
Endif && lnSucces
This.Disconnectroa()
Return (m.lnInregistrari > 0)
ENDPROC
PROCEDURE chkTVAIncasare.Valid
goApp.oSettings.SetVariable([general], [tva_incasare], thisform.chkTVAIncasare.Value)
@@ -2297,15 +2335,22 @@ DEFINE CLASS form1 AS form
PROCEDURE cmdExport.Click
Close Databases All
Local llSucces, ldData1, loEx as Exception
Local lnSucces, ldData1, llTest, loEx as Exception
ldData1 = Thisform.txtData1.Value
llTest = (Thisform.chkTest.Value = 1)
lnSucces = Thisform.ExportDate()
If m.lnSucces = CT_SUCCES
lnSucces = Thisform.CompleteazaParteneriROA()
If m.lnSucces = CT_SUCCES
* In modul de test notele nu ajung in ROA, deci xls-ul de verificare se genereaza si
* atunci cand completarea partenerilor nu a reusit
If m.lnSucces <> CT_SUCCES And m.llTest
Thisform.Trace('Completarea partenerilor nu a reusit; se continua doar pentru xls-ul de verificare.')
Endif
If m.lnSucces = CT_SUCCES Or m.llTest
lnSucces = Thisform.Creeazanote()
goapp.osettings.SetVariable("general", "last_data1", DTOC(thisform.txtData1.Value))