Veri*Factu

Re: Veri*Factu

Postby paquitohm » Mon Dec 16, 2024 8:30 pm

Hola Antonio,

Dos cosas:

- Veo que has puesto los tags sin NameSpace. Entiendo que cómo estamos creando el .xml, a pelillo, sí hace falta ponerlos
- Lo habitual en el .xml será que contenga varias facturas, así que hay que poner otros tags de superior nivel

Pego aquí un ejemplo generado con soapui que incluye la definicion del registro de Alta y el registro de Anulacion. Supongo que ambos tipos de registros pueden incluirse en un mismo envío con lo cual necesitamos dos subdivisiones (dos funciones) del .xml, una para el alta y otra para la anulacion

Code: Select all  Expand view  RUN
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sum="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd" xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">
   <soapenv:Header/>
   <soapenv:Body>
      <sum:RegFactuSistemaFacturacion>
         <sum:Cabecera>
            <sum1:ObligadoEmision>
               <sum1:NombreRazon>?</sum1:NombreRazon>
               <sum1:NIF>?</sum1:NIF>
            </sum1:ObligadoEmision>
            <!--Optional:-->
            <sum1:Representante>
               <sum1:NombreRazon>?</sum1:NombreRazon>
               <sum1:NIF>?</sum1:NIF>
            </sum1:Representante>
            <!--Optional:-->
            <sum1:RemisionVoluntaria>
               <!--Optional:-->
               <sum1:FechaFinVeriFactu>?</sum1:FechaFinVeriFactu>
               <!--Optional:-->
               <sum1:Incidencia>?</sum1:Incidencia>
            </sum1:RemisionVoluntaria>
            <!--Optional:-->
            <sum1:RemisionRequerimiento>
               <sum1:RefRequerimiento>?</sum1:RefRequerimiento>
               <!--Optional:-->
               <sum1:FinRequerimiento>?</sum1:FinRequerimiento>
            </sum1:RemisionRequerimiento>
         </sum:Cabecera>
         <!--1 to 1000 repetitions:-->
         <sum:RegistroFactura>
            <!--You have a CHOICE of the next 2 items at this level-->
            <sum1:RegistroAlta>
               <sum1:IDVersion>?</sum1:IDVersion>
               <sum1:IDFactura>
                  <sum1:IDEmisorFactura>?</sum1:IDEmisorFactura>
                  <sum1:NumSerieFactura>?</sum1:NumSerieFactura>
                  <sum1:FechaExpedicionFactura>?</sum1:FechaExpedicionFactura>
               </sum1:IDFactura>
               <!--Optional:-->
               <sum1:RefExterna>?</sum1:RefExterna>
               <sum1:NombreRazonEmisor>?</sum1:NombreRazonEmisor>
               <!--Optional:-->
               <sum1:Subsanacion>?</sum1:Subsanacion>
               <!--Optional:-->
               <sum1:RechazoPrevio>?</sum1:RechazoPrevio>
               <sum1:TipoFactura>?</sum1:TipoFactura>
               <!--Optional:-->
               <sum1:TipoRectificativa>?</sum1:TipoRectificativa>
               <!--Optional:-->
               <sum1:FacturasRectificadas>
                  <!--1 to 1000 repetitions:-->
                  <sum1:IDFacturaRectificada>
                     <sum1:IDEmisorFactura>?</sum1:IDEmisorFactura>
                     <sum1:NumSerieFactura>?</sum1:NumSerieFactura>
                     <sum1:FechaExpedicionFactura>?</sum1:FechaExpedicionFactura>
                  </sum1:IDFacturaRectificada>
               </sum1:FacturasRectificadas>
               <!--Optional:-->
               <sum1:FacturasSustituidas>
                  <!--1 to 1000 repetitions:-->
                  <sum1:IDFacturaSustituida>
                     <sum1:IDEmisorFactura>?</sum1:IDEmisorFactura>
                     <sum1:NumSerieFactura>?</sum1:NumSerieFactura>
                     <sum1:FechaExpedicionFactura>?</sum1:FechaExpedicionFactura>
                  </sum1:IDFacturaSustituida>
               </sum1:FacturasSustituidas>
               <!--Optional:-->
               <sum1:ImporteRectificacion>
                  <sum1:BaseRectificada>?</sum1:BaseRectificada>
                  <sum1:CuotaRectificada>?</sum1:CuotaRectificada>
                  <!--Optional:-->
                  <sum1:CuotaRecargoRectificado>?</sum1:CuotaRecargoRectificado>
               </sum1:ImporteRectificacion>
               <!--Optional:-->
               <sum1:FechaOperacion>?</sum1:FechaOperacion>
               <sum1:DescripcionOperacion>?</sum1:DescripcionOperacion>
               <!--Optional:-->
               <sum1:FacturaSimplificadaArt7273>?</sum1:FacturaSimplificadaArt7273>
               <!--Optional:-->
               <sum1:FacturaSinIdentifDestinatarioArt61d>?</sum1:FacturaSinIdentifDestinatarioArt61d>
               <!--Optional:-->
               <sum1:Macrodato>?</sum1:Macrodato>
               <!--Optional:-->
               <sum1:EmitidaPorTerceroODestinatario>?</sum1:EmitidaPorTerceroODestinatario>
               <!--Optional:-->
               <sum1:Tercero>
                  <sum1:NombreRazon>?</sum1:NombreRazon>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:NIF>?</sum1:NIF>
                  <sum1:IDOtro>
                     <!--Optional:-->
                     <sum1:CodigoPais>?</sum1:CodigoPais>
                     <sum1:IDType>?</sum1:IDType>
                     <sum1:ID>?</sum1:ID>
                  </sum1:IDOtro>
               </sum1:Tercero>
               <!--Optional:-->
               <sum1:Destinatarios>
                  <!--1 to 1000 repetitions:-->
                  <sum1:IDDestinatario>
                     <sum1:NombreRazon>?</sum1:NombreRazon>
                     <!--You have a CHOICE of the next 2 items at this level-->
                     <sum1:NIF>?</sum1:NIF>
                     <sum1:IDOtro>
                        <!--Optional:-->
                        <sum1:CodigoPais>?</sum1:CodigoPais>
                        <sum1:IDType>?</sum1:IDType>
                        <sum1:ID>?</sum1:ID>
                     </sum1:IDOtro>
                  </sum1:IDDestinatario>
               </sum1:Destinatarios>
               <!--Optional:-->
               <sum1:Cupon>?</sum1:Cupon>
               <sum1:Desglose>
                  <!--1 to 12 repetitions:-->
                  <sum1:DetalleDesglose>
                     <!--Optional:-->
                     <sum1:Impuesto>?</sum1:Impuesto>
                     <!--Optional:-->
                     <sum1:ClaveRegimen>?</sum1:ClaveRegimen>
                     <!--You have a CHOICE of the next 2 items at this level-->
                     <sum1:CalificacionOperacion>?</sum1:CalificacionOperacion>
                     <sum1:OperacionExenta>?</sum1:OperacionExenta>
                     <!--Optional:-->
                     <sum1:TipoImpositivo>?</sum1:TipoImpositivo>
                     <sum1:BaseImponibleOimporteNoSujeto>?</sum1:BaseImponibleOimporteNoSujeto>
                     <!--Optional:-->
                     <sum1:BaseImponibleACoste>?</sum1:BaseImponibleACoste>
                     <!--Optional:-->
                     <sum1:CuotaRepercutida>?</sum1:CuotaRepercutida>
                     <!--Optional:-->
                     <sum1:TipoRecargoEquivalencia>?</sum1:TipoRecargoEquivalencia>
                     <!--Optional:-->
                     <sum1:CuotaRecargoEquivalencia>?</sum1:CuotaRecargoEquivalencia>
                  </sum1:DetalleDesglose>
               </sum1:Desglose>
               <sum1:CuotaTotal>?</sum1:CuotaTotal>
               <sum1:ImporteTotal>?</sum1:ImporteTotal>
               <sum1:Encadenamiento>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:PrimerRegistro>?</sum1:PrimerRegistro>
                  <sum1:RegistroAnterior>
                     <sum1:IDEmisorFactura>?</sum1:IDEmisorFactura>
                     <sum1:NumSerieFactura>?</sum1:NumSerieFactura>
                     <sum1:FechaExpedicionFactura>?</sum1:FechaExpedicionFactura>
                     <sum1:Huella>?</sum1:Huella>
                  </sum1:RegistroAnterior>
               </sum1:Encadenamiento>
               <sum1:SistemaInformatico>
                  <sum1:NombreRazon>?</sum1:NombreRazon>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:NIF>?</sum1:NIF>
                  <sum1:IDOtro>
                     <!--Optional:-->
                     <sum1:CodigoPais>?</sum1:CodigoPais>
                     <sum1:IDType>?</sum1:IDType>
                     <sum1:ID>?</sum1:ID>
                  </sum1:IDOtro>
                  <sum1:NombreSistemaInformatico>?</sum1:NombreSistemaInformatico>
                  <sum1:IdSistemaInformatico>?</sum1:IdSistemaInformatico>
                  <sum1:Version>?</sum1:Version>
                  <sum1:NumeroInstalacion>?</sum1:NumeroInstalacion>
                  <sum1:TipoUsoPosibleSoloVerifactu>?</sum1:TipoUsoPosibleSoloVerifactu>
                  <sum1:TipoUsoPosibleMultiOT>?</sum1:TipoUsoPosibleMultiOT>
                  <sum1:IndicadorMultiplesOT>?</sum1:IndicadorMultiplesOT>
               </sum1:SistemaInformatico>
               <sum1:FechaHoraHusoGenRegistro>?</sum1:FechaHoraHusoGenRegistro>
               <!--Optional:-->
               <sum1:NumRegistroAcuerdoFacturacion>?</sum1:NumRegistroAcuerdoFacturacion>
               <!--Optional:-->
               <sum1:IdAcuerdoSistemaInformatico>?</sum1:IdAcuerdoSistemaInformatico>
               <sum1:TipoHuella>?</sum1:TipoHuella>
               <sum1:Huella>?</sum1:Huella>
               <!--Optional:-->
               <xd:Signature Id="?">
                  <xd:SignedInfo Id="?">
                     <xd:CanonicalizationMethod Algorithm="?">
                        e
                        <!--You may enter ANY elements at this point-->
                        gero
                     </xd:CanonicalizationMethod>
                     <xd:SignatureMethod Algorithm="?">
                        cum
                        <!--Optional:-->
                        <xd:HMACOutputLength>?</xd:HMACOutputLength>
                        sonoras
                        <!--You may enter ANY elements at this point-->
                        aeoliam
                     </xd:SignatureMethod>
                     <!--1 or more repetitions:-->
                     <xd:Reference Id="?" URI="?" Type="?">
                        <!--Optional:-->
                        <xd:Transforms>
                           <!--1 or more repetitions:-->
                           <xd:Transform Algorithm="?">
                              quae
                              <!--You have a CHOICE of the next 2 items at this level-->
                              <!--You may enter ANY elements at this point-->
                              <xd:XPath>?</xd:XPath>
                              ventos
                           </xd:Transform>
                        </xd:Transforms>
                        <xd:DigestMethod Algorithm="?">
                           verrantque
                           <!--You may enter ANY elements at this point-->
                           temperat
                        </xd:DigestMethod>
                        <xd:DigestValue>cid:157794525561</xd:DigestValue>
                     </xd:Reference>
                  </xd:SignedInfo>
                  <xd:SignatureValue Id="?">cid:1690578518962</xd:SignatureValue>
                  <!--Optional:-->
                  <xd:KeyInfo Id="?">
                     per
                     <!--You have a CHOICE of the next 8 items at this level-->
                     <xd:KeyName>?</xd:KeyName>
                     <xd:KeyValue>
                        turbine
                        <!--You have a CHOICE of the next 3 items at this level-->
                        <xd:DSAKeyValue>
                           <xd:P>cid:1711707281655</xd:P>
                           <xd:Q>cid:481201118711</xd:Q>
                           <!--Optional:-->
                           <xd:G>cid:10611753232</xd:G>
                           <xd:Y>cid:1626111862696</xd:Y>
                           <!--Optional:-->
                           <xd:J>cid:1004230167824</xd:J>
                           <xd:Seed>cid:1162600426329</xd:Seed>
                           <xd:PgenCounter>cid:1261683778659</xd:PgenCounter>
                        </xd:DSAKeyValue>
                        <xd:RSAKeyValue>
                           <xd:Modulus>cid:1469002496253</xd:Modulus>
                           <xd:Exponent>cid:859317294610</xd:Exponent>
                        </xd:RSAKeyValue>
                        <!--You may enter ANY elements at this point-->
                        circum
                     </xd:KeyValue>
                     <xd:RetrievalMethod URI="?" Type="?">
                        <!--Optional:-->
                        <xd:Transforms>
                           <!--1 or more repetitions:-->
                           <xd:Transform Algorithm="?">
                              regemque
                              <!--You have a CHOICE of the next 2 items at this level-->
                              <!--You may enter ANY elements at this point-->
                              <xd:XPath>?</xd:XPath>
                              nimborum
                           </xd:Transform>
                        </xd:Transforms>
                     </xd:RetrievalMethod>
                     <xd:X509Data>
                        <!--You have a CHOICE of the next 6 items at this level-->
                        <xd:X509IssuerSerial>
                           <xd:X509IssuerName>?</xd:X509IssuerName>
                           <xd:X509SerialNumber>?</xd:X509SerialNumber>
                        </xd:X509IssuerSerial>
                        <xd:X509SKI>cid:1604072216124</xd:X509SKI>
                        <xd:X509SubjectName>?</xd:X509SubjectName>
                        <xd:X509Certificate>cid:534264511089</xd:X509Certificate>
                        <xd:X509CRL>cid:300236998953</xd:X509CRL>
                        <!--You may enter ANY elements at this point-->
                     </xd:X509Data>
                     <xd:PGPData>
                        <!--You have a CHOICE of the next 2 items at this level-->
                        <xd:PGPKeyID>cid:734311530325</xd:PGPKeyID>
                        <!--Optional:-->
                        <xd:PGPKeyPacket>cid:703929686148</xd:PGPKeyPacket>
                        <!--You may enter ANY elements at this point-->
                        <xd:PGPKeyPacket>cid:786902941464</xd:PGPKeyPacket>
                        <!--You may enter ANY elements at this point-->
                     </xd:PGPData>
                     <xd:SPKIData>
                        <xd:SPKISexp>cid:1242727609185</xd:SPKISexp>
                        <!--You may enter ANY elements at this point-->
                     </xd:SPKIData>
                     <xd:MgmtData>?</xd:MgmtData>
                     <!--You may enter ANY elements at this point-->
                     fremunt
                  </xd:KeyInfo>
                  <!--Zero or more repetitions:-->
                  <xd:Object Id="?" MimeType="?" Encoding="?">
                     foedere
                     <!--You may enter ANY elements at this point-->
                     ferant
                  </xd:Object>
               </xd:Signature>
            </sum1:RegistroAlta>
            <sum1:RegistroAnulacion>
               <sum1:IDVersion>?</sum1:IDVersion>
               <sum1:IDFactura>
                  <sum1:IDEmisorFacturaAnulada>?</sum1:IDEmisorFacturaAnulada>
                  <sum1:NumSerieFacturaAnulada>?</sum1:NumSerieFacturaAnulada>
                  <sum1:FechaExpedicionFacturaAnulada>?</sum1:FechaExpedicionFacturaAnulada>
               </sum1:IDFactura>
               <!--Optional:-->
               <sum1:RefExterna>?</sum1:RefExterna>
               <!--Optional:-->
               <sum1:SinRegistroPrevio>?</sum1:SinRegistroPrevio>
               <!--Optional:-->
               <sum1:RechazoPrevio>?</sum1:RechazoPrevio>
               <!--Optional:-->
               <sum1:GeneradoPor>?</sum1:GeneradoPor>
               <!--Optional:-->
               <sum1:Generador>
                  <sum1:NombreRazon>?</sum1:NombreRazon>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:NIF>?</sum1:NIF>
                  <sum1:IDOtro>
                     <!--Optional:-->
                     <sum1:CodigoPais>?</sum1:CodigoPais>
                     <sum1:IDType>?</sum1:IDType>
                     <sum1:ID>?</sum1:ID>
                  </sum1:IDOtro>
               </sum1:Generador>
               <sum1:Encadenamiento>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:PrimerRegistro>?</sum1:PrimerRegistro>
                  <sum1:RegistroAnterior>
                     <sum1:IDEmisorFactura>?</sum1:IDEmisorFactura>
                     <sum1:NumSerieFactura>?</sum1:NumSerieFactura>
                     <sum1:FechaExpedicionFactura>?</sum1:FechaExpedicionFactura>
                     <sum1:Huella>?</sum1:Huella>
                  </sum1:RegistroAnterior>
               </sum1:Encadenamiento>
               <sum1:SistemaInformatico>
                  <sum1:NombreRazon>?</sum1:NombreRazon>
                  <!--You have a CHOICE of the next 2 items at this level-->
                  <sum1:NIF>?</sum1:NIF>
                  <sum1:IDOtro>
                     <!--Optional:-->
                     <sum1:CodigoPais>?</sum1:CodigoPais>
                     <sum1:IDType>?</sum1:IDType>
                     <sum1:ID>?</sum1:ID>
                  </sum1:IDOtro>
                  <sum1:NombreSistemaInformatico>?</sum1:NombreSistemaInformatico>
                  <sum1:IdSistemaInformatico>?</sum1:IdSistemaInformatico>
                  <sum1:Version>?</sum1:Version>
                  <sum1:NumeroInstalacion>?</sum1:NumeroInstalacion>
                  <sum1:TipoUsoPosibleSoloVerifactu>?</sum1:TipoUsoPosibleSoloVerifactu>
                  <sum1:TipoUsoPosibleMultiOT>?</sum1:TipoUsoPosibleMultiOT>
                  <sum1:IndicadorMultiplesOT>?</sum1:IndicadorMultiplesOT>
               </sum1:SistemaInformatico>
               <sum1:FechaHoraHusoGenRegistro>?</sum1:FechaHoraHusoGenRegistro>
               <sum1:TipoHuella>?</sum1:TipoHuella>
               <sum1:Huella>?</sum1:Huella>
               <!--Optional:-->
               <xd:Signature Id="?">
                  <xd:SignedInfo Id="?">
                     <xd:CanonicalizationMethod Algorithm="?">
                        profundum
                        <!--You may enter ANY elements at this point-->
                        sceptra
                     </xd:CanonicalizationMethod>
                     <xd:SignatureMethod Algorithm="?">
                        et
                        <!--Optional:-->
                        <xd:HMACOutputLength>?</xd:HMACOutputLength>
                        turbine
                        <!--You may enter ANY elements at this point-->
                        iovis
                     </xd:SignatureMethod>
                     <!--1 or more repetitions:-->
                     <xd:Reference Id="?" URI="?" Type="?">
                        <!--Optional:-->
                        <xd:Transforms>
                           <!--1 or more repetitions:-->
                           <xd:Transform Algorithm="?">
                              flammato
                              <!--You have a CHOICE of the next 2 items at this level-->
                              <!--You may enter ANY elements at this point-->
                              <xd:XPath>?</xd:XPath>
                              speluncis
                           </xd:Transform>
                        </xd:Transforms>
                        <xd:DigestMethod Algorithm="?">
                           profundum
                           <!--You may enter ANY elements at this point-->
                           bella
                        </xd:DigestMethod>
                        <xd:DigestValue>cid:1085730955294</xd:DigestValue>
                     </xd:Reference>
                  </xd:SignedInfo>
                  <xd:SignatureValue Id="?">cid:293982713997</xd:SignatureValue>
                  <!--Optional:-->
                  <xd:KeyInfo Id="?">
                     nubibus
                     <!--You have a CHOICE of the next 8 items at this level-->
                     <xd:KeyName>?</xd:KeyName>
                     <xd:KeyValue>
                        flammas
                        <!--You have a CHOICE of the next 3 items at this level-->
                        <xd:DSAKeyValue>
                           <xd:P>cid:214292880720</xd:P>
                           <xd:Q>cid:1227813663222</xd:Q>
                           <!--Optional:-->
                           <xd:G>cid:13824133043</xd:G>
                           <xd:Y>cid:1243910579088</xd:Y>
                           <!--Optional:-->
                           <xd:J>cid:492279340888</xd:J>
                           <xd:Seed>cid:1357677455119</xd:Seed>
                           <xd:PgenCounter>cid:1489448324499</xd:PgenCounter>
                        </xd:DSAKeyValue>
                        <xd:RSAKeyValue>
                           <xd:Modulus>cid:137681429226</xd:Modulus>
                           <xd:Exponent>cid:367138859443</xd:Exponent>
                        </xd:RSAKeyValue>
                        <!--You may enter ANY elements at this point-->
                        ac
                     </xd:KeyValue>
                     <xd:RetrievalMethod URI="?" Type="?">
                        <!--Optional:-->
                        <xd:Transforms>
                           <!--1 or more repetitions:-->
                           <xd:Transform Algorithm="?">
                              hoc
                              <!--You have a CHOICE of the next 2 items at this level-->
                              <!--You may enter ANY elements at this point-->
                              <xd:XPath>?</xd:XPath>
                              rapidum
                           </xd:Transform>
                        </xd:Transforms>
                     </xd:RetrievalMethod>
                     <xd:X509Data>
                        <!--You have a CHOICE of the next 6 items at this level-->
                        <xd:X509IssuerSerial>
                           <xd:X509IssuerName>?</xd:X509IssuerName>
                           <xd:X509SerialNumber>?</xd:X509SerialNumber>
                        </xd:X509IssuerSerial>
                        <xd:X509SKI>cid:1458261262390</xd:X509SKI>
                        <xd:X509SubjectName>?</xd:X509SubjectName>
                        <xd:X509Certificate>cid:900472804471</xd:X509Certificate>
                        <xd:X509CRL>cid:853807643670</xd:X509CRL>
                        <!--You may enter ANY elements at this point-->
                     </xd:X509Data>
                     <xd:PGPData>
                        <!--You have a CHOICE of the next 2 items at this level-->
                        <xd:PGPKeyID>cid:1431285563718</xd:PGPKeyID>
                        <!--Optional:-->
                        <xd:PGPKeyPacket>cid:188885434417</xd:PGPKeyPacket>
                        <!--You may enter ANY elements at this point-->
                        <xd:PGPKeyPacket>cid:494088434823</xd:PGPKeyPacket>
                        <!--You may enter ANY elements at this point-->
                     </xd:PGPData>
                     <xd:SPKIData>
                        <xd:SPKISexp>cid:1724923742318</xd:SPKISexp>
                        <!--You may enter ANY elements at this point-->
                     </xd:SPKIData>
                     <xd:MgmtData>?</xd:MgmtData>
                     <!--You may enter ANY elements at this point-->
                     ac
                  </xd:KeyInfo>
                  <!--Zero or more repetitions:-->
                  <xd:Object Id="?" MimeType="?" Encoding="?">
                     caelumque
                     <!--You may enter ANY elements at this point-->
                     speluncis
                  </xd:Object>
               </xd:Signature>
            </sum1:RegistroAnulacion>
         </sum:RegistroFactura>
      </sum:RegFactuSistemaFacturacion>
   </soapenv:Body>
</soapenv:Envelope>
Last edited by paquitohm on Tue Dec 17, 2024 7:36 am, edited 2 times in total.
paquitohm
 
Posts: 281
Joined: Fri Jan 14, 2022 8:37 am

Re: Veri*Factu

Postby paquitohm » Mon Dec 16, 2024 8:37 pm

FiveWiDi wrote:Hola a todos,

Ya se tienen algunas piezas del puzzle.

Creo que falta una, ¿Cómo leen Ustedes un XML?

Yo tengo una función pero creo que no es una solución muy ortodoxa, aunque funciona muy bien. El único requisito es saber a priori que Tag son iterativos.

Ya que usar la clase para crear un XML me costó entenderla, pensé que para leerlo me costaría también, por lo que opté por lo que me es fácil, y cuando quiero leer un XML paso su contenido a una array.

Me creé una función LoadXML() que devuelve una Array de arrays tridimensionales, cada array de esta array tiene:
-una cadena del path del tag completo
-el valor que tiene ese tag
-una array de arrays bidimensionales con el atributo y su valor (si tiene atributos)

Defino previamente aTagIter (son los Tags iterativos) que és una array de array bidimensionales, para Verifactu:

Code: Select all  Expand view  RUN
Local aTagIter  := { { "/env:Envelope/env:Body/tikR:RespuestaRegFactuSistemaFacturacion/tikR:RespuestaLinea/", 0 }, ;
                     { "/env:Envelope/env:Body/tikR:RespuestaRegFactuSistemaFacturacion/tikR:RespuestaLinea/tikR:CodigoErrorRegistro/", 0 }, ;
                     { "/env:Envelope/env:Body/tikR:RespuestaRegFactuSistemaFacturacion/tikR:RespuestaLinea/tikR:DescripcionErrorRegistro/", 0 } ;
                   }




Así es como leo la respuesta a los envíos que hago a Verifactu:
Code: Select all  Expand view  RUN
//----------------------------------------------------------------------------/
FUNCTION LoadXml( hFile, cBDPathFull, aTagIter )

Local oXmlDoc, oXmlIter
Local lAbreaqui := .F.
//Local oTagActual, oTagLast, aRoots := {}
Local oTagActual, oTagLast := {}

Local litetagA  := ""
Local litetagB  := ""
Local nContador := 0
Local aXml      := {}
Local cDummy    := ""

/* Tag iteratius i sumatori de iteracions trovades.
   L'estructura de l'array es:
   - 1er. element el tag que pot ser iteratiu
   - 2on. element el número de iteració del tag.
*/


/*
Local aTagIter  := { {"/Document/CstmrDrctDbtInitn/PmtInf/", 0}, ;
                     {"/Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf/", 0}, ;
                     {"/Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf/Dbtr/PstlAdr/AdrLine/", 0} }
*/


//Msgnowait( AMPAarra, GetTrad("Atenció!"), GetTrad("Llegint el fitxer: ") + cBDPathFull )


// Cal ordenar la array per a que es puguin controlar correctament les iteracions.
aTagIter := Asort( aTagIter,,, { |x, y| x[1] < y[1] } )

If hFile = 0
    hFile    = FOpen( cBDPathFull )
    lAbreaqui := .T.
EndIf

oXmlDoc  = TXmlDocument():New( hFile )
oXmlIter = TXmlIterator():New( oXmlDoc:oRoot )

oTagActual := oTagLast := Nil
   
litetagA := "/"
   
while ( oTagActual := oXmlIter:Next() ) != nil

    //Traza( 1, "oTagActual:Depth()-oTagActual:cName=", oTagActual:Depth(), "-", oTagActual:cName )

    If oTagLast != nil
     
        if oTagLast:Depth() < oTagActual:Depth()
            litetagA := litetagA + oTagActual:cName + "/"
        endif

        if oTagLast:Depth() > oTagActual:Depth()
            //Traza( 1, "litetagA=", litetagA )
            litetagB := "/"
            For nContador := 1 To ( oTagActual:Depth() - 1 )
                litetagB := litetagB + StrToken( litetagA, nContador, "/" ) + "/"
            EndFor
            litetagA := litetagB
            If Empty(oTagActual:cName)
                litetagA := litetagA + "/"
              Else
                litetagA := litetagA + oTagActual:cName + "/"
            EndIf
            //litetagA := CheckItera( litetagA, aTagIter )
        endif

        if oTagLast:Depth() == oTagActual:Depth()
            //Traza( 1, "litetagA=", litetagA )
            litetagB := "/"
            For nContador := 1 To ( oTagActual:Depth() - 1 )
                litetagB := litetagB + StrToken( litetagA, nContador, "/" ) + "/"
            EndFor
            litetagA := litetagB
            If Empty(oTagActual:cName)
                litetagA := litetagA + "/"
              Else
                litetagA := litetagA + oTagActual:cName + "/"
            EndIf
            //litetagA := CheckItera( litetagA, aTagIter )
        endif
       
        litetagA := CheckItera( litetagA, aTagIter )

      else
     
        If .Not. Empty(oTagActual:cName)
            litetagA := litetagA + oTagActual:cName + "/"
        EndIf
       
        //Traza( 1, "litetagA=", litetagA )
    endif
   
    //litetagA := CheckItera( litetagA, aTagIter )

    // Aquí es captura el TAG, el seu valor y els atributs si en té.
    // exemple: { "/Document/CstmrDrctDbtInitn/PmtInf<1>/DrctDbtTxInf<2>/Dbtr/PstlAdr/AdrLine<1>/", "BARCINO, 29 P-D - SELVA NEGRA", {} }
    //          { "/Document/CstmrDrctDbtInitn/PmtInf<1>/DrctDbtTxInf<2>/Dbtr/PstlAdr/AdrLine<2>/", "08750 Vallirana", {} }

    // Es captura el TAG si té data o si hi han atributs del TAG.
    If .Not. Empty( oTagActual:cData ) .or. Len( oTagActual:aAttributes ) > 0
        AADD( aXml, { litetagA, oTagActual:cData, {} } )
   
        HEval( oTagActual:aAttributes,;
               { | cKey, cData | AADD( ATail( aXml )[3], { cKey, cData } ) } )
    EndIf

    /* En aquesta traza s'enregistren els TAG i els seus valors.
       ------------------------------------------------------ */

    /*
    cDummy := ""
    HEval( oTagActual:aAttributes,;
           { | cKey, cData | cDummy := cDummy + cKey + ":" + cData + "-" } )

    If .Not. Empty( oTagActual:cData ) .or. Len( oTagActual:aAttributes ) > 0
        Traza( 1, "litetagA=", litetagA, "..", oTagActual:cData, "..", cDummy, "..", Len( ATail( aXml )[3]) )
    EndIf
    */

           
    //Traza( 1, "" )
     
    oTagLast = oTagActual
end

If lAbreaqui
    FClose( hFile )
EndIf

//EndMsgNoWait( AMPAarra )

// Podem ordenar l'array... però crec que no serà necessari.
//aXml := Asort( aXml,,, { |x, y| x[1] < y[1] } )

//Traza( 1 , aXml )

Return aXml
//----------------------------------------------------------------------------//
FUNCTION CheckItera( litetagA, aTagIter )

/* litetagA es reb acabat en '/'.

   Aquesta funció es llença al moment d'afegir un node de XML a litetagA, i
   es comprova si aquest nou node afegit és iteratiu, i si és el cas s'el
   numera. A la resta de nodes que arriberien a 'penjar' d'ell s'els posa
   el numeral a '0', doncs es tractaria d'una nova captura de nodes iteratius.
   
   Per a que la possada a zero de les iteracions que penjen de la que
   estem examinant, cal que aTagIter estigui ordenada ascendentment.
   ------------------------------------------------------------------------ */


Local cCadena     := litetagA
Local nContadorA  := 0
Local nContadorB  := 0
Local PosA        := 0
Local PosB        := 0
Local LenaTagIter := 0
Local LencCadena  := 0

Do While (PosA := AT( "<", cCadena) ) > 0
    //Traza( 1 , "a-cCadena=", cCadena )
    PosB := AT( ">", cCadena )
    cCadena := Left( cCadena, PosA - 1 ) + SubStr( cCadena, PosB + 1 )
    //Traza( 1 , "b-cCadena=", cCadena )
End

If ( nContadorA := ASCan( aTagIter, { |aVal| aVal[1] = cCadena } ) ) > 0
   
    /* Poso la resta d'elements iteratius que penjen del que estem examinant a zero (0).
       ------------------------------------------------------------------------------ */

    LenaTagIter := Len(aTagIter)
    LencCadena  := Len(cCadena)
   
    For nContadorB := ( nContadorA + 1 ) To LenaTagIter
        If cCadena = Left( aTagIter[nContadorB][1], LencCadena )
            aTagIter[nContadorB][2] := 0
        EndIf
    EndFor

    aTagIter[ nContadorA ][2] ++
    cCadena :=  Left( litetagA, Len(litetagA) - 1 ) + "<" + AllTrim(Str(aTagIter[ nContadorA ][2], 10,0)) + ">/"
   
  Else
    cCadena   := litetagA
EndIf

Return cCadena
//----------------------------------------------------------------------------//


Prueben a pasarle a LoadXML() un fichero XML y vean el array que les devuelve, hacer un AT() nos facilita recuperar el valor que lleva ese Tag.

Con mucho gusto compartiría mi código, pero no lo tengo tan bien estructurado para aislarlo del programa donde se utiliza, hay demasiadas llamadas a funciones que utilizo para otras cosas.

Si que puedo compartir parte de él y como he resuelto situaciones que voy detectando.

Saludos,



Hola FiveWIDI,

Gracias por tu aporte.

Hay una funcion, no sé si es del core o de contribs que se llama xml2hash() y que hace el trabajo sucio de convertir el xml en hash con lo cual hace la información muy accesible.
Yo la he usado con éxito con el tema del SII.

Salu2
paquitohm
 
Posts: 281
Joined: Fri Jan 14, 2022 8:37 am

Re: Veri*Factu

Postby Marc Venken » Wed Dec 18, 2024 8:13 pm

Antonio,

If I read correctly, your last post is the first code of a new class that can be used to create the XML invoices in a correct way. I tested and indeed, it is working.
I would like to help, but my programming skills are not that good. I can test however and share ideas ))))

Do you need more XML info's (fields that are used in the Belgium/Holland xml files ?

Once the XML is made, I will be nessesary to upload it to Peppol (at least in Belgium) but I believe also in the rest of EU.

I participate here in a project for a company that sell invoice system in the cloud. (No impact on the code or see source). My part is using my software to generate
a csv with all data needed to make a invoice. There systhem will import the CSV and process them to a XML. They then will send it to a secure Peppol account.
The business model of them will be to pay a yearly fee for the CSV module and also the Peppol account. You can only connect to Peppol by a official partner and that cannot be me since i'm a end user.

There will be so many users because everybody with a own made program, exel invoice etc.... can make a CVS to upload. XML programming will be more complex, but a MUST for FWin, so keep on working.
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1456
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: Veri*Factu

Postby Antonio Linares » Wed Dec 18, 2024 9:49 pm

Dear Marc,

Many thanks for your feedback

We already have a Class TXml that creates the invoice XML. Next is to complete the invoice details as needed.

Then we will sign it and send it. With the feedback and help from all surely we can do it :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Veri*Factu

Postby Marc Venken » Fri Dec 20, 2024 3:56 pm

I would like to try a other approuch. Looking at some Xml invoices, you see that they are not the same, but the items used are always named the same . (some have more items)

I take a random xml invoice that is compliant with the norm we need to use (we all recive already xml invoices from companys)

The Fwin function FW_XmlView( hFile ) will give all items from the invoice.
Option 2 : read with tXml

Put all items in a dbf and once map these items with dbf items from customers, invoices etc. for all items needed.

ID = Customer->ID
ISSUEDATE = Invoice->DATUM
etc...

Once created, this dbf will be called while invoicing and it will loop from 1 to xxx and process the invoice data into a Xml
The part with the invoice lines (detail) will be a second loop.

I think this can work. The final dbf can always be updated with extra items or changes.

What do you think ?? This code is only the code to show the items. Rest is not programmed yet

Code: Select all  Expand view  RUN

#include "fivewin.ch"

ANNOUNCE RDDSYS
REQUEST OrdKeyNo, OrdKeyCount, OrdCreate, OrdKeyGoto
REQUEST DBFCDX, DBFFPT, DBFDBT

FUNCTION Main()

   LOCAL oWnd
   LOCAL oBar
   LOCAL cTitle := "Testing Software module"

   PUBLIC lDebug:= .f.
   RDDSETDEFAULT("DBFCDX")
   DEFINE WINDOW oWnd TITLE cTitle

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar;
      CENTER;
      PROMPT "Test";
      ACTION xmlreader()

   ACTIVATE WINDOW oWnd;
      MAXIMIZED

   RETURN Nil

function Xmlreader()
   local aMail:={},nTel:= 1, i, aData:={}
   local hFile    := FOpen( "armor.xml" ) // random xmlfile
   Local aStruct := {}
   Local oXmlDoc  := TXmlDocument():New( hFile )
   Local oXmlIter := TXmlIterator():New( oXmlDoc:oRoot ), oTagActual
   Local cKleur, cHex, cId

   FW_XmlView( hFile )

   nTel = 1
   while .T.
      oTagActual = oXmlIter:Next()
      If oTagActual != nil
         aadd(aMail ,{oTagActual:cName,oTagActual:cData} )
         aadd(aData,oTagActual)
         //  Make code to fill a DBF (Xbrowse) with items and also with dbf customer and invoice mapped data
      Else
         Exit
      Endif
   End

   xbrowser(aMail)
   xbrowser(aData)

   FClose( hFile )
   close all
return nil

 
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1456
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: Veri*Factu

Postby Marc Venken » Fri Dec 20, 2024 4:04 pm

Off cource, when the Veri*Factu is ready to publish, I need to change my way.
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1456
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Previous

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 17 guests