sync SVN r18181
This commit is contained in:
@@ -377,6 +377,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
|||||||
*m: bifeazatrimismanual && Bifeaza o factura ca trimisa manual
|
*m: bifeazatrimismanual && Bifeaza o factura ca trimisa manual
|
||||||
*m: citesteraspunsuri
|
*m: citesteraspunsuri
|
||||||
*m: do_ataseaza
|
*m: do_ataseaza
|
||||||
|
*m: do_storno_efactura
|
||||||
*m: gettoken
|
*m: gettoken
|
||||||
*m: ltest_assign
|
*m: ltest_assign
|
||||||
*m: refreshdetaliifacturi
|
*m: refreshdetaliifacturi
|
||||||
@@ -5656,7 +5657,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
|||||||
lcCursor = 'crsFacturiEmise'
|
lcCursor = 'crsFacturiEmise'
|
||||||
CASE m.lnPaginaActiva = 2
|
CASE m.lnPaginaActiva = 2
|
||||||
* Facturi TRIMISE
|
* Facturi TRIMISE
|
||||||
lnOptiune = xmenu('Centralizator facturi;Lista facturi trimise - detaliat;Factura trimisa curenta;\-;PDF ANAF facturi alese;PDF ANAF factura curenta;\-;Editare in browser')
|
lnOptiune = xmenu('Centralizator facturi;Lista facturi trimise - detaliat;Factura trimisa curenta;\-;PDF ANAF facturi alese;PDF ANAF factura curenta;\-;Editare in browser;\-;Generare XML storno si trimitere la ANAF')
|
||||||
lcCursor = 'crsFacturiTrimise'
|
lcCursor = 'crsFacturiTrimise'
|
||||||
CASE m.lnPaginaActiva = 3
|
CASE m.lnPaginaActiva = 3
|
||||||
* Facturi PRIMITE
|
* Facturi PRIMITE
|
||||||
@@ -5822,6 +5823,10 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
|||||||
loSender = NEWOBJECT("eFacturaXmlPreview", "xmlefactura-preview.prg")
|
loSender = NEWOBJECT("eFacturaXmlPreview", "xmlefactura-preview.prg")
|
||||||
loSender.webURL = "https://romfast.ro/efactura-generator/"
|
loSender.webURL = "https://romfast.ro/efactura-generator/"
|
||||||
loSender.SendXML(m.lcDetalii, m.llVariable)
|
loSender.SendXML(m.lcDetalii, m.llVariable)
|
||||||
|
|
||||||
|
CASE m.lnOptiune = 10 AND m.lnPaginaActiva = 2
|
||||||
|
* Generare XML storno si trimitere la ANAF - doar pagina Trimise (D6)
|
||||||
|
This.do_storno_efactura()
|
||||||
Endcase
|
Endcase
|
||||||
|
|
||||||
Select (m.lcSelect)
|
Select (m.lcSelect)
|
||||||
@@ -5877,6 +5882,144 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
|||||||
|
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE do_storno_efactura
|
||||||
|
*!* 18.09.2026 stornare XML eFactura din borderou (docs\plan_storno_efactura.md)
|
||||||
|
LOCAL lnId, lcXmlOriginal, lcMesaj, lnRecno, lcNumarOriginal, ldDataOriginal
|
||||||
|
LOCAL lcClient, lcMoneda, lnTotal, lnTestRand, lcCifFirma, lcTempXml, loDom
|
||||||
|
LOCAL lcCifXml, loNod, lcIssueDateStr, ldIssueDate, lcCustomerCif, llB2C, loNoduri, lnI
|
||||||
|
LOCAL lcNumarNou, lcNumarNouSafe, lcFisierStorno, lcNotaIni, llSucces
|
||||||
|
LOCAL laModificari[1], lcAvertizare, laDubl[1], laProcesate[1], loForma
|
||||||
|
IF AMESSAGEBOX('Se genereaza XML-ul de stornare al facturii selectate (aceleasi linii, valori negative).' + CHR(13) + CHR(13) + ;
|
||||||
|
'Nu se trimite nimic la ANAF pana nu verificati XML-ul in fereastra urmatoare si apasati "Trimite la ANAF".', 1+64, _screen.Caption) <> 1
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
SELECT crsFacturiTrimise
|
||||||
|
lnRecno = Recno()
|
||||||
|
|
||||||
|
IF ALLTRIM(NVL(tip_mesaj_raspuns, '')) <> 'FACTURA TRIMISA'
|
||||||
|
AMESSAGEBOX('Stornarea este posibila doar pentru facturi acceptate (FACTURA TRIMISA).', 0+48, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
lnId = NVL(crsFacturiTrimise.Id, 0)
|
||||||
|
IF Empty(m.lnId)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lcNumarOriginal = ALLTRIM(NVL(crsFacturiTrimise.numar_act, ''))
|
||||||
|
lcClient = ALLTRIM(NVL(crsFacturiTrimise.xclient, ''))
|
||||||
|
lcMoneda = ALLTRIM(NVL(crsFacturiTrimise.nume_valuta, ''))
|
||||||
|
lnTotal = NVL(crsFacturiTrimise.total_cu_tva, 0)
|
||||||
|
lnTestRand = NVL(crsFacturiTrimise.test, 0)
|
||||||
|
|
||||||
|
lcCifFirma = ALLTRIM(Thisform.oAnaf.AnafeFacturaServer.cCodFiscal)
|
||||||
|
IF lnTestRand <> IIF(Thisform.oAnaf.AnafeFacturaServer.lTest, 1, 0)
|
||||||
|
AMESSAGEBOX('Documentul original e din mediul ' + IIF(m.lnTestRand=1,'TEST','PRODUCTIE') + ;
|
||||||
|
', dar borderoul este pe ' + IIF(Thisform.oAnaf.AnafeFacturaServer.lTest,'TEST','PRODUCTIE') + '. Comutati mediul inainte de stornare.', 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF !GetXmlOriginalEFactura(m.lnId, @lcXmlOriginal, @lcMesaj)
|
||||||
|
AMESSAGEBOX('Factura nu are XML descarcat: ' + m.lcMesaj, 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* parsez XML-ul pe fisier (nu .loadXML pe sir), ca sa nu risc reinterpretarea octetilor UTF-8
|
||||||
|
lcTempXml = Addbs(Sys(2023)) + 'storno_check_' + Sys(2015) + '.xml'
|
||||||
|
Strtofile(m.lcXmlOriginal, m.lcTempXml)
|
||||||
|
loDom = Createobject('MSXML2.DOMDocument.6.0')
|
||||||
|
loDom.setProperty('SelectionLanguage', 'XPath')
|
||||||
|
loDom.preserveWhiteSpace = .T.
|
||||||
|
llSucces = loDom.load(m.lcTempXml)
|
||||||
|
TRY
|
||||||
|
Delete File (m.lcTempXml)
|
||||||
|
CATCH
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
IF !m.llSucces OR !Inlist(loDom.documentElement.baseName, 'Invoice', 'CreditNote')
|
||||||
|
AMESSAGEBOX('Documentul nu e Invoice/CreditNote.', 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*!* 18.09.2026 CIF-ul poate fi in PartyTaxScheme sau PartyLegalEntity (acolo e uneori nr. Reg. Com.)
|
||||||
|
lcCifXml = ''
|
||||||
|
loNoduri = loDom.selectNodes("//*[local-name()='AccountingSupplierParty']//*[local-name()='CompanyID']")
|
||||||
|
FOR lnI = 0 TO m.loNoduri.length - 1
|
||||||
|
loNod = m.loNoduri.item(m.lnI)
|
||||||
|
lcCifXml = GetNrFromString(ALLTRIM(m.loNod.Text))
|
||||||
|
IF m.lcCifXml == ALLTRIM(m.lcCifFirma)
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
ENDFOR
|
||||||
|
IF Empty(m.lcCifXml) OR !(m.lcCifXml == ALLTRIM(m.lcCifFirma))
|
||||||
|
AMESSAGEBOX('Factura e emisa de alta firma (CIF ' + m.lcCifXml + ').', 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
loNod = loDom.selectSingleNode("//*[local-name()='IssueDate']")
|
||||||
|
lcIssueDateStr = IIF(Isnull(m.loNod), '', ALLTRIM(m.loNod.Text))
|
||||||
|
ldIssueDate = IIF(Len(m.lcIssueDateStr) < 10, {}, Date(Val(Substr(m.lcIssueDateStr,1,4)), Val(Substr(m.lcIssueDateStr,6,2)), Val(Substr(m.lcIssueDateStr,9,2))))
|
||||||
|
IF Empty(m.ldIssueDate)
|
||||||
|
AMESSAGEBOX('Nu s-a putut citi data facturii din XML.', 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IF is_luna_blocata(gcS, gnId_Prg_Owner, Year(m.ldIssueDate), Month(m.ldIssueDate))
|
||||||
|
AMESSAGEBOX('Luna ' + Padl(Month(m.ldIssueDate),2,'0') + '.' + Transform(Year(m.ldIssueDate)) + ' este inchisa.', 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
loNod = loDom.selectSingleNode("//*[local-name()='AccountingCustomerParty']//*[local-name()='PartyLegalEntity']/*[local-name()='CompanyID']")
|
||||||
|
lcCustomerCif = IIF(Isnull(m.loNod), '', ALLTRIM(m.loNod.Text))
|
||||||
|
llB2C = (Len(m.lcCustomerCif) = 13)
|
||||||
|
|
||||||
|
lcNumarNou = m.lcNumarOriginal + '-S'
|
||||||
|
lcNumarNouSafe = WindowsSpecialCharacters(m.lcNumarNou)
|
||||||
|
lcFisierStorno = GetPdfPath('EFACTURA','TRIMISE') + 'storno_' + m.lcNumarNouSafe + '_' + m.lcCifFirma + '.xml'
|
||||||
|
lcNotaIni = 'Stornare factura ' + m.lcNumarOriginal + ' din data ' + Dtoc(m.ldIssueDate)
|
||||||
|
|
||||||
|
llSucces = StornoEFacturaXML(m.lcXmlOriginal, m.lcNumarNou, m.lcNotaIni, m.lcFisierStorno, @laModificari, @lcMesaj)
|
||||||
|
IF !m.llSucces
|
||||||
|
AMESSAGEBOX('Nu s-a putut genera XML-ul de stornare: ' + m.lcMesaj, 0+16, _screen.Caption)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* Avertizari (nu blocheaza): termen transmitere, storno dublu, storno deja trimis local, sursa CreditNote/negativa (D13)
|
||||||
|
lcAvertizare = ''
|
||||||
|
IF (Date() - m.ldIssueDate) > 5
|
||||||
|
lcAvertizare = m.lcAvertizare + 'Au trecut mai mult de 5 zile de la data facturii (' + Dtoc(m.ldIssueDate) + ') - verificati termenul de transmitere la ANAF.' + Chr(13) + Chr(10)
|
||||||
|
ENDIF
|
||||||
|
SELECT Count(*) as nCnt FROM crsFacturiTrimise WHERE Alltrim(numar_act) == m.lcNumarNou INTO CURSOR cVerifDubl
|
||||||
|
IF cVerifDubl.nCnt > 0
|
||||||
|
lcAvertizare = m.lcAvertizare + 'Exista deja un document ' + m.lcNumarNou + ' in Trimise - posibila stornare dubla.' + Chr(13) + Chr(10)
|
||||||
|
ENDIF
|
||||||
|
USE IN (SELECT('cVerifDubl'))
|
||||||
|
IF !Empty(Adir(laProcesate, GetPdfPath('EFACTURA','TRIMISE') + 'procesat\*_storno_' + m.lcNumarNouSafe + '_' + m.lcCifFirma + '*.xml'))
|
||||||
|
lcAvertizare = m.lcAvertizare + 'Un storno cu acest numar a fost deja trimis de pe acest calculator.' + Chr(13) + Chr(10)
|
||||||
|
ENDIF
|
||||||
|
IF loDom.documentElement.baseName == 'CreditNote' OR m.lnTotal < 0
|
||||||
|
lcAvertizare = m.lcAvertizare + 'Documentul original e nota de credit / are total negativ - stornarea va produce valori pozitive.' + Chr(13) + Chr(10)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
CREATE CURSOR crsStornoDetalii (element C(60), original C(250), nou C(250), tip N(1))
|
||||||
|
|
||||||
|
loForma = NEWOBJECT('frm_storno_efactura', 'anaf_efactura.vcx', '', ;
|
||||||
|
Thisform.oAnaf.AnafeFacturaServer, m.lnId, m.lcXmlOriginal, m.lcNumarOriginal, m.ldIssueDate, ;
|
||||||
|
m.lcClient, m.lcCifFirma, m.lnTotal, m.lcMoneda, Thisform.oAnaf.AnafeFacturaServer.lTest, m.llB2C, ;
|
||||||
|
m.lcFisierStorno, m.lcNumarNou, m.lcAvertizare)
|
||||||
|
loForma.UmpleGrid(@laModificari)
|
||||||
|
loForma.Show(1)
|
||||||
|
|
||||||
|
IF Used('crsStornoDetalii')
|
||||||
|
USE IN (SELECT('crsStornoDetalii'))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
SELECT crsFacturiTrimise
|
||||||
|
TRY
|
||||||
|
Goto m.lnRecno
|
||||||
|
CATCH
|
||||||
|
ENDTRY
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
PROCEDURE do_verifica
|
PROCEDURE do_verifica
|
||||||
Local lcText, lnActivePage
|
Local lcText, lnActivePage
|
||||||
lnActivePage = This.pgfeFactura.ActivePage
|
lnActivePage = This.pgfeFactura.ActivePage
|
||||||
@@ -15360,3 +15503,504 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
|||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
ENDDEFINE
|
ENDDEFINE
|
||||||
|
|
||||||
|
DEFINE CLASS frm_storno_efactura AS _frmbase OF "_frm_base.vcx"
|
||||||
|
*< CLASSDATA: Baseclass="form" Timestamp="" Scale="Pixels" Uniqueid="" />
|
||||||
|
|
||||||
|
*-- OBJECTDATA items order determines ZOrder / El orden de los items OBJECTDATA determina el ZOrder
|
||||||
|
*< OBJECTDATA: ObjPath="But_renunt1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="lblAntet" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="lblNumar" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="txtNumar" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="lblMotiv" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="txtMotiv" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="lblAvertisment" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cElement.Header1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cElement.Text1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cOriginal.Header1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cOriginal.Text1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cNou.Header1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="grdModificari.cNou.Text1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="lblStare" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="edtStatus" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="cmdValideaza" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="cmdPdf" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="cmdTrimite" UniqueID="" Timestamp="" />
|
||||||
|
|
||||||
|
*<DefinedPropArrayMethod>
|
||||||
|
*m: enablebutoane
|
||||||
|
*m: regenereazaxml
|
||||||
|
*m: setstare
|
||||||
|
*m: umplegrid
|
||||||
|
*p: pcciffirma
|
||||||
|
*p: pcclient
|
||||||
|
*p: pcfisierstorno
|
||||||
|
*p: pcmoneda
|
||||||
|
*p: pcmotiv
|
||||||
|
*p: pcnumarnou
|
||||||
|
*p: pcnumaroriginal
|
||||||
|
*p: pcxmloriginal
|
||||||
|
*p: pddataoriginal
|
||||||
|
*p: plb2c
|
||||||
|
*p: pltest
|
||||||
|
*p: pnidefactura
|
||||||
|
*p: pnstare
|
||||||
|
*p: pntotal
|
||||||
|
*p: poanaf
|
||||||
|
*</DefinedPropArrayMethod>
|
||||||
|
|
||||||
|
*<PropValue>
|
||||||
|
BorderStyle = 1
|
||||||
|
DoCreate = .T.
|
||||||
|
Height = 560
|
||||||
|
Name = "frm_storno_efactura"
|
||||||
|
pcciffirma = ''
|
||||||
|
pcclient = ''
|
||||||
|
pcfisierstorno = ''
|
||||||
|
pcmoneda = ''
|
||||||
|
pcmotiv = ''
|
||||||
|
pcnumarnou = ''
|
||||||
|
pcnumaroriginal = ''
|
||||||
|
pcxmloriginal = ''
|
||||||
|
pddataoriginal = {}
|
||||||
|
plb2c = .F.
|
||||||
|
pltest = .F.
|
||||||
|
pnidefactura = 0
|
||||||
|
pnstare = 0
|
||||||
|
pntotal = 0
|
||||||
|
poanaf = .NULL.
|
||||||
|
Width = 760
|
||||||
|
_memberdata = <VFPData>
|
||||||
|
<memberdata name="poanaf" display="oAnaf"/>
|
||||||
|
<memberdata name="pnidefactura" display="nIdEfactura"/>
|
||||||
|
<memberdata name="pcxmloriginal" display="cXmlOriginal"/>
|
||||||
|
<memberdata name="pcnumaroriginal" display="cNumarOriginal"/>
|
||||||
|
<memberdata name="pddataoriginal" display="dDataOriginal"/>
|
||||||
|
<memberdata name="pcclient" display="cClient"/>
|
||||||
|
<memberdata name="pcciffirma" display="cCifFirma"/>
|
||||||
|
<memberdata name="pntotal" display="nTotal"/>
|
||||||
|
<memberdata name="pcmoneda" display="cMoneda"/>
|
||||||
|
<memberdata name="pltest" display="lTest"/>
|
||||||
|
<memberdata name="plb2c" display="lB2C"/>
|
||||||
|
<memberdata name="pcfisierstorno" display="cFisierStorno"/>
|
||||||
|
<memberdata name="pcnumarnou" display="cNumarNou"/>
|
||||||
|
<memberdata name="pcmotiv" display="cMotiv"/>
|
||||||
|
<memberdata name="pnstare" display="nStare"/>
|
||||||
|
<memberdata name="enablebutoane" display="EnableButoane"/>
|
||||||
|
<memberdata name="regenereazaxml" display="RegenereazaXml"/>
|
||||||
|
<memberdata name="setstare" display="SetStare"/>
|
||||||
|
<memberdata name="umplegrid" display="UmpleGrid"/>
|
||||||
|
</VFPData>
|
||||||
|
_shape1.Height = 29
|
||||||
|
_shape1.Left = 0
|
||||||
|
_shape1.Name = "_shape1"
|
||||||
|
_shape1.Top = 0
|
||||||
|
_shape1.Width = 760
|
||||||
|
_shape2.Left = 701
|
||||||
|
_shape2.Name = "_shape2"
|
||||||
|
_shape2.Top = 0
|
||||||
|
Lb_titlu_alb_b121.Caption = "Stornare eFactura"
|
||||||
|
Lb_titlu_alb_b121.Name = "Lb_titlu_alb_b121"
|
||||||
|
BUT_TERMIN1.Name = "BUT_TERMIN1"
|
||||||
|
BUT_TERMIN1.Visible = .F.
|
||||||
|
Gridsort1.Name = "Gridsort1"
|
||||||
|
*</PropValue>
|
||||||
|
|
||||||
|
ADD OBJECT 'But_renunt1' AS but_renunt WITH ;
|
||||||
|
Anchor = 8, ;
|
||||||
|
Left = 701, ;
|
||||||
|
Name = "But_renunt1", ;
|
||||||
|
Top = 2
|
||||||
|
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||||
|
|
||||||
|
ADD OBJECT 'cmdPdf' AS cmd_executa WITH ;
|
||||||
|
Caption = "\<PDF ANAF", ;
|
||||||
|
Height = 30, ;
|
||||||
|
Left = 160, ;
|
||||||
|
Name = "cmdPdf", ;
|
||||||
|
TabIndex = 4, ;
|
||||||
|
Top = 512, ;
|
||||||
|
Width = 140
|
||||||
|
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||||
|
|
||||||
|
ADD OBJECT 'cmdTrimite' AS cmd_executa WITH ;
|
||||||
|
Caption = "\<Trimite la ANAF", ;
|
||||||
|
FontBold = .T., ;
|
||||||
|
ForeColor = 0,128,0, ;
|
||||||
|
Height = 30, ;
|
||||||
|
Left = 588, ;
|
||||||
|
Name = "cmdTrimite", ;
|
||||||
|
TabIndex = 5, ;
|
||||||
|
Top = 512, ;
|
||||||
|
Width = 160
|
||||||
|
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||||
|
|
||||||
|
ADD OBJECT 'cmdValideaza' AS cmd_executa WITH ;
|
||||||
|
Caption = "\<Valideaza", ;
|
||||||
|
Height = 30, ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "cmdValideaza", ;
|
||||||
|
TabIndex = 3, ;
|
||||||
|
Top = 512, ;
|
||||||
|
Width = 140
|
||||||
|
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||||
|
|
||||||
|
ADD OBJECT 'edtStatus' AS _editbox WITH ;
|
||||||
|
Height = 50, ;
|
||||||
|
Left = 220, ;
|
||||||
|
Name = "edtStatus", ;
|
||||||
|
ReadOnly = .T., ;
|
||||||
|
Top = 448, ;
|
||||||
|
Width = 528
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="editbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari' AS _grdbase WITH ;
|
||||||
|
ColumnCount = 3, ;
|
||||||
|
DeleteMark = .F., ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
Height = 280, ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "grdModificari", ;
|
||||||
|
Panel = 1, ;
|
||||||
|
ReadOnly = .T., ;
|
||||||
|
RecordSource = "crsStornoDetalii", ;
|
||||||
|
RowHeight = 19, ;
|
||||||
|
TabIndex = 6, ;
|
||||||
|
Top = 164, ;
|
||||||
|
Width = 736, ;
|
||||||
|
Column1.ControlSource = "crsStornoDetalii.element", ;
|
||||||
|
Column1.FontSize = 10, ;
|
||||||
|
Column1.Name = "cElement", ;
|
||||||
|
Column1.ReadOnly = .T., ;
|
||||||
|
Column1.Width = 300, ;
|
||||||
|
Column2.Alignment = 1, ;
|
||||||
|
Column2.ControlSource = "crsStornoDetalii.original", ;
|
||||||
|
Column2.FontSize = 10, ;
|
||||||
|
Column2.Name = "cOriginal", ;
|
||||||
|
Column2.ReadOnly = .T., ;
|
||||||
|
Column2.Width = 200, ;
|
||||||
|
Column3.Alignment = 1, ;
|
||||||
|
Column3.ControlSource = "crsStornoDetalii.nou", ;
|
||||||
|
Column3.FontSize = 10, ;
|
||||||
|
Column3.Name = "cNou", ;
|
||||||
|
Column3.ReadOnly = .T., ;
|
||||||
|
Column3.Width = 200
|
||||||
|
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cElement.Header1' AS header WITH ;
|
||||||
|
Caption = "Element", ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
Name = "Header1"
|
||||||
|
*< END OBJECT: BaseClass="header" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cElement.Text1' AS textbox WITH ;
|
||||||
|
BackColor = 255,255,255, ;
|
||||||
|
BorderStyle = 0, ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
ForeColor = 0,0,0, ;
|
||||||
|
Margin = 0, ;
|
||||||
|
Name = "Text1", ;
|
||||||
|
ReadOnly = .T., ;
|
||||||
|
SelectedBackColor = 100,185,255
|
||||||
|
*< END OBJECT: BaseClass="textbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cNou.Header1' AS header WITH ;
|
||||||
|
Alignment = 1, ;
|
||||||
|
Caption = "Storno", ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
Name = "Header1"
|
||||||
|
*< END OBJECT: BaseClass="header" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cNou.Text1' AS textbox WITH ;
|
||||||
|
Alignment = 1, ;
|
||||||
|
BackColor = 255,255,255, ;
|
||||||
|
BorderStyle = 0, ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
ForeColor = 0,0,0, ;
|
||||||
|
Margin = 0, ;
|
||||||
|
Name = "Text1", ;
|
||||||
|
ReadOnly = .T., ;
|
||||||
|
SelectedBackColor = 100,185,255
|
||||||
|
*< END OBJECT: BaseClass="textbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cOriginal.Header1' AS header WITH ;
|
||||||
|
Alignment = 1, ;
|
||||||
|
Caption = "Original", ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
Name = "Header1"
|
||||||
|
*< END OBJECT: BaseClass="header" />
|
||||||
|
|
||||||
|
ADD OBJECT 'grdModificari.cOriginal.Text1' AS textbox WITH ;
|
||||||
|
Alignment = 1, ;
|
||||||
|
BackColor = 255,255,255, ;
|
||||||
|
BorderStyle = 0, ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
ForeColor = 0,0,0, ;
|
||||||
|
Margin = 0, ;
|
||||||
|
Name = "Text1", ;
|
||||||
|
ReadOnly = .T., ;
|
||||||
|
SelectedBackColor = 100,185,255
|
||||||
|
*< END OBJECT: BaseClass="textbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'lblAntet' AS _label WITH ;
|
||||||
|
AutoSize = .F., ;
|
||||||
|
Caption = "", ;
|
||||||
|
Height = 46, ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "lblAntet", ;
|
||||||
|
Top = 38, ;
|
||||||
|
Width = 736, ;
|
||||||
|
WordWrap = .T.
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
|
||||||
|
|
||||||
|
ADD OBJECT 'lblAvertisment' AS _label WITH ;
|
||||||
|
AutoSize = .F., ;
|
||||||
|
Caption = "", ;
|
||||||
|
ForeColor = 192,0,0, ;
|
||||||
|
Height = 40, ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "lblAvertisment", ;
|
||||||
|
Top = 118, ;
|
||||||
|
Width = 736, ;
|
||||||
|
WordWrap = .T.
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
|
||||||
|
|
||||||
|
ADD OBJECT 'lblMotiv' AS _label WITH ;
|
||||||
|
Caption = "Motiv (optional):", ;
|
||||||
|
Left = 270, ;
|
||||||
|
Name = "lblMotiv", ;
|
||||||
|
Top = 90
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
|
||||||
|
|
||||||
|
ADD OBJECT 'lblNumar' AS _label WITH ;
|
||||||
|
Caption = "Numar storno:", ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "lblNumar", ;
|
||||||
|
Top = 90
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
|
||||||
|
|
||||||
|
ADD OBJECT 'lblStare' AS _label WITH ;
|
||||||
|
Caption = "Nevalidat", ;
|
||||||
|
FontBold = .T., ;
|
||||||
|
Left = 12, ;
|
||||||
|
Name = "lblStare", ;
|
||||||
|
Top = 452, ;
|
||||||
|
Width = 200
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
|
||||||
|
|
||||||
|
ADD OBJECT 'txtMotiv' AS _textbox WITH ;
|
||||||
|
ControlSource = "Thisform.pcmotiv", ;
|
||||||
|
Height = 23, ;
|
||||||
|
Left = 375, ;
|
||||||
|
MaxLength = 200, ;
|
||||||
|
Name = "txtMotiv", ;
|
||||||
|
TabIndex = 2, ;
|
||||||
|
Top = 87, ;
|
||||||
|
Width = 373
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="textbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'txtNumar' AS _textbox WITH ;
|
||||||
|
ControlSource = "Thisform.pcnumarnou", ;
|
||||||
|
Height = 23, ;
|
||||||
|
Left = 105, ;
|
||||||
|
Name = "txtNumar", ;
|
||||||
|
TabIndex = 1, ;
|
||||||
|
Top = 87, ;
|
||||||
|
Width = 150
|
||||||
|
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="textbox" />
|
||||||
|
|
||||||
|
PROCEDURE Activate
|
||||||
|
DODEFAULT()
|
||||||
|
TRY
|
||||||
|
This.cmdValideaza.SetFocus()
|
||||||
|
CATCH
|
||||||
|
ENDTRY
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE EnableButoane
|
||||||
|
LPARAMETERS tlEnable
|
||||||
|
This.cmdValideaza.Enabled = m.tlEnable
|
||||||
|
This.cmdPdf.Enabled = m.tlEnable
|
||||||
|
This.cmdTrimite.Enabled = m.tlEnable
|
||||||
|
This.txtNumar.Enabled = m.tlEnable
|
||||||
|
This.txtMotiv.Enabled = m.tlEnable
|
||||||
|
_screen.MousePointer = IIF(m.tlEnable, 0, 11)
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE Init
|
||||||
|
LPARAMETERS toAnaf, tnIdEfactura, tcXmlOriginal, tcNumarOriginal, tdDataOriginal, ;
|
||||||
|
tcClient, tcCifFirma, tnTotal, tcMoneda, tlTest, tlB2C, tcFisierStorno, tcNumarNou, ;
|
||||||
|
tcAvertizare
|
||||||
|
|
||||||
|
This.poAnaf = toAnaf
|
||||||
|
This.pnIdEfactura = tnIdEfactura
|
||||||
|
This.pcXmlOriginal = tcXmlOriginal
|
||||||
|
This.pcNumarOriginal = tcNumarOriginal
|
||||||
|
This.pdDataOriginal = tdDataOriginal
|
||||||
|
This.pcClient = tcClient
|
||||||
|
This.pcCifFirma = tcCifFirma
|
||||||
|
This.pnTotal = tnTotal
|
||||||
|
This.pcMoneda = tcMoneda
|
||||||
|
This.plTest = tlTest
|
||||||
|
This.plB2C = tlB2C
|
||||||
|
This.pcFisierStorno = tcFisierStorno
|
||||||
|
This.pcNumarNou = tcNumarNou
|
||||||
|
|
||||||
|
This.Caption = 'Stornare eFactura ' + m.tcNumarOriginal + ' - ' + IIF(m.tlTest, 'TEST', 'PRODUCTIE')
|
||||||
|
This.Lb_titlu_alb_b121.Caption = This.Caption
|
||||||
|
This.lblAntet.Caption = 'Factura ' + m.tcNumarOriginal + ' din ' + Dtoc(m.tdDataOriginal) + ' -> Storno' + Chr(13) + Chr(10) + ;
|
||||||
|
'Client: ' + m.tcClient + ' CIF firma: ' + m.tcCifFirma + ' Moneda: ' + m.tcMoneda
|
||||||
|
This.lblAvertisment.Caption = m.tcAvertizare
|
||||||
|
|
||||||
|
This.grdModificari.SetAll("DynamicFontBold", "tip = 2", "Column")
|
||||||
|
|
||||||
|
This.SetStare(0)
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE RegenereazaXml
|
||||||
|
LOCAL lcNumarNou, lcMotiv, lcNotaFinal, laModif[1], lcMesaj, llSucces
|
||||||
|
lcNumarNou = ALLTRIM(This.pcNumarNou)
|
||||||
|
lcMotiv = ALLTRIM(This.pcMotiv)
|
||||||
|
IF Empty(m.lcNumarNou)
|
||||||
|
AMESSAGEBOX('Numarul stornului nu poate fi gol.', 0+48, _screen.Caption)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
lcNotaFinal = 'Stornare factura ' + This.pcNumarOriginal + ' din data ' + Dtoc(This.pdDataOriginal) + IIF(Empty(m.lcMotiv), '', '. ' + m.lcMotiv)
|
||||||
|
|
||||||
|
llSucces = StornoEFacturaXML(This.pcXmlOriginal, m.lcNumarNou, m.lcNotaFinal, This.pcFisierStorno, @laModif, @lcMesaj)
|
||||||
|
IF !m.llSucces
|
||||||
|
This.edtStatus.Value = 'Eroare la regenerare: ' + m.lcMesaj
|
||||||
|
This.SetStare(0)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
This.UmpleGrid(@laModif)
|
||||||
|
RETURN .T.
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE SetStare
|
||||||
|
LPARAMETERS tnStare
|
||||||
|
This.pnStare = m.tnStare
|
||||||
|
This.cmdPdf.Enabled = .T.
|
||||||
|
DO CASE
|
||||||
|
CASE m.tnStare = 2
|
||||||
|
* trimis - stare terminala (D26/D35)
|
||||||
|
This.lblStare.Caption = 'Trimis'
|
||||||
|
This.cmdValideaza.Enabled = .F.
|
||||||
|
This.cmdTrimite.Enabled = .F.
|
||||||
|
This.txtNumar.Enabled = .F.
|
||||||
|
This.txtMotiv.Enabled = .F.
|
||||||
|
CASE m.tnStare = 1
|
||||||
|
This.lblStare.Caption = 'Valid'
|
||||||
|
This.cmdValideaza.Enabled = .T.
|
||||||
|
This.cmdTrimite.Enabled = .T.
|
||||||
|
This.txtNumar.Enabled = .T.
|
||||||
|
This.txtMotiv.Enabled = .T.
|
||||||
|
OTHERWISE
|
||||||
|
This.lblStare.Caption = 'Nevalidat'
|
||||||
|
This.cmdValideaza.Enabled = .T.
|
||||||
|
This.cmdTrimite.Enabled = .F.
|
||||||
|
This.txtNumar.Enabled = .T.
|
||||||
|
This.txtMotiv.Enabled = .T.
|
||||||
|
ENDCASE
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE UmpleGrid
|
||||||
|
LPARAMETERS taModificari
|
||||||
|
LOCAL lnI, lcSelect
|
||||||
|
lcSelect = Select()
|
||||||
|
SELECT crsStornoDetalii
|
||||||
|
ZAP
|
||||||
|
FOR lnI = 1 TO Alen(taModificari, 1)
|
||||||
|
INSERT INTO crsStornoDetalii (element, original, nou, tip) VALUES ;
|
||||||
|
(taModificari[m.lnI,1], Transform(taModificari[m.lnI,2]), Transform(taModificari[m.lnI,3]), taModificari[m.lnI,4])
|
||||||
|
ENDFOR
|
||||||
|
SELECT (m.lcSelect)
|
||||||
|
This.grdModificari.Refresh()
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE cmdPdf.Click
|
||||||
|
LOCAL lcXmlCurent, lcFisierPdf
|
||||||
|
lcXmlCurent = Filetostr(Thisform.pcFisierStorno)
|
||||||
|
lcFisierPdf = GetPdfPath('EFACTURA','TRIMISE') + 'storno_' + WindowsSpecialCharacters(ALLTRIM(Thisform.pcNumarNou)) + '.pdf'
|
||||||
|
lcFisierPdf = Thisform.poAnaf.Xml2PdfAnaf(m.lcXmlCurent, m.lcFisierPdf, .T.)
|
||||||
|
IF !Empty(m.lcFisierPdf) AND File(m.lcFisierPdf)
|
||||||
|
open_default_app(m.lcFisierPdf)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE cmdTrimite.Click
|
||||||
|
LOCAL lcMesajConf, loReturn, lcDirProcesat, lcFisierProcesat
|
||||||
|
IF Thisform.pnStare <> 1
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lcMesajConf = 'Trimiteti la ANAF (' + IIF(Thisform.plTest,'TEST','PRODUCTIE') + ') stornarea facturii ' + Thisform.pcNumarOriginal + ;
|
||||||
|
' ca ' + ALLTRIM(Thisform.pcNumarNou) + ', total ' + Transform(Thisform.pnTotal) + ' ' + Thisform.pcMoneda + '? Operatia nu se poate anula.'
|
||||||
|
IF AMESSAGEBOX(m.lcMesajConf, 4+32+256, _screen.Caption) <> 6
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
Thisform.EnableButoane(.F.)
|
||||||
|
WAIT WINDOW 'Se trimite...' NOWAIT
|
||||||
|
Thisform.poAnaf.RefreshTokenAuto()
|
||||||
|
loReturn = Thisform.poAnaf.TrimiteFacturaXML(Thisform.pcFisierStorno, .F., .F., .F., .F., Thisform.plB2C)
|
||||||
|
CLEAR TYPEAHEAD
|
||||||
|
WAIT CLEAR
|
||||||
|
|
||||||
|
IF !Empty(loReturn.cIdIncarcare)
|
||||||
|
lcDirProcesat = GetPdfPath('EFACTURA','TRIMISE') + 'procesat\'
|
||||||
|
lcFisierProcesat = loReturn.cIdIncarcare + '_' + Justfname(Thisform.pcFisierStorno)
|
||||||
|
IF Thisform.poAnaf.SaveFile(Thisform.pcFisierStorno, .F., m.lcDirProcesat, m.lcFisierProcesat)
|
||||||
|
TRY
|
||||||
|
Delete File (Thisform.pcFisierStorno)
|
||||||
|
CATCH
|
||||||
|
ENDTRY
|
||||||
|
ENDIF
|
||||||
|
goLog.Log('Storno eFactura: ' + Thisform.pcNumarOriginal + ' -> ' + ALLTRIM(Thisform.pcNumarNou) + ', index ' + loReturn.cIdIncarcare + ', ' + IIF(Thisform.plTest,'TEST','PRODUCTIE'))
|
||||||
|
Thisform.edtStatus.Value = 'Trimis. Index incarcare ' + loReturn.cIdIncarcare + ' (' + IIF(Thisform.plTest,'TEST','PRODUCTIE') + '). ' + ;
|
||||||
|
'Stergeti factura din ROA si emiteti factura corecta cu acelasi numar. Storno-ul apare in Trimise dupa descarcarea mesajelor.'
|
||||||
|
Thisform.EnableButoane(.T.)
|
||||||
|
Thisform.SetStare(2)
|
||||||
|
ELSE
|
||||||
|
Thisform.edtStatus.Value = 'Eroare: ' + loReturn.cMesaj + '. Verificati in Trimise, dupa descarcare, inainte de a retrimite.'
|
||||||
|
Thisform.EnableButoane(.T.)
|
||||||
|
Thisform.SetStare(0)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE cmdValideaza.Click
|
||||||
|
LOCAL llValid, lcMesajValid, loSrv, loExport
|
||||||
|
IF !Thisform.RegenereazaXml()
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
loSrv = Thisform.poAnaf
|
||||||
|
Thisform.EnableButoane(.F.)
|
||||||
|
WAIT WINDOW 'Se valideaza...' NOWAIT
|
||||||
|
loSrv.RefreshTokenAuto()
|
||||||
|
loExport = CREATEOBJECT('ExportEFactura', .T., loSrv.cToken)
|
||||||
|
llValid = m.loExport.ValidareEFacturaANAF(Thisform.pcFisierStorno, @lcMesajValid)
|
||||||
|
CLEAR TYPEAHEAD
|
||||||
|
WAIT CLEAR
|
||||||
|
Thisform.EnableButoane(.T.)
|
||||||
|
IF m.llValid
|
||||||
|
Thisform.edtStatus.Value = 'Valid.'
|
||||||
|
Thisform.SetStare(1)
|
||||||
|
ELSE
|
||||||
|
Thisform.edtStatus.Value = IIF(Empty(m.lcMesajValid), 'Validare indisponibila - verificati tokenul/reteaua.', 'Invalid: ' + m.lcMesajValid)
|
||||||
|
Thisform.SetStare(0)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE txtMotiv.InteractiveChange
|
||||||
|
IF Thisform.pnStare <> 0
|
||||||
|
Thisform.SetStare(0)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE txtNumar.InteractiveChange
|
||||||
|
IF Thisform.pnStare <> 0
|
||||||
|
Thisform.SetStare(0)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
ENDDEFINE
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ Cand un bug apare "de azi", compara cu clasa veche fara sa atingi SVN:
|
|||||||
`INKEY(0)` asteapta, timerele VFP nu se declanseaza, deci un dialog/o bucla blocata asa nu poate
|
`INKEY(0)` asteapta, timerele VFP nu se declanseaza, deci un dialog/o bucla blocata asa nu poate
|
||||||
fi deblocata din interiorul procesului - in rulare headless arata ca un proces viu care nu mai
|
fi deblocata din interiorul procesului - in rulare headless arata ca un proces viu care nu mai
|
||||||
scrie in log.
|
scrie in log.
|
||||||
|
- **Doua constructii care NU compileaza, dar trec de `txt2vcx`** (storno eFactura, 18.09.2026): `NEWOBJECT('c', 'lib.vcx', , p1, ...)` cu argumentul 3 omis ("Function argument value, type, or count is invalid" - pune `''`) si `CREATEOBJECT(...).Metoda()` inlantuit ("Syntax error"). `txt2vcx` (si `-DryRun`) NU compileaza metodele: dupa write-back, copiaza `.vcx`/`.vct` in ACELASI folder sub alt nume (parintii se rezolva relativ), `COMPILE CLASSLIB` headless, citeste `.ERR`, sterge copia.
|
||||||
|
- **`FOR EACH` pe `loDom.selectNodes(...)`** da la rulare "Expression evaluator failed". Foloseste `loN = loDom.selectNodes(...)` + `FOR i = 0 TO loN.length - 1` / `loN.item(i)`.
|
||||||
|
|
||||||
## 7. Capcane la SCRIEREA scriptului de test
|
## 7. Capcane la SCRIEREA scriptului de test
|
||||||
|
|
||||||
@@ -178,3 +180,14 @@ Cand un bug apare "de azi", compara cu clasa veche fara sa atingi SVN:
|
|||||||
si apoi apeleaza cod care citeste globalul masoara valoarea veche, fara niciun semn de eroare.
|
si apoi apeleaza cod care citeste globalul masoara valoarea veche, fara niciun semn de eroare.
|
||||||
Verifica intai pe ce cale citeste codul testat; daca e globalul, seteaza-l direct in test (si
|
Verifica intai pe ce cale citeste codul testat; daca e globalul, seteaza-l direct in test (si
|
||||||
restaureaza-l la final), nu prin `scrie_optiune()`.
|
restaureaza-l la final), nu prin `scrie_optiune()`.
|
||||||
|
- **Liniile de dinainte de `ON ERROR` dau dialog nativ pe ecranul utilizatorului.** `ALLTRIM(NVL(tcParam, ''))` pe un
|
||||||
|
parametru nepasat (`.F.`) = "Function argument value..." ca dialog "Program Error", nu in log. Seteaza `ON ERROR` pe
|
||||||
|
primele linii si foloseste `TRANSFORM(tcParam)` pentru parametri optionali.
|
||||||
|
- **Eroarea SQL prin `goExecutor` e o forma modala INTERNA VFP**: `watchdog_vfp.ps1` nu o vede (nu e fereastra top-level),
|
||||||
|
procesul sta pana la timeout. Verifica fiecare `SELECT` din test cu `sqlplus` inainte de rulare (ex. `anaf_efactura`
|
||||||
|
nu are `numar_act`/`data_act` - sunt in view-urile `anaf_vefactura_*`).
|
||||||
|
- **Forma din `.vcx` cu `CREATEOBJECT` direct poate pica in `Init` cu erori de binding** ("Error with _checkbox1 - Value :
|
||||||
|
Data type mismatch", CREATEOBJECT intoarce `.F.`), desi in aplicatie merge. Fa un stub `.scx` bazat pe clasa si deschide-l
|
||||||
|
cu `DO FORM ... NAME lo NOSHOW` - asa se instantiaza ca in aplicatie, iar erorile ar arata calea completa a controlului.
|
||||||
|
- **Rularile de test se fac DOAR prin `watchdog_vfp.ps1 -AutoDismiss`**: un lansator propriu fara plasa a lasat 3 dialoguri
|
||||||
|
modale pe ecranul utilizatorului (18.09.2026).
|
||||||
|
|||||||
@@ -802,7 +802,8 @@ 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
|
* parseaza un director cu xml efactura si le trimite la API ANAF
|
||||||
********************************
|
********************************
|
||||||
Procedure TrimiteFacturaXML
|
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 loXmlEFactura As 'ExportEFactura'
|
||||||
Local lcErrorMessage, lcExecutionStatus, lcFile, lcIndexIncarcare, lcMesaj, llSucces, llValid, loEx
|
Local lcErrorMessage, lcExecutionStatus, lcFile, lcIndexIncarcare, lcMesaj, llSucces, llValid, loEx
|
||||||
@@ -833,7 +834,7 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
IF m.llValid AND !m.tlNuTrimiteEFacturaANAF
|
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
|
llSucces = loReturn.lSucces
|
||||||
AddProperty(loReturn, "cIdIncarcare", '')
|
AddProperty(loReturn, "cIdIncarcare", '')
|
||||||
AddProperty(loReturn, "cMesaj", '')
|
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
|
* Genereaza xml eFactura, valideaza xml si trimite la ANAF
|
||||||
Function SendEfactura
|
Function SendEfactura
|
||||||
Lparameters tcFile, tlExtern, tlMesaj
|
Lparameters tcFile, tlExtern, tlMesaj, tlB2C
|
||||||
* tcFile: calea catre fisierul xml efactura / sau xml mesaj
|
* tcFile: calea catre fisierul xml efactura / sau xml mesaj
|
||||||
* tlExtern: daca se apeleaza cu parametrul Extern=DA (pentru clientii externi)
|
* tlExtern: daca se apeleaza cu parametrul Extern=DA (pentru clientii externi)
|
||||||
* tlMesaj: daca mesajul este o factura sau un mesaj catre furnizor
|
* 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 loEx As Exception
|
||||||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||||||
Local loReturn As "empty"
|
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
|
LOCAL lcCustomer, lcPartyLegal, lcCodFiscalClient
|
||||||
|
|
||||||
loReturn = Createobject("empty")
|
loReturn = Createobject("empty")
|
||||||
@@ -949,11 +951,12 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
lcCustomer = STREXTRACT(lcSend, '<cac:AccountingCustomerParty>', '</cac:AccountingCustomerParty>',1,1)
|
lcCustomer = STREXTRACT(lcSend, '<cac:AccountingCustomerParty>', '</cac:AccountingCustomerParty>',1,1)
|
||||||
lcPartyLegal = STREXTRACT(lcCustomer, '<cac:PartyLegalEntity>', '</cac:PartyLegalEntity>',1,1)
|
lcPartyLegal = STREXTRACT(lcCustomer, '<cac:PartyLegalEntity>', '</cac:PartyLegalEntity>',1,1)
|
||||||
lcCodFiscalClient = ALLTRIM(STREXTRACT(m.lcPartyLegal, '<cbc:CompanyID>','</cbc:CompanyID>',1,1))
|
lcCodFiscalClient = ALLTRIM(STREXTRACT(m.lcPartyLegal, '<cbc:CompanyID>','</cbc:CompanyID>',1,1))
|
||||||
llB2C = (LEN(m.lcCodFiscalClient) = 13) && persoane fizice
|
llB2C = (LEN(m.lcCodFiscalClient) = 13) OR m.tlB2C && persoane fizice
|
||||||
|
lcStandard = IIF('CreditNote'$m.lcSend, 'CN', 'UBL')
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
IF !m.tlMesaj
|
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
|
ELSE
|
||||||
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/upload] + IIF(m.llB2C,'b2c','') + [?standard=RASP&cif=] + m.lcCodFiscal
|
lcServer = [https://api.anaf.ro/] + Iif(m.llTest, [test], [prod]) + [/FCTEL/rest/upload] + IIF(m.llB2C,'b2c','') + [?standard=RASP&cif=] + m.lcCodFiscal
|
||||||
ENDIF
|
ENDIF
|
||||||
@@ -4069,6 +4072,432 @@ Procedure ParseEFactura
|
|||||||
Return loReturn
|
Return loReturn
|
||||||
Endproc && ParseEFactura
|
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
|
PROCEDURE TestParseEFactura
|
||||||
|
|
||||||
|
|||||||
@@ -1240,7 +1240,7 @@ Define Class ExportEFactura As Custom
|
|||||||
* lReturn: .T. valid, .F. invalid
|
* lReturn: .T. valid, .F. invalid
|
||||||
Local loReturn, llValid
|
Local loReturn, llValid
|
||||||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
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
|
Local lnMesaj, lnMesaje, loJson, loMessage, loEx as Exception, lcToken
|
||||||
|
|
||||||
llValid = .F.
|
llValid = .F.
|
||||||
@@ -1268,13 +1268,14 @@ Define Class ExportEFactura As Custom
|
|||||||
If !Empty(m.lcFileName) And Type('lcFileName') = 'C' And File(m.lcFileName)
|
If !Empty(m.lcFileName) And Type('lcFileName') = 'C' And File(m.lcFileName)
|
||||||
TRY
|
TRY
|
||||||
lcSend = Filetostr(m.lcFileName)
|
lcSend = Filetostr(m.lcFileName)
|
||||||
|
lcTip = IIF('CreditNote'$m.lcSend, 'FCN', 'FACT1')
|
||||||
|
|
||||||
IF !EMPTY(m.lcToken)
|
IF !EMPTY(m.lcToken)
|
||||||
* validare oauth
|
* validare oauth
|
||||||
lcServer = [https://api.anaf.ro/prod/FCTEL/rest/validare/FACT1]
|
lcServer = [https://api.anaf.ro/prod/FCTEL/rest/validare/] + m.lcTip
|
||||||
ELSE
|
ELSE
|
||||||
* validare fara autentificare
|
* 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
|
ENDIF
|
||||||
|
|
||||||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||||||
|
|||||||
19
utile/Teste/storno/frmtest_anaf.sc2
Normal file
19
utile/Teste/storno/frmtest_anaf.sc2
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
*--------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
|
||||||
|
*--------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
*< FOXBIN2PRG: Version="1.21" SourceFile="frmtest_anaf.scx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
DEFINE CLASS dataenvironment AS dataenvironment
|
||||||
|
*< CLASSDATA: Baseclass="dataenvironment" Timestamp="" Scale="" Uniqueid="" ClassIcon="1" />
|
||||||
|
|
||||||
|
*<PropValue>
|
||||||
|
DataSource = .NULL.
|
||||||
|
Height = 0
|
||||||
|
Left = 0
|
||||||
|
Name = "Dataenvironment"
|
||||||
|
Top = 0
|
||||||
|
Width = 0
|
||||||
|
*</PropValue>
|
||||||
|
|
||||||
|
ENDDEFINE
|
||||||
Reference in New Issue
Block a user