sync SVN r18181
This commit is contained in:
@@ -802,8 +802,9 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
||||
* parseaza un director cu xml efactura si le trimite la API ANAF
|
||||
********************************
|
||||
Procedure TrimiteFacturaXML
|
||||
LPARAMETERS tcFile, tlValidare, tlValidareOnline, tlNuTrimiteEFacturaANAF, tlExtern
|
||||
|
||||
LPARAMETERS tcFile, tlValidare, tlValidareOnline, tlNuTrimiteEFacturaANAF, tlExtern, tlB2C
|
||||
* tlB2C: (optional) forteaza uploadb2c la trimitere, vezi SendEfactura
|
||||
|
||||
Local loXmlEFactura As 'ExportEFactura'
|
||||
Local lcErrorMessage, lcExecutionStatus, lcFile, lcIndexIncarcare, lcMesaj, llSucces, llValid, loEx
|
||||
Local loXML, lcMesajValidare, llExtern, lcToken
|
||||
@@ -833,7 +834,7 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
||||
ENDIF
|
||||
|
||||
IF m.llValid AND !m.tlNuTrimiteEFacturaANAF
|
||||
loReturn = This.SendEfactura(m.lcFile, m.llExtern)
|
||||
loReturn = This.SendEfactura(m.lcFile, m.llExtern, .F., m.tlB2C)
|
||||
llSucces = loReturn.lSucces
|
||||
AddProperty(loReturn, "cIdIncarcare", '')
|
||||
AddProperty(loReturn, "cMesaj", '')
|
||||
@@ -915,15 +916,16 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
||||
|
||||
* Genereaza xml eFactura, valideaza xml si trimite la ANAF
|
||||
Function SendEfactura
|
||||
Lparameters tcFile, tlExtern, tlMesaj
|
||||
Lparameters tcFile, tlExtern, tlMesaj, tlB2C
|
||||
* 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
|
||||
* tlB2C: (optional) forteaza uploadb2c, pentru xml-uri cu prefixe straine unde detectia CIF nu se aplica
|
||||
|
||||
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 lcCodFiscal, lcExtern, lcFile, lcSend, lcServer, lcStandard, lcToken, llOk, llTest, llB2C
|
||||
LOCAL lcCustomer, lcPartyLegal, lcCodFiscalClient
|
||||
|
||||
loReturn = Createobject("empty")
|
||||
@@ -948,15 +950,16 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
||||
* 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
|
||||
lcCodFiscalClient = ALLTRIM(STREXTRACT(m.lcPartyLegal, '<cbc:CompanyID>','</cbc:CompanyID>',1,1))
|
||||
llB2C = (LEN(m.lcCodFiscalClient) = 13) OR m.tlB2C && persoane fizice
|
||||
lcStandard = IIF('CreditNote'$m.lcSend, 'CN', 'UBL')
|
||||
|
||||
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
|
||||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/upload] + IIF(m.llB2C,'b2c','') + [?standard=] + m.lcStandard + [&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
|
||||
ENDIF
|
||||
|
||||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||||
loHTTP.Open('POST', lcServer, .F.)
|
||||
@@ -4069,6 +4072,432 @@ Procedure ParseEFactura
|
||||
Return loReturn
|
||||
Endproc && ParseEFactura
|
||||
|
||||
****************************************
|
||||
* Extrage xml-ul original descarcat de la ANAF pentru un rand ANAF_EFACTURA: dezarhiveaza
|
||||
* detalii_zip (BLOB din baza), cu rezerva fisierul zip de pe disc din filepath.
|
||||
* tnId: ANAF_EFACTURA.ID
|
||||
* tcXml: OUT continutul xml (octetii bruti din arhiva ANAF)
|
||||
* tcMesaj: OUT mesaj de eroare daca RETURN = .F.
|
||||
****************************************
|
||||
FUNCTION GetXmlOriginalEFactura
|
||||
LPARAMETERS tnId, tcXml, tcMesaj
|
||||
|
||||
LOCAL lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcGroup, llModParam, lcFiltruOriginal
|
||||
LOCAL lcIdIncarcare, lcFilePath, lcZip, lcDir, lcXmlFile, lcSemnatura, llSucces, llResult
|
||||
PRIVATE poXmlOriginalZip
|
||||
|
||||
tcXml = ''
|
||||
tcMesaj = ''
|
||||
lcIdIncarcare = ''
|
||||
lcFilePath = ''
|
||||
lcZip = ''
|
||||
llResult = .F.
|
||||
poXmlOriginalZip = Null
|
||||
|
||||
IF Vartype(m.tnId) <> 'N' OR m.tnId <= 0
|
||||
tcMesaj = 'Id factura invalid.'
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
* RETURN e interzis in TRY/CATCH (eroare 4165) - iesire unica prin EXIT, RETURN dupa ENDTRY
|
||||
TRY
|
||||
DO WHILE .T.
|
||||
lcSchema = [id_incarcare V(36), lc_filepath V(250), fisier W]
|
||||
lcSelect = [select id_incarcare, filepath, detalii_zip from anaf_efactura where id = ] + Transform(m.tnId)
|
||||
lcFiltru = ''
|
||||
lcOrder = ''
|
||||
llAfiseaza = .F.
|
||||
lcGroup = ''
|
||||
llModParam = .T.
|
||||
lcFiltruOriginal = ''
|
||||
|
||||
Gencursor('poXmlOriginalZip', 'cXmlOriginalTemp', m.lcSelect, m.lcFiltru, m.lcSchema, m.lcOrder, m.llAfiseaza, m.lcGroup, m.llModParam, m.lcFiltruOriginal)
|
||||
poXmlOriginalZip.ca_baza1.afisare()
|
||||
|
||||
IF Used('cXmlOriginalTemp') AND Reccount('cXmlOriginalTemp') = 1
|
||||
SELECT cXmlOriginalTemp
|
||||
lcIdIncarcare = Alltrim(Nvl(id_incarcare, ''))
|
||||
lcFilePath = Alltrim(Nvl(lc_filepath, ''))
|
||||
IF !Empty(Nvl(fisier, ''))
|
||||
lcZip = Addbs(Sys(2023)) + 'storno_' + Transform(m.tnId) + '_' + Sys(2015) + '.zip'
|
||||
Strtofile(fisier, m.lcZip)
|
||||
ENDIF
|
||||
USE IN (SELECT('cXmlOriginalTemp'))
|
||||
ENDIF
|
||||
|
||||
IF Empty(m.lcZip) AND !Empty(m.lcFilePath) AND File(m.lcFilePath)
|
||||
lcZip = m.lcFilePath
|
||||
ENDIF
|
||||
|
||||
IF Empty(m.lcZip) OR !File(m.lcZip)
|
||||
tcMesaj = 'Factura nu are XML descarcat.'
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
IF Empty(m.lcIdIncarcare)
|
||||
tcMesaj = 'Factura nu are id_incarcare.'
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
lcDir = ''
|
||||
llSucces = MyUnzip(m.lcZip, @lcDir, @tcMesaj, .T.)
|
||||
IF m.lcZip <> m.lcFilePath
|
||||
Delete File (m.lcZip)
|
||||
ENDIF
|
||||
IF !m.llSucces
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
lcXmlFile = Addbs(m.lcDir) + m.lcIdIncarcare + '.xml'
|
||||
lcSemnatura = Addbs(m.lcDir) + 'semnatura_' + m.lcIdIncarcare + '.xml'
|
||||
|
||||
IF !File(m.lcXmlFile)
|
||||
tcMesaj = 'Arhiva nu contine fisierul ' + m.lcIdIncarcare + '.xml.'
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
tcXml = Filetostr(m.lcXmlFile)
|
||||
Delete File (m.lcXmlFile)
|
||||
IF File(m.lcSemnatura)
|
||||
Delete File (m.lcSemnatura)
|
||||
ENDIF
|
||||
|
||||
llResult = .T.
|
||||
EXIT
|
||||
ENDDO
|
||||
CATCH TO loEx
|
||||
tcMesaj = 'GetXmlOriginalEFactura eroare: ' + loEx.Message
|
||||
ENDTRY
|
||||
RETURN m.llResult
|
||||
ENDFUNC && GetXmlOriginalEFactura
|
||||
|
||||
****************************************
|
||||
* Insereaza loNewNode inaintea lui loRefNode, sau la sfarsit daca loRefNode nu exista
|
||||
* (insertBefore cu referinta null nu se poate apela sigur din VFP)
|
||||
****************************************
|
||||
FUNCTION InsertBeforeSafe
|
||||
LPARAMETERS loParent, loNewNode, loRefNode
|
||||
|
||||
IF Isnull(m.loRefNode)
|
||||
RETURN loParent.appendChild(m.loNewNode)
|
||||
ENDIF
|
||||
RETURN loParent.insertBefore(m.loNewNode, m.loRefNode)
|
||||
ENDFUNC && InsertBeforeSafe
|
||||
|
||||
****************************************
|
||||
* Neaga (schimba semnul) unui sir numeric din xml, pastrand zecimalele exact ca in original.
|
||||
* tcValoare: valoarea trim-uita din xml
|
||||
* tlOk: OUT .F. daca tcValoare nu e un numar valid (^[+-]?(\d+(\.\d*)?|\.\d+)$)
|
||||
* Zero (orice forma, inclusiv -0.00) ramane neschimbat.
|
||||
****************************************
|
||||
FUNCTION NegheazaValoareXml
|
||||
LPARAMETERS tcValoare, tlOk
|
||||
|
||||
LOCAL lcMatch, lcNumeric
|
||||
|
||||
tlOk = .F.
|
||||
lcMatch = GetRegExp(m.tcValoare, '^[+-]?(\d+(\.\d*)?|\.\d+)$')
|
||||
IF Empty(m.lcMatch) OR m.lcMatch <> m.tcValoare
|
||||
RETURN ''
|
||||
ENDIF
|
||||
tlOk = .T.
|
||||
|
||||
DO CASE
|
||||
CASE Left(m.tcValoare, 1) = '-'
|
||||
lcNumeric = Substr(m.tcValoare, 2)
|
||||
RETURN Iif(Val(m.lcNumeric) = 0, m.tcValoare, m.lcNumeric)
|
||||
CASE Left(m.tcValoare, 1) = '+'
|
||||
lcNumeric = Substr(m.tcValoare, 2)
|
||||
RETURN Iif(Val(m.lcNumeric) = 0, m.tcValoare, '-' + m.lcNumeric)
|
||||
OTHERWISE
|
||||
RETURN Iif(Val(m.tcValoare) = 0, m.tcValoare, '-' + m.tcValoare)
|
||||
ENDCASE
|
||||
ENDFUNC && NegheazaValoareXml
|
||||
|
||||
****************************************
|
||||
* '' daca loNod nu e sub o linie (InvoiceLine/CreditNoteLine), altfel 'Linia <nr> - '
|
||||
****************************************
|
||||
FUNCTION LineiaEticheta
|
||||
LPARAMETERS loNod
|
||||
|
||||
LOCAL loParinte, loIdLinie, lcNr
|
||||
|
||||
loParinte = loNod.parentNode
|
||||
DO WHILE !Isnull(m.loParinte)
|
||||
IF Inlist(loParinte.baseName, 'InvoiceLine', 'CreditNoteLine')
|
||||
lcNr = ''
|
||||
loIdLinie = loParinte.selectSingleNode("*[local-name()='ID']")
|
||||
IF !Isnull(m.loIdLinie)
|
||||
lcNr = Alltrim(loIdLinie.Text)
|
||||
ENDIF
|
||||
RETURN 'Linia ' + m.lcNr + ' - '
|
||||
ENDIF
|
||||
loParinte = loParinte.parentNode
|
||||
ENDDO
|
||||
RETURN ''
|
||||
ENDFUNC && LineiaEticheta
|
||||
|
||||
****************************************
|
||||
* Eticheta romana pentru gridul Element | Original | Storno al unui nod negat
|
||||
****************************************
|
||||
FUNCTION EtichetaNodXmlStorno
|
||||
LPARAMETERS loNod
|
||||
|
||||
LOCAL lcBase, lcMoneda, lcLinie, loAttrCur, lcEticheta
|
||||
|
||||
lcBase = loNod.baseName
|
||||
lcMoneda = ''
|
||||
loAttrCur = loNod.Attributes.getNamedItem('currencyID')
|
||||
IF !Isnull(m.loAttrCur)
|
||||
lcMoneda = ' (' + loAttrCur.Text + ')'
|
||||
ENDIF
|
||||
lcLinie = LineiaEticheta(m.loNod)
|
||||
|
||||
DO CASE
|
||||
CASE Inlist(m.lcBase, 'InvoicedQuantity', 'CreditedQuantity')
|
||||
lcEticheta = 'Cantitate'
|
||||
CASE m.lcBase = 'LineExtensionAmount'
|
||||
lcEticheta = Iif(Empty(m.lcLinie), 'Valoare neta totala', 'Valoare linie')
|
||||
CASE m.lcBase = 'TaxAmount'
|
||||
lcEticheta = 'TVA'
|
||||
CASE m.lcBase = 'TaxableAmount'
|
||||
lcEticheta = 'Baza TVA'
|
||||
CASE m.lcBase = 'Amount'
|
||||
lcEticheta = 'Reducere/majorare'
|
||||
CASE m.lcBase = 'BaseAmount'
|
||||
lcEticheta = 'Baza reducere/majorare'
|
||||
CASE m.lcBase = 'TaxExclusiveAmount'
|
||||
lcEticheta = 'Total fara TVA'
|
||||
CASE m.lcBase = 'TaxInclusiveAmount'
|
||||
lcEticheta = 'Total cu TVA'
|
||||
CASE m.lcBase = 'AllowanceTotalAmount'
|
||||
lcEticheta = 'Total reduceri'
|
||||
CASE m.lcBase = 'ChargeTotalAmount'
|
||||
lcEticheta = 'Total taxe suplimentare'
|
||||
CASE m.lcBase = 'PrepaidAmount'
|
||||
lcEticheta = 'Avans platit'
|
||||
CASE m.lcBase = 'PayableRoundingAmount'
|
||||
lcEticheta = 'Rotunjire'
|
||||
CASE m.lcBase = 'PayableAmount'
|
||||
lcEticheta = 'Total de plata'
|
||||
OTHERWISE
|
||||
lcEticheta = m.lcBase
|
||||
ENDCASE
|
||||
|
||||
RETURN m.lcLinie + m.lcEticheta + m.lcMoneda
|
||||
ENDFUNC && EtichetaNodXmlStorno
|
||||
|
||||
****************************************
|
||||
* Genereaza xml-ul de stornare al unei facturi eFactura deja trimise la ANAF: neaga
|
||||
* sumele/cantitatile, schimba numarul, adauga BillingReference catre factura originala si o Nota.
|
||||
* tcXml: continutul original al xml-ului (FILETOSTR pe fisierul din arhiva ANAF, GetXmlOriginalEFactura)
|
||||
* tcNumarNou: numarul noii facturi (gol = numarul original + '-S')
|
||||
* tcNota: text Nota adaugat pe document (gol = nu se adauga)
|
||||
* tcFisier: calea unde se salveaza xml-ul storno
|
||||
* taModificari: OUT array [n,4] (eticheta romana, original, nou, tip: 1 antet/2 total/3 linie)
|
||||
* tcMesaj: OUT mesaj de eroare daca RETURN = .F. (numeste nodul/motivul blocarii)
|
||||
****************************************
|
||||
FUNCTION StornoEFacturaXML
|
||||
LPARAMETERS tcXml, tcNumarNou, tcNota, tcFisier, taModificari, tcMesaj
|
||||
|
||||
LOCAL loDOM, loRoot, loNodID, loNodSupplier, loNodIssueDate, loNod, loNoduri
|
||||
LOCAL lcPrefixCbc, lcUriCbc, lcPrefixCac, lcUriCac, lcNumarVechi, lcDataOriginala
|
||||
LOCAL lcXPath, lcTemp, lcValoare, lcValoareNoua, lcLinieEticheta, lnI, lnModif, llOk, llValoareInvalida, llResult
|
||||
LOCAL loBillingRef, loInvDocRef, loIdRef, loDateRef, loChild, loInsertBefore
|
||||
LOCAL loNoteNode, loLastNote, loTypeCode
|
||||
|
||||
Dimension taModificari[1, 4]
|
||||
taModificari[1, 1] = ''
|
||||
tcMesaj = ''
|
||||
lnModif = 0
|
||||
llResult = .F.
|
||||
|
||||
IF Vartype(m.tcNumarNou) <> 'C'
|
||||
tcNumarNou = ''
|
||||
ENDIF
|
||||
IF Vartype(m.tcNota) <> 'C'
|
||||
tcNota = ''
|
||||
ENDIF
|
||||
|
||||
IF Empty(m.tcXml)
|
||||
tcMesaj = 'XML original gol.'
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
lcTemp = Addbs(Sys(2023)) + 'storno_src_' + Sys(2015) + '.xml'
|
||||
|
||||
* RETURN e interzis in TRY/CATCH (eroare 4165) - iesire unica prin EXIT, RETURN dupa ENDTRY
|
||||
TRY
|
||||
DO WHILE .T.
|
||||
Strtofile(m.tcXml, m.lcTemp)
|
||||
|
||||
loDOM = Createobject('MSXML2.DOMDocument.6.0')
|
||||
loDOM.Async = .F.
|
||||
loDOM.preserveWhiteSpace = .T.
|
||||
loDOM.setProperty('SelectionLanguage', 'XPath')
|
||||
loDOM.Load(m.lcTemp)
|
||||
|
||||
IF loDOM.parseError.errorcode <> 0
|
||||
tcMesaj = 'Eroare parsare XML: ' + loDOM.parseError.reason
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
loRoot = loDOM.documentElement
|
||||
IF Isnull(m.loRoot) OR !Inlist(loRoot.baseName, 'Invoice', 'CreditNote')
|
||||
tcMesaj = 'Documentul nu e Invoice/CreditNote.'
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
loNodID = loRoot.selectSingleNode("*[local-name()='ID']")
|
||||
loNodSupplier = loRoot.selectSingleNode("*[local-name()='AccountingSupplierParty']")
|
||||
loNodIssueDate = loRoot.selectSingleNode("*[local-name()='IssueDate']")
|
||||
IF Isnull(m.loNodID) OR Isnull(m.loNodSupplier) OR Isnull(m.loNodIssueDate)
|
||||
tcMesaj = 'Lipseste ID, IssueDate sau AccountingSupplierParty pe radacina.'
|
||||
EXIT
|
||||
ENDIF
|
||||
lcPrefixCbc = loNodID.Prefix
|
||||
lcUriCbc = loNodID.namespaceURI
|
||||
lcPrefixCac = loNodSupplier.Prefix
|
||||
lcUriCac = loNodSupplier.namespaceURI
|
||||
|
||||
lcNumarVechi = Alltrim(loNodID.Text)
|
||||
lcDataOriginala = Alltrim(loNodIssueDate.Text)
|
||||
IF Empty(m.tcNumarNou)
|
||||
tcNumarNou = m.lcNumarVechi + '-S'
|
||||
ENDIF
|
||||
IF Empty(m.tcNumarNou)
|
||||
tcMesaj = 'Numar factura gol.'
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
taModificari[1, 1] = 'Numar factura'
|
||||
taModificari[1, 2] = m.lcNumarVechi
|
||||
taModificari[1, 3] = m.tcNumarNou
|
||||
taModificari[1, 4] = 1
|
||||
lnModif = 1
|
||||
loNodID.Text = m.tcNumarNou
|
||||
|
||||
* BillingReference catre factura originala, inaintea primului nod din multimea UBL cunoscuta
|
||||
loInvDocRef = loDOM.createNode(1, Iif(Empty(m.lcPrefixCac), 'InvoiceDocumentReference', m.lcPrefixCac + ':InvoiceDocumentReference'), m.lcUriCac)
|
||||
loIdRef = loDOM.createNode(1, Iif(Empty(m.lcPrefixCbc), 'ID', m.lcPrefixCbc + ':ID'), m.lcUriCbc)
|
||||
loIdRef.Text = m.lcNumarVechi
|
||||
loInvDocRef.appendChild(m.loIdRef)
|
||||
loDateRef = loDOM.createNode(1, Iif(Empty(m.lcPrefixCbc), 'IssueDate', m.lcPrefixCbc + ':IssueDate'), m.lcUriCbc)
|
||||
loDateRef.Text = m.lcDataOriginala
|
||||
loInvDocRef.appendChild(m.loDateRef)
|
||||
loBillingRef = loDOM.createNode(1, Iif(Empty(m.lcPrefixCac), 'BillingReference', m.lcPrefixCac + ':BillingReference'), m.lcUriCac)
|
||||
loBillingRef.appendChild(m.loInvDocRef)
|
||||
|
||||
loInsertBefore = Null
|
||||
loChild = loRoot.firstChild
|
||||
DO WHILE !Isnull(m.loChild)
|
||||
IF Inlist(loChild.baseName, 'DespatchDocumentReference', 'ReceiptDocumentReference', 'StatementDocumentReference', ;
|
||||
'OriginatorDocumentReference', 'ContractDocumentReference', 'AdditionalDocumentReference', ;
|
||||
'ProjectReference', 'Signature', 'AccountingSupplierParty')
|
||||
loInsertBefore = m.loChild
|
||||
EXIT
|
||||
ENDIF
|
||||
loChild = loChild.nextSibling
|
||||
ENDDO
|
||||
IF Isnull(m.loInsertBefore)
|
||||
loInsertBefore = m.loNodSupplier
|
||||
ENDIF
|
||||
InsertBeforeSafe(m.loRoot, m.loBillingRef, m.loInsertBefore)
|
||||
|
||||
lnModif = m.lnModif + 1
|
||||
Dimension taModificari[m.lnModif, 4]
|
||||
taModificari[m.lnModif, 1] = 'Referinta (factura originala)'
|
||||
taModificari[m.lnModif, 2] = ''
|
||||
taModificari[m.lnModif, 3] = m.lcNumarVechi + ' / ' + m.lcDataOriginala
|
||||
taModificari[m.lnModif, 4] = 1
|
||||
|
||||
* Nota, dupa ultima Note existenta sau dupa TypeCode-ul radacinii
|
||||
IF !Empty(m.tcNota)
|
||||
loNoteNode = loDOM.createNode(1, Iif(Empty(m.lcPrefixCbc), 'Note', m.lcPrefixCbc + ':Note'), m.lcUriCbc)
|
||||
loNoteNode.Text = m.tcNota
|
||||
|
||||
loLastNote = Null
|
||||
loChild = loRoot.firstChild
|
||||
DO WHILE !Isnull(m.loChild)
|
||||
IF loChild.baseName = 'Note'
|
||||
loLastNote = m.loChild
|
||||
ENDIF
|
||||
loChild = loChild.nextSibling
|
||||
ENDDO
|
||||
|
||||
IF !Isnull(m.loLastNote)
|
||||
InsertBeforeSafe(m.loRoot, m.loNoteNode, m.loLastNote.nextSibling)
|
||||
ELSE
|
||||
loTypeCode = loRoot.selectSingleNode("*[local-name()='InvoiceTypeCode' or local-name()='CreditNoteTypeCode']")
|
||||
IF !Isnull(m.loTypeCode)
|
||||
InsertBeforeSafe(m.loRoot, m.loNoteNode, m.loTypeCode.nextSibling)
|
||||
ELSE
|
||||
InsertBeforeSafe(m.loRoot, m.loNoteNode, m.loRoot.firstChild)
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lnModif = m.lnModif + 1
|
||||
Dimension taModificari[m.lnModif, 4]
|
||||
taModificari[m.lnModif, 1] = 'Nota'
|
||||
taModificari[m.lnModif, 2] = ''
|
||||
taModificari[m.lnModif, 3] = m.tcNota
|
||||
taModificari[m.lnModif, 4] = 1
|
||||
ENDIF
|
||||
|
||||
* negare sume/cantitati: o singura interogare, fiecare nod o singura data, in ordinea din document
|
||||
lcXPath = "//*[(local-name()='InvoicedQuantity' or local-name()='CreditedQuantity'" + ;
|
||||
" or local-name()='LineExtensionAmount' or local-name()='TaxAmount' or local-name()='TaxableAmount'" + ;
|
||||
" or local-name()='TaxExclusiveAmount' or local-name()='TaxInclusiveAmount' or local-name()='AllowanceTotalAmount'" + ;
|
||||
" or local-name()='ChargeTotalAmount' or local-name()='PrepaidAmount' or local-name()='PayableRoundingAmount'" + ;
|
||||
" or local-name()='PayableAmount'" + ;
|
||||
" or ((local-name()='Amount' or local-name()='BaseAmount') and local-name(parent::*)='AllowanceCharge'))" + ;
|
||||
" and not(ancestor::*[local-name()='Price'])]"
|
||||
|
||||
loNoduri = loRoot.selectNodes(m.lcXPath)
|
||||
llValoareInvalida = .F.
|
||||
FOR lnI = 0 TO loNoduri.length - 1
|
||||
loNod = loNoduri.Item(m.lnI)
|
||||
lcValoare = Alltrim(loNod.Text)
|
||||
lcValoareNoua = NegheazaValoareXml(m.lcValoare, @llOk)
|
||||
IF !m.llOk
|
||||
tcMesaj = 'Valoare nenumerica in ' + loNod.baseName + ': "' + m.lcValoare + '".'
|
||||
llValoareInvalida = .T.
|
||||
EXIT
|
||||
ENDIF
|
||||
IF m.lcValoareNoua <> m.lcValoare
|
||||
lcLinieEticheta = LineiaEticheta(m.loNod)
|
||||
lnModif = m.lnModif + 1
|
||||
Dimension taModificari[m.lnModif, 4]
|
||||
taModificari[m.lnModif, 1] = EtichetaNodXmlStorno(m.loNod)
|
||||
taModificari[m.lnModif, 2] = m.lcValoare
|
||||
taModificari[m.lnModif, 3] = m.lcValoareNoua
|
||||
taModificari[m.lnModif, 4] = Iif(Empty(m.lcLinieEticheta), 2, 3)
|
||||
loNod.Text = m.lcValoareNoua
|
||||
ENDIF
|
||||
ENDFOR
|
||||
IF m.llValoareInvalida
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
loDOM.save(m.tcFisier)
|
||||
IF !File(m.tcFisier)
|
||||
tcMesaj = 'Salvarea xml-ului storno a esuat: ' + m.tcFisier
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
llResult = .T.
|
||||
EXIT
|
||||
ENDDO
|
||||
CATCH TO loEx
|
||||
tcMesaj = 'StornoEFacturaXML eroare: ' + loEx.Message
|
||||
FINALLY
|
||||
IF File(m.lcTemp)
|
||||
Delete File (m.lcTemp)
|
||||
ENDIF
|
||||
ENDTRY
|
||||
RETURN m.llResult
|
||||
ENDFUNC && StornoEFacturaXML
|
||||
|
||||
******************************
|
||||
PROCEDURE TestParseEFactura
|
||||
|
||||
|
||||
@@ -1240,7 +1240,7 @@ Define Class ExportEFactura As Custom
|
||||
* lReturn: .T. valid, .F. invalid
|
||||
Local loReturn, llValid
|
||||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||||
Local lcFileName, lcFisierRaspuns, lcMesaj, lcSend, lcServer, lcStare, llOk, llSilentios, llSucces
|
||||
Local lcFileName, lcFisierRaspuns, lcMesaj, lcSend, lcServer, lcStare, lcTip, llOk, llSilentios, llSucces
|
||||
Local lnMesaj, lnMesaje, loJson, loMessage, loEx as Exception, lcToken
|
||||
|
||||
llValid = .F.
|
||||
@@ -1268,13 +1268,14 @@ Define Class ExportEFactura As Custom
|
||||
If !Empty(m.lcFileName) And Type('lcFileName') = 'C' And File(m.lcFileName)
|
||||
TRY
|
||||
lcSend = Filetostr(m.lcFileName)
|
||||
lcTip = IIF('CreditNote'$m.lcSend, 'FCN', 'FACT1')
|
||||
|
||||
IF !EMPTY(m.lcToken)
|
||||
* validare oauth
|
||||
lcServer = [https://api.anaf.ro/prod/FCTEL/rest/validare/FACT1]
|
||||
lcServer = [https://api.anaf.ro/prod/FCTEL/rest/validare/] + m.lcTip
|
||||
ELSE
|
||||
* validare fara autentificare
|
||||
lcServer = [https://webservicesp.anaf.ro/prod/FCTEL/rest/validare/FACT1]
|
||||
lcServer = [https://webservicesp.anaf.ro/prod/FCTEL/rest/validare/] + m.lcTip
|
||||
ENDIF
|
||||
|
||||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||||
|
||||
Reference in New Issue
Block a user