AnafeFacturaServer.ImportZipLocal (programe/anaf_efactura.prg): dezarhiveaza arhiva aleasa de utilizator, ia xml-ul facturii (ignora semnatura MFinante), ParseEFactura, decide FACTURA PRIMITA/TRIMISA dupa codul fiscal al firmei curente, copiaza arhiva in directorul local de raspunsuri si scrie in Oracle prin acelasi lant ca descarcarea din SPV (cursor temporar canaf_efactura_temp + cUpdateFactura + UpdateDb -> pack_anaf.AdaugaRaspunsFactura si anaf_efactura_detalii). Fara SQL scris de mana si fara duplicarea maparii de campuri. clase/anaf_efactura.vcx (clasa anaf_efactura, metoda citesteraspunsuri): optiunea 8 in meniul butonului "Raspunsuri" - "Import arhiva zip de pe disc...". Necesar cand mesajul nu mai e in lista de raspunsuri ANAF (expira dupa 60 zile) si factura primita nu a ajuns in borderou. Testare (CENTRAL/MARIUSM_AUTO, ianuarie 2026, 12 PASS / 0 FAIL): utile/Teste/efactura_import/ - garda pe cod fiscal, import complet cu verificarea campurilor si a liniilor in anaf_efactura_detalii, factura vizibila in grila reala "Facturi primite in SPV". utile/Teste/test_init_env_auto.prg: adauga goFirma.codfiscalfro ca in start_firma (ostartfirma.prg) - proprietatea nu e coloana in v_firme, iar fara ea orice cod care o citeste nepazit crapa in mediul headless. docs/depanare_testare_vfp.md: verificarea de sintaxa prin compilare headless (config.fpw cu SAFETY=OFF, copie in scratchpad) si capcana literalelor string mai lungi de 255 de caractere (eroare de compilare, nu de runtime). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RqJ7D5ftMbChDyz5mpVkCd
4109 lines
159 KiB
Plaintext
4109 lines
159 KiB
Plaintext
#DEFINE LF CHR(10)
|
||
#DEFINE CRLF CHR(13)+CHR(10)
|
||
|
||
#DEFINE CT_SUCCES 1
|
||
#DEFINE CT_INSUCCES -1
|
||
|
||
|
||
*!* 12.08.2024
|
||
*!* ParseEFactura - discount factura, discount linie
|
||
|
||
*!* 21.08.2024
|
||
*!* xml2PdfAnaf - tratare Invoice / CreditNote
|
||
|
||
*!* 03.12.2024
|
||
*!* AnafeFactura.RefreshToken, SaveToken apeleaza AnafeFacturaServer.RefreshToken, SaveToken
|
||
*!* AnafeFacturaServer.RefreshToken - automat daca data expirarii este mai mare sau egala, fara sa mai apara formularul de Actualizare
|
||
*!* astfel incat si pe server sa se apeleze automat daca expira tokenul
|
||
|
||
*!* 07.01.2025
|
||
*!* UpdateDbFactura - corectie double byte characters la mesaj_raspuns
|
||
*!* RefreshToken - tratare eroare cu Try Catch
|
||
|
||
*!* 26.03.2025
|
||
*!* SendEfactura - uploadb2c pentru persoane fizice len(codfiscal) = 13
|
||
|
||
*!* 20.05.2025
|
||
*!* DescarcareRaspunsuri - se afiseaza eroare daca nu sunt drepturi in spv
|
||
|
||
*!* 13.03.2026
|
||
*!* Validarea si xml2pdfanaf se fac cu serviciul autentificat cu token efactura api.anaf.ro in loc de serviciul neautentificat https://webservicesp.anaf.ro/
|
||
*!* serviciul neautentificat nu mai raspundea
|
||
|
||
*********************************
|
||
* Se apeleaza din ROACONT > Borderou eFactura
|
||
* Intoarce .T. daca descarcarea zip efactura si actualizarea efactura in baza de date s-au realizat cu succes
|
||
*********************************
|
||
PROCEDURE efactura_client
|
||
LPARAMETERS tnZile, tlFortareRaspunsuri, tlTest
|
||
|
||
LOCAL lnExitCode, lcHost, lcPassword, lcUser, lnIsServer, lnFortareRaspunsuri, lnZile, llSucces
|
||
Local loAnaf As 'AnafeFacturaServer'
|
||
Local lcErrorMessage, llFortareRaspunsuri, llServer, loEx, llTest
|
||
|
||
lcHost = ''
|
||
lcUser = IIF(TYPE('gcS') = 'C', m.gcS, '')
|
||
lcPassword = ''
|
||
llServer = .F.
|
||
lnZile = IIF(EMPTY(m.tnZile), 60, m.tnZile)
|
||
llFortareRaspunsuri = m.tlFortareRaspunsuri
|
||
llTest = m.tlTest
|
||
llSucces = .F.
|
||
|
||
TRY
|
||
loAnaf = Createobject('AnafeFacturaServer', m.llServer, m.lcHost, m.lcuser, m.lcPassword)
|
||
loAnaf.ltest = m.llTest
|
||
llSucces = loAnaf.Run(m.lnZile, m.llFortareRaspunsuri)
|
||
|
||
IF loAnaf.lError
|
||
goLog.Log(loAnaf.cErrorMessage)
|
||
ENDIF
|
||
CATCH TO loEx
|
||
lnExitCode = 1
|
||
lcErrorMessage = TTOC(DATETIME(),1) + ' Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut: ' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
WAIT WINDOW m.lcErrorMessage NOWAIT
|
||
AMESSAGEBOX(m.lcErrorMessage)
|
||
This.Log(m.lcErrorMessage)
|
||
ENDTRY
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC && efactura_client
|
||
|
||
Define Class AnafeFacturaServer As Custom
|
||
dLastRunDate1 = {} && dataora inceput pentru ultima citire a raspunsurilor
|
||
dLastRunDate2 = {} && dataora sfarsit pentru ultima citire a raspunsurilor
|
||
nLastRunDays = 0 && numarul de zile pentru citirea raspunsurilor
|
||
nLastRunSucces = 0 && succes la ultima citire a raspunsurilor
|
||
|
||
cLogFile = ''
|
||
|
||
cToken = ''
|
||
cRefreshToken = ''
|
||
dTokenGendate = {}
|
||
dTokenExpdate = {}
|
||
cTokenUrl = ''
|
||
|
||
cCodFiscal = '' && cod fiscal contribuabil fara atribut fiscal
|
||
lTest = .F. && .T. = transmite eFactura TEST
|
||
|
||
cResponsesPath = '' && Citire raspunsuri. Calea unde se salveaza fisierele xml primite, semnatura MFIN, pdf generat de ANAF: z:\e-factura\<an>\<luna> <an>\<furnizor>\<id_descarcare
|
||
nDaysResponses = 60
|
||
|
||
cSendPath = '' && cale unde sunt fisierele xml de trimis
|
||
cSendInvalidPath = '' && calea unde se muta fisierele invalide
|
||
cSendOkPath = '' && calea unde se muta fisierele trimise
|
||
|
||
cSaveFurnizoriPath = '' && cale template unde se copie xml, semnatura, generare pdf in ProcesCopiere
|
||
cSaveClientiPath = ''
|
||
cSaveFurnizoriFile = '' && nume fisier template pentru xml, semnatura, pdf
|
||
cSaveClientiFile = '' && nume fisier template pentru xml, semnatura, pdf
|
||
|
||
nSaveFile = 1 && 1 = se salveaza arhivele zip in calea template, 0 nu se salveaza
|
||
nSaveAnafPdfFile = 1 && 1 = se salveaza arhivele zip in calea template, 0 nu se salveaza
|
||
|
||
cSaveLogsPath = '' && directorul unde se salveaza fisierele cu raspunsuri de la ANAF descarcate (optional)
|
||
|
||
cServerPath = '' && directorul de pe server EFACTURA_SERVER_PATH
|
||
cNetworkPath = '' && directorul din retea accesibil de pe clienti, daca se ruleaza din ROACONT. EFACTURA_NETWORK_PATH
|
||
|
||
cErrorMessage = ''
|
||
lError = .F.
|
||
|
||
cDatabaseFileName = 'anaf_efactura.dbf'
|
||
cDatabaseFilePath = ''
|
||
|
||
lServer = .T.
|
||
cHost = ''
|
||
cUser = ''
|
||
cPassword = ''
|
||
|
||
lConnected = .F. && daca programul este deja conectat la baza de date si nu este necesar sa se conecteze/deconecteze
|
||
|
||
lZipDatabase = .T. && daca se salveaza zip efactura in baza de date
|
||
|
||
lTokenAutoRefresh = .F. && daca se actualizeaza automat tokenul cu 10 zile inainte de expirare
|
||
|
||
oAnafeFactura = null
|
||
|
||
Procedure Init
|
||
Lparameters tlServer, tcHost, tcUser, tcPassword
|
||
|
||
Local lcTest, llSucces, lcUser
|
||
This.cErrorMessage = ''
|
||
|
||
lcUser = tcUser
|
||
IF TYPE('tcUser') = 'C' AND !EMPTY(m.tcUser)
|
||
lcUser = m.tcUser
|
||
ELSE
|
||
lcUser = IIF(TYPE('gcS') = 'C', m.gcS, '')
|
||
ENDIF
|
||
|
||
this.lServer = m.tlServer
|
||
This.cHost = m.tcHost
|
||
this.cUser = m.lcUser
|
||
this.cPassword = m.tcPassword
|
||
|
||
|
||
* Initializare baza date
|
||
goConn.cHost = This.cHost
|
||
goConn.cUser = this.cUser
|
||
goConn.cPassword = this.cPassword
|
||
|
||
This.lConnected = This.IsConnected()
|
||
|
||
This.cLogFile = goLog.cLogFile
|
||
|
||
llSucces = This.ReadSettingsFromDb()
|
||
|
||
Endproc && Init
|
||
|
||
PROCEDURE Run
|
||
LPARAMETERS tnZile, tlFortareRaspunsuri
|
||
|
||
Local llSucces, lnZile, llFortareRaspunsuri
|
||
lnZile = m.tnZile
|
||
This.nDaysResponses = m.lnZile
|
||
llFortareRaspunsuri = m.tlFortareRaspunsuri
|
||
|
||
This.PreRun()
|
||
|
||
llSucces = This.InitDB(m.lnZile)
|
||
|
||
IF m.llSucces
|
||
llSucces = This.DescarcareRaspunsuri(m.lnZile, m.llFortareRaspunsuri)
|
||
IF !m.llSucces AND !This.lServer
|
||
AMESSAGEBOX(This.cErrorMessage,0+48, _SCREEN.Caption)
|
||
ENDIF
|
||
ENDIF
|
||
|
||
IF m.llSucces
|
||
llSucces = This.ProcesareRaspunsuri(m.llFortareRaspunsuri)
|
||
|
||
|
||
IF m.llSucces
|
||
llSucces = This.UpdateDb()
|
||
IF !m.llSucces AND !This.lServer AND !EMPTY(This.cErrorMessage)
|
||
AMESSAGEBOX(This.cErrorMessage,0+48, _SCREEN.Caption)
|
||
ENDIF
|
||
|
||
ELSE
|
||
IF !m.llSucces AND !This.lServer AND !EMPTY(This.cErrorMessage)
|
||
AMESSAGEBOX(This.cErrorMessage,0+48, _SCREEN.Caption)
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
|
||
This.PostRun(m.llSucces)
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC && Run
|
||
|
||
*****************************
|
||
PROCEDURE PreRun
|
||
|
||
Local llSucces, lnHandle
|
||
|
||
This.dLastRunDate1 = DATETIME()
|
||
This.dLastRunDate2 = {//::}
|
||
This.nLastRunDays = This.nDaysResponses
|
||
This.nLastRunSucces = 0
|
||
|
||
lnHandle = This.ConnectROA()
|
||
llSucces = (m.lnHandle > 0)
|
||
IF m.llSucces
|
||
scrie_optiune('EFACTURA_LASTRUN_DATE1', ttoc(This.dLastRunDate1), 'Efactura data inceput cand au fost verificate raspunsurile SPV')
|
||
scrie_optiune('EFACTURA_LASTRUN_DATE2', ttoc(This.dLastRunDate2), 'Efactura data sfarsit cand au fost verificate raspunsurile SPV')
|
||
scrie_optiune('EFACTURA_LASTRUN_DAYS', ALLTRIM(STR(This.nLastRunDays)), 'Efactura cate zile de raspunsuri au fost verificate ultima data')
|
||
scrie_optiune('EFACTURA_LASTRUN_SUCCES', ALLTRIM(STR(This.nLastRunSucces)), 'Efactura succes la ultima verificare de raspunsuri SPV')
|
||
ENDIF
|
||
|
||
ENDPROC && PreRun
|
||
|
||
*****************************
|
||
PROCEDURE PostRun
|
||
LPARAMETERS tlSucces
|
||
Local llSucces, lnHandle
|
||
|
||
This.nLastRunSucces = IIF(m.llSucces, 1, 0)
|
||
This.dLastRunDate2 = DATETIME()
|
||
|
||
lnHandle = This.ConnectROA()
|
||
llSucces = (m.lnHandle > 0)
|
||
IF m.llSucces
|
||
scrie_optiune('EFACTURA_LASTRUN_SUCCES', ALLTRIM(STR(This.nLastRunSucces)), 'Efactura succes la ultima verificare de raspunsuri SPV')
|
||
scrie_optiune('EFACTURA_LASTRUN_DATE2', ttoc(This.dLastRunDate2), 'Efactura data sfarsit cand au fost verificate raspunsurile SPV')
|
||
scrie_optiune('EFACTURA_LASTRUN_SUCCES', IIF(m.tlSucces, "1", "0"), 'Efactura succes la ultima verificare de raspunsuri SPV')
|
||
ENDIF
|
||
|
||
ENDPROC && PostRun
|
||
|
||
*******************************
|
||
* Verifica daca programul este conectat la baza de date
|
||
*******************************
|
||
PROCEDURE IsConnected
|
||
LOCAL lcSql, llSucces
|
||
LOCAL loEx as Exception
|
||
Local lcErrorMessage
|
||
|
||
|
||
llSucces = .F.
|
||
lcSql = "SELECT sysdate FROM dual"
|
||
|
||
TRY
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
CATCH TO loEx
|
||
lcErrorMessage = TTOC(DATETIME(),1) + ' Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.Log(m.lcErrorMessage)
|
||
ENDTRY
|
||
|
||
RETURN m.llSucces
|
||
|
||
ENDPROC && IsConnected
|
||
|
||
PROCEDURE ReadSettingsFromDb
|
||
|
||
Local lcSql, llSucces, lcCodFiscal
|
||
Local lcErrorMessage, lcFirma, lcLastRunDate1, lcLastRunDate2, lcPath, lnHandle, lnSucces
|
||
Local lnZipDatabase
|
||
*:Global gcFirma, gnAn, gnLuna
|
||
|
||
llSucces = .F.
|
||
|
||
TEXT TO lcSql TEXTMERGE NOSHOW
|
||
select MAX(cod_fiscal) as cod_fiscal, MAX(firma) AS firma from syn_v_nom_firme where UPPER(schema) = '<<UPPER(ALLTRIM(This.cUser))>>' AND STERS = 0 AND (E_MAMA = 1 OR (E_MAMA = 0 AND ID_MAMA IS NULL))
|
||
ENDTEXT
|
||
|
||
lnHandle = This.ConnectROA()
|
||
llSucces = (m.lnHandle > 0)
|
||
IF m.llSucces
|
||
lnSucces = actualizeaza_optiuni()
|
||
llSucces = (lnSucces = CT_SUCCES)
|
||
|
||
IF m.llSucces
|
||
lcCodFiscal = ''
|
||
lcFirma = ''
|
||
llSucces = goExecutor.oExecuta(m.lcSql, "cFirmaTemp")
|
||
IF m.llSucces
|
||
lcCodFiscal = ALLTRIM(NVL(cFirmaTemp.cod_fiscal, ''))
|
||
lcFirma = ALLTRIM(NVL(cFirmaTemp.firma, ''))
|
||
This.cCodFiscal = UPPER(ALLTRIM(GetNrFromString(NVL(m.lcCodFiscal,''))))
|
||
IF TYPE('gcFirma') = 'C' AND EMPTY(m.gcFirma)
|
||
gcFirma = m.lcFirma
|
||
ENDIF
|
||
ENDIF
|
||
USE IN (SELECT('cFirmaTemp'))
|
||
ENDIF
|
||
IF m.llSucces
|
||
IF TYPE('gnAn') = 'N' AND EMPTY(m.gnAn)
|
||
lcSql = "SELECT AN, LUNA FROM CALENDAR WHERE AN*12 + LUNA = (SELECT MAX(AN*12+LUNA) FROM CALENDAR)"
|
||
llSucces = goExecutor.oExecuta(m.lcSql, 'cCalendarTemp')
|
||
IF m.llSucces
|
||
gnAn = cCalendarTemp.an
|
||
gnLuna = cCalendarTemp.luna
|
||
ENDIF
|
||
USE IN (SELECT('cCalendarTemp'))
|
||
ENDIF
|
||
ENDIF
|
||
lnSucces = This.DisconnectROA()
|
||
llSucces = (lnSucces = CT_SUCCES)
|
||
ENDIF
|
||
|
||
IF m.llSucces
|
||
This.cResponsesPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_RESPONSESPATH"), ''))) && RASPUNSURI && <path>\<firma>\raspunsuri\
|
||
This.cSendPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_SENDPATH"),''))) && FACTURI DE TRIMIS && <path>\<firma>\emise\
|
||
|
||
This.cSaveFurnizoriPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_SAVE_FURNIZORI_PATH"), ''))) && <path>\<firma>\furnizori\<an>\<luna> <an>\<furnizor>\<id_descarcare>
|
||
This.cSaveFurnizoriFile = ALLTRIM(citeste_optiune("EFACTURA_SAVE_FURNIZORI_FILE")) && <id_incarcare>_<datafact>_<furnizor>
|
||
This.cSaveClientiPath = Addbs(ALLTRIM(NVL(citeste_optiune("EFACTURA_SAVE_CLIENTI_PATH"), ''))) && <path>\<firma>\clienti\<an>\<luna> <an>\<client>\<id_descarcare>
|
||
This.cSaveClientiFile = ALLTRIM(citeste_optiune("EFACTURA_SAVE_CLIENTI_FILE")) && <id_incarcare>_<id_descarcare>_<datafact>_<client>
|
||
This.nSaveFile = INT(VAL(ALLTRIM(citeste_optiune("EFACTURA_SAVE")))) && 1
|
||
This.nSaveAnafPdfFile = INT(VAL(ALLTRIM(citeste_optiune("EFACTURA_SAVE_ANAF_PDF")))) && 1
|
||
|
||
This.cServerPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_SERVER_PATH"),''))) && C:\ROA-EFACTURA\
|
||
This.cNetworkPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_NETWORK_PATH"),''))) && W:\
|
||
|
||
lcPath = IIF(This.lServer, this.cServerPath, this.cNetworkPath)
|
||
This.cSaveFurnizoriPath = STRTRAN(STRTRAN(This.cSaveFurnizoriPath, '<path>', m.lcPath, 1, 1, 1), '\\', '\', 1, 10, 1)
|
||
This.cSaveClientiPath = STRTRAN(STRTRAN(This.cSaveClientiPath, '<path>', m.lcPath, 1, 1, 1), '\\', '\', 1, 10, 1)
|
||
|
||
This.cResponsesPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_RESPONSESPATH"),''))) && RASPUNSURI && <firma>\raspunsuri\
|
||
This.cSendPath = ADDBS(ALLTRIM(NVL(citeste_optiune("EFACTURA_SENDPATH"),''))) && FACTURI DE TRIMIS && <firma>\emise\
|
||
|
||
This.cResponsesPath = STRTRAN(STRTRAN(This.cResponsesPath, '<path>', m.lcPath, 1, 1, 1), '\\', '\', 1, 10, 1)
|
||
This.cResponsesPath = STRTRAN(This.cResponsesPath,'<firma>', UPPER(This.cUser),1,1,1)
|
||
This.cResponsesPath = This.cResponsesPath + IIF(this.lTest, 'test\', '')
|
||
This.cSaveLogsPath = This.cResponsesPath + 'logs\'
|
||
|
||
This.cSendPath = STRTRAN(STRTRAN(This.cSendPath, '<path>', m.lcPath, 1, 1, 1), '\\', '\', 1, 10, 1)
|
||
This.cSendPath = STRTRAN(This.cSendPath,'<firma>', UPPER(This.cUser),1,1,1)
|
||
This.cSendPath = This.cSendPath + IIF(this.lTest, 'test\', '')
|
||
This.cSendInvalidPath = This.cSendPath + 'invalid\'
|
||
This.cSendOkPath = This.cSendPath + 'ok\'
|
||
|
||
lnZipDatabase = INT(VAL(ALLTRIM(citeste_optiune("EFACTURA_ZIP_DATABASE")))) && 1
|
||
This.lZipDatabase = (m.lnZipDatabase = 1)
|
||
|
||
lcLastRunDate1 = ALLTRIM(NVL(citeste_optiune("EFACTURA_LASTRUN_DATE1"), ''))
|
||
This.dLastRunDate1 = Iif(!Empty(m.lcLastRunDate1), CTOT(m.lcLastRunDate1), {//::})
|
||
lcLastRunDate2 = ALLTRIM(NVL(citeste_optiune("EFACTURA_LASTRUN_DATE2"), ''))
|
||
This.dLastRunDate2 = Iif(!Empty(m.lcLastRunDate2), CTOT(m.lcLastRunDate2), {//::})
|
||
This.nLastRunDays = INT(VAL(ALLTRIM(NVL(citeste_optiune("EFACTURA_LASTRUN_DAYS"), ''))))
|
||
This.nLastRunSucces = INT(VAL(ALLTRIM(NVL(citeste_optiune("EFACTURA_LASTRUN_SUCCES"), ''))))
|
||
|
||
************
|
||
* Actualizeaza Token automat si citeste Token din baza de date
|
||
* This.GetToken()
|
||
This.RefreshTokenAuto()
|
||
ELSE
|
||
lcErrorMessage = 'ReadSettingsFromDb Eroare la initializarea setarilor'
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
ENDIF
|
||
|
||
This.Log('This.nSaveFile ' + TRANSFORM(This.nSaveFile) + CHR(13) + CHR(10) + ;
|
||
'This.nSaveAnafPdfFile ' + TRANSFORM(This.nSaveAnafPdfFile ) + CHR(13) + CHR(10) + ;
|
||
'This.cServerPath ' + ALLTRIM(This.cServerPath) + CHR(13) + CHR(10) + ;
|
||
'This.cNetworkPath ' + ALLTRIM(This.cNetworkPath) + CHR(13) + CHR(10) + ;
|
||
'This.cSaveFurnizoriPath ' + ALLTRIM(This.cSaveFurnizoriPath ) + CHR(13) + CHR(10) + ;
|
||
'This.cSaveClientiPath ' + ALLTRIM(This.cSaveClientiPath ) + CHR(13) + CHR(10) + ;
|
||
'This.cResponsesPath ' + ALLTRIM(This.cResponsesPath ) + CHR(13) + CHR(10) + ;
|
||
'This.cSaveLogsPath ' + ALLTRIM(This.cSaveLogsPath ))
|
||
RETURN m.llSucces
|
||
|
||
ENDPROC && ReadSettingsFromDb
|
||
*********************
|
||
*
|
||
*********************
|
||
PROCEDURE InitDB
|
||
LPARAMETERS tnZile
|
||
* tnZile: cate zile de raspunsuri se descarca, pentru a se verifica si cu baza de date cu tnZile de raspunsuri
|
||
LOCAL llSucces, lnZile
|
||
lnZile = IIF(EMPTY(m.tnZile), 60, m.tnZile) + 10 && adaug 10 zile pentru precautie
|
||
|
||
lnHandle = This.ConnectROA()
|
||
llSucces = (m.lnHandle > 0)
|
||
IF m.llSucces
|
||
pdData2 = DATE()+1
|
||
pdData1 = DATE() - m.lnZile
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
||
from anaf_efactura a
|
||
where a.data_raspuns between ?pdData1 and ?pdData2
|
||
ENDTEXT
|
||
|
||
llSucces = goExecutor.oExecuta(m.lcSql,"anaf_efactura")
|
||
IF m.llSucces
|
||
SELECT anaf_efactura
|
||
INDEX on id_incarcare TAG id_inc
|
||
INDEX on id_descarcare TAG id_desc
|
||
ENDIF
|
||
|
||
lnSucces = This.DisconnectROA()
|
||
ENDIF && lnSucces
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC && InitDB
|
||
|
||
PROCEDURE ConnectROA
|
||
Local lnSucces
|
||
|
||
IF This.lConnected
|
||
* Nu ma conectez la baza de date daca sunt deja conectat (ex: Daca se apeleaza programul din ROACONT si sunt deja conectat la baza de date)
|
||
lnSucces = CT_SUCCES
|
||
ELSE
|
||
lnSucces = IIF(goConn.Connect() > 0, CT_SUCCES, CT_INSUCCES)
|
||
ENDIF
|
||
Return lnSucces
|
||
ENDPROC
|
||
|
||
PROCEDURE DisconnectROA
|
||
Local lnSucces
|
||
|
||
IF This.lConnected
|
||
lnSucces = CT_SUCCES
|
||
ELSE
|
||
lnSucces = goConn.Disconnect()
|
||
ENDIF
|
||
RETURN m.lnSucces
|
||
ENDPROC && DisconnectROA
|
||
|
||
Procedure Log
|
||
Lparameters tcText, tcProgram
|
||
|
||
IF TYPE('goLog') = 'O'
|
||
goLog.Log(tcText, tcProgram)
|
||
ELSE
|
||
lcText = Ttoc(Datetime(),3) + ' ' + IIF(!EMPTY(m.tcProgram), m.tcProgram + ' ', '') + m.tcText + CRLF
|
||
Strtofile(m.lcText, This.cLogFile, 1)
|
||
ENDIF
|
||
Endproc && Log
|
||
|
||
|
||
*******************************************************************
|
||
* Actualizare automata Token
|
||
*******************************************************************
|
||
FUNCTION RefreshTokenAuto
|
||
|
||
This.GetToken()
|
||
|
||
IF (This.lTokenAutoRefresh AND !EMPTY(NVL(This.cToken,'')) AND !EMPTY(NVL(This.cRefreshToken, ''))) AND (This.dTokenExpdate <= DATE())
|
||
This.RefreshToken()
|
||
ENDIF
|
||
|
||
This.GetToken()
|
||
ENDFUNC
|
||
|
||
************************************************************************
|
||
Function GetToken
|
||
Local lcRefreshToken, lcToken, lcTokenExpDate, lcTokenGenDate, ldTokenExpDate, ldTokenGenDate
|
||
|
||
lnTokenAutoRefresh = INT(VAL(ALLTRIM(citeste_optiune("ANAF_TOKEN_AUTO_REFRESH")))) && 1
|
||
This.lTokenAutoRefresh = (m.lnTokenAutoRefresh = 1)
|
||
|
||
* TokenJWT are dimensiunea mai mare. Il salvez in optiuni.varvalue2
|
||
lcToken = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN', .T.), ''))
|
||
lcRefreshToken = Alltrim(Nvl(citeste_optiune('ANAF_REFRESH_TOKEN', .T.), ''))
|
||
|
||
lcTokenGenDate = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN_GENDATE'), ''))
|
||
ldTokenGenDate = Iif(!Empty(m.lcTokenGenDate), Ctod(m.lcTokenGenDate), {})
|
||
lcTokenExpDate = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN_EXPDATE'), ''))
|
||
ldTokenExpDate = Iif(!Empty(m.lcTokenExpDate), Ctod(m.lcTokenExpDate), {})
|
||
ldTokenExpDate = Iif(!Empty(m.ldTokenExpDate), m.ldTokenExpDate, m.ldTokenGenDate + 90)
|
||
lcTokenURL = Alltrim(Nvl(citeste_optiune('ANAF_URL_TOKEN'), ''))
|
||
|
||
This.cToken = m.lcToken
|
||
This.cRefreshToken = m.lcRefreshToken
|
||
This.dTokenGendate = m.ldTokenGenDate
|
||
This.dTokenExpdate = m.ldTokenExpDate
|
||
This.cTokenUrl = m.lcTokenURL
|
||
|
||
Do Case
|
||
Case Empty(m.lcToken)
|
||
This.Log('Token nu este configurat.')
|
||
Case m.ldTokenExpDate <= Date()
|
||
This.Log('Token expirat.')
|
||
Endcase
|
||
|
||
Return This.cToken
|
||
Endfunc
|
||
|
||
***************************
|
||
* Salveaza tokenul in baza de date optiuni firma
|
||
***************************
|
||
Procedure SaveToken
|
||
scrie_optiune('ANAF_TOKEN', This.cToken, 'ANAF Token SPV eFactura', .T.)
|
||
scrie_optiune('ANAF_REFRESH_TOKEN', This.cRefreshToken, 'ANAF Refresh Token SPV eFactura', .T.)
|
||
scrie_optiune('ANAF_TOKEN_GENDATE', Dtoc(This.dTokenGendate), 'ANAF Token SPV eFactura data generare')
|
||
scrie_optiune('ANAF_TOKEN_EXPDATE', Dtoc(This.dTokenExpdate), 'ANAF Token SPV eFactura data expirare')
|
||
Endproc && SaveToken
|
||
|
||
|
||
*!* 07.07.2026
|
||
*!* newToken - flux automat OAuth2: state + sesiune PHP + polling pick.php
|
||
*!* implementare unica in AnafeFacturaServer; ANAFeFactura deleaga
|
||
*!* kill switch ANAF_TOKEN_AUTOFLOW (1=automat, 0=vechi), garda headless
|
||
|
||
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
||
* Se apeleaza din formularul anaf_token.do_executa (prin ANAFeFactura.newToken)
|
||
Function newToken
|
||
LOCAL lnAutoFlowVal, lcAutoFlowStr, lcTokenURL, lcState, lcStatePrefix
|
||
LOCAL lcBuf1, lcBuf2, lni, lnAscByte, lcHexChars
|
||
LOCAL lcBrowserUrl, lcPickUrl, lcExitCode
|
||
LOCAL loHTTP, lnStatus, lcResponse, loJson
|
||
LOCAL lnStartSec, lnElapsed, lnStep, lnKey
|
||
LOCAL loExHTTP, loExJson, loExSave
|
||
|
||
* --- Garda headless: server/ROAEFACTURA (lServer=.T.) sau _SCREEN invizibil ---
|
||
* Pastreaza EXACT comportamentul vechi al AnafeFacturaServer.newToken
|
||
IF This.lServer OR !_SCREEN.Visible
|
||
This.Log('Introduceti in calculator tokenul USB cu semnatura electronica' + LF + ;
|
||
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + LF + ;
|
||
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ' + m.gcGeneralIniFile)
|
||
lcTokenURL = This.cTokenUrl
|
||
open_default_app(m.gcGeneralIniFile)
|
||
open_default_app(m.lcTokenURL)
|
||
RETURN
|
||
ENDIF
|
||
|
||
* --- Kill switch: default 1 la NULL/inexistent/Oracle indisponibil ---
|
||
lnAutoFlowVal = 1
|
||
TRY
|
||
lcAutoFlowStr = ALLTRIM(NVL(citeste_optiune("ANAF_TOKEN_AUTOFLOW"), ''))
|
||
IF !EMPTY(lcAutoFlowStr)
|
||
lnAutoFlowVal = INT(VAL(lcAutoFlowStr))
|
||
ENDIF
|
||
CATCH
|
||
lnAutoFlowVal = 1
|
||
ENDTRY
|
||
|
||
lcTokenURL = ALLTRIM(NVL(This.cTokenUrl, ''))
|
||
IF EMPTY(lcTokenURL)
|
||
lcTokenURL = 'https://romfast.ro/oauth2/'
|
||
ENDIF
|
||
|
||
* --- Kill switch OFF (0) -> comportament vechi nemodificat ---
|
||
IF lnAutoFlowVal <> 1
|
||
AMESSAGEBOX('Introduceti in calculator tokenul USB cu semnatura electronica' + CHR(13) + CHR(10) + ;
|
||
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + CHR(13) + CHR(10) + ;
|
||
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ROA.', 0 + 64, _Screen.Caption)
|
||
open_default_app(m.lcTokenURL)
|
||
RETURN
|
||
ENDIF
|
||
|
||
* --- Modal initial OK/Anulare ---
|
||
IF aMESSAGEBOX('Se va genera un token nou eFactura.' + CHR(13) + ;
|
||
'1. Introduceti tokenul USB cu semnatura electronica in calculator.' + CHR(13) + ;
|
||
'2. Se va deschide pagina ANAF in browser: selectati certificatul dvs. si introduceti PIN-ul.' + CHR(13) + ;
|
||
'3. Reveniti in aplicatie - tokenul se preia automat.' + CHR(13) + CHR(13) + ;
|
||
'Continuati?', 1 + 64, _Screen.Caption) <> 1
|
||
RETURN
|
||
ENDIF
|
||
|
||
IF RIGHT(lcTokenURL, 1) <> '/'
|
||
lcTokenURL = lcTokenURL + '/'
|
||
ENDIF
|
||
|
||
* --- State anti-CSRF: 2 GUID-uri CoCreateGuid -> 64 hex (SYS(2015) e predictibil) ---
|
||
TRY
|
||
DECLARE INTEGER CoCreateGuid IN ole32 STRING @pguid
|
||
CATCH
|
||
* deja declarata in aceasta sesiune VFP
|
||
ENDTRY
|
||
lcBuf1 = REPLICATE(CHR(0), 16)
|
||
lcBuf2 = REPLICATE(CHR(0), 16)
|
||
CoCreateGuid(@lcBuf1)
|
||
CoCreateGuid(@lcBuf2)
|
||
lcBuf1 = lcBuf1 + lcBuf2 && 32 octeti aleatori = 256 biti entropie
|
||
lcHexChars = '0123456789abcdef'
|
||
lcState = ''
|
||
FOR lni = 1 TO 32
|
||
lnAscByte = ASC(SUBSTR(lcBuf1, lni, 1))
|
||
lcState = lcState + SUBSTR(lcHexChars, INT(lnAscByte/16)+1, 1) + SUBSTR(lcHexChars, MOD(lnAscByte,16)+1, 1)
|
||
ENDFOR
|
||
lcStatePrefix = LEFT(lcState, 8) && doar prefixul apare in log, niciodata tokenuri
|
||
|
||
lcBrowserUrl = lcTokenURL + '?state=' + lcState
|
||
lcPickUrl = lcTokenURL + 'pick.php'
|
||
This.Log('[' + lcStatePrefix + '] start flux automat token')
|
||
|
||
* --- Lansare browser; open_default_app (oexport.prg) intoarce .T./.F. (ShellExecute > 32) ---
|
||
IF !open_default_app(lcBrowserUrl)
|
||
AMESSAGEBOX('Nu s-a putut deschide browserul. Se continua cu fluxul manual: se va deschide pagina care afiseaza codurile pentru copiere.', 0 + 64, _Screen.Caption)
|
||
This.Log('[' + lcStatePrefix + '] esec lansare browser -> fallback manual')
|
||
open_default_app(lcTokenURL) && fara ?state -> pagina afiseaza codurile (retro-compat)
|
||
RETURN
|
||
ENDIF
|
||
|
||
* --- Polling pick.php la 2s: timeout 10 minute, Esc = anulare ---
|
||
lcExitCode = ''
|
||
lnStartSec = SECONDS()
|
||
DO WHILE .T.
|
||
lnElapsed = SECONDS() - lnStartSec
|
||
IF lnElapsed < 0
|
||
lnElapsed = lnElapsed + 86400 && trecere miezul noptii
|
||
ENDIF
|
||
IF lnElapsed >= 600
|
||
lcExitCode = 'timeout'
|
||
EXIT
|
||
ENDIF
|
||
WAIT WINDOW 'Asteptare autorizare ANAF... Continuati in fereastra browserului: selectati certificatul si introduceti PIN-ul. (Esc = anulare)' NOWAIT
|
||
|
||
lnStatus = 0
|
||
lcResponse = ''
|
||
TRY
|
||
loHTTP = CREATEOBJECT('WinHttp.WinHttpRequest.5.1')
|
||
loHTTP.SetTimeouts(5000, 5000, 5000, 5000)
|
||
loHTTP.Open('POST', lcPickUrl, .F.)
|
||
loHTTP.SetRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
|
||
loHTTP.Send('state=' + lcState)
|
||
lnStatus = loHTTP.Status
|
||
lcResponse = loHTTP.ResponseText
|
||
CATCH TO loExHTTP
|
||
* eroare retea tranzitorie -> continuam polling pana la timeout
|
||
ENDTRY
|
||
|
||
IF lnStatus = 200
|
||
loJson = NULL
|
||
TRY
|
||
loJson = nfjsonread(lcResponse)
|
||
CATCH TO loExJson
|
||
This.Log('[' + lcStatePrefix + '] eroare parsare JSON: ' + loExJson.Message)
|
||
ENDTRY
|
||
IF TYPE('loJson') = 'O' AND !ISNULL(loJson)
|
||
IF TYPE('loJson.error') <> 'U'
|
||
lcExitCode = 'anaf_error'
|
||
EXIT
|
||
ENDIF
|
||
IF TYPE('loJson.access_token') <> 'U' AND TYPE('loJson.refresh_token') <> 'U'
|
||
* Tokenuri primite - populare proprietati (fara valori de tokenuri in log)
|
||
This.cToken = loJson.access_token
|
||
This.cRefreshToken = loJson.refresh_token
|
||
This.dTokenGendate = DATE()
|
||
IF TYPE('loJson.expires_in') <> 'U'
|
||
This.dTokenExpdate = DATE() + INT(VAL(TRANSFORM(loJson.expires_in)) / 86400)
|
||
ELSE
|
||
This.dTokenExpdate = DATE() + 90
|
||
ENDIF
|
||
lcExitCode = 'success'
|
||
EXIT
|
||
ENDIF
|
||
* {"status":"pending"} sau alt continut -> continuam polling
|
||
ENDIF
|
||
ENDIF
|
||
|
||
* asteptare 2s cu verificare Esc la fiecare 0.5s
|
||
lnStep = 0
|
||
DO WHILE lnStep < 4
|
||
lnKey = INKEY(0.5)
|
||
IF lnKey = 27 && Esc
|
||
lcExitCode = 'esc'
|
||
EXIT
|
||
ENDIF
|
||
lnStep = lnStep + 1
|
||
ENDDO
|
||
IF lcExitCode = 'esc'
|
||
EXIT
|
||
ENDIF
|
||
ENDDO
|
||
WAIT CLEAR
|
||
This.Log('[' + lcStatePrefix + '] iesire: ' + lcExitCode)
|
||
|
||
DO CASE
|
||
CASE lcExitCode = 'success'
|
||
TRY
|
||
This.SaveToken()
|
||
AMESSAGEBOX('S-a generat token-ul eFactura, valabil pana la ' + DTOC(This.dTokenExpdate), 0 + 64, _Screen.Caption)
|
||
CATCH TO loExSave
|
||
* tokenul ramane in This.cToken; la reluarea operatiei va fi necesar PIN-ul din nou
|
||
AMESSAGEBOX('Tokenul a fost generat, dar salvarea in baza de date a esuat: ' + loExSave.Message + CHR(13) + ;
|
||
'Reluati operatia Token nou sau contactati suportul ROA.', 0 + 48, _Screen.Caption)
|
||
ENDTRY
|
||
|
||
CASE lcExitCode = 'esc'
|
||
AMESSAGEBOX('Ati anulat asteptarea. Daca ati introdus deja PIN-ul, autorizarea respectiva va fi ignorata; la reluare va trebui sa introduceti PIN-ul din nou.', 0 + 64, _Screen.Caption)
|
||
|
||
CASE lcExitCode = 'timeout'
|
||
AMESSAGEBOX('Nu s-a primit tokenul in 10 minute. Se deschide pagina pentru completare manuala; puteti si relua operatia Token nou.', 0 + 48, _Screen.Caption)
|
||
open_default_app(lcTokenURL)
|
||
|
||
CASE lcExitCode = 'anaf_error'
|
||
AMESSAGEBOX('Eroare la autorizarea ANAF: ' + TRANSFORM(NVL(loJson.error, '')) + '. Reluati operatia sau folositi completarea manuala (se deschide pagina care afiseaza codurile).', 0 + 48, _Screen.Caption)
|
||
open_default_app(lcTokenURL)
|
||
ENDCASE
|
||
|
||
Endfunc && newToken
|
||
|
||
* Actualizeaza data expirarii tokenului ANAF eFactura
|
||
* Se apeleaza din formularul anaf_token.do_executa
|
||
Function refreshToken
|
||
LPARAMETERS tcMesaj
|
||
* tcMesaj (OUT)
|
||
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local lcRefreshToken, lcResponse, lcURL, llSucces, loJson, loEx as Exception
|
||
llSucces = .T.
|
||
lcRefreshToken = Alltrim(This.cRefreshToken)
|
||
tcMesaj = ''
|
||
SET STEP ON
|
||
If Empty(m.lcRefreshToken)
|
||
tcMesaj = 'Completati Refresh Token'
|
||
This.Log(m.tcMesaj)
|
||
Else
|
||
lcURL = This.cTokenUrl
|
||
|
||
TRY
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
loHTTP.Open('POST', lcURL, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
||
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
||
|
||
CATCH TO loEx
|
||
llSucces = .F.
|
||
ENDTRY
|
||
|
||
IF !m.llSucces OR TYPE('loHTTP') <> 'O'
|
||
TRY
|
||
loHTTP = Createobject('MSXML2.XMLHTTP.6.0')
|
||
loHTTP.Open('POST', lcURL, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
||
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
||
CATCH TO loEx
|
||
llSucces = .F.
|
||
AMESSAGEBOX(loEx.Message,0,_screen.Caption)
|
||
ENDTRY
|
||
ENDIF
|
||
|
||
llSucces = (TYPE('loHTTP') = 'O')
|
||
IF m.llSucces
|
||
lcResponse = loHTTP.ResponseText
|
||
llSucces = (loHTTP.Status = 200)
|
||
ENDIF
|
||
If !m.llSucces
|
||
lcResponse = loHTTP.StatusText
|
||
Endif
|
||
|
||
If m.llSucces
|
||
TRY
|
||
loJson = nfjsonread(m.lcResponse)
|
||
CATCH TO loEx
|
||
llSucces = .F.
|
||
tcMesaj = 'Refresh token - eroare extragere raspuns json: ' + loEx.message + CRLF + m.lcResponse
|
||
this.Log(m.tcMesaj)
|
||
ENDTRY
|
||
If Type('loJson.expires_in') <> 'U' And Type('loJson.access_token') <> 'U' And Type('loJson.refresh_token') <> 'U'
|
||
This.dTokenExpdate = Date() + Int(Val(Transform(loJson.expires_in)) / 24 / 3600) && 90 zile
|
||
This.dTokenGendate = Date()
|
||
This.cToken = loJson.access_token
|
||
This.cRefreshToken = loJson.refresh_token
|
||
|
||
This.SaveToken()
|
||
tcMesaj = 'S-a regenerat token-ul, cu valabilitate pana la ' + Dtoc(This.dTokenExpdate)
|
||
This.Log(m.tcMesaj)
|
||
ELSE
|
||
tcMesaj ='Nu s-a regenerat token-ul! Generati un token nou!' + LF + m.lcResponse
|
||
This.Log(m.tcMesaj)
|
||
Endif
|
||
ELSE
|
||
tcMesaj = 'Nu s-a regenerat token-ul! Status = ' + Transform(loHTTP.Status) + CRLF + m.lcResponse
|
||
This.Log(m.tcMesaj)
|
||
Endif
|
||
Endif
|
||
|
||
Return m.llSucces
|
||
Endfunc
|
||
|
||
|
||
*********************
|
||
* Trimite fisiere xml eFactura in SPV
|
||
*********************
|
||
PROCEDURE VizeFacturaXml
|
||
|
||
CREATE CURSOR cXmlFiles (ales N(1), filepath c(250), procesat N(1), stare c(100), mesaj c(250), extern N(1))
|
||
|
||
loXmlFiles = CREATEOBJECT("anaf_efactura_xml", This)
|
||
loXmlFiles.Show(1)
|
||
|
||
USE IN (SELECT('cXmlFiles'))
|
||
|
||
ENDPROC && VizeFacturaXml
|
||
|
||
********************************
|
||
* Genereaza xml efactura, valideaza xml si trimite la API ANAF
|
||
* parseaza un director cu xml efactura si le trimite la API ANAF
|
||
********************************
|
||
Procedure TrimiteFacturaXML
|
||
LPARAMETERS tcFile, tlValidare, tlValidareOnline, tlNuTrimiteEFacturaANAF, tlExtern
|
||
|
||
Local loXmlEFactura As 'ExportEFactura'
|
||
Local lcErrorMessage, lcExecutionStatus, lcFile, lcIndexIncarcare, lcMesaj, llSucces, llValid, loEx
|
||
Local loXML, lcMesajValidare, llExtern, lcToken
|
||
PRIVATE pcIdIncarcare, pcMesajTrimis, pnTrimis
|
||
|
||
LOCAL loReturn
|
||
|
||
lcFile = m.tcFile
|
||
lcMesaj = ''
|
||
lcMesajValidare = ''
|
||
|
||
lcToken = This.cToken
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", .F.)
|
||
AddProperty(loReturn, "cFile", '')
|
||
AddProperty(loReturn, "cResponse", '')
|
||
AddProperty(loReturn, "nStatus", 0)
|
||
|
||
llExtern = m.tlExtern
|
||
|
||
llValid = .T.
|
||
IF m.tlValidare
|
||
llSilentios = .T.
|
||
loXmlEFactura = CREATEOBJECT('ExportEFactura', m.llSilentios, m.lcToken)
|
||
llValid = loXmlEFactura.ValidareEFactura(m.lcFile, @lcMesajValidare, m.tlValidareOnline)
|
||
ENDIF
|
||
|
||
IF m.llValid AND !m.tlNuTrimiteEFacturaANAF
|
||
loReturn = This.SendEfactura(m.lcFile, m.llExtern)
|
||
llSucces = loReturn.lSucces
|
||
AddProperty(loReturn, "cIdIncarcare", '')
|
||
AddProperty(loReturn, "cMesaj", '')
|
||
|
||
If m.llSucces
|
||
pcMesajTrimis = Iif(This.lTest, 'TEST ', '')
|
||
loXML = Null
|
||
Try
|
||
loXML = nfxmlread(loReturn.cResponse)
|
||
Catch To loEx
|
||
lcErrorMessage = loEx.Message
|
||
Endtry
|
||
|
||
lcExecutionStatus = ''
|
||
lcIndexIncarcare = ''
|
||
lcErrorMessage = ''
|
||
If Type('loxml.header._attr_.executionstatus') <> 'U'
|
||
lcExecutionStatus = loXML.Header._attr_.executionstatus
|
||
Endif
|
||
If Type('loxml.header._attr_.index__incarcare') <> 'U'
|
||
lcIndexIncarcare = loXML.Header._attr_.index__incarcare
|
||
Endif
|
||
If Type('loxml.header.errors._attr_.errorMessage') <> 'U'
|
||
lcErrorMessage = loXML.Header.errors._attr_.ErrorMessage
|
||
Endif
|
||
|
||
Do Case
|
||
Case lcExecutionStatus = "0"
|
||
pcIdIncarcare = m.lcIndexIncarcare
|
||
pnTrimis = 1
|
||
pcMesajTrimis = m.pcMesajTrimis + 'Transmis cu succes. Index incarcare = ' + m.pcIdIncarcare
|
||
loReturn.cIdIncarcare = m.pcIdIncarcare
|
||
loReturn.lSucces = .T.
|
||
|
||
Case !Empty(m.lcErrorMessage)
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 1
|
||
pcMesajTrimis = m.pcMesajTrimis + Iif(This.lTest, 'TEST ', '') + 'Eroare. ' + m.lcErrorMessage
|
||
|
||
Case [VALID] $ Upper(loReturn.cResponse)
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 0
|
||
pcMesajTrimis = m.pcMesajTrimis + loReturn.cResponse
|
||
|
||
Otherwise
|
||
pcMesajTrimis = m.pcMesajTrimis + Iif(This.lTest, 'TEST ', '') + 'Eroare. ' + m.lcErrorMessage
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 1
|
||
Endcase
|
||
|
||
loReturn.cMesaj = m.pcMesajTrimis + ' ' + m.lcMesajValidare
|
||
Else
|
||
pcMesajTrimis = ' Eroare transmitere - Http Status: ' + Transform(loReturn.nStatus) + ' Http Response: ' + Alltrim(Transform(loReturn.cResponse)) + ' ' + loReturn.cResponse
|
||
loReturn.cResponse = pcMesajTrimis
|
||
loReturn.cMesaj = m.pcMesajTrimis + ' ' + m.lcMesajValidare
|
||
This.Log(loReturn.cResponse)
|
||
ENDIF
|
||
ELSE
|
||
AddProperty(loReturn, "cIdIncarcare", '')
|
||
AddProperty(loReturn, "cMesaj", '')
|
||
|
||
pcMesajTrimis = '. Nu s-a trimis fisierul la ANAF.'
|
||
loReturn.cResponse = m.pcMesajTrimis
|
||
|
||
IF m.llValid
|
||
loReturn.cMesaj = 'Nu s-a trimis fisierul. ' + m.lcMesajValidare
|
||
loReturn.lSucces = .T.
|
||
llSucces = .T.
|
||
ELSE
|
||
loReturn.cMesaj = 'Eroare validare. Nu s-a trimis fisierul: ' + m.lcMesajValidare
|
||
loReturn.lSucces = .F.
|
||
llSucces = .F.
|
||
ENDIF
|
||
ENDIF
|
||
|
||
RETURN loReturn
|
||
|
||
Endproc && TrimiteFacturaXML
|
||
|
||
* Genereaza xml eFactura, valideaza xml si trimite la ANAF
|
||
Function SendEfactura
|
||
Lparameters tcFile, tlExtern, tlMesaj
|
||
* tcFile: calea catre fisierul xml efactura / sau xml mesaj
|
||
* tlExtern: daca se apeleaza cu parametrul Extern=DA (pentru clientii externi)
|
||
* tlMesaj: daca mesajul este o factura sau un mesaj catre furnizor
|
||
|
||
Local loEx As Exception
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local loReturn As "empty"
|
||
Local lcCodFiscal, lcExtern, lcFile, lcSend, lcServer, lcToken, llOk, llTest, llB2C
|
||
LOCAL lcCustomer, lcPartyLegal, lcCodFiscalClient
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", .F.)
|
||
AddProperty(loReturn, "cFile", '')
|
||
AddProperty(loReturn, "cResponse", '')
|
||
AddProperty(loReturn, "nStatus", 0)
|
||
|
||
lcToken = This.cToken
|
||
lcCodFiscal = ALLTRIM(This.cCodFiscal)
|
||
llTest = This.lTest
|
||
llOk = .F.
|
||
lcFile = ''
|
||
|
||
lcFile = Iif(Type('tcFile') = 'C' and !Empty(m.tcFile), m.tcFile, '')
|
||
loReturn.cFile = m.lcFile
|
||
lcExtern = Iif(m.tlExtern, '&extern=DA', '')
|
||
This.Log('SendEFactura: ' + m.lcFile)
|
||
If File(m.lcFile)
|
||
lcSend = Filetostr(m.lcFile)
|
||
|
||
* Verific daca clientul este persoana fizica si folosesc upload2bc in loc de upload
|
||
lcCustomer = STREXTRACT(lcSend, '<cac:AccountingCustomerParty>', '</cac:AccountingCustomerParty>',1,1)
|
||
lcPartyLegal = STREXTRACT(lcCustomer, '<cac:PartyLegalEntity>', '</cac:PartyLegalEntity>',1,1)
|
||
lcCodFiscalClient = ALLTRIM(STREXTRACT(m.lcPartyLegal, '<cbc:CompanyID>','</cbc:CompanyID>',1,1))
|
||
llB2C = (LEN(m.lcCodFiscalClient) = 13) && persoane fizice
|
||
|
||
TRY
|
||
IF !m.tlMesaj
|
||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/upload] + IIF(m.llB2C,'b2c','') + [?standard=UBL&cif=] + m.lcCodFiscal + m.lcExtern
|
||
ELSE
|
||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/upload] + IIF(m.llB2C,'b2c','') + [?standard=RASP&cif=] + m.lcCodFiscal
|
||
ENDIF
|
||
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
loHTTP.Open('POST', lcServer, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/xml;")
|
||
loHTTP.setRequestHeader('Authorization', 'Bearer ' + m.lcToken) && 9b1f44af738c16aa10c78347b9a064857f034b03a20704a03c131b99f019cee5
|
||
poLog.Log(m.lcServer)
|
||
|
||
loHTTP.Send(m.lcSend)
|
||
|
||
loReturn.nStatus = loHTTP.Status
|
||
loReturn.cResponse = loHTTP.ResponseText
|
||
loReturn.lSucces = (loHTTP.Status = 200)
|
||
|
||
CATCH TO loEx
|
||
loReturn.lSucces = .F.
|
||
loReturn.cResponse = '<errorMessage="' + loEx.message + '">'
|
||
ENDTRY
|
||
Else
|
||
loReturn.cResponse = '<errorMessage="Nu exista fisierul' + m.lcFile + '">'
|
||
loReturn.lSucces = .F.
|
||
ENDIF
|
||
|
||
This.Log('SendEFactura: ' + Transform(loReturn.nStatus) + ' ' + Transform(loReturn.lSucces) + ' ' + loReturn.cResponse)
|
||
Return loReturn
|
||
Endfunc
|
||
|
||
* Genereaza xml mesaj catre furnizor si trimite la ANAF
|
||
Function SendMesaj
|
||
Lparameters tnIdIncarcare, tcMesaj
|
||
|
||
LOCAL lnIdIncarcare, lcMesaj, llMesaj, loReturn, lcFile
|
||
lcFile = ADDBS(SYS(2023)) + FORCEEXT(SYS(2015), 'xml')
|
||
llMesaj = .T.
|
||
lcMesaj = Alltrim(XmlSpecialCharacters(RemoveCharacters(m.tcMesaj, .T.)))
|
||
lnIdIncarcare = ALLTRIM(NVL(m.tnIdIncarcare,''))
|
||
|
||
TEXT TO lcText TEXTMERGE NOSHOW
|
||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||
<header xmlns="mfp:anaf:dgti:spv:reqMesaj:v1" index_incarcare="<<m.lnIdIncarcare>>" message="<<m.lcMesaj>>"/>
|
||
ENDTEXT
|
||
STRTOFILE(m.lcText, m.lcFile)
|
||
|
||
loReturn = This.SendEFactura(m.lcFile,,m.llMesaj)
|
||
IF FILE(m.lcFile)
|
||
DELETE FILE (m.lcFile)
|
||
ENDIF
|
||
RETURN loReturn
|
||
ENDFUNC
|
||
|
||
*************************
|
||
* Dezarhiveaza o arhiva si intoarce .T./.F.
|
||
*************************
|
||
Procedure UnzipFile
|
||
Lparameters tcZipFile, tcDir, tcErrorMessage
|
||
* tcZipFile: arhiva zip cu detaliile raspunsului unei eFactura
|
||
* tcDir: IN/OUT directorul cu fisierele dezarhivate
|
||
* tcErrorMessage: OUT mesaj de eroare
|
||
|
||
Local laZipTemp[1, 3], lcDir, lcFileName, llSucces, llSilent
|
||
tcErrorMessage = ''
|
||
llSilent = .T.
|
||
|
||
IF TYPE('tcDir') <> 'C' OR EMPTY(NVL(m.tcDir, ''))
|
||
tcDir = ADDBS(JUSTPATH(m.tcZipFile))
|
||
ENDIF
|
||
|
||
This.Log('UnzipFile ' + m.tcZipFile)
|
||
llSucces = MyUnzip(m.tcZipFile, @tcDir, @tcErrorMessage, m.llSilent)
|
||
|
||
Return m.llSucces
|
||
ENDPROC && UnzipFile
|
||
|
||
*********************************
|
||
* Proces ProcesCopiere: copiez arhiva zip intr-o structura de directoare, dezarhivez, transform xml in pdf
|
||
*********************************
|
||
PROCEDURE ProcesareRaspunsuri
|
||
LPARAMETERS tlFortareRaspunsuri
|
||
|
||
Local lcDir, lcDir2, lcErrorMessage, lcFile, lcFile2, lcFile2Semnatura, lcFilePdf, lcFileSemnatura
|
||
Local lcIdDescarcare, lcIdIncarcare, lcTipRaspuns, lcZipFile, llSucces, loEx, loFactura, llFortareRaspunsuri
|
||
|
||
llFortareRaspunsuri = m.tlFortareRaspunsuri
|
||
|
||
This.Log('Procesare Raspunsuri')
|
||
|
||
* procesez server si nu este descarcat sau client (borderou eFactura ROACONT) si nu este procesat (completat detalii)
|
||
SELECT id_incarcare, id_descarcare, tip_mesaj_raspuns, filepath, procesat ;
|
||
FROM anaf_efactura WITH (BUFFERING = .T.) ;
|
||
WHERE ((This.lServer AND (procesat_server = 0 OR procesat = 0)) OR (!This.lServer AND (procesat = 0 OR modificat = 1))) AND ;
|
||
!EMPTY(NVL(filepath,'')) ;
|
||
ORDER BY id_incarcare ;
|
||
INTO CURSOR cRaspunsuriTemp
|
||
|
||
This.Log('Procesare Raspunsuri ' + ALLTRIM(STR(RECCOUNT('cRaspunsuriTemp'))) + ' fisiere de procesat')
|
||
|
||
llSucces = .T.
|
||
SELECT cRaspunsuriTemp
|
||
SCAN
|
||
lcIdIncarcare = ALLTRIM(id_incarcare)
|
||
lcIdDescarcare = ALLTRIM(id_descarcare)
|
||
lcZipFile = ALLTRIM(filepath)
|
||
lcTipRaspuns = UPPER(ALLTRIM(tip_mesaj_raspuns))
|
||
|
||
lcText = 'ProcesareRaspunsuri ' + ALLTRIM(STR(RECNO())) + '/' + ALLTRIM(STR(RECCOUNT()))
|
||
WAIT WINDOW m.lcText NOWAIT
|
||
This.Log(m.lcText)
|
||
|
||
IF FILE(m.lcZipFile)
|
||
lcDir = ''
|
||
lcErrorMessage = ''
|
||
|
||
llSucces = This.UnzipFile(m.lcZipFile, @lcDir, @lcErrorMessage)
|
||
|
||
IF !m.llSucces
|
||
lcErrorMessage = 'ProcesareRaspunsuri Eroare dezarhivare detalii factura id_incarcare = ' + Alltrim(m.lcIdIncarcare) + '. ' + m.lcErrorMessage
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
WAIT WINDOW m.lcErrorMessage NOWAIT
|
||
This.Log(m.lcErrorMessage)
|
||
ELSE
|
||
TRY
|
||
lcFile = Addbs(m.lcDir) + m.lcIdIncarcare + '.xml'
|
||
lcFileSemnatura = Addbs(m.lcDir) + 'semnatura_' + m.lcIdIncarcare + '.xml'
|
||
|
||
* Completez xml dezarhivat in anaf_efactura
|
||
lcDetalii = FILETOSTR(m.lcFile)
|
||
|
||
llSucces = This.cUpdateDetalii(m.lcIdIncarcare, m.lcDetalii)
|
||
|
||
IF !m.llSucces
|
||
lcErrorMessage = 'ProcesareRaspunsuri Eroare actualizare detalii id_incarcare ' + m.lcIdIncarcare
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
WAIT WINDOW m.lcErrorMessage NOWAIT
|
||
This.Log(m.lcErrorMessage)
|
||
ENDIF
|
||
|
||
* Parsez doar FATURA PRIMITA/FACTURA TRIMISA
|
||
IF Inlist(m.lcTipRaspuns, 'FACTURA PRIMITA', 'FACTURA TRIMISA') AND FILE(m.lcFile)
|
||
loFactura = ParseEFactura(m.lcFile)
|
||
|
||
ADDPROPERTY(loFactura, 'cIdIncarcare', m.lcIdIncarcare)
|
||
ADDPROPERTY(loFactura, 'cIdDescarcare', m.lcIdDescarcare)
|
||
ADDPROPERTY(loFactura, 'tip_mesaj_raspuns', m.lcTipRaspuns)
|
||
|
||
llSucces = This.cUpdateFactura(loFactura)
|
||
|
||
* Pe server, copiez arhiva zip, generez pdf in structura directoare custom
|
||
IF (This.nSaveFile = 1) AND ((This.lServer AND !EMPTY(NVL(This.cServerPath,''))) OR (!This.lServer AND !EMPTY(NVL(This.cNetworkPath,''))))
|
||
lcFile2 = This.GetFacturaSavePath(loFactura, 'zip')
|
||
lcDir2 = ADDBS(JUSTPATH(m.lcFile2))
|
||
lcFilePdf = m.lcDir2 + Juststem(m.lcFile2) + '.pdf'
|
||
If !File(m.lcFile2)
|
||
llSucces = This.SaveFile(m.lcZipFile, .F., m.lcDir2, JUSTFNAME(m.lcFile2))
|
||
ENDIF
|
||
IF (this.nSaveAnafPdfFile = 1) AND !FILE(m.lcFilePdf)
|
||
lcFilePdf = This.xml2PdfAnaf(m.lcFile, m.lcFilePdf)
|
||
ENDIF
|
||
|
||
This.cUpdateProcesatServer(m.lcIdIncarcare)
|
||
ELSE
|
||
* Marchez procesat server si daca nu trece prin procesul de procesare, pentru ca altfel il procesez din nou si urmatoarea data (dezarhivare, copiere)
|
||
This.cUpdateProcesatServer(m.lcIdIncarcare)
|
||
ENDIF && This.nSaveFile = 1
|
||
ENDIF && lcTipRaspuns
|
||
|
||
DELETE FILE(m.lcFile)
|
||
DELETE FILE(m.lcFileSemnatura)
|
||
|
||
Catch To loEx
|
||
llSucces = .F.
|
||
|
||
lcErrorMessage = 'ProcesareRaspunsuri Eroare la salvarea datelor extrase din xml eFactura. ' + 'Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
WAIT WINDOW m.lcErrorMessage NOWAIT
|
||
This.Log(m.lcErrorMessage)
|
||
ENDTRY
|
||
ENDIF
|
||
ENDIF
|
||
ENDSCAN && cRaspunsuriTemp
|
||
|
||
USE IN (SELECT('cRaspunsuriTemp'))
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC && ProcesareRaspunsuri
|
||
*********************************
|
||
*!* 24.07.2026 marius.mutu - import manual arhiva zip eFactura descarcata din SPV
|
||
*********************************
|
||
PROCEDURE ImportZipLocal
|
||
LPARAMETERS tcZipFile
|
||
* tcZipFile: (optional) arhiva zip descarcata din SPV. Daca lipseste, se alege cu Getfile
|
||
|
||
Local laFiles[1], lcCodFiscalClient, lcCodFiscalFurnizor, lcDir, lcErrorMessage, lcFilePath
|
||
Local lcId, lcSemnatura, lcTip, lcXmlFile, lcZipFile, llSucces, lnFile, lnFiles, loFactura
|
||
|
||
lcZipFile = IIF(TYPE('tcZipFile') = 'C' AND !EMPTY(NVL(m.tcZipFile, '')), ALLTRIM(m.tcZipFile), GETFILE('zip', 'Arhiva zip eFactura', 'Import'))
|
||
IF EMPTY(m.lcZipFile) OR !FILE(m.lcZipFile)
|
||
RETURN .F.
|
||
ENDIF
|
||
|
||
lcDir = ADDBS(SYS(2023)) + SYS(2015) + '\'
|
||
lcErrorMessage = ''
|
||
llSucces = This.UnzipFile(m.lcZipFile, @lcDir, @lcErrorMessage)
|
||
|
||
IF !m.llSucces
|
||
AMESSAGEBOX('Eroare la dezarhivarea ' + m.lcZipFile + CHR(13) + CHR(10) + m.lcErrorMessage, 0+48, _SCREEN.Caption)
|
||
RETURN .F.
|
||
ENDIF
|
||
|
||
* xml-ul facturii este fisierul xml care nu este semnatura MFinante
|
||
lcXmlFile = ''
|
||
lnFiles = ADIR(laFiles, ADDBS(m.lcDir) + '*.xml')
|
||
FOR lnFile = 1 TO m.lnFiles
|
||
IF !('SEMNATURA' $ UPPER(laFiles[m.lnFile, 1]))
|
||
lcXmlFile = ADDBS(m.lcDir) + ALLTRIM(laFiles[m.lnFile, 1])
|
||
EXIT
|
||
ENDIF
|
||
ENDFOR
|
||
|
||
IF EMPTY(m.lcXmlFile)
|
||
AMESSAGEBOX('Arhiva nu contine fisierul xml al facturii!', 0+48, _SCREEN.Caption)
|
||
RETURN .F.
|
||
ENDIF
|
||
|
||
lcId = ALLTRIM(JUSTSTEM(m.lcXmlFile))
|
||
loFactura = ParseEFactura(m.lcXmlFile)
|
||
|
||
IF TYPE('loFactura') <> 'O' OR loFactura.Eroare
|
||
AMESSAGEBOX('Eroare la citirea facturii din ' + m.lcXmlFile, 0+48, _SCREEN.Caption)
|
||
RETURN .F.
|
||
ENDIF
|
||
|
||
lcCodFiscalFurnizor = UPPER(ALLTRIM(GetNrFromString(NVL(loFactura.CodFiscalFurnizor, ''))))
|
||
lcCodFiscalClient = UPPER(ALLTRIM(GetNrFromString(NVL(loFactura.CodFiscalClient, ''))))
|
||
|
||
DO CASE
|
||
CASE !EMPTY(m.lcCodFiscalClient) AND m.lcCodFiscalClient == ALLTRIM(This.cCodFiscal)
|
||
lcTip = 'FACTURA PRIMITA'
|
||
CASE !EMPTY(m.lcCodFiscalFurnizor) AND m.lcCodFiscalFurnizor == ALLTRIM(This.cCodFiscal)
|
||
lcTip = 'FACTURA TRIMISA'
|
||
OTHERWISE
|
||
AMESSAGEBOX('Factura nu apartine firmei curente (cod fiscal ' + ALLTRIM(This.cCodFiscal) + ')!' + CHR(13) + CHR(10) + ;
|
||
'Emitent: ' + m.lcCodFiscalFurnizor + ' Beneficiar: ' + m.lcCodFiscalClient, 0+48, _SCREEN.Caption)
|
||
RETURN .F.
|
||
ENDCASE
|
||
|
||
* Salvez arhiva in directorul local de raspunsuri, ca la descarcarea din SPV
|
||
lcFilePath = GetPdfPath('EFACTURA', IIF(m.lcTip == 'FACTURA PRIMITA', 'PRIMITE', 'TRIMISE')) + m.lcId + '_' + m.lcId + '.zip'
|
||
IF !FILE(m.lcFilePath)
|
||
This.SaveFile(m.lcZipFile, .F., JUSTPATH(m.lcFilePath), JUSTFNAME(m.lcFilePath))
|
||
ENDIF
|
||
|
||
* Cursor temporar cu structura din InitDB, cu factura importata
|
||
llSucces = goExecutor.oExecuta("select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat from anaf_efactura a where 1 = 0", "canaf_efactura_temp")
|
||
|
||
IF !m.llSucces
|
||
AMESSAGEBOX('Eroare la citirea structurii anaf_efactura!', 0+48, _SCREEN.Caption)
|
||
RETURN .F.
|
||
ENDIF
|
||
|
||
INSERT INTO canaf_efactura_temp (id_incarcare, id_descarcare, data_raspuns, mesaj_raspuns, tip_mesaj_raspuns, ;
|
||
cod_fiscal_emitent, cod_fiscal_beneficiar, factura_emisa, test, descarcat, filepath, detalii, modificat) ;
|
||
VALUES (m.lcId, m.lcId, DATETIME(), 'Import manual ' + JUSTFNAME(m.lcZipFile), m.lcTip, ;
|
||
m.lcCodFiscalFurnizor, m.lcCodFiscalClient, IIF(m.lcTip == 'FACTURA PRIMITA', 0, 1), IIF(This.lTest, 1, 0), ;
|
||
0, m.lcFilePath, FILETOSTR(m.lcXmlFile), 1)
|
||
|
||
TABLEUPDATE(1, .F., 'canaf_efactura_temp')
|
||
|
||
ADDPROPERTY(loFactura, 'cIdIncarcare', m.lcId)
|
||
This.cUpdateFactura(loFactura, 'canaf_efactura_temp')
|
||
|
||
llSucces = This.UpdateDb('canaf_efactura_temp')
|
||
|
||
USE IN (SELECT('canaf_efactura_temp'))
|
||
|
||
lcSemnatura = ADDBS(m.lcDir) + 'semnatura_' + m.lcId + '.xml'
|
||
DELETE FILE (m.lcXmlFile)
|
||
IF FILE(m.lcSemnatura)
|
||
DELETE FILE (m.lcSemnatura)
|
||
ENDIF
|
||
|
||
IF m.llSucces
|
||
AMESSAGEBOX('Factura ' + ALLTRIM(loFactura.NumarAct) + ' din ' + DTOC(loFactura.DataAct) + ' a fost importata in borderoul eFactura!', 0+64, _SCREEN.Caption)
|
||
ENDIF
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC && ImportZipLocal
|
||
|
||
|
||
*********************************
|
||
* RASPUNSURI FACTURI
|
||
* Trebuie sa descarc ERORI FACTURI TRIMISE si FACTURI PRIMITE si sa citesc detalii (mesaj eroare, numar, data factura, detalii factura furnizor)
|
||
* Citesc lista de raspunsuri ANAF
|
||
* Descarc detaliile fiecarui raspuns neprocesat
|
||
* Salvez arhiva zip detalii in directorul zilei curente
|
||
*********************************
|
||
Procedure DescarcareRaspunsuri
|
||
Lparameters tnZile, tlFortareRaspunsuri
|
||
* tnZile : Cate zile de raspunsuri de la ANAF
|
||
* tlFortareRaspunsuri: .T. = se proceseaza si mesajele + detaliile deja salvate si procesate, default .F.
|
||
|
||
Local lcFile2, lcSelect, llSucces, lnMesaj, lnMesaje, lnRecno, lnZile, loAnafMesaj, loEx, loJson
|
||
Local loReturn, loMesaj, lnFortareRaspunsuri, loEx As Exception
|
||
|
||
llFortareRaspunsuri = Iif(Type('tlFortareRaspunsuri') = 'L', m.tlFortareRaspunsuri, .F.)
|
||
|
||
lcSelect = Select()
|
||
llSucces = .F.
|
||
|
||
*************************************************
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local loReturn As "empty"
|
||
Local lcServer, llTest, lcToken, lcCodFiscal, lnZile, lcText
|
||
|
||
llTest = This.lTest
|
||
lcToken = This.cToken
|
||
lcCodFiscal = This.cCodfiscal
|
||
lnZile = Iif(!Empty(m.tnZile), Min(m.tnZile, 60), 60)
|
||
|
||
ltEndTime = GetUtcTime(DATETIME()-60) && 60 de secunde in urma, ca sa fiu sigur? ca ceasul calculatorului nu este inainte fata de timpul serverului ANAF. Poate fi si cu mai mult de 1 minut
|
||
ltStartTime = ltEndTime - m.lnZile*24*60*60
|
||
|
||
lcStartTime = ALLTRIM(STR(Datetime2UnixTime(m.ltStartTime))) + '000'
|
||
lcEndTime = ALLTRIM(STR(Datetime2UnixTime(m.ltEndTime))) + '000'
|
||
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
|
||
lnPagina = 1
|
||
lnNumarTotalPagini = 99999
|
||
|
||
DO WHILE m.lnPagina <= m.lnNumarTotalPagini
|
||
TEXT TO lcServer TEXTMERGE NOSHOW
|
||
https://api.anaf.ro/<<Iif(m.llTest, [test], [prod])>>/FCTEL/rest/listaMesajePaginatieFactura?startTime=<<lcStartTime>>&endTime=<<lcEndTime>>&cif=<<lcCodFiscal>>&pagina=<<lnPagina>>
|
||
ENDTEXT
|
||
|
||
lcText = 'Descarcare Raspunsuri ultimele ' + TRANSFORM(m.lnZile) + ' zile : ' + TTOC(m.ltStartTime,3) + '-' + TTOC(m.ltEndTime,3)
|
||
WAIT WINDOW m.lcText NOWAIT
|
||
This.Log(m.lcText + ' ' + m.lcServer)
|
||
|
||
loHTTP.Open('GET', lcServer, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/xml;")
|
||
loHTTP.setRequestHeader('Authorization', 'Bearer ' + m.lcToken)
|
||
loHTTP.Send()
|
||
|
||
llSucces = (loHttp.Status = 200)
|
||
IF !m.llSucces
|
||
lcErrorMessage = This.cUser + ' ' + 'DescarcareRaspunsuri Eroare la citirea raspunsurilor! Solutii: 1. Reincercati operatia cu o perioada mai mica. 2. Actualizati/Regenerati token-ul de acces daca este expirat.' + LF + loHTTP.ResponseText
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
EXIT
|
||
ENDIF
|
||
|
||
llSucces = This.SaveFile(loHttp.ResponseText, .T.,This.cSaveLogsPath,'response_json_' + TTOC(Datetime(),1) + '.txt')
|
||
|
||
TRY
|
||
loJson = nfjsonread(loHTTP.ResponseText)
|
||
CATCH TO loEx
|
||
llSucces = .F.
|
||
lcErrorMessage = This.cUser + ' ' + 'DescarcareRaspunsuri ' + LF + ' Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
ENDTRY
|
||
|
||
IF TYPE('loJson') <> 'O'
|
||
llSucces = .F.
|
||
lcErrorMessage = This.cUser + ' ' + 'DescarcareRaspunsuri ' + LF + ' Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
EXIT
|
||
ENDIF
|
||
|
||
If Type('loJson.numar_total_pagini') = 'N'
|
||
lnNumarTotalPagini = loJson.numar_total_pagini
|
||
ENDIF
|
||
|
||
If Type('loJson.eroare') = 'C' And !Empty(loJson.eroare)
|
||
llSucces = .F.
|
||
lcErrorMessage = This.cUser + LF + loJson.eroare
|
||
This.cErrorMessage = m.lcErrorMessage + ;
|
||
IIF(ATC('Nu exista mesaje in intervalul selectat', loJson.eroare) > 0, '', ;
|
||
LF + 'Posibile cauze/solutii: Token expirat (regenerati tokenul), semnatura electronica expirata (reinnoiti semnatura in SPV)' + ;
|
||
LF + ;
|
||
LF + 'Apasati pe butonul Chatbot (stanga) pentru alte solutii!')
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
EXIT
|
||
ENDIF
|
||
|
||
If Type('loJson.mesaje') = 'U'
|
||
llSucces = .F.
|
||
lcErrorMessage = This.cUser + ' ' + 'DescarcareRaspunsuri Eroare: Nu exista informatia [mesaje] in raspuns.' + LF + loHttp.ResponseText
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
EXIT
|
||
ENDIF
|
||
|
||
lnMesaje = Alen(loJson.mesaje)
|
||
For lnMesaj = 1 To m.lnMesaje
|
||
lcText = This.cUser + ' ' + 'DescarcareRaspunsuri Raspuns ' + Alltrim(Str(m.lnMesaj)) + '/' + Alltrim(Str(m.lnMesaje))
|
||
WAIT WINDOW m.lcText NOWAIT
|
||
This.Log(m.lcText)
|
||
|
||
loMesaj = loJson.mesaje[m.lnMesaj]
|
||
AddProperty(loMesaj, 'recno', m.lnMesaj)
|
||
AddProperty(loMesaj, 'recc', m.lnMesaje)
|
||
|
||
lcIdIncarcare = IIF(Type('loMesaj.id_solicitare') = 'C' And !Empty(Nvl(loMesaj.id_solicitare, '')), loMesaj.id_solicitare, '')
|
||
IF !EMPTY(m.lcIdIncarcare)
|
||
* Nu procesez mesajele deja descarcate, decat daca fortez procesarea tuturor mesajelor
|
||
IF m.llFortareRaspunsuri OR (This.lServer AND !This.cIsDescarcat(m.lcIdIncarcare)) OR (!This.lServer AND !This.cIsProcesat(m.lcIdIncarcare))
|
||
loAnafMesaj = This.ProceseazaMesaj(loMesaj)
|
||
llSucces = !loAnafMesaj.lEroare
|
||
IF loAnafMesaj.lEroare
|
||
This.lError = .T.
|
||
This.cErrorMessage = loAnafMesaj.cEroare
|
||
ENDIF
|
||
ENDIF
|
||
ELSE
|
||
llSucces = .F.
|
||
lcErrorMessage = This.cUser + ' ' + 'DescarcareRaspunsuri Eroare: EMPTY(loMesaj.id_solicitare) Mesaj ' + Alltrim(Str(m.lnMesaj)) + '/' + Alltrim(Str(m.lnMesaje))
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
EXIT
|
||
ENDIF && empty
|
||
Endfor && lnMesaj
|
||
|
||
lnPagina = m.lnPagina + 1
|
||
ENDDO && .T.
|
||
|
||
Select (m.lcSelect)
|
||
Return m.llSucces
|
||
Endproc && DescarcareRaspunsuri
|
||
|
||
*****************************
|
||
* Dezarhiveaza mesajul, parseaza xml efactura trimisa/primita si salveaza pe disk si in baza de date
|
||
* Intoarce un obiect AnafMesaj (cEroare, lEroare)
|
||
****************************
|
||
Procedure ProceseazaMesaj
|
||
Lparameters toMesaj
|
||
|
||
Local loDate As "empty"
|
||
Local lcDirectory, lcFile, lcTip, lcTipRaspuns, llSucces, lnAn, lnLuna, lnMin, lnOra, lnSec, lnZi
|
||
Local loAnafMesaj, loDetalii, lcFilePath
|
||
|
||
loAnafMesaj = This.NewMesaj()
|
||
|
||
With toMesaj
|
||
loAnafMesaj.cIdIncarcare = .id_solicitare
|
||
|
||
lnAn = Val(Substr(.data_creare, 1, 4))
|
||
lnLuna = Val(Substr(.data_creare, 5, 2))
|
||
lnZi = Val(Substr(.data_creare, 7, 2))
|
||
lnOra = Val(Substr(.data_creare, 9, 2))
|
||
lnMin = Val(Substr(.data_creare, 11, 2))
|
||
lnSec = Val(Substr(.data_creare, 13, 2))
|
||
loAnafMesaj.dDataRaspuns = Datetime(m.lnAn, m.lnLuna, m.lnZi, m.lnOra, m.lnMin, m.lnSec)
|
||
|
||
loAnafMesaj.cMesajRaspuns = .detalii
|
||
loAnafMesaj.cTipMesajRaspuns = .tip
|
||
loAnafMesaj.cIdDescarcare = .Id
|
||
loAnafMesaj.cCodFiscalEmitent = Strextract(.detalii, [cif_emitent=], [ ],1,1+2)
|
||
loAnafMesaj.cCodFiscalBeneficiar = Strextract(.detalii, [cif_beneficiar=], [ ],1,1+2)
|
||
loAnafMesaj.nTest = Iif(This.lTest, 1, 0) && server TEST ANAF
|
||
loAnafMesaj.nFacturaEmisa = IIF(UPPER(ALLTRIM(.tip)) = 'FACTURA PRIMITA', 0, 1)
|
||
|
||
lcTipRaspuns = Alltrim(Upper(loAnafMesaj.cTipMesajRaspuns))
|
||
|
||
|
||
* Adaug mesajul in cRaspunsuri
|
||
This.cAddMesaj(loAnafMesaj)
|
||
|
||
|
||
lcTip = Iif('ERORI'$m.lcTipRaspuns, 'ERORI', Iif('PRIMIT'$m.lcTipRaspuns, 'PRIMITE', Iif('TRIMIS'$m.lcTipRaspuns, 'TRIMISE', IIF('MESAJ CUMPARATOR TRANSMIS'$m.lcTipRaspuns, 'MESAJE', 'ALTELE'))))
|
||
lcFile = loAnafMesaj.cIdIncarcare + '_' + loAnafMesaj.cIdDescarcare + '.zip' && C:\EFACTURA\PRIMITE\20240112\1234_1234\
|
||
|
||
IF this.lServer
|
||
lcDirectory = This.cResponsesPath + m.lcTip + '\' + Dtos(Date()) + '\'
|
||
ELSE
|
||
lcDirectory = GetPdfPath('EFACTURA', m.lcTip)
|
||
ENDIF
|
||
|
||
lcFilePath = m.lcDirectory + m.lcFile
|
||
|
||
* Daca nu exista fisierul zip descarcat de alt program
|
||
IF !FILE(m.lcFilePath)
|
||
* Descarca detalii raspuns
|
||
loDetalii = This.DownloadDetaliiEFactura(loAnafMesaj.cIdDescarcare, ' Descarcare detalii factura ID: ' + loAnafMesaj.cIdDescarcare)
|
||
llSucces = loDetalii.lSucces
|
||
|
||
If !m.llSucces
|
||
loAnafMesaj.cEroare = 'Eroare descarcare detalii factura id_descarcare = ' + Alltrim(loAnafMesaj.cIdDescarcare) + ;
|
||
'. Cod eroare: ' + Alltrim(Transform(loDetalii.nStatus)) + ' ' + loDetalii.cErrorMessage
|
||
loAnafMesaj.lEroare = .T.
|
||
Else
|
||
If 'eroare' $ Lower(loDetalii.cResponse)
|
||
loAnafMesaj.cEroare = 'Eroare descarcare detalii raspuns id_descarcare = ' + Alltrim(loAnafMesaj.cIdDescarcare) + '. ' + loDetalii.cResponse
|
||
loAnafMesaj.lEroare = .T.
|
||
Endif && 'eroare' $ Lower(loDetalii.cResponse)
|
||
Endif && m.llSucces loDetalii.lSucces
|
||
|
||
IF loAnafMesaj.lEroare
|
||
This.Log('Proceseaza Mesaj ' + loAnafMesaj.cEroare)
|
||
ELSE
|
||
llSucces = This.SaveFile(loDetalii.cResponse, .T., m.lcDirectory, m.lcFile)
|
||
This.Log('Proceseaza Mesaj salvare fisier: ' + Transform(m.llSucces) + ' ' + m.lcFilePath)
|
||
ENDIF && lEroare
|
||
|
||
ENDIF && !file
|
||
ENDWITH && toMesaj
|
||
|
||
* Salvez arhiva pe disk
|
||
IF FILE(m.lcFilePath)
|
||
This.Log('Proceseaza Mesaj. Exista fisierul: ' + m.lcFilePath)
|
||
loAnafMesaj.lEroare = .F.
|
||
llSucces = .T.
|
||
* Actualizez cRaspunsuri.descarcat, filepath
|
||
lnDescarcatServer = IIF(this.lServer, 1, 0) && marchez descarcat doar daca am descarcat pe server
|
||
This.cUpdateDescarcat(loAnafMesaj.cIdIncarcare, m.lnDescarcatServer, m.lcFilePath)
|
||
ENDIF
|
||
|
||
Return loAnafMesaj
|
||
Endproc && ProceseazaMesaj
|
||
|
||
* Salveaza fisiere/variabile pe disk
|
||
Procedure SaveFile
|
||
Lparameters tcFile, tlVariable, tcDirectory, tcFileName
|
||
* tcFile: calea catre fisierul sursa
|
||
* tlVariable: .T. daca tcFile este o variabila cu continutul fisierului
|
||
* tcFileName: numele fisierului destinatie
|
||
Local lcFile2, llSucces, loEx As Exception
|
||
|
||
llSucces = .T.
|
||
lcFileName2 = Iif(!Empty(m.tcFileName), m.tcFileName, Justfname(m.tcFile))
|
||
lcFile2 = Addbs(m.tcDirectory) + m.lcFileName2
|
||
If !Empty(m.tcDirectory) And !Directory(m.tcDirectory)
|
||
Try
|
||
Md (m.tcDirectory)
|
||
Catch To loEx
|
||
llSucces = .F.
|
||
This.Log('SaveFile ' + 'Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure)
|
||
Endtry
|
||
Endif
|
||
If !Empty(m.tcDirectory) And Directory(m.tcDirectory)
|
||
Try
|
||
If m.tlVariable
|
||
Strtofile(m.tcFile, m.lcFile2)
|
||
Else
|
||
Copy File (m.tcFile) To (m.lcFile2)
|
||
ENDIF
|
||
This.Log('SaveFile ' + m.lcFile2)
|
||
llSucces = .T.
|
||
Catch To loEx
|
||
llSucces = .F.
|
||
This.Log('SaveFile ' + 'Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure)
|
||
Endtry
|
||
Endif
|
||
Return m.llSucces
|
||
Endproc && SaveFile
|
||
|
||
************
|
||
* Intoarce calea de salvare xml intr-un director comun, definit in baza de date OPTIUNI
|
||
************
|
||
Procedure GetFacturaSavePath
|
||
Lparameters toFactura, tcExt
|
||
* tcExt: optional, default xml
|
||
|
||
Local loReturn As "empty"
|
||
Local lcAn, lcDataAct, lcFile2, lcFile2Semnatura, lcFilePdf, lcFileSemnatura, lcFurnizor
|
||
Local lcIdDescarcare, lcIdIncarcare, lcLuna, lcLuna2, lcLuna3, lcNumarAct, lcSaveFile, lcSavePath
|
||
Local llSucces, lcExt, lcFirma
|
||
|
||
llSucces = .F.
|
||
lcExt = IIF(!EMPTY(m.tcExt), m.tcExt, 'xml')
|
||
|
||
lcTip = ALLTRIM(UPPER(toFactura.tip_mesaj_raspuns)) && FACTURI TRIMISE / FACTURI PRIMITE
|
||
llFurnizor = 'PRIMIT'$m.lcTip
|
||
|
||
IF m.llFurnizor
|
||
lcPartener = WindowsSpecialCharacters(toFactura.Furnizor)
|
||
lcSavePath = This.cSaveFurnizoriPath
|
||
lcSaveFile = This.cSaveFurnizoriFile
|
||
ELSE
|
||
lcPartener = WindowsSpecialCharacters(toFactura.Client)
|
||
lcSavePath = This.cSaveClientiPath
|
||
lcSaveFile = This.cSaveClientiFile
|
||
ENDIF
|
||
lcFirma = This.cUser
|
||
lcPartener = Alltrim(Left(Strtran(m.lcPartener, '.', '',1,100,1), 50))
|
||
|
||
lcAn = Alltrim(Str(Year(toFactura.dataact)))
|
||
lcLuna = c_luna(Month(toFactura.dataact))
|
||
lcLuna3 = cluna3(Month(toFactura.dataact))
|
||
lcLuna2 = Padl(Month(toFactura.dataact), 2, '0')
|
||
lcDataAct = Dtos(toFactura.dataact)
|
||
lcIdIncarcare = toFactura.cIdIncarcare
|
||
lcIdDescarcare = toFactura.cIdDescarcare
|
||
lcNumarAct = Alltrim(WindowsSpecialCharacters(toFactura.numaract))
|
||
|
||
lcSavePath = Strtran(m.lcSavePath, '<an>', m.lcAn, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<aaaa>', m.lcAn, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<id_incarcare>', m.lcIdIncarcare, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<id_descarcare>', m.lcIdDescarcare, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<luna>', m.lcLuna, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<lll>', m.lcLuna3, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<ll>', m.lcLuna2, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<yyyymmdd>', m.lcDataAct, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<datafact>', m.lcDataAct, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<furnizor>', m.lcPartener, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<client>', m.lcPartener, 1, 100, 1)
|
||
lcSavePath = Strtran(m.lcSavePath, '<firma>', m.lcFirma, 1, 100, 1)
|
||
|
||
lcSavePath = Addbs(m.lcSavePath)
|
||
|
||
|
||
If Empty(m.lcSaveFile)
|
||
lcFile2 = m.lcSavePath + m.lcIdIncarcare + '_' + m.lcIdDescarcare + '_' + m.lcDataAct + '_' + m.lcNumarAct + '.' + m.lcExt
|
||
Else
|
||
lcFile2 = m.lcSavePath + Strtran(m.lcSaveFile, '<id_incarcare>', m.lcIdIncarcare, 1, 100, 1)
|
||
lcFile2 = Strtran(m.lcFile2, '<id_descarcare>', m.lcIdDescarcare, 1, 100, 1)
|
||
lcFile2 = Strtran(m.lcFile2, '<datafact>', m.lcDataAct, 1, 100, 1)
|
||
lcFile2 = Strtran(m.lcFile2, '<furnizor>', m.lcPartener, 1, 100, 1)
|
||
lcFile2 = Strtran(m.lcFile2, '<client>', m.lcPartener, 1, 100, 1)
|
||
If EMPTY(Justext(Lower(m.lcFile2)))
|
||
lcFile2 = m.lcFile2 + '.' + m.lcExt
|
||
Endif
|
||
ENDIF
|
||
|
||
RETURN m.lcFile2
|
||
|
||
Endproc && GetFacturaSavePath
|
||
|
||
|
||
************************************
|
||
* Intoarce un obiect tip ANAF_EFACTURA, doar informatiile din mesajul ANAF, pentru salvarea in baza de date
|
||
************************************
|
||
Function NewMesaj
|
||
Local loMesaj
|
||
loMesaj= Createobject("empty")
|
||
AddProperty(loMesaj, 'nId', Null)
|
||
AddProperty(loMesaj, 'cIdIncarcare', Null)
|
||
AddProperty(loMesaj, 'cMesajRaspuns', Null)
|
||
AddProperty(loMesaj, 'dDataRaspuns', Null)
|
||
AddProperty(loMesaj, 'cMesajRaspuns', Null)
|
||
AddProperty(loMesaj, 'cTipMesajRaspuns', Null)
|
||
AddProperty(loMesaj, 'cIdDescarcare', Null)
|
||
AddProperty(loMesaj, 'cCodFiscalEmitent', Null)
|
||
AddProperty(loMesaj, 'cCodFiscalBeneficiar', Null)
|
||
AddProperty(loMesaj, 'cDetalii', Null)
|
||
AddProperty(loMesaj, 'nFacturaEmisa', Null)
|
||
AddProperty(loMesaj, 'nTest', 0)
|
||
AddProperty(loMesaj, 'lEroare', .F.)
|
||
AddProperty(loMesaj, 'cEroare', '')
|
||
|
||
Return loMesaj
|
||
Endfunc && NewMesaj
|
||
|
||
|
||
* Citeste raspunsuri eFactura de la ANAF
|
||
Function ReadResponseEFactura
|
||
Lparameters tnZile
|
||
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local loReturn As "empty"
|
||
Local lcServer, llTest, lcToken, lcCodFiscal, lnZile
|
||
llTest = This.lTest
|
||
lcToken = This.cToken
|
||
lcCodFiscal = This.cCodFiscal
|
||
lnZile = Iif(!Empty(m.tnZile), Min(m.tnZile, 60), 60)
|
||
|
||
This.Log('ReadResponseEfactura: Citire raspunsuri ANAF ultimele ' + Alltrim(Str(m.lnZile)) + '...')
|
||
|
||
Try
|
||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/listaMesajeFactura?zile=] + Alltrim(Str(m.lnZile)) + [&cif=] + m.lcCodFiscal && 1879855
|
||
This.Log(m.lcServer)
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
loHTTP.Open('GET', lcServer, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/xml;")
|
||
loHTTP.setRequestHeader('Authorization', 'Bearer ' + m.lcToken)
|
||
|
||
loHTTP.Send()
|
||
Catch To loEx
|
||
This.Log('ReadResponseEfactura ' + loEx.Message)
|
||
Endtry
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", (loHTTP.Status = 200))
|
||
AddProperty(loReturn, "cResponse", loHTTP.ResponseText)
|
||
AddProperty(loReturn, "nStatus", loHTTP.Status)
|
||
If loHTTP.Status <> 200
|
||
loReturn.cResponse = loHTTP.StatusText && 403 Forbidden
|
||
Endif
|
||
This.Log('ReadResponseEfactura ' + Transform(loHTTP.Status))
|
||
|
||
Return loReturn
|
||
|
||
Endfunc
|
||
|
||
******************
|
||
* Citeste detalii factura eFactura de la ANAF
|
||
* Intoarce un obiect cu cResponse (continutul arhivei zip)
|
||
*****************
|
||
Function DownloadDetaliiEFactura
|
||
Lparameters tcIdDescarcare, tcWaitWindowText
|
||
* tcIdDescarcare: Id descarcare ANAF
|
||
* tcWaitWindowText: optional, text pentru wait window:
|
||
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local loReturn As "empty", loEx As Exception
|
||
Local lcServer, llTest, lcToken, lcCodFiscal, lcIdDescarcare, lcErrorMessage, lcWaitWindowText
|
||
llTest = This.lTest
|
||
lcToken = This.cToken
|
||
lcIdDescarcare = m.tcIdDescarcare
|
||
lcErrorMessage = ''
|
||
lcWaitWindowText = Iif(!Empty(m.tcWaitWindowText), m.tcWaitWindowText, 'Descarcare detalii factura ID: ' + m.tcIdDescarcare)
|
||
|
||
WAIT WINDOW m.lcWaitWindowText NOWAIT
|
||
|
||
Try
|
||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/descarcare?id=] + m.lcIdDescarcare
|
||
This.Log('DownloadDetaliieFactura ' + m.lcServer)
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
loHTTP.Open('GET', lcServer, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "application/xml;")
|
||
loHTTP.setRequestHeader('Authorization', 'Bearer ' + m.lcToken)
|
||
|
||
loHTTP.Send()
|
||
Catch To loEx
|
||
This.Log('DownloadDetaliieFactura ' + loEx.Message)
|
||
Endtry
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", (loHTTP.Status = 200))
|
||
If 'eroare' $ Lower(loHTTP.ResponseText)
|
||
lcResponse = loHTTP.ResponseText
|
||
lcErrorMessage = m.lcResponse
|
||
Else
|
||
lcResponse = loHTTP.ResponseBody
|
||
Endif
|
||
AddProperty(loReturn, "cResponse", m.lcResponse) && arhiva zip sau json cu text eroare {'eroare' : 'Factura cu id 1112 nu exista'}
|
||
AddProperty(loReturn, "nStatus", loHTTP.Status)
|
||
AddProperty(loReturn, "cErrorMessage", m.lcErrorMessage)
|
||
|
||
This.Log('DownloadDetaliieFactura ' + Transform(loHTTP.Status) + ' ' + m.lcErrorMessage)
|
||
Return loReturn
|
||
|
||
Endfunc
|
||
|
||
|
||
*****************
|
||
* Adauga/actualizeaza datele si detaliile facturii in baza de date ANAF_EFACTURA
|
||
* Foloseste obiect returnat din ParseEFactura
|
||
* Intoarce SUCCES = .T.
|
||
*****************
|
||
Procedure cUpdateFactura
|
||
Parameters toFactura, tcCursor
|
||
|
||
*toFactura: obiect din ParseEFactura
|
||
* tcCursor: optional, anaf_efactura sau un cursor asemanator, temporar
|
||
|
||
LOCAL llSucces, lcSql, lcCursor
|
||
lcCursor = IIF(EMPTY(m.tcCursor), 'anaf_efactura', m.tcCursor)
|
||
|
||
UPDATE (m.lcCursor) ;
|
||
set xnumar_act = toFactura.NumarAct, ;
|
||
xdata_act = toFactura.DataAct, ;
|
||
xdata_scad = toFactura.DataScad, ;
|
||
xdescriere = toFactura.Detalii, ;
|
||
xdetalii_plata = Left(toFactura.Detaliiplata, 500), ;
|
||
xtotal_fara_tva = toFactura.TotalFaraTva, ;
|
||
xtotal_tva = toFactura.TotalTva, ;
|
||
xtotal_tva_ron = toFactura.TotalTvaRON, ;
|
||
xtotal_cu_tva = toFactura.TotalCuTva, ;
|
||
xdiscount_fara_tva = toFactura.DiscountFaraTVA, ;
|
||
xtaxe_fara_tva = toFactura.TaxeFaraTVA, ;
|
||
xvaloare_fara_tva = toFactura.ValoareFaraTVA, ;
|
||
xtotal_de_plata = toFactura.TotaldePlata, ;
|
||
xnume_valuta = toFactura.Valuta, ;
|
||
xfurnizor = toFactura.Furnizor, ;
|
||
xclient = toFactura.Client, ;
|
||
factura_detalii = toFactura.FacturaDetalii, ;
|
||
creditnote = toFactura.CreditNote, ;
|
||
cod_fiscal_emitent = IIF(EMPTY(NVL(cod_fiscal_emitent,'')), UPPER(ALLTRIM(GetNrFromString(NVL(toFactura.CodFiscalFurnizor,'')))), cod_fiscal_emitent), ;
|
||
cod_fiscal_beneficiar = IIF(EMPTY(NVL(cod_fiscal_beneficiar,'')), UPPER(ALLTRIM(GetNrFromString(NVL(toFactura.CodFiscalClient,'')))), cod_fiscal_beneficiar), ;
|
||
modificat = 1 ;
|
||
where id_incarcare = toFactura.cIdIncarcare
|
||
llSucces = .T.
|
||
|
||
TABLEUPDATE(1,.F., m.lcCursor)
|
||
|
||
RETURN m.llSucces
|
||
Endproc && cUpdateFactura
|
||
|
||
*****************
|
||
* Adauga/actualizeaza un raspuns FACTURA PRIMITA/TRIMISA/EROARE in ANAF_EFACTURA
|
||
* Mesajul intoarce ANAF_EFACTURA.ID
|
||
* Intoarce SUCCES = .T.
|
||
*****************
|
||
Procedure UpdateRaspuns
|
||
Parameters toMesaj
|
||
Private pnId
|
||
pnId = 0
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
BEGIN
|
||
pack_anaf.UpdateRaspuns(?.cIdIncarcare,
|
||
?.dDataRaspuns,
|
||
?.cMesajRaspuns,
|
||
?.cTipMesajRaspuns,
|
||
?.cIdDescarcare,
|
||
?.cCodFiscalEmitent,
|
||
?.cCodFiscalBeneficiar,
|
||
?.cDetalii,
|
||
?.nTest,
|
||
?@pnId);
|
||
end;
|
||
ENDTEXT
|
||
With toMesaj
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
Endwith
|
||
If m.llSucces
|
||
toMesaj.nId = m.pnId
|
||
Endif
|
||
|
||
Return m.llSucces
|
||
Endproc && UpdateRaspuns
|
||
|
||
*****************
|
||
* Actualizeaza un ANAF_EFACTURA.DETALII, DETALII_ZIP (arhiva xml efactura) dupa ce se descarca arhiva cu detaliile unui raspuns
|
||
* Intoarce SUCCES = .T.
|
||
*****************
|
||
Procedure UpdateRaspunsDetalii
|
||
Parameters pcIdDescarcare, pcDetalii, pcDetaliiZip
|
||
|
||
Local lcSql, llSucces
|
||
* Fac update direct pe tabela in loc de pack_anaf.UpdateRaspunsDetalii, pentru ca da cateaodata eroare (BUG oracle)
|
||
llSucces = goExecutor.oExecuta('update anaf_efactura set detalii = ?pcDetalii, detalii_zip = ?pcDetaliiZip where id_descarcare = ?pcIdDescarcare')
|
||
|
||
If .F. && am facut direct update pe tabela
|
||
lcSql = [BEGIN pack_anaf.UpdateRaspunsDetalii(?pcIdDescarcare, ?pcDetalii, ?pcDetaliiZip); end;]
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
If !m.llSucces
|
||
* Da eroare cateodata, asa ca reincerc update direct pe tabela
|
||
If AMESSAGEBOX('Doriti sa reincercati actualizarea detaliilor?',4+32,_Screen.Caption) = 6
|
||
llSucces = goExecutor.oExecuta('update anaf_efactura set detalii = ?pcDetalii, detalii_zip = ?pcDetaliiZip where id_descarcare = ?pcIdDescarcare')
|
||
Endif
|
||
Endif
|
||
Endif
|
||
|
||
Return m.llSucces
|
||
Endproc && UpdateRaspunsDetalii
|
||
|
||
*****************
|
||
* Marcheaza ANAF_EFACTURA.PROCESAT = 1 ca sa nu se mai descarce arhiva cu detaliile raspunsului, daca mesajul a fost procesat
|
||
*****************
|
||
Procedure UpdateProcesat
|
||
Parameters tcIdDescarcare, tnProcesat
|
||
* tnIdEfactura: ANAF_EFACTURA.ID_DESCARCARE
|
||
* tnProcesat: OPTIONAL, DEFAULT (1)
|
||
|
||
Local lcSql, llSucces
|
||
Private pnProcesat
|
||
pnProcesat = Iif(!Empty(m.tnProcesat) And Type('tnProcesat') = 'N' And Inlist(m.tnProcesat,0,1), m.tnProcesat, 1)
|
||
|
||
lcSql = [BEGIN pack_anaf.UpdateProcesat(?tcIdDescarcare, ?pnProcesat); END;]
|
||
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
Return m.llSucces
|
||
Endproc && UpdateProcesat
|
||
|
||
*****************
|
||
* Intoarce .T. daca un IdDescarcare a fost descarcat
|
||
*****************
|
||
Function cIsDescarcat
|
||
Parameters tcIdIncarcare
|
||
Local llDescarcat
|
||
|
||
IF SEEK(m.tcIdIncarcare, 'anaf_efactura', 'id_inc')
|
||
llDescarcat = (anaf_efactura.descarcat = 1)
|
||
ENDIF
|
||
|
||
RETURN m.llDescarcat
|
||
Endfunc && cIsDescarcat
|
||
|
||
*****************
|
||
* Intoarce .T. daca un IdIncarcare a fost procesat
|
||
*****************
|
||
Function cIsProcesat
|
||
Parameters tcIdIncarcare
|
||
Local llProcesat
|
||
|
||
IF SEEK(m.tcIdIncarcare, 'anaf_efactura', 'id_inc')
|
||
llProcesat = (anaf_efactura.procesat = 1)
|
||
ENDIF
|
||
|
||
RETURN m.llProcesat
|
||
Endfunc && cIsProcesat
|
||
|
||
*****************
|
||
* Completeaza raspunsuri.descarcat, filepath, dupa salvarea arhivei raspuns
|
||
*****************
|
||
PROCEDURE cAddMesaj
|
||
PARAMETERS toMesaj
|
||
|
||
LOCAL lcSql, llSucces
|
||
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
merge into anaf_efactura a using dual b ON (a.id_incarcare = ?tcIdIncarcare)
|
||
when not matched then
|
||
INSERT (id_incarcare, id_descarcare) VALUES (?tcIdIncarcare, ?tcIdDescarcare)
|
||
ENDTEXT
|
||
*!* llSucces = goExecutor.oExecuta(m.lcSql)
|
||
|
||
*!* IF m.llSucces
|
||
WITH toMesaj
|
||
IF !SEEK(.cIdIncarcare,'anaf_efactura', 'id_inc')
|
||
INSERT INTO anaf_efactura (id_incarcare, id_descarcare,tip_mesaj_raspuns,mesaj_raspuns,data_raspuns,cod_fiscal_emitent,cod_fiscal_beneficiar,factura_emisa,test) ;
|
||
VALUES (.cIdIncarcare, .cIdDescarcare, .cTipMesajRaspuns,.cMesajRaspuns,.dDataRaspuns,.cCodFiscalEmitent,.cCodFiscalBeneficiar,.nFacturaEmisa,.nTest)
|
||
|
||
TABLEUPDATE(1,.F.,'ANAF_EFACTURA')
|
||
ENDIF
|
||
ENDWITH
|
||
llSucces = .T.
|
||
*!* ENDIF
|
||
RETURN m.llSucces
|
||
ENDPROC && AddMesaj
|
||
|
||
*****************
|
||
* Completeaza raspunsuri.descarcat, filepath, dupa salvarea arhivei raspuns
|
||
*****************
|
||
PROCEDURE cUpdateDescarcat
|
||
PARAMETERS tcIdIncarcare, tnDescarcat, tcFilePath
|
||
|
||
TEXT TO lcSql noshow
|
||
UPDATE anaf_efactura SET descarcat = ?tnDescarcat, filepath = ?tcFilePath WHERE id_incarcare = ?tcIdIncarcare
|
||
ENDTEXT
|
||
|
||
*!* llSucces = goExecutor.oExecuta(m.lcSql)
|
||
*!* IF m.llSucces
|
||
UPDATE anaf_efactura SET descarcat = m.tnDescarcat, filepath = m.tcFilePath, modificat = 1 WHERE id_incarcare = m.tcIdIncarcare
|
||
|
||
TABLEUPDATE(1,.F.,'ANAF_EFACTURA')
|
||
llSucces = .T.
|
||
*!* ENDIF
|
||
RETURN m.llSucces
|
||
ENDPROC
|
||
|
||
*****************
|
||
* Completeaza raspunsuri.descarcat, filepath, dupa salvarea arhivei raspuns
|
||
*****************
|
||
PROCEDURE cUpdateProcesat
|
||
PARAMETERS tcIdIncarcare
|
||
|
||
UPDATE anaf_efactura SET procesat = 1, modificat = 1 WHERE id_incarcare = m.tcIdIncarcare
|
||
|
||
TABLEUPDATE(1,.F.,'ANAF_EFACTURA')
|
||
|
||
llSucces = .T.
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC
|
||
|
||
*****************
|
||
* Completeaza anaf_efactura.procesat_server = 1, dupa procesarea arhivei pe servers sau in directorul din retea
|
||
*****************
|
||
PROCEDURE cUpdateProcesatServer
|
||
PARAMETERS tcIdIncarcare
|
||
|
||
UPDATE anaf_efactura SET procesat_server = 1, modificat = 1 WHERE id_incarcare = m.tcIdIncarcare
|
||
|
||
TABLEUPDATE(1,.F.,'ANAF_EFACTURA')
|
||
llSucces = .T.
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC
|
||
|
||
*****************
|
||
* Completeaza anaf_efactura.detalii (continutul fisierului xml din raspuns)
|
||
*****************
|
||
PROCEDURE cUpdateDetalii
|
||
PARAMETERS tcIdIncarcare, tcDetalii
|
||
|
||
UPDATE anaf_efactura SET detalii = m.tcDetalii, modificat = 1 WHERE id_incarcare = m.tcIdIncarcare
|
||
|
||
TABLEUPDATE(1,.F.,'ANAF_EFACTURA')
|
||
llSucces = .T.
|
||
|
||
RETURN m.llSucces
|
||
ENDPROC
|
||
|
||
|
||
*****************
|
||
* actualizeaza anaf_efactura
|
||
*****************
|
||
PROCEDURE UpdateDb
|
||
LPARAMETERS tcCursor
|
||
|
||
LOCAL lcSql, llSucces, lnSucces, lcSelect, lcCursor
|
||
|
||
lcSelect = SELECT()
|
||
lcCursor = IIF(EMPTY(m.tcCursor), 'anaf_efactura', m.tcCursor)
|
||
|
||
llSucces = .T.
|
||
|
||
lnSucces = This.ConnectROA()
|
||
|
||
IF m.lnSucces = CT_SUCCES
|
||
* Actualizez datele doar pentru facturile care nu au fost procesate (fie de catre server, fie de catre clienti)
|
||
SELECT * FROM (m.lcCursor) WITH (BUFFERING = .T.) WHERE modificat = 1 OR procesat = 0 INTO CURSOR crsUpdateTemp
|
||
|
||
SELECT crsUpdateTemp
|
||
SCAN
|
||
SCATTER NAME loRec MEMO
|
||
lcText = 'Actualizare baza de date ' + ALLTRIM(STR(RECNO())) + '/' + ALLTRIM(STR(RECCOUNT()))
|
||
WAIT WINDOW m.lcText NOWAIT
|
||
This.Log(m.lcText)
|
||
llSucces = This.UpdateDbFactura(loRec)
|
||
|
||
IF !m.llSucces
|
||
lcErrorMessage = This.cErrorMessage
|
||
IF LEN(m.lcErrorMessage) > 200
|
||
IF This.lServer
|
||
WAIT WINDOW LEFT(m.lcErrorMessage,200) NOWAIT
|
||
ELSE
|
||
AMESSAGEBOX(m.lcErrorMessage,0+48,_Screen.Caption)
|
||
ENDIF
|
||
ELSE
|
||
WAIT WINDOW m.lcErrorMessage NOWAIT
|
||
ENDIF
|
||
|
||
This.Log(m.lcErrorMessage)
|
||
IF !This.lServer
|
||
* daca imi da eroare la o factura, incerc sa le actualizez pe celelalte
|
||
IF AMESSAGEBOX('Continuati actualizarea celorlalte facturi in baza de date?',4+32,_screen.Caption) <> 6
|
||
EXIT
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
ENDSCAN
|
||
|
||
USE IN (SELECT('crsUpdateTemp'))
|
||
ENDIF && lnSucces
|
||
|
||
lnSucces = This.DisConnectROA()
|
||
|
||
SELECT (m.lcSelect)
|
||
RETURN m.llSucces
|
||
|
||
ENDPROC && UpdateDb
|
||
|
||
|
||
*****************
|
||
* actualizeaza o linie de factura in anaf_efactura
|
||
*****************
|
||
PROCEDURE UpdateDbFactura
|
||
LPARAMETERS toFactura
|
||
* toFactura : obiect din anaf_efactura
|
||
|
||
Local lcSql, llSucces, lcText
|
||
Local lcFacturaDetalii, lnIdEfactura, llZipDatabase
|
||
PRIVATE pcDetalii, pcDetaliiZip, pnId, pcDetaliiPlata
|
||
|
||
lcText = StripNonAscii(NVL(toFactura.xdetalii_plata,''), '')
|
||
lcText = RemoveCharactersDB(m.lcText, .T.)
|
||
lcText = LEFT(ALLTRIM(m.lcText), 495)
|
||
toFactura.xdetalii_plata = m.lcText && LEFT(ALLTRIM(StripNonAscii(NVL(toFactura.xdetalii_plata,''), '')), 495)
|
||
|
||
lcText = StripNonAscii(NVL(toFactura.xdescriere,''), '')
|
||
lcText = RemoveCharactersDB(m.lcText, .T.)
|
||
lcText = LEFT(ALLTRIM(m.lcText), 3995)
|
||
toFactura.xdescriere = m.lcText && LEFT(ALLTRIM(StripNonAscii(NVL(toFactura.xdescriere, ''), '')), 3995)
|
||
|
||
lcText = StripNonAscii(NVL(toFactura.mesaj_raspuns,''), '')
|
||
lcText = RemoveCharactersDB(m.lcText, .T.)
|
||
lcText = LEFT(ALLTRIM(m.lcText), 250)
|
||
toFactura.mesaj_raspuns = m.lcText
|
||
|
||
llZipDatabase = This.lZipDatabase && daca se salveaza zip efactura in baza de date
|
||
pnId = 0
|
||
* Nu mai actualizez anaf_detalii in pack_anaf.UpdateFactura, pentru ca da eroare cateodata (cand sunt prea multe linii?)
|
||
* Actualizez separat liniile
|
||
pcDetalii = toFactura.Detalii
|
||
pcDetaliiZip = ''
|
||
|
||
IF m.llZipDatabase AND TYPE('toFactura.filepath') = 'C' AND !EMPTY(NVL(toFactura.filepath,'')) AND FILE(NVL(toFactura.filepath,''))
|
||
pcDetaliiZip = FILETOSTR(ALLTRIM(NVL(toFactura.filepath,'')))
|
||
ENDIF
|
||
lcFacturaDetalii = NVL(toFactura.factura_detalii, '')
|
||
toFactura.xnumar_act = RIGHT(ALLTRIM(toFactura.xnumar_act), 30)
|
||
toFactura.procesat = 1 && sa se actualizeze anaf_efactura.procesat
|
||
llSucces = .F.
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
begin
|
||
pack_anaf.AdaugaRaspunsFactura(v_id_incarcare => ?TRIM(.id_incarcare),
|
||
v_data_raspuns => ?.data_raspuns,
|
||
v_mesaj_raspuns => ?TRIM(.mesaj_raspuns),
|
||
v_tip_mesaj_raspuns => ?TRIM(.tip_mesaj_raspuns),
|
||
v_id_descarcare => ?TRIM(.id_descarcare),
|
||
v_cod_fiscal_emitent => ?TRIM(.cod_fiscal_emitent),
|
||
v_cod_fiscal_beneficiar => ?TRIM(.cod_fiscal_beneficiar),
|
||
v_detalii => ?.detalii,
|
||
v_test => ?.test,
|
||
v_numar_act => ?TRIM(.xnumar_act),
|
||
v_data_act => ?.xdata_act,
|
||
v_data_scad => ?.xdata_scad,
|
||
v_furnizor => ?TRIM(.xfurnizor),
|
||
v_client => ?TRIM(.xclient),
|
||
v_descriere => ?TRIM(LEFT(.xdescriere,3995)),
|
||
v_detalii_plata => ?.xdetalii_plata,
|
||
v_total_fara_tva => ?.xtotal_fara_tva,
|
||
v_total_tva => ?.xtotal_tva,
|
||
v_total_tva_ron => ?.xtotal_tva_ron,
|
||
v_total_cu_tva => ?.xtotal_cu_tva,
|
||
v_discount_fara_tva => ?.xdiscount_fara_tva,
|
||
v_taxe_fara_tva => ?.xtaxe_fara_tva,
|
||
v_valoare_fara_tva => ?.xvaloare_fara_tva,
|
||
v_total_de_plata => ?.xtotal_de_plata,
|
||
v_nume_valuta => ?TRIM(.xnume_valuta),
|
||
v_descarcat => ?.descarcat,
|
||
v_filepath => ?.filepath,
|
||
v_procesat_server => ?.procesat_server,
|
||
v_procesat => ?.procesat,
|
||
v_xmldetalii => ?.factura_detalii,
|
||
v_creditnote => ?.creditnote,
|
||
V_ID_EFACTURA => ?@pnId);
|
||
end;
|
||
ENDTEXT
|
||
|
||
|
||
* Daca len(FacturaDetalii) > 5000, da eroare si trebuie sa actualizez separat
|
||
IF LEN(m.lcFacturaDetalii) < 5000 AND LEN(m.pcDetalii) < 5000
|
||
WITH toFactura
|
||
lnSucces = goExecutor.oExecute(m.lcSql)
|
||
llSucces = (m.lnSucces = CT_SUCCES)
|
||
ENDWITH
|
||
|
||
IF !m.llSucces
|
||
SET STEP ON
|
||
This.lError = .T.
|
||
This.cErrorMessage = goExecutor.cEroare
|
||
ENDIF
|
||
|
||
IF m.llSucces AND m.llZipDatabase AND !EMPTY(m.pcDetaliiZip)
|
||
* Fac update direct pe tabela in loc de pack_anaf.UpdateRaspunsDetalii, pentru ca da cateodata eroare (BUG oracle)
|
||
lcSql = 'update anaf_efactura set detalii_zip = ?pcDetaliiZip where id = ?pnId'
|
||
lnSucces = goExecutor.oExecute(m.lcSql)
|
||
llSucces = (m.lnSucces = CT_SUCCES)
|
||
IF !m.llSucces
|
||
|
||
This.lError = .T.
|
||
This.cErrorMessage = goExecutor.cEroare
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF && len
|
||
|
||
*********************************************
|
||
* Daca da eroare, mai incerc o data fara transmiterea detalii factura = lista articole.
|
||
* Articolele le salvez separat
|
||
IF !m.llSucces
|
||
* ORA-01460
|
||
toFactura.factura_detalii = ''
|
||
toFactura.detalii = ''
|
||
|
||
WITH toFactura
|
||
lnSucces = goExecutor.oExecute(m.lcSql)
|
||
llSucces = (m.lnSucces = CT_SUCCES)
|
||
ENDWITH
|
||
|
||
IF !m.llSucces
|
||
SET STEP ON
|
||
This.lError = .T.
|
||
This.cErrorMessage = goExecutor.cEroare
|
||
ELSE
|
||
* Adaug fiecare linie in anaf_efactura_detalii pentru ca cateodata se blocheaza Oracle BUG, daca este > 4.000 caractere
|
||
llSucces = This.UpdateFacturaDetalii(m.pnId, m.lcFacturaDetalii)
|
||
ENDIF
|
||
|
||
IF m.llSucces
|
||
* Fac update direct pe tabela in loc de pack_anaf.UpdateRaspunsDetalii, pentru ca da cateodata eroare (BUG oracle)
|
||
lcSql = 'update anaf_efactura set detalii = ?pcDetalii' + IIF(m.llZipDatabase and !EMPTY(m.pcDetaliiZip), ', detalii_zip = ?pcDetaliiZip', '') + ' where id = ?pnId'
|
||
lnSucces = goExecutor.oExecute(m.lcSql)
|
||
llSucces = (m.lnSucces = CT_SUCCES)
|
||
|
||
IF !m.llSucces
|
||
SET STEP ON
|
||
This.lError = .T.
|
||
This.cErrorMessage = goExecutor.cEroare
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
|
||
IF !m.llSucces
|
||
lcErrorMessage = 'UpdateDb Eroare la actualizarea datelor facturii pe server anaf_efactura.id = ' + TRANSFORM(m.pnId) + ' numar = ' + TRANSFORM(toFactura.xnumar_act) + CHR(13) + CHR(10) + ;
|
||
This.cErrorMessage
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
ENDIF
|
||
|
||
RETURN m.llSucces
|
||
|
||
ENDPROC && UpdateDb
|
||
|
||
*************************
|
||
*** Adaug linii una cate una, din cauza ca uneori are eroare la UpdateFactura cu toate detaliile, cand sunt prea multe linii poate?
|
||
*************************
|
||
Procedure UpdateFacturaDetalii
|
||
Parameters tnIdEfactura, tcFacturaDetalii
|
||
* tnIdEfactura: Id efactura
|
||
* tcFacturaDetalii: xml detalii factura
|
||
|
||
Local lcSql, llSucces, lnCount, lnRec, lnRecs
|
||
Private poRec
|
||
|
||
llSucces = .T.
|
||
lnCount = 0
|
||
|
||
* Verific daca exista deja introduse linii factura. Nu mai introduc
|
||
lcSql = "select count(*) from ANAF_EFACTURA_DETALII WHERE ID_EFACTURA = ?tnIdEfactura"
|
||
llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @lnCount)
|
||
If Nvl(m.lnCount,0) > 0
|
||
Return m.llSucces
|
||
Endif
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
INSERT INTO ANAF_EFACTURA_DETALII (ID_EFACTURA, NR, ARTICOL, DESCRIERE, DETALII, UM, CANTITATE, PRET, PROCTVA, TIPTVA, VALOAREFARATVA, DISCOUNTFARATVA)
|
||
VALUES (?tnIdEfactura, ?.NR, ?.ARTICOL, ?.DESCRIERE, ?.DETALII, ?.UM, ?.CANT, ?.PRET, ?.PROCTVA, ?.TIPTVA, ?.VALOAREFARATVA, ?.DISCOUNTFARATVA)
|
||
ENDTEXT
|
||
|
||
|
||
TRY
|
||
lnRecs = Xmltocursor(tcFacturaDetalii, "cFacturaDetaliiTemp")
|
||
|
||
Select cFacturaDetaliiTemp
|
||
Scan
|
||
Scatter Name poRec Memo
|
||
Wait Window 'eFactura ID ' + Alltrim(Str(m.tnIdEfactura)) + ' Salvare articol ' + Alltrim(Str(Recno())) + '/' + Alltrim(Str(m.lnRecs)) + ' ...' Nowait
|
||
|
||
With poRec
|
||
.descriere = RemoveCharactersDB(.descriere, .T.)
|
||
.descriere = LEFT(ALLTRIM(.descriere), 300)
|
||
.articol = RemoveCharactersDB(.articol, .T.)
|
||
.articol = LEFT(ALLTRIM(.articol), 300)
|
||
|
||
lnSucces = goExecutor.oExecute(m.lcSql)
|
||
llSucces = (m.lnSucces = CT_SUCCES)
|
||
If !m.llSucces
|
||
This.cErrorMessage = goExecutor.cEroare
|
||
This.lError = .T.
|
||
Exit
|
||
Endif
|
||
Endwith
|
||
Endscan
|
||
|
||
Use In (Select('cFacturaDetaliITemp'))
|
||
CATCH TO loEx
|
||
This.Log('tcFacturaDetalii ' + tcFacturaDetalii)
|
||
ENDTRY
|
||
|
||
Return m.llSucces
|
||
|
||
Endproc && UpdateFacturaDetalii
|
||
|
||
****************
|
||
* Genereaza pdf din xml eFactura pe serverul ANAF
|
||
****************
|
||
Procedure xml2PdfAnaf
|
||
Lparameters tcFile, tcFisierPdf, tlVariable
|
||
* tcXml: xml eFactura
|
||
* tcFisierPdf : (optional) calea catre fisierul Pdf generat. Altfel, se intreaba utilizatorul
|
||
* tlVariable: .T. daca tcFile este o variabila cu continutul xml efactura
|
||
|
||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||
Local loReturn As "empty"
|
||
Local lcMesaj, lcSend, lcServer, lcStare, llValid, lnBytes, lnMesaj, lnMesaje, loJson, loMessage, lcTip, lcToken
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", .F.)
|
||
AddProperty(loReturn, "cFile", '')
|
||
AddProperty(loReturn, "cResponse", '')
|
||
AddProperty(loReturn, "cResponseBody", '')
|
||
AddProperty(loReturn, "nStatus", 0)
|
||
AddProperty(loReturn, "cFilePdf", '')
|
||
If !Empty(m.tcFisierPdf)
|
||
loReturn.cFilePdf = m.tcFisierPdf
|
||
Endif
|
||
|
||
lcSend = ''
|
||
If m.tlVariable
|
||
lcSend = m.tcFile
|
||
Else
|
||
If File(m.tcFile)
|
||
lcSend = Filetostr(m.tcFile)
|
||
Endif
|
||
ENDIF
|
||
lcTip = 'FACT1'
|
||
IF 'CreditNote'$m.lcSend
|
||
lcTip = 'FCN'
|
||
ENDIF
|
||
lcToken = This.cToken
|
||
|
||
*!* lcServer = [https://webservicesp.anaf.ro/prod/FCTEL/rest/transformare/] + m.lcTip + [/DA] && serviciu neautentificat
|
||
lcServer = [https://api.anaf.ro/prod/FCTEL/rest/transformare/] + m.lcTip + [/DA] && serviciu autentificat
|
||
|
||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||
loHTTP.Open('POST', lcServer, .F.)
|
||
loHTTP.setRequestHeader("Content-Type", "text/plain")
|
||
loHTTP.setRequestHeader('Authorization', 'Bearer ' + m.lcToken) && 9b1f44af738c16aa10c78347b9a064857f034b03a20704a03c131b99f019cee5
|
||
|
||
Try
|
||
This.Log(m.lcServer)
|
||
Catch
|
||
Endtry
|
||
|
||
|
||
|
||
* Elimin caracterele Chr(13), Chr(10)
|
||
* Da eroare la serviciul ANAF
|
||
lcSend = Strtran(m.lcSend, [
], [])
|
||
|
||
* Sterg xsi:schemaLocation pentru ca poate da request rejected
|
||
* xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 ../../UBL-2.1(1)/xsd/maindoc/UBL-Invoice-2.1.xsd"
|
||
lcXsi = Strextract(lcSend, [xsi:schemaLocation="], [.xsd"], 1, 1)
|
||
lcSend = Strtran(m.lcSend, m.lcXsi, '', 1, 1, 1)
|
||
loHTTP.Send(m.lcSend)
|
||
|
||
loReturn.nStatus = loHTTP.Status
|
||
loReturn.cResponse = loHTTP.ResponseText
|
||
loReturn.cResponseBody = loHTTP.ResponseBody
|
||
loReturn.lSucces = (loHTTP.Status = 200)
|
||
lcMesaj = ''
|
||
|
||
If loReturn.lSucces
|
||
Do Case
|
||
Case ["stare"] $ Lower(loReturn.cResponse)
|
||
* Daca nu este valid xml
|
||
loJson = nfjsonread(loReturn.cResponse)
|
||
If Type('loJson.stare') = 'C' And !Empty(loJson.stare)
|
||
lcStare = Alltrim(Lower(loJson.stare))
|
||
llValid = (m.lcStare == 'ok')
|
||
If !m.llValid
|
||
If Type('loJson.messages_vfpsafe_') = 'U'
|
||
lcMesaj = 'Fisierul nu s-a validat. Nu exista informatia [messages] in raspuns. ' + Chr(13) + Chr(10) + loReturn.cResponse
|
||
Else
|
||
lnMesaje = Alen(loJson.messages_vfpsafe_)
|
||
lcMesaj = ''
|
||
For lnMesaj = 1 To m.lnMesaje
|
||
loMessage = loJson.messages_vfpsafe_[m.lnMesaj]
|
||
If Type('loMessage.message') = 'C'
|
||
lcMesaj = lcMesaj + loMessage.Message + Chr(13) + Chr(10)
|
||
Endif
|
||
Endfor
|
||
Endif && messages
|
||
Endif && llValid
|
||
Endif
|
||
If !Empty(m.lcMesaj)
|
||
lcErrorMessage = 'XML2PDFANAF ' + m.lcMesaj
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
Endif
|
||
Case 'request rejected' $ Lower(loReturn.cResponse)
|
||
lcErrorMessage = 'XML2PDFANAF Fisierul nu s-a validat.' + CRLF + loReturn.cResponse
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
|
||
Otherwise
|
||
* Daca este valid xml
|
||
If Empty(loReturn.cFilePdf)
|
||
loReturn.cFilePdf = Putfile('Fisier pdf', 'efactura.pdf', 'pdf')
|
||
Endif
|
||
|
||
Try
|
||
Delete File loReturn.cFilePdf
|
||
Endtry
|
||
lnBytes = Strtofile(loReturn.cResponseBody, loReturn.cFilePdf)
|
||
This.Log('XML2PDFANAF ' + loReturn.cFilePdf)
|
||
|
||
Endcase
|
||
Endif && loReturn.lSucces
|
||
|
||
Return loReturn.cFilePdf
|
||
Endproc && Xml2PdfAnaf
|
||
|
||
*********************
|
||
* Trimite fisiere xml eFactura in SPV
|
||
*********************
|
||
PROCEDURE VizSPV
|
||
|
||
* [{"id":"100000000","detalii":"recipisa pentru CIF 8000000000, tip D112, numar_inregistrare INTERNT-130000000-2017/20-12-2017, perioada raportare 11.2017","cif":"8000000000","data_creare":"20.12.2017 12:00:00","id_solicitare":null,"tip":"RECIPISA"}],"cnp":"1111111111118","cui":"8000000000,8000000001,8000000002","serial":"xxxxxxxxxxxxxxxxxxx"}
|
||
|
||
*!* CREATE CURSOR cMesajeSPV (ales N(1), id V(32), detalii V(250) null, cif V(20) null, data_creare T null, id_solicitare V(32) null, tip V(50) null, atasament W null, descarcat N(1), citit N(1), arhivat N(1))
|
||
*!* lcSql = [select id, cif, data_creare, detalii, id_solicitare, tip, '' as atasament, citit, arhivat, descarcat from anaf_spv ] + ;
|
||
*!* IIF(!EMPTY(m.tnArhivat) and m.tnArhivat = 1, "", "where arhivat=0")
|
||
*!* llSucces = goExecutor.oExecuta(m.lcSql, 'cMesajeSPVTemp')
|
||
|
||
*!* SELECT cMesajeSPV
|
||
*!* APPEND FROM DBF('cMesajeSPVTemp')
|
||
*!* INDEX on ID TAG Id DESCENDING
|
||
*!* USE IN (SELECT('cMesajeSPVTemp'))
|
||
|
||
Local loFrmSPV As "anaf_spv"
|
||
Local lcFiltru, lcFiltruOriginal, lcGroup, lcOrder, lcSchema, lcSelect, llAfisare, llModParam
|
||
PRIVATE poMesaje
|
||
|
||
lcSelect=[select 0 as ales, id, detalii, cif, data_creare, id_solicitare, tip, '' as atasament, citit, arhivat, descarcat from anaf_spv]
|
||
lcFiltru=[arhivat=0]
|
||
lcSchema=[ales N(1), id V(32), detalii V(250) null, cif V(20) null, data_creare T null, id_solicitare V(32) null, tip V(50) null, atasament W null, citit N(1), arhivat N(1), descarcat N(1)]
|
||
lcOrder=[data_creare desc]
|
||
llAfisare=.F.
|
||
lcGroup = []
|
||
llModParam = .T.
|
||
lcFiltruOriginal = []
|
||
poMesaje = null
|
||
gencursor('poMesaje','cMesajeSPV', m.lcSelect, m.lcFiltru, m.lcSchema, m.lcOrder, m.llAfisare, m.lcGroup, m.llModParam, m.lcFiltruOriginal)
|
||
poMesaje.ca_baza1.afisare()
|
||
|
||
SELECT cMesajeSPV
|
||
loFrmSPV = CREATEOBJECT("anaf_spv", This)
|
||
loFrmSPV.Show(1)
|
||
|
||
USE IN (SELECT('cMesajeSPV '))
|
||
ENDPROC && VizSPV
|
||
|
||
*****************
|
||
* Citeste lista de mesaje din SPV si salveaza in baza de date
|
||
*****************
|
||
PROCEDURE GetSPV
|
||
|
||
Local loHTTP As "MSXML2.XMLHTTP"
|
||
Local lcCIF, lcDetaliiMesaj, lcErrorMessage, lcIdMesaj, lcIdSolicitare, lcMesaj, lcResponse, lcTip
|
||
Local llSucces, loEx, loJson, loMesaj, ltDataCreare
|
||
LOCAL lcCodFiscal, lcURL, lnZile, lcZile, loEx as Exception
|
||
|
||
DECLARE INTEGER InternetSetOption IN "wininet.dll" ;
|
||
INTEGER hInternet, INTEGER dwOption, STRING lpBuffer, INTEGER dwBufferLength
|
||
|
||
#DEFINE INTERNET_OPTION_END_BROWSER_SESSION 42
|
||
|
||
* Clear SSL cache by ending the browser session
|
||
=InternetSetOption(0, INTERNET_OPTION_END_BROWSER_SESSION, 0, 0)
|
||
|
||
lnZile = 1000
|
||
lcZile = ALLTRIM(STR(m.lnZile))
|
||
lcCodFiscal = ALLTRIM(NVL(This.cCodFiscal, ''))
|
||
lcURL = "https://webserviced.anaf.ro/SPVWS2/rest/listaMesaje?zile=" + m.lcZile + "&cif=" + m.lcCodFiscal
|
||
|
||
llSucces = .F.
|
||
TRY
|
||
loHTTP = Createobject("MSXML2.XMLHTTP")
|
||
loHTTP.Open("GET", lcURL , .F.)
|
||
loHTTP.setRequestHeader("content-type", "text/plain")
|
||
loHTTP.Send()
|
||
llSucces = .T.
|
||
CATCH TO loEx
|
||
This.cErrorMessage = loEx.message
|
||
This.lError = .T.
|
||
ENDTRY
|
||
llSucces = .T.
|
||
lcMesaj = ''
|
||
* Verificam statusul raspunsului
|
||
IF TYPE('loHttp') = 'O' AND loHttp.Status <> 200
|
||
* Daca cererea HTTP a esuat
|
||
lcMesaj = "Eroare la conectarea la server: " + TRANSFORM(loHttp.Status)
|
||
This.cErrorMessage = m.lcMesaj
|
||
This.lError = .T.
|
||
llSucces = .F.
|
||
ENDIF
|
||
|
||
* Preluam raspunsul JSON
|
||
IF m.llSucces
|
||
lcResponse = loHttp.ResponseText
|
||
IF ATC('<head>', m.lcResponse) > 0
|
||
llSucces = .F.
|
||
DO CASE
|
||
CASE ATC('utilizator neautorizat', m.lcResponse) > 0
|
||
lcMesaj = 'Utilizator neautorizat. Posibile cauze: parola eronata sau certificat fara drepturi.'
|
||
CASE ATC('certificatul nu a fost prezentat', m.lcResponse) > 0
|
||
lcMesaj = 'Certificatul nu a fost prezentat.'
|
||
|
||
OTHERWISE
|
||
lcMesaj = 'Eroare certificat'
|
||
ENDCASE
|
||
This.cErrorMessage = m.lcMesaj
|
||
This.lError = .T.
|
||
ENDIF
|
||
ENDIF
|
||
|
||
IF m.llSucces
|
||
* Transformam raspunsul JSON intr-un obiect FoxPro
|
||
TRY
|
||
loJson = nfjsonread(m.lcResponse)
|
||
CATCH TO loEx
|
||
llSucces = .F.
|
||
lcErrorMessage = 'GetSPV ' + LF + ' Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure
|
||
This.cErrorMessage = m.lcErrorMessage
|
||
This.lError = .T.
|
||
This.Log(m.lcErrorMessage)
|
||
ENDTRY
|
||
|
||
* Verificam daca exista mesaje disponibile
|
||
IF TYPE("loJson.mesaje") <> "U"
|
||
* Daca avem mesaje, le salvam intr-un array
|
||
*!* laMesaje = loJson.mesaje
|
||
*!* lnMesajeCount = ALEN(laMesaje, 1)
|
||
|
||
* Iteram prin lista de mesaje si descarcam fiecare mesaj
|
||
lnMesaje = 0
|
||
FOR EACH loMesaj IN loJson.mesaje
|
||
lnMesaje = lnMesaje + 1
|
||
*i = 1 TO lnMesajeCount
|
||
*!* lcIdMesaj = laMesaje[i].id
|
||
*!* lcDetaliiMesaj = laMesaje[i].detalii
|
||
lcIdMesaj = loMesaj.id
|
||
lcDetaliiMesaj = loMesaj.detalii
|
||
lcTip = loMesaj.tip
|
||
lcCIF = loMesaj.cif
|
||
ltDataCreare = CTOT(loMesaj.data_creare)
|
||
lcIdSolicitare = loMesaj.id_solicitare
|
||
WAIT WINDOW 'Mesaj: ' + ALLTRIM(STR(m.lnMesaje)) + ' ' + m.lcTip NOWAIT
|
||
|
||
llSucces = This.UpdateDbSPV(m.loMesaj)
|
||
*!* IF !SEEK(m.lcIdMesaj, 'cMesajeSPV', 'id')
|
||
*!*
|
||
*!* INSERT INTO cMesajeSPV (id, detalii, tip, cif, data_creare, id_solicitare) VALUES (m.lcIdMesaj, m.lcDetaliiMesaj, m.lcTip, m.lcCIF, m.ltDataCreare, m.lcIdSolicitare)
|
||
*!* SELECT cMesajeSPV
|
||
*!* IF SEEK(m.lcIdMesaj)
|
||
*!* SCATTER NAME loMesaj MEMO
|
||
*!* llSucces = This.UpdateDbSPV(m.loMesaj)
|
||
*!* ENDIF
|
||
*!* ENDIF
|
||
ENDFOR
|
||
*!* GO TOP IN cMesajeSPV
|
||
WAIT WINDOW ALLTRIM(STR(m.lnMesaje)) + ' mesaje verificate/adaugate' NOWAIT
|
||
ELSE
|
||
* Daca nu exista mesaje
|
||
lcMesaj = "Nu exista mesaje disponibile in ultimele " + lcZile + " zile."
|
||
ENDIF
|
||
ENDIF && llSucces
|
||
|
||
IF !This.lServer AND !EMPTY(This.cErrorMessage)
|
||
AMESSAGEBOX(This.cErrorMessage, 0+48, _screen.Caption)
|
||
ENDIF
|
||
|
||
RETURN m.llSucces
|
||
|
||
ENDPROC && GetSPV
|
||
|
||
***************************
|
||
* Salveaza un mesaj SPV in baza de date anaf_spv
|
||
***************************
|
||
PROCEDURE UpdateDbSPV
|
||
LPARAMETERS toMesaj
|
||
|
||
Local lcSql, llSucces
|
||
PRIVATE pcCIF, pcDetalii, pcId, pcIdSolicitare, pcTip, ptDataCreare
|
||
|
||
TEXT TO lcSql NOSHOW
|
||
merge into anaf_spv a using dual b ON (a.id = ?pcId)
|
||
when not matched then
|
||
INSERT (id, detalii, tip, cif, data_creare, id_solicitare) VALUES (?pcId, ?pcDetalii, ?pcTip, ?pcCIF, ?ptDataCreare, ?pcIdSolicitare)
|
||
ENDTEXT
|
||
WITH toMesaj
|
||
pcId = ALLTRIM(.id)
|
||
pcDetalii = ALLTRIM(.detalii)
|
||
pcTip = ALLTRIM(.tip)
|
||
pcCIF = ALLTRIM(.cif)
|
||
ptDataCreare = CTOT(.data_creare)
|
||
pcIdSolicitare = ALLTRIM(.id_solicitare)
|
||
ENDWITH
|
||
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
IF !m.llSucces
|
||
goLog.Log(NVL(pcId, '') + ' ' + NVL(pcTip, '') + ' ' + NVL(pcCIF, '') + ' ' + TRANSFORM(NVL(ptDataCreare, {})) + ' ' + NVL(pcIdSolicitare, '') + ' ' + NVL(pcDetalii, ''))
|
||
SET STEP ON
|
||
ENDIF
|
||
RETURN m.llSucces
|
||
ENDPROC && UpdateDbSPV
|
||
|
||
***************************
|
||
* Salveaza atasamentul pentru un mesaj SPV in baza de date anaf_spv
|
||
***************************
|
||
PROCEDURE UpdateDbSPVFile
|
||
PARAMETERS tcIdMesaj, tcContinut, tcFileName
|
||
* tcIdMesaj: Id mesaj SPV
|
||
* tcContinut: continutul pdf/zip mesaj
|
||
|
||
Local lcSql, llSucces
|
||
|
||
lcSql = [UPDATE anaf_spv SET atasament = ?tcContinut, filename = ?tcFileName, descarcat = 1 WHERE id = ?tcIdMesaj]
|
||
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
IF !m.llSucces
|
||
goLog.Log(TRANSFORM(NVL(tcContinut, '')) + ' ' + TRANSFORM(NVL(tcIdMesaj, '')) + ' ' + TRANSFORM(m.tcFileName))
|
||
SET STEP ON
|
||
ENDIF
|
||
RETURN m.llSucces
|
||
ENDPROC && UpdateDbSPVFile
|
||
|
||
****************
|
||
* Actualizeaza anaf_spv.citit, descarcat, arhivat
|
||
****************
|
||
PROCEDURE UpdateSPV
|
||
LPARAMETERS tcIdMesaj, tcAtribut, tnValoare
|
||
|
||
lcSql = [update anaf_spv set ] + m.tcAtribut + [ = ] + ALLTRIM(STR(m.tnValoare)) + [ where id = ] + ALLTRIM(m.tcIdMesaj)
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
RETURN m.llSucces
|
||
ENDPROC
|
||
|
||
*****************
|
||
* Descarca atasamentul pdf al unui mesaj din SPV si il salveaza pe disc
|
||
*****************
|
||
PROCEDURE DescarcaDetaliiSPV
|
||
LPARAMETERS tcIdMesaj
|
||
* tnIdMesaj (optional): Id mesaj, altfel se descarca mesajele cMesajeSPV.ales = 1
|
||
* ttDataCreare, tcTip (optional): pentru numele fisierului
|
||
|
||
Local loHTTP As "MSXML2.XMLHTTP"
|
||
Local lcDirectory, lcIdMesaj, lcPdfData, lcPdfFileName, lcRecc, lcUrlDescarcare
|
||
Local lcData, lcDataCreare, lcExtensie, lcFileName, lcFiltru, lcTip, llSucces, lcIdMesaj
|
||
|
||
lcIdMesaj = IIF(!EMPTY(m.tcIdMesaj), ALLTRIM(m.tcIdMesaj), '')
|
||
|
||
|
||
*!* ******************
|
||
*!* DECLARE INTEGER InternetSetOption IN "wininet.dll" ;
|
||
*!* INTEGER hInternet, INTEGER dwOption, STRING lpBuffer, INTEGER dwBufferLength
|
||
|
||
*!* #DEFINE INTERNET_OPTION_END_BROWSER_SESSION 42
|
||
*!* * Clear SSL cache by ending the browser session
|
||
*!* =InternetSetOption(0, INTERNET_OPTION_END_BROWSER_SESSION, 0, 0)
|
||
*!* ******************
|
||
IF this.lServer
|
||
lcDirectory = This.cResponsesPath + 'SPV' + '\' + Dtos(Date()) + '\'
|
||
ELSE
|
||
lcDirectory = GetPdfPath('SPV')
|
||
ENDIF
|
||
|
||
lcFiltru = 'descarcat = 0'
|
||
DO CASE
|
||
CASE !EMPTY(m.lcIdMesaj)
|
||
lcFiltru = 'id = lcIdMesaj'
|
||
OTHERWISE
|
||
SELECT * FROM cMesajeSPV WHERE ales = 1 INTO CURSOR cMesajeSelectateTemp
|
||
IF _tally > 0
|
||
lcFiltru = 'ales = 1'
|
||
ENDIF
|
||
USE IN (SELECT('cMesajeSelectateTemp'))
|
||
ENDCASE
|
||
|
||
SELECT * FROM cMesajeSPV WHERE &lcFiltru INTO CURSOR cMesajeTemp NOFILTER
|
||
|
||
lcRecc = TRANSFORM(RECCOUNT('cMesajeTemp'))
|
||
|
||
llSucces = .F.
|
||
TRY
|
||
loHTTP = Createobject("MSXML2.XMLHTTP")
|
||
llSucces = .T.
|
||
CATCH TO loEx
|
||
This.cErrorMessage = loEx.message
|
||
This.lError = .T.
|
||
IF !This.lServer
|
||
AMESSAGEBOX('Eroare ' + This.cErrorMessage,0+48, _Screen.Caption)
|
||
ENDIF
|
||
ENDTRY
|
||
|
||
IF m.llSucces AND TYPE('loHttp') = 'O'
|
||
This.lError = .F.
|
||
SELECT cMesajeTemp
|
||
SCAN
|
||
lcIdMesaj = ALLTRIM(id)
|
||
lcDataCreare = TTOC(data_creare,1)
|
||
lcTip = ALLTRIM(tip)
|
||
lcDetalii = ALLTRIM(detalii)
|
||
llSucces = .T.
|
||
|
||
WAIT WINDOW TRANSFORM(RECNO()) + '/' + m.lcRecc NOWAIT
|
||
|
||
* Construim URL-ul pentru descarcarea mesajului
|
||
lcUrlDescarcare = "https://webserviced.anaf.ro/SPVWS2/rest/descarcare?id=" + m.lcIdMesaj
|
||
|
||
* Facem cererea pentru descarcarea mesajului PDF
|
||
|
||
llSucces = .F.
|
||
TRY
|
||
loHttp.Open("GET", m.lcUrlDescarcare, .F.)
|
||
loHttp.Send()
|
||
llSucces = .T.
|
||
CATCH TO loEx
|
||
This.cErrorMessage = loEx.message
|
||
This.lError = .T.
|
||
IF !This.lServer
|
||
AMESSAGEBOX('Eroare ' + This.cErrorMessage,0+48, _Screen.Caption)
|
||
ENDIF
|
||
ENDTRY
|
||
|
||
* Verificam statusul descarcarii
|
||
IF m.llSucces AND loHttp.Status = 200
|
||
|
||
* Verific daca raspunsul contine un mesaj de eroare in html
|
||
lcResponse = loHttp.ResponseText
|
||
DO CASE
|
||
CASE ATC('<head>', m.lcResponse) > 0
|
||
llSucces = .F.
|
||
DO CASE
|
||
CASE ATC('utilizator neautorizat', m.lcResponse) > 0
|
||
lcMesaj = 'Utilizator neautorizat. Posibile cauze: parola eronata sau certificat fara drepturi.'
|
||
CASE ATC('certificatul nu a fost prezentat', m.lcResponse) > 0
|
||
lcMesaj = 'Certificatul nu a fost prezentat.'
|
||
|
||
OTHERWISE
|
||
lcMesaj = 'Eroare certificat'
|
||
ENDCASE
|
||
This.cErrorMessage = m.lcMesaj
|
||
This.lError = .T.
|
||
WAIT WINDOW "Eroare la descarcarea mesajului " + m.lcIdMesaj + ' : ' + m.lcMesaj NOWAIT
|
||
IF !This.lServer
|
||
AMESSAGEBOX("Eroare la descarcarea mesajului " + m.lcIdMesaj + ' : ' + m.lcMesaj + '!',0+48,_Screen.Caption)
|
||
EXIT
|
||
ENDIF
|
||
CASE LEFT(m.lcResponse, 1) = "{"
|
||
*!* {"titlu":"Descarcare mesaj","eroare":"A aparut o eroare tehnica. Cod: 2000"}
|
||
lcMesaj = GetRegExp(m.lcResponse, '(?<="eroare":")[^"]+', 1)
|
||
This.cErrorMessage = m.lcMesaj
|
||
This.lError = .T.
|
||
WAIT WINDOW "Eroare la descarcarea mesajului " + m.lcIdMesaj + ' : ' + m.lcMesaj NOWAIT
|
||
IF !This.lServer
|
||
AMESSAGEBOX("Eroare la descarcarea mesajului " + m.lcIdMesaj + ' : ' + m.lcMesaj + '!',0+48,_Screen.Caption)
|
||
EXIT
|
||
ENDIF
|
||
OTHERWISE
|
||
* Obtinem continutul PDF/ZIP
|
||
lcResponse = loHttp.ResponseBody
|
||
ENDCASE
|
||
|
||
|
||
* Salvam fisierul PDF/zip pe disc
|
||
*detalii: recipisa pentru CIF 1879855, tip D300, numar_inregistrare INTERNT-767970463-2024/16-08-2024, perioada raportare 7.2024
|
||
lcTipD = GetRegExp(m.lcDetalii, ", tip ([^,]+)", 1) && obtin Tip declaratie ",tip D300,"
|
||
lcTipD = ALLTRIM(STRTRAN(m.lcTipD, ", tip", "",1,1,1))
|
||
lcTipD = IIF(!EMPTY(m.lcTipD), '_' + ALLTRIM(m.lcTipD), '')
|
||
|
||
lcPerioadaR = GetRegExp(m.lcDetalii, "perioada raportare (\d+\.\d+)", 1) && perioada raportare "7.2024"
|
||
lcPerioadaR = ALLTRIM(STRTRAN(m.lcPerioadaR, "perioada raportare", "",1,1,1))
|
||
lcPerioadaR = IIF(!EMPTY(m.lcPerioadaR), '_' + ALLTRIM(m.lcPerioadaR), '')
|
||
|
||
lcExtensie = IIF(This.lError, 'html', IIF(LOWER(LEFT(loHttp.responseText, 4)) = '%pdf', 'pdf', 'zip'))
|
||
lcFileName = m.lcDirectory + "mesaj_spv_" + m.lcIdMesaj + "_" + m.lcDataCreare + "_" + m.lcTip + m.lcTipD + m.lcPerioadaR + "." + m.lcExtensie
|
||
|
||
STRTOFILE(m.lcResponse, m.lcFileName, 0)
|
||
IF m.llSucces
|
||
* Salvez atasamentul in baza de date
|
||
llSucces = This.UpdateDbSPVFile(m.lcIdMesaj, m.lcResponse, JUSTFNAME(m.lcFileName))
|
||
ENDIF
|
||
IF m.llSucces
|
||
UPDATE cMesajeSPV SET descarcat = 1 WHERE id = m.lcIdMesaj
|
||
ENDIF
|
||
* Afisam un mesaj de succes
|
||
WAIT WINDOW "Mesajul " + m.lcIdMesaj + " descarcat cu succes: " + m.lcFileName NOWAIT
|
||
ELSE
|
||
* Daca apare o eroare la descarcare, afisam mesajul de eroare
|
||
WAIT WINDOW "Eroare la descarcarea mesajului " + m.lcIdMesaj NOWAIT
|
||
ENDIF
|
||
ENDSCAN && cMesajeTemp
|
||
ENDIF && llSucces
|
||
|
||
USE IN (SELECT('cMesajeTemp'))
|
||
|
||
IF !This.lServer
|
||
open_default_app(m.lcDirectory)
|
||
ENDIF
|
||
|
||
ENDPROC && DescarcaDetaliiSPV
|
||
|
||
*************
|
||
* Deschide directorul cu atasamente SPV si atasamentul dorit, dupa id mesaj
|
||
*************
|
||
PROCEDURE DeschideAtasamentSPV
|
||
LPARAMETERS tcIdMesaj
|
||
|
||
PRIVATE pcIdMesaj
|
||
Local laFiles[1], lcDirectory, lcFile, lcFileSkeleton, lcFiltru, lcFiltruOriginal, lcFisier, lcId
|
||
Local lcOrder, lcSchema, lcSelect, lcgroup, llAfiseaza, llModParam, lnFile, lnFiles
|
||
|
||
pcIdMesaj = tcIdMesaj
|
||
|
||
IF this.lServer
|
||
lcDirectory = This.cResponsesPath + 'SPV' + '\' + Dtos(Date()) + '\'
|
||
ELSE
|
||
lcDirectory = GetPdfPath('SPV')
|
||
ENDIF
|
||
lcDirectory = ADDBS(m.lcDirectory)
|
||
|
||
lcFileSkeleton = m.lcDirectory + '*' + ALLTRIM(m.tcIdMesaj) + '*.*'
|
||
lnFiles = ADIR(laFiles, m.lcFileSkeleton)
|
||
IF m.lnFiles > 0
|
||
open_default_app(m.lcDirectory)
|
||
|
||
FOR lnFile = 1 TO m.lnFiles
|
||
lcFile = m.lcDirectory + laFiles[m.lnFile,1]
|
||
IF FILE(m.lcFile)
|
||
open_default_app(m.lcFile)
|
||
ENDIF
|
||
ENDFOR
|
||
ELSE
|
||
* daca nu sunt fisiere pe disk, descarc din baza de date
|
||
PRIVATE poDetaliiZip
|
||
poDetaliiZip = null
|
||
|
||
lcSchema = [id V(36), fisier W, filename V(100)]
|
||
lcSelect = [select id, atasament, filename from anaf_spv where id = ?pcIdMesaj]
|
||
lcOrder = []
|
||
lcgroup = []
|
||
lcFiltru = []
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
gencursor('poDetaliiZip','cRegFisierTemp', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poDetaliiZip.ca_baza1.afisare()
|
||
If Used('cRegFisierTemp')
|
||
lcId= ALLTRIM(NVL(id, ''))
|
||
lcFisier = fisier
|
||
lcFileName = IIF(!EMPTY(NVL(filename, '')), ALLTRIM(NVL(filename, '')), m.pcIdMesaj + '.pdf')
|
||
Use In (Select('cRegFisierTemp'))
|
||
|
||
lcFile = PUTFILE('Fisier', m.lcFileName, JUSTEXT(m.lcFileName))
|
||
IF !EMPTY(m.lcFile)
|
||
Strtofile(lcFisier, m.lcFile)
|
||
open_default_app(JUSTPATH(m.lcFile))
|
||
open_default_app(m.lcFile)
|
||
ENDIF
|
||
Endif
|
||
ENDIF
|
||
|
||
ENDPROC && DeschideAtasamentSPV
|
||
|
||
Enddefine && ANAFeFacturaServer
|
||
|
||
Procedure viz_borderou_efactura
|
||
LOCAL loAnafeFactura
|
||
If !m.glEfactura
|
||
AMESSAGEBOX('Trebuie activata functionalitatea eFactura!', 0 + 48, _Screen.Caption)
|
||
Return
|
||
Endif
|
||
* gcAcces = [1;2;3;4;5;6]
|
||
loAnafeFactura = Createobject("ANAFeFactura")
|
||
loAnafeFactura.vizeFactura()
|
||
ENDPROC
|
||
|
||
*****************************
|
||
PROCEDURE viz_efactura_xml
|
||
LOCAL loAnafeFactura
|
||
|
||
loAnafeFactura = CREATEOBJECT("AnafeFacturaServer")
|
||
loAnafeFactura.vizeFacturaXml()
|
||
ENDPROC && viz_efactura_xml
|
||
|
||
*****************************
|
||
PROCEDURE viz_spv
|
||
|
||
LOCAL loAnafeFactura
|
||
loAnafeFactura = CREATEOBJECT("AnafeFacturaServer")
|
||
loAnafeFactura.VizSPV()
|
||
ENDPROC && viz_spv
|
||
|
||
Define Class ANAFeFactura As Custom
|
||
|
||
AnafeFacturaServer = null
|
||
|
||
token = ''
|
||
refresh_token = ''
|
||
token_gendate = {}
|
||
token_expdate = {}
|
||
codfiscal = '' && cod fiscal contribuabil fara atribut fiscal
|
||
lTest = .F. && .T. = transmite eFactura TEST
|
||
cResponsesPath = ''
|
||
|
||
Procedure Init
|
||
this.AnafeFacturaServer = Createobject('AnafeFacturaServer')
|
||
|
||
This.codfiscal = IIF(TYPE('goFirma') = 'O', gofirma.codfiscalfro, '')
|
||
This.cResponsesPath = GetPdfPath('EFACTURA') && ADDBS(m.gcEFACTURA_RESPONSESPATH) && RASPUNSURI daca se descarca automat cu ROAEFACTURA
|
||
|
||
Endproc && Init
|
||
|
||
Procedure vizeFactura
|
||
Local lcToken
|
||
Local loFrmBorderou As "frm_borderou_efactura"
|
||
Local lcFiltru, lcFiltruOriginal, lcOrder, lcSchema, lcSelect, lcgroup, llAfiseaza, llModParam, lcData1, lnInregistrariAfisare
|
||
Local lcSqlCount, llSucces
|
||
Private poFacturiEmise, poFacturiPrimite, poFacturiTrimise, poFacturiDetalii, pnRecCnt
|
||
poFacturiEmise = Null
|
||
poFacturiPrimite = Null
|
||
poFacturiTrimise = Null
|
||
poFacturiDetalii = Null
|
||
|
||
lcToken = This.getToken()
|
||
If Empty(m.lcToken)
|
||
AMESSAGEBOX('Nu s-a obtinut token-ul eFactura!', 0 + 48, _Screen.Caption)
|
||
Endif
|
||
|
||
* La facturi primite/trimise aduc 0 inregistrari.
|
||
* Afisez inregistrarile la prima activare a paginilor Trimise/Primite din Borderou
|
||
* Nu aduc coloana ANAF_EFACTURA.DETALII (xml efactura) pentru ca este prea mult trafic de date si merge greu pentru multe inregistrari. Aduc detalii doar pentru cate o factura
|
||
|
||
* FACTURI PRIMITE
|
||
lcData1 = '01' + PADL(INT(m.gnLuna),2,'0') + ALLTRIM(STR(m.gnAn))
|
||
Text To lcSchema Noshow
|
||
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
|
||
Endtext
|
||
Text To lcSelect Noshow
|
||
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_primit
|
||
Endtext
|
||
lcOrder = [data_act,numar_act,data_raspuns]
|
||
lcgroup = []
|
||
* Aduc inregistrarile cand se activeaza prima data pagina cu facturi primite
|
||
lcFiltru = [1=2] && [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))]
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
gencursor('poFacturiPrimite', 'crsFacturiPrimite', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poFacturiPrimite.ca_baza1.afisare()
|
||
Select crsFacturiPrimite
|
||
Go Top
|
||
|
||
* FACTURI TRIMISE
|
||
Text To lcSchema Noshow
|
||
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, mesaj_trimis C(250) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
|
||
Endtext
|
||
Text To lcSelect Noshow
|
||
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, mesaj_trimis, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_trimis
|
||
Endtext
|
||
lcOrder = [data_act,numar_act,data_trimis,data_raspuns]
|
||
lcgroup = []
|
||
* Aduc inregistrarile cand se activeaza prima data pagina cu facturi trimise
|
||
lcFiltru = [1=2] && [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))]
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
gencursor('poFacturiTrimise', 'crsFacturiTrimise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poFacturiTrimise.ca_baza1.afisare()
|
||
Select crsFacturiTrimise
|
||
Go Top
|
||
|
||
* FACTURI EMISE
|
||
Text To lcSchema Noshow
|
||
ales N(1), id N(20), id_fact N(20), id_vanzare N(10), data_act D, numar_act N(14), in_valuta N(1) null, curs N(10,4) null, valval N(16,2), tvaval N(16,2),totval N(16,2), total_fara_tva N(16,2), total_tva N(16,2), total_cu_tva N(16,2), nume_valuta C(5) null, client C(100), id_client N(10), cod_fiscal C(30), tip_persoana N(1) null, trimis N(1) null, data_trimis T null, stare C(100) null, id_incarcare C(36) null, mesaj_trimis C(250) null, id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, xfurnizor C(200), xclient C(200), xdata_act D, xnumar_act C(30), xtotal_fara_tva N(16,4), xtotal_tva N(16,4), xtotal_tva_ron N(16,4), xtotal_cu_tva N(16,4), xdiscount_fara_tva N(16,4), xtaxe_fara_tva N(16,4), xvaloare_fara_tva N(16,4), xtotal_de_plata N(16,4), xnume_valuta C(5), test N(1) null, id_util N(10), utilizator C(100), jtotctva N(16,4), diferenta N(16,4), procesat N(1), procesat_server N(1), creditnote N(1)
|
||
Endtext
|
||
Text To lcSelect Noshow
|
||
SELECT 0 as ales, id, id_fact, id_vanzare, data_act, numar_act, in_valuta, curs, valval, tvaval, totval, total_fara_tva, total_tva,total_cu_tva, nume_valuta, client, id_client, cod_fiscal, NVL(tip_persoana,1) as tip_persoana, NVL(trimis,0) as trimis, data_trimis, stare, id_incarcare, mesaj_trimis, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, xfurnizor, xclient, xdata_act, xnumar_act, xtotal_fara_tva, xtotal_tva, xtotal_tva_ron, xtotal_cu_tva, xdiscount_fara_tva, xtaxe_fara_tva, xvaloare_fara_tva, xtotal_de_plata, xnume_valuta, test, id_util, utilizator, jtotctva, decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00) as diferenta, procesat, procesat_server,creditnote FROM anaf_vefactura_emis
|
||
Endtext
|
||
lcOrder = [data_act,numar_act]
|
||
lcgroup = []
|
||
lcFiltru = [(extract(year from data_act)=?gnAn and extract(month from data_act)=?gnLuna) OR (trimis = 1 and tip_mesaj_raspuns is null and extract(year from data_act) >=2023)]
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
* Afisez toate facturile emise, ca sa le pot vizualiza pe cele netrimise sau trimise cu starea lor (trimis, eroare etc.)
|
||
gencursor('poFacturiEmise', 'crsFacturiEmise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poFacturiEmise.ca_baza1.afisare()
|
||
|
||
|
||
* DETALII FACTURI PRIMITE/TRIMISE/EMISE
|
||
Text To lcSchema Noshow
|
||
id N(20), id_efactura N(20), nr N(5), articol V(250), descriere V(250), detalii M, cantitate N(18,6), um V(20), pret N(20,6), proctva N(7,2), valoarefaratva N(20,6), discountfaratva N(20,6)
|
||
Endtext
|
||
Text To lcSelect Noshow
|
||
select id, id_efactura, nr, articol, descriere, detalii, cantitate, um, pret, proctva, valoarefaratva, discountfaratva from anaf_vefactura_detalii
|
||
Endtext
|
||
lcOrder = [nr]
|
||
lcgroup = []
|
||
lcFiltru = [1=2] && IIF(!EMPTY(NVL(crsFacturiPrimite.id,0)), [id_efactura=] + ALLTRIM(STR(crsFacturiPrimite.id)), [1=2])
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
gencursor('poFacturiDetalii', 'crsDetaliiFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poFacturiDetalii.ca_baza1.afisare()
|
||
|
||
|
||
Select crsFacturiEmise
|
||
loFrmBorderou = Createobject("anaf_efactura", This)
|
||
* Do Form anaf_efactura Name loFrmBorderou Linked With this Noshow
|
||
|
||
loFrmBorderou.Show(1)
|
||
|
||
Use In (Select('crsFacturiEmise'))
|
||
Use In (Select('crsFacturiTrimise'))
|
||
Use In (Select('crsFacturiPrimite'))
|
||
Use In (Select('crsDetaliiFacturi'))
|
||
Endproc && vizeFactura
|
||
|
||
Function getToken
|
||
Lparameters tlShow
|
||
* tlShow: .T. arata formularul chiar daca este generat Token si nu este expirat 90 zile
|
||
Private poToken
|
||
|
||
Local loFrmToken As "anaf_token"
|
||
Local lcToken, lcRefreshToken, lcTokenGenDate, ldTokenGenDate, loServer
|
||
|
||
loServer = This.AnafeFacturaServer
|
||
|
||
* TokenJWT are dimensiunea mai mare. Il salvez in optiuni.varvalue2
|
||
IF .F.
|
||
lcToken = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN', .T.), ''))
|
||
lcRefreshToken = Alltrim(Nvl(citeste_optiune('ANAF_REFRESH_TOKEN', .T.), ''))
|
||
|
||
lcTokenGenDate = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN_GENDATE'), ''))
|
||
ldTokenGenDate = Iif(!Empty(m.lcTokenGenDate), Ctod(m.lcTokenGenDate), {})
|
||
lcTokenExpDate = Alltrim(Nvl(citeste_optiune('ANAF_TOKEN_EXPDATE'), ''))
|
||
ldTokenExpDate = Iif(!Empty(m.lcTokenExpDate), Ctod(m.lcTokenExpDate), {})
|
||
ldTokenExpDate = Iif(!Empty(m.ldTokenExpDate), m.ldTokenExpDate, m.ldTokenGenDate + 90)
|
||
ELSE
|
||
lcToken = loServer.cToken
|
||
lcRefreshToken = loServer.cRefreshToken
|
||
ldTokenGenDate = loServer.dTokenGendate
|
||
ldTokenExpDate = loServer.dTokenExpdate
|
||
ENDIF
|
||
|
||
This.token = m.lcToken
|
||
This.refresh_token = m.lcRefreshToken
|
||
This.token_gendate = m.ldTokenGenDate
|
||
This.token_expdate = m.ldTokenExpDate
|
||
|
||
If m.tlShow Or Empty(m.lcToken) Or m.ldTokenExpDate <= Date()
|
||
loFrmToken = Createobject("anaf_token", This)
|
||
loFrmToken.Show(1)
|
||
*!* 07.07.2026
|
||
*!* dupa fluxul automat (newToken) datele sunt deja setate corect din expires_in
|
||
*!* (dTokenGendate = azi); suprascrierea cu +90 ramane doar pentru completarea manuala
|
||
If m.lcToken <> loServer.cToken And loServer.dTokenGendate <> Date()
|
||
loServer.dTokenGendate = Date()
|
||
loServer.dTokenExpdate = Date() + 90
|
||
Endif
|
||
|
||
This.SaveToken()
|
||
Endif
|
||
|
||
Return loServer.cToken
|
||
Endfunc
|
||
|
||
***************************
|
||
* Salveaza tokenul in baza de date optiuni firma
|
||
***************************
|
||
Procedure SaveToken
|
||
LOCAL loServer
|
||
|
||
loServer = This.AnafeFacturaServer
|
||
loServer.SaveToken()
|
||
Endproc && SaveToken
|
||
|
||
|
||
*!* 07.07.2026
|
||
*!* newToken - deleaga la AnafeFacturaServer.newToken (implementare unica FR-7)
|
||
*!* pattern identic cu refreshToken: loServer = This.AnafeFacturaServer
|
||
|
||
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
||
* Se apeleaza din formularul anaf_token.do_executa
|
||
Function newToken
|
||
LOCAL loServer
|
||
loServer = This.AnafeFacturaServer
|
||
* Asigura cTokenUrl populat din optiunile firmei (citit de GetToken din citeste_optiune)
|
||
loServer.GetToken()
|
||
loServer.newToken()
|
||
* Propagare proprietati actualizate catre ANAFeFactura (consistent cu getToken)
|
||
This.token = loServer.cToken
|
||
This.refresh_token = loServer.cRefreshToken
|
||
This.token_gendate = loServer.dTokenGendate
|
||
This.token_expdate = loServer.dTokenExpdate
|
||
Endfunc
|
||
|
||
* Actualizeaza data expirarii tokenului ANAF eFactura
|
||
* Se apeleaza din formularul anaf_token.do_executa
|
||
Function refreshToken
|
||
LOCAL loServer, lcMesaj, llSucces
|
||
llSucces = .F.
|
||
|
||
loServer = This.AnafeFacturaServer
|
||
lcMesaj = ''
|
||
llSucces = loServer.RefreshToken(@lcMesaj)
|
||
|
||
AMESSAGEBOX(m.lcMesaj, 0 + 48, _Screen.Caption)
|
||
|
||
Return m.llSucces
|
||
Endfunc
|
||
|
||
********************************
|
||
* Bifeaza Trimis o factura trimisa manual la ANAF
|
||
********************************
|
||
Procedure BifeazaTrimisManual
|
||
Lparameters tnIdFact, tnTrimis
|
||
Private pnIdFact, pnTrimis
|
||
pnIdFact = m.tnIdFact
|
||
pnTrimis = m.tnTrimis
|
||
pnTest = IIF(This.lTest, 1, 0) && server TEST ANAF
|
||
lcSql = 'begin pack_anaf.BifeazaEFactTrimisManual(?pnIdFact, ?pnTrimis, ?pnTest, ?gnIdUtil); end;'
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
Return m.llSucces
|
||
Endproc && BifeazaTrimisManual
|
||
|
||
|
||
********************************
|
||
* Suprascrie Id Incarcare manual, in caz ca pe factura este un Id Incarcare al trimiterilor ulterioare care au primit raspuns Eroare factura duplicata
|
||
* Este posibil si ca la prima incarcare anaf.ro sa dea timeout si sa nu intoarca Id Incarcare si sa se trimita din nou factura. Se primeste id incarcare, dar mesajul de descarcare este EROARE factura duplicata.
|
||
********************************
|
||
Procedure SuprascrieIdIncarcare
|
||
Lparameters tnIdFact, tcIdIncarcare
|
||
Private pnIdFact, pcIdIncarcare
|
||
pnIdFact = m.tnIdFact
|
||
pcIdIncarcare = m.tcIdIncarcare
|
||
pnTest = IIF(This.lTest, 1, 0) && server TEST ANAF
|
||
lcSql = 'begin pack_anaf.SuprascrieIdIncarcare(?pnIdFact, ?pcIdIncarcare, ?pnTest, ?gnIdUtil); end;'
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
Return m.llSucces
|
||
Endproc && SuprascrieIdIncarcare
|
||
|
||
|
||
********************************
|
||
* Genereaza xml efactura, valideaza xml si trimite la API ANAF
|
||
********************************
|
||
Procedure TrimiteFacturi
|
||
Lparameters tlNuTrimiteEFacturaANAF
|
||
|
||
Local lcTip, llSucces, lnValoare, lnRecno, loEx as Exception
|
||
Local lcFilter, lcSql, lnIdVanzare
|
||
Local lcRecc, lcRecno, ldDataFact, lnNumarFact, loReturn, lnTrimis
|
||
Local lcMesaj
|
||
Local lcErrorMessage, lcExecutionStatus, lcIndexIncarcare, loXML
|
||
Private pnIdFact, pnValoare, pcMesajTrimis, pnTrimis, pcIdIncarcare, pnTest
|
||
|
||
llSucces = .F.
|
||
pnIdFact = crsFacturiEmise.id_fact
|
||
pnTest = IIF(This.lTest, 1, 0) && server TEST ANAF
|
||
lnRecno = Recno('crsFacturiEmise')
|
||
lcFilter = "id_fact = " + Alltrim(Str(m.pnIdFact))
|
||
|
||
Select crsFacturiEmise
|
||
Locate For ales = 1
|
||
If !Found()
|
||
Locate For id_fact = m.pnIdFact
|
||
Else
|
||
lcFilter = "ales = 1"
|
||
Endif
|
||
|
||
If Empty(m.pnIdFact)
|
||
Return m.llSucces
|
||
Endif
|
||
|
||
lcSql = 'begin pack_anaf.BifeazaEFactTrimis(?pnIdFact, ?pnTrimis, ?pcMesajTrimis, ?pcIdIncarcare, ?pnTest, ?gnIdUtil); end;'
|
||
|
||
Select crsFacturiEmise
|
||
lcRecc = Alltrim(Str(Reccount()))
|
||
Scan For &lcFilter
|
||
pnIdFact = id_fact
|
||
lnIdVanzare = id_vanzare
|
||
lnNumarFact = crsFacturiEmise.numar_act
|
||
ldDataFact = crsFacturiEmise.data_act
|
||
pnTrimis = Nvl(trimis, 0)
|
||
lnTrimis = Nvl(trimis, 0)
|
||
pcIdIncarcare = Nvl(id_incarcare, '')
|
||
|
||
lcRecno = Alltrim(Str(Recno()))
|
||
|
||
Wait Window 'Factura ' + Alltrim(Str(m.lnNumarFact)) + ' / ' + Dtoc(m.ldDataFact) + ' ' + m.lcRecno + '/' + m.lcRecc Nowait
|
||
|
||
loReturn = This.TrimiteEfactura(m.lnIdVanzare, m.tlNuTrimiteEFacturaANAF)
|
||
llSucces = loReturn.lSucces
|
||
|
||
If m.llSucces
|
||
pcMesajTrimis = Iif(This.lTest, 'TEST ', '')
|
||
loXML = NULL
|
||
IF !m.tlNuTrimiteEFacturaANAF
|
||
TRY
|
||
loXML = nfxmlread(loReturn.cResponse)
|
||
CATCH TO loEx
|
||
lcErrorMessage = loEx.Message
|
||
ENDTRY
|
||
ENDIF
|
||
lcExecutionStatus = ''
|
||
lcIndexIncarcare = ''
|
||
lcErrorMessage = ''
|
||
IF TYPE('loxml.header._attr_.executionstatus') <> 'U'
|
||
lcExecutionStatus = loxml.header._attr_.executionstatus
|
||
ENDIF
|
||
IF TYPE('loxml.header._attr_.index__incarcare') <> 'U'
|
||
lcIndexIncarcare = loxml.header._attr_.index__incarcare
|
||
ENDIF
|
||
IF TYPE('loxml.header.errors._attr_.errorMessage') <> 'U'
|
||
lcErrorMessage = loxml.header.errors._attr_.errorMessage
|
||
ENDIF
|
||
|
||
Do Case
|
||
Case lcExecutionStatus = "0"
|
||
pcIdIncarcare = m.lcIndexIncarcare
|
||
pnTrimis = 1
|
||
pcMesajTrimis = m.pcMesajTrimis + 'Transmis cu succes. Index incarcare = ' + m.pcIdIncarcare
|
||
|
||
Case !EMPTY(m.lcErrorMessage)
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 1
|
||
pcMesajTrimis = m.pcMesajTrimis + Iif(This.lTest, 'TEST ', '') + 'Eroare. ' + m.lcErrorMessage
|
||
|
||
Case [VALID] $ Upper(loReturn.cResponse)
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 0
|
||
pcMesajTrimis = m.pcMesajTrimis + loReturn.cResponse
|
||
Otherwise
|
||
pcMesajTrimis = m.pcMesajTrimis + Iif(This.lTest, 'TEST ', '') + 'Eroare. ' + m.lcErrorMessage
|
||
pcIdIncarcare = ''
|
||
pnTrimis = 1
|
||
Endcase
|
||
|
||
* Completez doar cu raspunsul de la trimiterea la ANAF, nu si de la validare
|
||
If !m.tlNuTrimiteEFacturaANAF
|
||
pcMesajTrimis = LEFT(m.pcMesajTrimis,250)
|
||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||
Endif
|
||
|
||
If [VALID] $ Upper(loReturn.cResponse) And m.lnTrimis = 0
|
||
Replace trimis With m.pnTrimis, id_incarcare With m.pcIdIncarcare, data_trimis With Datetime(), mesaj_trimis With m.pcMesajTrimis, ales With 0, ;
|
||
id_descarcare WITH '', data_raspuns WITH null, tip_mesaj_raspuns WITH '', mesaj_raspuns WITH null ;
|
||
In crsFacturiEmise
|
||
Else
|
||
Replace trimis With m.pnTrimis, id_incarcare With m.pcIdIncarcare, data_trimis With Datetime(), mesaj_trimis With m.pcMesajTrimis, ales With 0, ;
|
||
id_descarcare WITH '', data_raspuns WITH null, tip_mesaj_raspuns WITH '', mesaj_raspuns WITH null ;
|
||
In crsFacturiEmise
|
||
Endif
|
||
ELSE
|
||
|
||
lcMesaj = 'Eroare transmitere factura ' + Alltrim(Str(m.lnNumarFact)) + ' / ' + Dtoc(m.ldDataFact) + Chr(13) + Chr(10) + ;
|
||
'Fisier xml: ' + Alltrim(Transform(loReturn.cFile)) + Chr(13) + Chr(10) + ;
|
||
'ANAF Http Status: ' + Transform(loReturn.nStatus) + Chr(13) + Chr(10) + ;
|
||
IIF(loReturn.nStatus = 403, 'Acces interzis. Token-ul a expirat si trebuie regenerat.' + Chr(13) + Chr(10), '') + ;
|
||
'ANAF Http Response: ' + Alltrim(Transform(loReturn.cResponse))
|
||
poLog.Log(m.lcMesaj)
|
||
|
||
If AMESSAGEBOX(m.lcMesaj + Chr(10) + ;
|
||
'Doriti sa continuati?', 4 + 32, _Screen.Caption) <> 6
|
||
Exit
|
||
Endif
|
||
Endif
|
||
Endscan
|
||
|
||
Select crsFacturiEmise
|
||
Try
|
||
If m.lnRecno > 0
|
||
Goto m.lnRecno
|
||
Else
|
||
Go Top
|
||
Endif
|
||
Catch
|
||
Go Top
|
||
Endtry
|
||
Endproc && TrimiteFacturi
|
||
|
||
* Genereaza xml eFactura, valideaza xml si trimite la ANAF
|
||
FUNCTION TrimiteEfactura
|
||
Lparameters tnIdVanzare, tlNuTrimiteEFacturaANAF
|
||
PRIVATE pcTokenEfactura
|
||
LOCAL loReturn
|
||
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "lSucces", .F.)
|
||
AddProperty(loReturn, "cFile", '')
|
||
AddProperty(loReturn, "cResponse", '')
|
||
AddProperty(loReturn, "nStatus", 0)
|
||
|
||
* Genereaza xml eFactura
|
||
llSilent = .T.
|
||
llJustPDF = .F.
|
||
lcTipDocument = 'FACTURA'
|
||
llEFactura = .T.
|
||
llOk = .F.
|
||
lcFile = ''
|
||
lcMesaj = ''
|
||
|
||
pcTokenEfactura = This.Token && variabila privata pentru getxmlefactura > ValidareEFacturaAnaf
|
||
|
||
loDate = listeaza_formular(m.tnIdVanzare, m.llSilent, m.llJustPDF, m.lcTipDocument, m.llEFactura)
|
||
loInfo = loDate.oInfoEFactura
|
||
If Type('loInfo.cFile') = 'C'
|
||
lcFile = Iif(Type('loInfo.cFile') = 'C', loInfo.cFile, '')
|
||
llOk = loInfo.lOk
|
||
lcMesaj = loInfo.cMesaj
|
||
Endif
|
||
|
||
loReturn.cFile = m.lcFile
|
||
|
||
lcCodTara = 'RO'
|
||
IF TYPE('loDate.oClient.cod_tara') <> 'U'
|
||
lcCodTara = ALLTRIM(NVL(loDate.oClient.cod_tara, ''))
|
||
IF EMPTY(m.lcCodTara)
|
||
lcCodTara = 'RO'
|
||
ENDIF
|
||
ENDIF
|
||
|
||
llAtributFiscalRO = .F.
|
||
IF TYPE('loDate.oClient.cod_fiscal') <> 'U'
|
||
llAtributFiscalRO = 'RO'$UPPER(ALLTRIM(NVL(loDate.oClient.cod_fiscal, '')))
|
||
ENDIF
|
||
|
||
llExtern = (m.lcCodTara <> 'RO' AND !m.llAtributFiscalRO) && sa aiba sediul fiscal extern si sa nu fie inregistrat TVA in Romania
|
||
lcExtern = IIF(m.llExtern, '&extern=DA', '')
|
||
|
||
If m.llOk And !Empty(m.lcFile) And Type('lcFile') = 'C' And File(m.lcFile)
|
||
If !m.tlNuTrimiteEFacturaANAF
|
||
loReturn = This.AnafeFacturaServer.SendEfactura(m.lcFile, m.llExtern)
|
||
Else
|
||
loReturn.cResponse = Iif(!Empty(m.lcMesaj), m.lcMesaj + Chr(13) + Chr(10), '') + 'VALID. Nu s-a trimis fisierul la ANAF.'
|
||
loReturn.lSucces = .T.
|
||
Endif
|
||
Else
|
||
loReturn.cResponse = m.lcMesaj + Chr(13) + Chr(10) + '<errorMessage="Nu s-a trimis fisierul la ANAF">'
|
||
loReturn.lSucces = .F.
|
||
Endif
|
||
|
||
RETURN m.loReturn
|
||
|
||
ENDFUNC && TrimiteEfactura
|
||
|
||
|
||
****************
|
||
* Parseaza un xml efactura si actualizeaza ANAF_EFACTURA
|
||
****************
|
||
PROCEDURE Detalii2UpdateFactura
|
||
LPARAMETERS tnId, tcDetalii
|
||
|
||
LOCAL llVariable
|
||
llVariable = .T.
|
||
|
||
TRY
|
||
loFactura = ParseEFactura(m.tcDetalii, m.llVariable)
|
||
loFactura.nId = m.tnId
|
||
|
||
lcSql = [select a.*, 1 as modificat, to_clob(null) as factura_detalii from anaf_efactura a where id = ] + ALLTRIM(STR(m.tnId))
|
||
llSucces = goExecutor.oExecuta(m.lcSql, 'cAnafEfacturaTemp')
|
||
IF m.llSucces
|
||
ADDPROPERTY(loFactura, 'cIdIncarcare', cAnafEfacturaTemp.id_incarcare)
|
||
ADDPROPERTY(loFactura, 'cIdDescarcare', cAnafEfacturaTemp.id_incarcare)
|
||
|
||
llSucces = This.AnafeFacturaServer.cUpdateFactura(loFactura, 'cAnafEfacturaTemp')
|
||
|
||
IF m.llSucces
|
||
llSucces = This.AnafeFacturaServer.UpdateDb('cAnafEfacturaTemp')
|
||
ENDIF
|
||
ENDIF
|
||
|
||
USE IN (SELECT('cAnafEfacturaTemp'))
|
||
Catch To loEx
|
||
llSucces = .F.
|
||
ENDTRY
|
||
RETURN m.llSucces
|
||
ENDPROC && Detalii2UpdateFactura
|
||
|
||
|
||
|
||
|
||
* Salveaza pe disk arhiva cu detalii ANAF_EFACTURA.DETALII_ZIP
|
||
FUNCTION DownloadDetaliiZip
|
||
LPARAMETERS tnIdeFactura
|
||
|
||
PRIVATE poDetaliiZip
|
||
poDetaliiZip = null
|
||
|
||
lcSchema = [id_incarcare V(36), fisier W]
|
||
lcSelect = [select id_incarcare, detalii_zip from anaf_efactura where id = ] + Alltrim(Str(tnIdeFactura))
|
||
lcOrder = []
|
||
lcgroup = []
|
||
lcFiltru = []
|
||
lcFiltruOriginal = []
|
||
llModParam = .T.
|
||
llAfiseaza = .F.
|
||
|
||
gencursor('poDetaliiZip','cRegFisierTemp', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
|
||
poDetaliiZip.ca_baza1.afisare()
|
||
If Used('cRegFisierTemp')
|
||
lcIdIncarcare = ALLTRIM(NVL(id_incarcare, ''))
|
||
lcFisier = fisier
|
||
Use In (Select('cRegFisierTemp'))
|
||
|
||
lcFile = PUTFILE('Fisier', m.lcIdIncarcare, 'zip')
|
||
IF !EMPTY(m.lcFile)
|
||
Strtofile(lcFisier, m.lcFile)
|
||
open_default_app(JUSTPATH(m.lcFile))
|
||
ENDIF
|
||
Endif
|
||
ENDFUNC && DownloadDetaliiZip
|
||
|
||
ENDDEFINE && ANAFeFactura
|
||
|
||
|
||
|
||
*********************
|
||
* Parseaza xml efactura si intoarce obiect VFP cu datele facturii xml cu detaliile facturii
|
||
*********************
|
||
Procedure ParseEFactura
|
||
Lparameters tcFile, tlVariable
|
||
* tcFile: fisier sau variabila care contine xml eFactura
|
||
* tlVariable: .T. daca tcFile este o variabila care contine xml eFactura
|
||
|
||
Local lcFileText, lcDetalii, lcFacturaDetalii, loEx As Exception, loReturn
|
||
Local laLinii[1], laLiniiDisc[1], laDetalii[1], laDetaliiLinie[1], laDetaliiPlata[1], laCommodityClassification[1]
|
||
Local lcDataFactura, lcDataScad, lcDetaliiLinie, lcUM, lcValuta, lnAn, lnCant, lnDetalii
|
||
Local lnDetaliiLinie, lnDetaliu, lnDetaliuLinie, lnLinie, lnLinii, lnLuna, lnNr, lnPret, lnProcTva
|
||
Local lnZi, loFactura, loLinie, lcArticol, lcDetaliu
|
||
Local lcArticolDescriere, lcBanca, lcCodClient, lcCodFurnizor, lcTip, lcCod, lcCodBare, lcCodCPV, lcCodNC8
|
||
Local lcCodPlata, lcContBanca, lcPrefixInvoice, llCreditNote
|
||
Local lnCommodityClassification, lnCommodityClassifications, lnValoareFaraTVA
|
||
Local loCommodityClassification, loDetaliu, loItemClassificationCode
|
||
Local lnDiscount, lnDiscountLinie, lnValoareTVA, loTaxTotal
|
||
|
||
|
||
|
||
*!* IF '4114569629'$lcfile
|
||
*!* SET STEP ON
|
||
*!* ENDIF
|
||
loReturn = Createobject("empty")
|
||
AddProperty(loReturn, "nId", "") && ANAF_EFACTURA.ID
|
||
AddProperty(loReturn, "NumarAct", "")
|
||
AddProperty(loReturn, "DataAct", {})
|
||
AddProperty(loReturn, "DataScad", {})
|
||
|
||
AddProperty(loReturn, "Furnizor", "")
|
||
AddProperty(loReturn, "CodTaraFurnizor", "")
|
||
AddProperty(loReturn, "CodJudetFurnizor", "")
|
||
AddProperty(loReturn, "LocalitateFurnizor", "")
|
||
AddProperty(loReturn, "StradaFurnizor", "")
|
||
AddProperty(loReturn, "CodFiscalFurnizor", "")
|
||
|
||
AddProperty(loReturn, "Client", "")
|
||
AddProperty(loReturn, "CodTaraClient", "")
|
||
AddProperty(loReturn, "CodJudetClient", "")
|
||
AddProperty(loReturn, "LocalitateClient", "")
|
||
AddProperty(loReturn, "StradaClient", "")
|
||
AddProperty(loReturn, "CodFiscalClient", "")
|
||
|
||
AddProperty(loReturn, "TotalFaraTva", 0.00)
|
||
AddProperty(loReturn, "TotalTva", 0.00)
|
||
AddProperty(loReturn, "TotalTvaRON", 0.00)
|
||
AddProperty(loReturn, "TotalCuTva", 0.00)
|
||
AddProperty(loReturn, "TaxeFaraTVA", 0.00)
|
||
AddProperty(loReturn, "DiscountFaraTVA", 0.00)
|
||
AddProperty(loReturn, "ValoareFaraTVA", 0.00) && suma valoare articole
|
||
AddProperty(loReturn, "TotaldePlata", 0.00)
|
||
AddProperty(loReturn, "Valuta", "")
|
||
AddProperty(loReturn, "Detalii", "") && note factura
|
||
AddProperty(loReturn, "DetaliiPlata", "") && detalii plata (conturi bancare)
|
||
AddProperty(loReturn, "FacturaDetalii", "") && liniile facturii
|
||
AddProperty(loReturn, "FacturaDetaliiDisc", "") && linii discount la nivel de factura
|
||
AddProperty(loReturn, "Eroare", .F.) && daca a aparut o eroare la parsarea facturii
|
||
AddProperty(loReturn, "CreditNote", 0) && 1 = CreditNote, 0 = Invoice
|
||
|
||
Create Cursor cFacturaDetaliiTemp(nr I, cant N(16, 6), um V(20), articol V(250), descriere V(250), detalii M, Pret N(16, 6), proctva N(10, 2), tiptva V(2), valoarefaratva N(16,4), discountfaratva N(16,4), codfurnizor V(100), codclient V(100), codbare V(50), codcpv V(50), codnc8 V(50))
|
||
CREATE CURSOR cFacturaDetaliiDisc(valoare N(20,6), procentTVA N(5,2), tiptva V(10), discount N(1), motivdiscount V(200), motivdiscountcod V(50))
|
||
|
||
If m.tlVariable
|
||
lcFileText = m.tcFile
|
||
Else
|
||
lcFileText = Iif(File(m.tcFile), Filetostr(m.tcFile), '')
|
||
Endif
|
||
|
||
If Empty(m.lcFileText)
|
||
loReturn.eroare = .T.
|
||
Return loReturn
|
||
Endif
|
||
|
||
* CreditNote to Invoice
|
||
llCreditNote = 'CreditNote' $ lcFileText
|
||
loReturn.CreditNote = IIF(m.llCreditNote, 1, 0)
|
||
lcFileText = Strtran(lcFileText, 'CreditNote', 'Invoice', 1, 100000, 1)
|
||
lcFileText = Strtran(lcFileText, 'Credited', 'Invoiced', 1, 100000, 1)
|
||
|
||
* Scot cbc: cac:
|
||
* Unele fisiere nu au, altele au. Le scot din toate
|
||
lcFileText = Strtran(lcFileText, 'cac:', '', 1, 1000000, 1)
|
||
lcFileText = Strtran(lcFileText, 'cbc:', '', 1, 1000000, 1)
|
||
|
||
lcPrefixInvoice = STREXTRACT(m.lcFileText, [<], [Invoice],1,1) && un prefix custom la Invoice <p:Invoice xlmns...
|
||
IF LEN(m.lcPrefixInvoice) > 10 && caut prefixul la a doua aparitie a <
|
||
lcPrefixInvoice = STREXTRACT(m.lcFileText, [<], [Invoice],2,1) && un prefix custom la Invoice <p:Invoice xlmns...
|
||
ENDIF
|
||
IF !EMPTY(m.lcPrefixInvoice)
|
||
lcFileText = Strtran(lcFileText, m.lcPrefixInvoice, '', 1, 100000, 1) && elimin prefixul custom Invoice
|
||
ENDIF
|
||
|
||
* elimin prefixuri custom: n2:, n3:
|
||
lcPattern = [<\/.{1,6}:Amount>] && [<n3:Amount ]
|
||
lcPrefix = GetRegExp(m.lcFileText, m.lcPattern)
|
||
lcPrefix = STREXTRACT(NVL(m.lcPrefix, ''), [</], [Amount],1,1)
|
||
IF !EMPTY(m.lcPrefix)
|
||
lcFileText = Strtran(lcFileText, m.lcPrefix, '', 1, 100000, 1) && elimin prefixul custom
|
||
ENDIF
|
||
|
||
lcPattern = [<\/.{1,6}:AccountingSupplierParty>]
|
||
lcPrefix = GetRegExp(m.lcFileText, m.lcPattern)
|
||
lcPrefix = STREXTRACT(NVL(m.lcPrefix, ''), [</], [AccountingSupplierParty],1,1)
|
||
IF !EMPTY(m.lcPrefix)
|
||
lcFileText = Strtran(lcFileText, m.lcPrefix, '', 1, 100000, 1) && elimin prefixul custom
|
||
ENDIF
|
||
|
||
lcPattern = [<\/.{1,6}:LineExtensionAmount>]
|
||
lcPrefix = GetRegExp(m.lcFileText, m.lcPattern)
|
||
lcPrefix = STREXTRACT(NVL(m.lcPrefix, ''), [</], [LineExtensionAmount],1,1)
|
||
IF !EMPTY(m.lcPrefix)
|
||
lcFileText = Strtran(lcFileText, m.lcPrefix, '', 1, 100000, 1) && elimin prefixul custom
|
||
ENDIF
|
||
|
||
|
||
TRY
|
||
* Nu prea functioneaza transformarea in array-uri a tag-urilor care apar o singura data
|
||
loFactura = nfxmlread(m.lcFileText)
|
||
*!* MESSAGEBOX(lofactura.invoice.cac_legalmonetarytotal.cbc_taxinclusiveamount._attr_.currencyid)
|
||
*!* MESSAGEBOX(lofactura.invoice.cac_legalmonetarytotal.cbc_taxinclusiveamount._nodetext_)
|
||
*!* loNrFacturaPrimit = nfxmlread(m.pcDetalii, '.Invoice.cac:InvoiceLine[]', '//Invoice/cbc:ID' )
|
||
*!* loDataFacturaPrimit = nfxmlread(m.pcDetalii, '.Invoice.cac:InvoiceLine[]', '//Invoice/cbc:IssueDate' ) && 2022-09-30
|
||
*!* loDataFacturaPrimit = nfxmlread(m.pcDetalii, '.Invoice.cac:InvoiceLine[]', '//Invoice/cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount' ) && 2022-09-30
|
||
DO CASE
|
||
CASE Type('loFactura.invoice.id') = 'C'
|
||
loReturn.numaract = loFactura.Invoice.id
|
||
CASE Type('loFactura.invoice.id._nodetext_') = 'C'
|
||
loReturn.numaract = loFactura.Invoice.id._nodetext_
|
||
ENDCASE
|
||
|
||
If Type('loFactura.invoice.issuedate') = 'C'
|
||
lcDataFactura = loFactura.Invoice.issuedate
|
||
Else
|
||
If Type('loFactura.invoice.issuedate._nodetext_ ') = 'C'
|
||
lcDataFactura = loFactura.Invoice.issuedate._nodetext_
|
||
Endif
|
||
Endif
|
||
If !Empty(m.lcDataFactura)
|
||
lnAn = Int(Val(Substr(m.lcDataFactura, 1, 4)))
|
||
lnLuna = Int(Val(Substr(m.lcDataFactura, 6, 2)))
|
||
lnZi = Int(Val(Substr(m.lcDataFactura, 9, 2)))
|
||
loReturn.dataact = Date(m.lnAn, m.lnLuna, m.lnZi)
|
||
Endif
|
||
|
||
If Type('loFactura.invoice.duedate') = 'C'
|
||
lcDataScad = loFactura.Invoice.duedate
|
||
Else
|
||
If Type('loFactura.invoice.duedate._nodetext_') = 'C'
|
||
lcDataScad = loFactura.Invoice.duedate._nodetext_
|
||
Endif
|
||
Endif
|
||
If !Empty(m.lcDataScad)
|
||
lnAn = Int(Val(Substr(m.lcDataScad, 1, 4)))
|
||
lnLuna = Int(Val(Substr(m.lcDataScad, 6, 2)))
|
||
lnZi = Int(Val(Substr(m.lcDataScad, 9, 2)))
|
||
loReturn.datascad = Date(m.lnAn, m.lnLuna, m.lnZi)
|
||
Endif
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.LineExtensionAmount._nodetext_') = 'C'
|
||
loReturn.valoarefaratva = Val(loFactura.Invoice.legalmonetarytotal.LineExtensionAmount._nodetext_)
|
||
Endif
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.taxinclusiveamount._nodetext_') = 'C'
|
||
loReturn.totalcutva = Val(loFactura.Invoice.legalmonetarytotal.taxinclusiveamount._nodetext_)
|
||
Endif
|
||
If Type('lofactura.invoice.legalmonetarytotal.taxinclusiveamount._attr_.currencyid') = 'C'
|
||
loReturn.valuta = loFactura.Invoice.legalmonetarytotal.taxinclusiveamount._attr_.currencyid
|
||
Endif
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.TaxExclusiveAmount._nodetext_') = 'C'
|
||
loReturn.totalfaratva = Val(loFactura.Invoice.legalmonetarytotal.TaxExclusiveAmount._nodetext_)
|
||
Endif
|
||
|
||
loReturn.totaltva = loReturn.totalcutva - loReturn.totalfaratva
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.AllowanceTotalAmount._nodetext_') = 'C'
|
||
loReturn.discountfaratva = Val(loFactura.Invoice.legalmonetarytotal.AllowanceTotalAmount._nodetext_)
|
||
Endif
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.ChargeTotalAmount._nodetext_') = 'C'
|
||
* Transport trecut ca valoare totala pe document, in loc de o linie din factura
|
||
loReturn.taxefaratva = Val(loFactura.Invoice.legalmonetarytotal.ChargeTotalAmount._nodetext_)
|
||
Endif
|
||
|
||
If Type('lofactura.invoice.legalmonetarytotal.PayableAmount._nodetext_') = 'C'
|
||
loReturn.totaldeplata = Val(loFactura.Invoice.legalmonetarytotal.PayableAmount._nodetext_)
|
||
Endif
|
||
|
||
* Daca moneda facturii este in valuta <> RON, atunci extrag valoare tva in RON
|
||
* Sunt 2 TaxTotal, una in valuta facturii si una in RON
|
||
*!* <cac:TaxTotal>
|
||
*!* <cbc:TaxAmount currencyID="RON">0.00</cbc:TaxAmount>
|
||
*!* </cac:TaxTotal>
|
||
IF UPPER(ALLTRIM(loReturn.valuta)) <> 'RON'
|
||
If Type('loFactura.Invoice.TaxTotal') <> 'U'
|
||
If Type('loFactura.Invoice.TaxTotal', 1) = 'A'
|
||
FOR EACH loTaxTotal IN loFactura.Invoice.TaxTotal
|
||
IF TYPE('loTaxTotal.TaxAmount._attr_.CurrencyId') = 'C' AND TYPE('loTaxTotal.TaxAmount._nodetext_') = 'C' AND loTaxTotal.TaxAmount._attr_.CurrencyId = "RON"
|
||
loReturn.TotalTVARON = VAL(loTaxTotal.TaxAmount._nodetext_)
|
||
ENDIF
|
||
ENDFOR
|
||
ELSE
|
||
IF TYPE('loFactura.Invoice.TaxTotal') = 'O'
|
||
loTaxTotal = loFactura.Invoice.TaxTotal
|
||
IF TYPE('loTaxTotal.TaxAmount._attr_') = 'C' AND TYPE('loTaxTotal.TaxAmount._nodetext_') = 'C' AND loTaxTotal.TaxAmount._attr_.CurrencyId = "RON"
|
||
loReturn.TotalTVARON = VAL(loTaxTotal.TaxAmount._nodetext_)
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF && <> U
|
||
ELSE
|
||
loReturn.TotalTVARON = loReturn.totaltva
|
||
ENDIF && <> RON
|
||
|
||
|
||
|
||
loReturn.detalii = ""
|
||
If Type('loFactura.Invoice.note') <> 'U'
|
||
If Type('loFactura.Invoice.note', 1) = 'A'
|
||
Acopy(loFactura.Invoice.note, laDetalii)
|
||
ELSE
|
||
IF TYPE('loFactura.Invoice.note') = 'C'
|
||
laDetalii[1] = loFactura.Invoice.note
|
||
ELSE
|
||
IF TYPE('loFactura.Invoice.note._nodetext_') = 'C'
|
||
laDetalii[1] = loFactura.Invoice.note._nodetext_
|
||
ENDIF
|
||
ENDIF
|
||
Endif
|
||
|
||
lnDetalii = Alen(laDetalii)
|
||
For lnDetaliu = 1 To m.lnDetalii
|
||
lcDetaliu = ''
|
||
IF TYPE('laDetalii[m.lnDetaliu]') = 'C'
|
||
lcDetaliu = laDetalii[m.lnDetaliu]
|
||
ELSE
|
||
IF TYPE('laDetalii[m.lnDetaliu]._nodetext_') = 'C'
|
||
lcDetaliu = laDetalii[m.lnDetaliu]._nodetext_
|
||
ENDIF
|
||
ENDIF
|
||
loReturn.detalii = loReturn.detalii + Iif(m.lnDetaliu > 1, " ", "") + m.lcDetaliu
|
||
Endfor
|
||
Endif
|
||
|
||
* Detalii plata = conturi bancare plata
|
||
loReturn.detaliiplata = ""
|
||
If Type('loFactura.Invoice.paymentmeans') <> 'U'
|
||
If Type('loFactura.Invoice.paymentmeans', 1) = 'A'
|
||
Acopy(loFactura.Invoice.paymentmeans, laDetaliiPlata)
|
||
Else
|
||
laDetaliiPlata[1] = loFactura.Invoice.paymentmeans
|
||
Endif
|
||
|
||
lnDetalii = Alen(laDetaliiPlata)
|
||
For lnDetaliu = 1 To m.lnDetalii
|
||
loDetaliu = laDetaliiPlata[m.lnDetaliu]
|
||
lcCodPlata = ''
|
||
lcContBanca = ''
|
||
lcBanca = ''
|
||
If Type('loDetaliu.paymentmeanscode') = 'C'
|
||
lcCodPlata = loDetaliu.paymentmeanscode
|
||
Else
|
||
If Type('loDetaliu.paymentmeanscode._nodetext_') = 'C'
|
||
lcCodPlata = loDetaliu.paymentmeanscode._nodetext_
|
||
Endif
|
||
Endif
|
||
If !Empty(m.lcCodPlata)
|
||
Do Case
|
||
Case lcCodPlata = '10'
|
||
lcCodPlata = lcCodPlata + ' Numerar'
|
||
Case lcCodPlata = '20'
|
||
lcCodPlata = lcCodPlata + ' CEC'
|
||
Case lcCodPlata = '31'
|
||
lcCodPlata = lcCodPlata + ' Transfer'
|
||
Case lcCodPlata = '42'
|
||
lcCodPlata = lcCodPlata + ' OP'
|
||
Case lcCodPlata = '48'
|
||
lcCodPlata = lcCodPlata + ' Card'
|
||
Case lcCodPlata = '60'
|
||
lcCodPlata = lcCodPlata + ' BO'
|
||
Case lcCodPlata = '68'
|
||
lcCodPlata = lcCodPlata + ' Online'
|
||
Case lcCodPlata = '97'
|
||
lcCodPlata = lcCodPlata + ' Compensare'
|
||
Endcase
|
||
Endif
|
||
|
||
If Type('loDetaliu.payeefinancialaccount.id') = 'C'
|
||
lcContBanca = loDetaliu.payeefinancialaccount.id
|
||
Else
|
||
If Type('loDetaliu.payeefinancialaccount.id._nodetext_') = 'C'
|
||
lcContBanca = loDetaliu.payeefinancialaccount.id._nodetext_
|
||
Endif
|
||
Endif
|
||
If Type('loDetaliu.payeefinancialaccount.name') = 'C'
|
||
lcBanca = loDetaliu.payeefinancialaccount.name
|
||
Else
|
||
If Type('loDetaliu.payeefinancialaccount.name._nodetext_') = 'C'
|
||
lcBanca = loDetaliu.payeefinancialaccount.name._nodetext_
|
||
Endif
|
||
Endif
|
||
loReturn.detaliiplata = loReturn.detaliiplata + Iif(m.lnDetaliu > 1, "; ", "") + ;
|
||
Iif(Empty(m.lcCodPlata), '', 'Tip: ' + m.lcCodPlata) + ;
|
||
Iif(Empty(m.lcContBanca), '', Iif(!Empty(m.lcCodPlata), ',', '') + ' IBAN: ' + m.lcContBanca) + ;
|
||
Iif(Empty(m.lcBanca), '', Iif(!Empty(m.lcContBanca), ',', '') + ' Banca: ' + m.lcBanca)
|
||
Endfor
|
||
Endif
|
||
|
||
* Furnizor Denumire
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName') = 'C'
|
||
loReturn.Furnizor = Alltrim(loFactura.Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName._nodetext_') = 'C'
|
||
loReturn.Furnizor = Alltrim(loFactura.Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName._nodetext_)
|
||
ELSE
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity[1].RegistrationName') = 'C'
|
||
loReturn.Furnizor = Alltrim(loFactura.Invoice.AccountingSupplierParty.Party.PartyLegalEntity[1].RegistrationName)
|
||
ELSE
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity[2].RegistrationName') = 'C'
|
||
loReturn.Furnizor = Alltrim(loFactura.Invoice.AccountingSupplierParty.Party.PartyLegalEntity[2].RegistrationName)
|
||
ENDIF
|
||
ENDIF
|
||
Endif
|
||
ENDIF
|
||
|
||
* Cod fiscal Furnizor
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyId') = 'C'
|
||
loReturn.CodFiscalFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyId)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyId._nodetext_') = 'C'
|
||
loReturn.CodFiscalFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyId._nodetext_)
|
||
ELSE
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.CompanyId') = 'C'
|
||
loReturn.CodFiscalFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.CompanyId)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.CompanyId._nodetext_') = 'C'
|
||
loReturn.CodFiscalFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PartyLegalEntity.CompanyId._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
|
||
|
||
* Furnizor Cod Tara
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode') = 'C'
|
||
loReturn.CodTaraFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode._nodetext_') = 'C'
|
||
loReturn.CodTaraFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Furnizor Cod Judet
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity') = 'C'
|
||
loReturn.CodJudetFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity._nodetext_') = 'C'
|
||
loReturn.CodJudetFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity._nodetext_)
|
||
Endif
|
||
Endif
|
||
|
||
* Furnizor Localitate
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CityName') = 'C'
|
||
loReturn.LocalitateFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CityName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CityName._nodetext_') = 'C'
|
||
loReturn.LocalitateFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.CityName._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Furnizor Strada
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.StreetName') = 'C'
|
||
loReturn.StradaFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.StreetName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.StreetName._nodetext_') = 'C'
|
||
loReturn.StradaFurnizor = Alltrim(lofactura.invoice.AccountingSupplierParty.Party.PostalAddress.StreetName._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Client Denumire
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName') = 'C'
|
||
loReturn.client = Alltrim(loFactura.Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName._nodetext_') = 'C'
|
||
loReturn.client = Alltrim(loFactura.Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Cod fiscal Client
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyId') = 'C'
|
||
loReturn.CodFiscalClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyId)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyId._nodetext_') = 'C'
|
||
loReturn.CodFiscalClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyId._nodetext_)
|
||
ELSE
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.CompanyId') = 'C'
|
||
loReturn.CodFiscalClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.CompanyId)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.CompanyId._nodetext_') = 'C'
|
||
loReturn.CodFiscalClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PartyLegalEntity.CompanyId._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
ENDIF
|
||
ENDIF
|
||
|
||
* Client Cod Tara
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode') = 'C'
|
||
loReturn.CodTaraClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode._nodetext_') = 'C'
|
||
loReturn.CodTaraClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Client Cod Judet
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity') = 'C'
|
||
loReturn.CodJudetClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity._nodetext_') = 'C'
|
||
loReturn.CodJudetClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity._nodetext_)
|
||
Endif
|
||
Endif
|
||
|
||
* Client Localitate
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CityName') = 'C'
|
||
loReturn.LocalitateClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CityName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CityName._nodetext_') = 'C'
|
||
loReturn.LocalitateClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.CityName._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Client Strada
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.StreetName') = 'C'
|
||
loReturn.StradaClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.StreetName)
|
||
Else
|
||
If Type('lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.StreetName._nodetext_') = 'C'
|
||
loReturn.StradaClient = Alltrim(lofactura.invoice.AccountingCustomerParty.Party.PostalAddress.StreetName._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
|
||
* Cursor linii factura
|
||
If Type('lofactura.invoice.invoiceline', 1) = 'A'
|
||
Acopy(loFactura.Invoice.invoiceline, laLinii)
|
||
Else
|
||
laLinii[1] = loFactura.Invoice.invoiceline
|
||
Endif
|
||
|
||
Try
|
||
lnLinii = Alen(laLinii)
|
||
For lnLinie = 1 To m.lnLinii
|
||
loLinie = laLinii[m.lnLinie]
|
||
lnNr = 0
|
||
If Type('loLinie.id') = 'C'
|
||
lnNr = Int(Val(loLinie.id))
|
||
Else
|
||
If Type('loLinie.id._nodetext_') = 'C'
|
||
lnNr = Int(Val(loLinie.id._nodetext_))
|
||
Endif
|
||
ENDIF
|
||
|
||
lnValoareFaraTVA = 0
|
||
If Type('loLinie.LineExtensionAmount._nodetext_') = 'C'
|
||
lnValoareFaraTVA = Val(loLinie.LineExtensionAmount._nodetext_)
|
||
Endif
|
||
|
||
lcArticol = ''
|
||
If Type('loLinie.item.name') = 'C'
|
||
lcArticol = Alltrim(loLinie.item.name)
|
||
Else
|
||
If Type('loLinie.item.name._nodetext_') = 'C'
|
||
lcArticol = Alltrim(loLinie.item.name._nodetext_)
|
||
Endif
|
||
Endif
|
||
lcArticolDescriere = ''
|
||
If Type('loLinie.item.description') = 'C'
|
||
lcArticolDescriere = Alltrim(loLinie.item.description)
|
||
Else
|
||
If Type('loLinie.item.description._nodetext_') = 'C'
|
||
lcArticolDescriere = Alltrim(loLinie.item.description._nodetext_)
|
||
Endif
|
||
Endif
|
||
|
||
lcDetaliiLinie = ''
|
||
If Type('loLinie.note') <> 'U'
|
||
If Type('loLinie.note', 1) = 'A'
|
||
Acopy(loLinie.note, laDetaliiLinie)
|
||
Else
|
||
If Type('loLinie.note') = 'C'
|
||
laDetaliiLinie[1] = loLinie.note
|
||
Else
|
||
If Type('loLinie.note._nodetext_') = 'C'
|
||
laDetaliiLinie[1] = loLinie.note._nodetext_
|
||
Endif
|
||
Endif
|
||
Endif
|
||
|
||
lnDetaliiLinie = Alen(laDetaliiLinie)
|
||
For lnDetaliuLinie = 1 To m.lnDetaliiLinie
|
||
lcDetaliiLinie = m.lcDetaliiLinie + Iif(m.lnDetaliuLinie > 1, " ", "") + laDetaliiLinie[m.lnDetaliuLinie]
|
||
Endfor
|
||
ENDIF
|
||
|
||
* Cod articol cumparator/client
|
||
lcCodClient = ''
|
||
If Type('loLinie.item.BuyersItemIdentification.ID') = 'C'
|
||
lcCodClient = Alltrim(loLinie.item.BuyersItemIdentification.ID)
|
||
Else
|
||
If Type('loLinie.item.BuyersItemIdentification.ID._nodetext_') = 'C'
|
||
lcCodClient = Alltrim(loLinie.item.BuyersItemIdentification.ID._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Cod articol vanzator/furnizor
|
||
lcCodFurnizor = ''
|
||
If Type('loLinie.item.SellersItemIdentification.ID') = 'C'
|
||
lcCodFurnizor = Alltrim(loLinie.item.SellersItemIdentification.ID)
|
||
Else
|
||
If Type('loLinie.item.SellersItemIdentification.ID._nodetext_') = 'C'
|
||
lcCodFurnizor = Alltrim(loLinie.item.SellersItemIdentification.ID._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
* Cod de bare articol
|
||
lcCodBare = ''
|
||
If Type('loLinie.item.StandardItemIdentification.ID') = 'C'
|
||
lcCodBare = Alltrim(loLinie.item.StandardItemIdentification.ID)
|
||
Else
|
||
If Type('loLinie.item.StandardItemIdentification.ID._nodetext_') = 'C'
|
||
lcCodBare = Alltrim(loLinie.item.StandardItemIdentification.ID._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
lcCodCPV = ''
|
||
lcCodNC8 = ''
|
||
If Type('loLinie.item.CommodityClassification') <> 'U'
|
||
If Type('loLinie.item.CommodityClassification', 1) = 'A'
|
||
Acopy(loLinie.item.CommodityClassification, laCommodityClassification)
|
||
Else
|
||
If Type('loLinie.item.CommodityClassification') = 'O'
|
||
laCommodityClassification[1] = loLinie.item.CommodityClassification
|
||
Endif
|
||
Endif
|
||
|
||
lnCommodityClassifications = Alen(laCommodityClassification)
|
||
For lnCommodityClassification = 1 To m.lnCommodityClassifications
|
||
loCommodityClassification = laCommodityClassification[lnCommodityClassification]
|
||
IF TYPE('loCommodityClassification.ItemClassificationCode') = 'O'
|
||
loItemClassificationCode = loCommodityClassification.ItemClassificationCode
|
||
IF TYPE('loItemClassificationCode._attr_.listid') = 'C' AND TYPE('loItemClassificationCode._nodetext_') = 'C'
|
||
lcTip = UPPER(ALLTRIM(loItemClassificationCode._attr_.listid))
|
||
lcCod = ALLTRIM(loItemClassificationCode._nodetext_)
|
||
DO CASE
|
||
CASE m.lcTip = 'EN' AND EMPTY(m.lcCodBare)&& cod bare
|
||
lcCodBare = m.lcCod
|
||
CASE m.lcTip = 'STI' && cod CPV
|
||
lcCodCPV = m.lcCod
|
||
CASE m.lcTip = 'TSP' && cod NC8
|
||
lcCodNC8 = m.lcCod
|
||
ENDCASE
|
||
ENDIF && type
|
||
ENDIF && type
|
||
Endfor
|
||
ENDIF
|
||
|
||
lnCant = Val(loLinie.invoicedquantity._nodetext_)
|
||
lcUM = loLinie.invoicedquantity._attr_.unitcode
|
||
lnPret = Val(loLinie.price.priceamount._nodetext_)
|
||
lcValuta = loLinie.price.priceamount._attr_.currencyid
|
||
lnDiscountLinie = 0
|
||
IF TYPE('loLinie.AllowanceCharge.Amount._nodetext_') = 'C'
|
||
lnDiscountLinie = Val(loLinie.AllowanceCharge.Amount._nodetext_)
|
||
ENDIF
|
||
|
||
lnProcTva = 0
|
||
If Type('loLinie.item.ClassifiedTaxCategory.percent') = 'C'
|
||
lnProcTva = Val(loLinie.item.ClassifiedTaxCategory.percent)
|
||
Else
|
||
If Type('loLinie.item.ClassifiedTaxCategory.percent._nodetext_') = 'C'
|
||
lnProcTva = Val(loLinie.item.ClassifiedTaxCategory.percent._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
lcTipTVA = "" && S standard/Z neplatitor TVA/AE taxare inversa
|
||
If Type('loLinie.item.ClassifiedTaxCategory.ID') = 'C'
|
||
lcTipTva = loLinie.item.ClassifiedTaxCategory.ID
|
||
Else
|
||
If Type('loLinie.item.ClassifiedTaxCategory.ID._nodetext_') = 'C'
|
||
lcTipTva = loLinie.item.ClassifiedTaxCategory.ID._nodetext_
|
||
Endif
|
||
Endif
|
||
|
||
* Tip CreditNote am vazut ca nu are cantitate si pret negative pe linie, dar are valoare fara tva negativ!!!
|
||
If m.llCreditNote And m.lnCant > 0 And m.lnPret > 0 And m.lnValoareFaraTVA< 0
|
||
lnCant = -1 * m.lnCant
|
||
Endif
|
||
|
||
Insert Into cFacturaDetaliiTemp(nr, cant, um, articol, descriere, detalii, Pret, proctva, tiptva, valoarefaratva, discountfaratva, codfurnizor, codclient, codbare, codcpv, codnc8) Values (m.lnNr, m.lnCant, m.lcUM, m.lcArticol, m.lcArticolDescriere, m.lcDetaliiLinie, m.lnPret, lnProcTva, m.lcTipTva, m.lnValoareFaraTVA, m.lnDiscountLinie, m.lcCodFurnizor, m.lcCodClient, m.lcCodBare, m.lcCodCPV, m.lcCodNC8)
|
||
Endfor
|
||
Catch To loEx
|
||
loReturn.eroare = .T.
|
||
goLog.Log('Eroare la salvarea datelor extrase din xml eFactura. ' + 'Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure)
|
||
Set Step On
|
||
Endtry
|
||
|
||
Cursortoxml("cfacturadetaliitemp", "lcFacturaDetalii", 1, 0 + 8, 0, "1")
|
||
loReturn.facturadetalii = m.lcFacturaDetalii
|
||
|
||
USE IN (SELECT('cFacturaDetaliiTemp'))
|
||
|
||
* cursor linii discount/taxe la nivel de factura
|
||
IF TYPE('lofactura.invoice.AllowanceCharge') <> 'U'
|
||
|
||
If Type('lofactura.invoice.AllowanceCharge', 1) = 'A'
|
||
Acopy(loFactura.Invoice.AllowanceCharge, laLiniiDisc)
|
||
Else
|
||
laLiniiDisc[1] = loFactura.Invoice.AllowanceCharge
|
||
Endif
|
||
|
||
Try
|
||
lnLinii = Alen(laLiniiDisc)
|
||
For lnLinie = 1 To m.lnLinii
|
||
loLinie = laLiniiDisc[m.lnLinie]
|
||
lnDiscount = 1
|
||
If Type('loLinie.ChargeIndicator') = 'C'
|
||
lnDiscount = IIF(LOWER(ALLTRIM(loLinie.ChargeIndicator)) = 'false', 1, 0) && discount = false, taxe = true
|
||
Else
|
||
If Type('loLinie.ChargeIndicator._nodetext_') = 'C'
|
||
lnDiscount = IIF(LOWER(ALLTRIM(loLinie.ChargeIndicator._nodetext_)) = 'false', 1, 0)
|
||
Endif
|
||
ENDIF
|
||
|
||
lcMotivDiscount = ''
|
||
If Type('loLinie.AllowanceChargeReason') = 'C'
|
||
lcMotivDiscount = ALLTRIM(loLinie.AllowanceChargeReason)
|
||
Else
|
||
If Type('loLinie.AllowanceChargeReason._nodetext_') = 'C'
|
||
lcMotivDiscount = ALLTRIM(loLinie.AllowanceChargeReason._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
lcMotivDiscountCod = ''
|
||
If Type('loLinie.AllowanceChargeReasonCode') = 'C'
|
||
lcMotivDiscountCod = ALLTRIM(loLinie.AllowanceChargeReasonCode)
|
||
Else
|
||
If Type('loLinie.AllowanceChargeReasonCode._nodetext_') = 'C'
|
||
lcMotivDiscountCod = ALLTRIM(loLinie.AllowanceChargeReasonCode._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
lnValoare = 0
|
||
If Type('loLinie.Amount._nodetext_') = 'C'
|
||
lnValoare = Val(loLinie.Amount._nodetext_)
|
||
ENDIF
|
||
|
||
lnProcTva = 0
|
||
If Type('loLinie.TaxCategory.Percent') = 'C'
|
||
lnProcTva = val(loLinie.TaxCategory.Percent)
|
||
Else
|
||
If Type('loLinie.TaxCategory.Percent._nodetext_') = 'C'
|
||
lnProcTva = val(loLinie.TaxCategory.Percent._nodetext_)
|
||
Endif
|
||
ENDIF
|
||
|
||
lcTipTVA = "" && S standard/Z neplatitor TVA/AE taxare inversa
|
||
If Type('loLinie.item.ClassifiedTaxCategory.ID') = 'C'
|
||
lcTipTva = loLinie.item.ClassifiedTaxCategory.ID
|
||
Else
|
||
If Type('loLinie.item.ClassifiedTaxCategory.ID._nodetext_') = 'C'
|
||
lcTipTva = loLinie.item.ClassifiedTaxCategory.ID._nodetext_
|
||
Endif
|
||
Endif
|
||
|
||
Insert Into cFacturaDetaliiDisc(valoare, procenttva, tiptva, discount, motivdiscount, motivdiscountcod) Values (m.lnValoare, m.lnProcTva, m.lcTipTVA, m.lnDiscount, m.lcMotivDiscount, m.lcMotivDiscountCod)
|
||
Endfor
|
||
Catch To loEx
|
||
loReturn.eroare = .T.
|
||
goLog.Log('Eroare la salvarea datelor extrase din xml eFactura. ' + 'Eroare: ' + TRANSFORM(loEx.ErrorNo) + ' ' + loEx.Message + ' Continut:' + loEx.LineContents + + ' Linia: ' + TRANSFORM(loEx.LineNo) + ' Program: ' + loEx.Procedure)
|
||
Set Step On
|
||
Endtry
|
||
|
||
Cursortoxml("cFacturaDetaliiDisc", "lcFacturaDetaliiDisc", 1, 0 + 8, 0, "")
|
||
loReturn.facturadetaliiDisc = m.lcFacturaDetaliiDisc
|
||
|
||
USE IN (SELECT('cFacturaDetaliiTVA'))
|
||
ENDIF && TYPE('lofactura.invoice.AllowanceCharge') <> 'U'
|
||
|
||
Catch To loEx
|
||
loReturn.eroare = .T.
|
||
AMESSAGEBOX(loEx.Message)
|
||
Set Step On
|
||
Endtry
|
||
|
||
Return loReturn
|
||
Endproc && ParseEFactura
|
||
|
||
******************************
|
||
PROCEDURE TestParseEFactura
|
||
|
||
Local loEfactura As "ExportEFactura"
|
||
Local lcFile, loFactura
|
||
*:Global pcDetaliiXML, pcFurnizorXML, pcNumarActXML, pcNumeValutaXML, pcXMLFacturaDetalii
|
||
*:Global pdDataActXML, pdDataScadXML, pnDiscountFaraTVAXML, pnTaxeFaraTVAXML, pnTotalCuTVAXML
|
||
*:Global pnTotalFaraTVAXML, pnTotalTVAXML, pnTotaldePlataXML, pnValoareFaraTVAXML
|
||
|
||
lcSetProcedure = LOWER(SET("Procedure"))
|
||
lcSetClasslib = LOWER(SET("Classlib"))
|
||
|
||
* json read
|
||
IF !'nfxmlread'$lcSetProcedure
|
||
SET PROCEDURE TO 'd:\roa\roacont\comun\utile\nfxml\nfxmlread.prg' ADDITIVE
|
||
ENDIF
|
||
|
||
* amessagebox
|
||
IF !'oproceduri_comune'$lcSetProcedure
|
||
SET PROCEDURE TO 'd:\roa\roacont\comun\programe\oproceduri_comune.prg' ADDITIVE
|
||
ENDIF
|
||
SET STEP ON
|
||
|
||
lcFile = GETFILE('xml','Fisier xml','Deschide', 0, "Fisier xml eFactura")
|
||
IF EMPTY(m.lcFile)
|
||
RETURN
|
||
ENDIF
|
||
|
||
TRY
|
||
loFactura = ParseEfactura(m.lcFile)
|
||
|
||
pcNumarActXML = loFactura.numaract
|
||
pdDataActXML = loFactura.dataact
|
||
pdDataScadXML = loFactura.datascad
|
||
pcFurnizorXML = loFactura.furnizor
|
||
pcDetaliiXML = loFactura.detalii
|
||
pcDetaliiPlataXML = loFactura.DetaliiPlata
|
||
pnTotalFaraTVAXML = loFactura.TotalFaraTva
|
||
pnTotalTVAXML = loFactura.TotalTva
|
||
pnTotalTVARONXML = loFactura.TotalTvaRON && daca factura este in valuta, se completeaza TotalTVARON
|
||
pnTotalCuTVAXML = loFactura.TotalCuTva
|
||
pnDiscountFaraTVAXML = loFactura.DiscountFaraTVA
|
||
pnTaxeFaraTVAXML = loFactura.TaxeFaraTVA
|
||
pnValoareFaraTVAXML = loFactura.ValoareFaraTVA && suma valoare fara tva articole
|
||
pnTotaldePlataXML = loFactura.TotaldePlata
|
||
pcNumeValutaXML = loFactura.valuta
|
||
pcXMLFacturaDetalii = loFactura.FacturaDetalii
|
||
|
||
XMLTOCURSOR(m.pcXmlFacturaDetalii, "factura_detalii")
|
||
Catch To loEx
|
||
MESSAGEBOX(loEx.message)
|
||
ENDTRY
|
||
|
||
ENDPROC && TestParseEFactura
|
||
|