Ver Mensaje Individual
  #1436  
Antiguo 07-03-2024
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 233
Reputación: 16
espinete Va camino a la fama
Gran aporte, Delphier!

Yo el año pasado empecé a hacer algo, pero lo dejé porque veía que la cosa no avanzaba. De hecho la web de la AEAT sobre VeriFactu estuvo casi un año en la versión 0.1.

Sin duda cuando lo retome en breve, tu post será de gran ayuda.

Gracias a la experiencia que hemos cogido todos con TicketBAI, no creo que nos encontremos con problemas serios, salvo las dudas de siempre, que seguimos teniendo con TicketBAI 2 años después: fechas de la factura, rectificativas, anular/borrar/cancelar/modificar facturas, etc.
Pero a nivel técnico, todo debería estar ya en el foro.


Cita:
Empezado por Delphier Ver Mensaje
Pues lo dicho , aquí va mi primer ptototipo de unit para verifactu , con el código para generar un RegistroFacturacion de una factura y extraer el XML , por si le sirve a alguien para algo.
Evidentemente los campos y als tablas son los míos y no va a funcionar directamente, pero el esqueleto del registrofafcturacion de Alta está.


Código Delphi [-]
unit UVerifactu;

interface

Uses

System.SysUtils,
Xml.xmldom,
Xml.XMLIntf,
Xml.XMLDoc,
Data.Win.ADODB,
System.DateUtils,
Vcl.Dialogs,
Udatam, // Use interno propio
System.hash,
System.StrUtils,
GesAdoDataset, // Use interno propio
SistemaFacturacionSOAPv12,
Soap.InvokeRegistry,
Soap.OPConvert,
Soap.SOAPDomConv,
Soap.OPToSOAPDomConv;

function Trimestre(Dia:TDate):integer;
function TipoFacturaVerifactu(DTFactura : TGesAdoDataset) : ClaveTipoFacturaType;
function TipoRectificativaVerifactu(CorrectionMethod : String) : ClaveTipoRectificativaType;
function ClaveRegimenVerifactu(Conexion : TAdoConnection ; RegimenIva : Integer) : IdOperacionesTrascendenciaTributariaType;
function TipoCalificacionOperacion : CalificacionOperacionType;
function TipoOperacionExenta : OperacionExentaType;

function GenerarRegistroFacturacion_AltaVerifactu(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdDocumento : String) : String;
procedure AgregarRelacionRectificadasPorDiferencias(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdFactura : String; Factura :FacturasEmitidasType);
procedure AgregarRelacionRectificadasPorSustitucion(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdFactura : String; Factura :FacturasEmitidasType);


function GenerarHashRegistroVerifactu(CadenaVerifactu : String) : String;


implementation

Uses Ur_user; // Use interno propio

function GenerarHashRegistroVerifactu(CadenaVerifactu : String) : String;
Begin

// NIF (RegistroFactura/RegistroAlta/IDFactura/IDEmisorFactura/NIF)
// NumserieFacturaEmisor (RegistroFactura/RegistroAlta/IDFactura/NumSerieFacturaEmisor)
// FechaExpedicionFacturaEmisor (RegistroFactura/RegistroAlta/IDFactura/FechaExpedicionFacturaEmisor)
// TipoRegistroSIF (RegistroFactura/RegistroAlta/TipoRegistroSIF)
// TipoFactura (RegistroFactura/RegistroAlta/TipoFactura)
// CuotaTotal (RegistroFactura/RegistroAlta/CuotaTotal)
// ImporteTotal (RegistroFactura/RegistroAlta/ImporteTotal)
// HuellaRegistroAnterior (RegistroFactura/RegistroAlta/EncadenamientoRegistroAnterior/HuellaRegistroAnterior)
// FechaHoraHusoGenRegistro (RegistroFactura/RegistroAlta/FechaHoraHusoGenRegistro)

// formato fECHAS verifactu (dd-mm-yyyy)

 // Ejemplo cadena
 {
 CadenaVerifactu :=
 'BXXXXXXXXXX'+
 'F1-01-150'+
 '27-02-2024'+
 'VERIFACTU'+ // ???
 'F1'+
 '1000'+
 '1210'+
 '27-02-2024 11:19:00';
  }

 Result := THashSHA2.GetHashString(CadenaVerifactu,THashSHA2.TSHA2Version.SHA256);


End;



function GenerarRegistroFacturacion_AltaVerifactu(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdDocumento : String) : String;
var NombreTabla,NombreVista,IdFactura : String;
var DTFactura,DTDesgloseIvas : TGesAdoDataset;
begin



  // Buscamos pro tabla
  NombreTabla := f_devolver_valor_campo(0,Conexion,'C','Tablas','Codigo','Nombre',TablaMaestra);
  NombreVista := 'Vista'+NombreTabla;


  // Vamos a Buscar la Factura
  DTFactura      := f_crear_dataset(Conexion,DTFactura,'DTFactura','');
  DTDesgloseIvas := f_crear_dataset(Conexion,DTDesgloseIvas,'DTDesgloseIvas','');

  DTFactura.TableName := NombreTabla;
  DTFactura.VistaName := NombreVista;



  DTFactura.CommandText := 'Select * From '+NombreVista+' where Identificador = :Identificador';
  f_valor_parametro_tabla(DTFactura,'Identificador',IdDocumento);
  f_open_adodataset(DTFactura,ltReadOnly);

  DTDesgloseIvas.CommandText := 'Select * From DocumentosDesgloseIvas where IdDocumento = :Identificador';
  f_valor_parametro_tabla(DTDesgloseIvas,'Identificador',IdDocumento);
  f_open_adodataset(DTDesgloseIvas,ltReadOnly);


  IdFactura := DTFactura.FieldByName('Identificador').AsString;

  ///EsPrimera factura del ejercicio?

  //vamos vamos


  // Factura ejemplo

  var Factura :FacturasEmitidasType;
  Factura := FacturasEmitidasType.Create;

  Factura.RegistroFacturacion := RegistroFacturacionType.Create;
  Factura.DatosControl  := DatosControlType.Create;



  //IdFactura
  Factura.RegistroFacturacion.IDFactura := IDFacturaExpedidaType.Create;

  Factura.RegistroFacturacion.IDFactura.IDEmisorFactura := IDEmisorFactura.Create;
  Factura.RegistroFacturacion.IDFactura.IDEmisorFactura.NIF   := Datam.TBEmpresa.FieldByName('NIF').AsString;
  Factura.RegistroFacturacion.IDFactura.NumSerieFacturaEmisor := DTFactura.FieldByName('ReferenciaDocumento').AsString;
  Factura.RegistroFacturacion.IDFactura.FechaExpedicionFacturaEmisor := StringReplace(DTFactura.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',
  [rfReplaceAll, rfIgnoreCase]); // (dd-mm-yyyy)

  Factura.RegistroFacturacion.NombreRazonEmisor := Datam.TBEmpresa.FieldByName('C_EMPRESA').AsString;
  Factura.RegistroFacturacion.TipoRegistroSIF   := TipoRegistroSIFType.S0; // averiguar cuando usar //S0  Alta inicial del registro de facturación en el SIF ,  
//S1  Alta sustitutiva del registro de facturación en el SIF,  
//S2  Anulación inicial del registro de facturación en el SIF,  
//S3  Anulación sustitutiva del registro de facturación en el SIF
  Factura.RegistroFacturacion.TipoFactura       := TipoFacturaVerifactu(DTFactura);
  if Length(Trim(DTFactura.FieldByName('CorrectionMethod1').AsString)) > 0 then
  Factura.RegistroFacturacion.TipoRectificativa := TipoRectificativaVerifactu(DTFactura.FieldByName('CorrectionMethod1').AsString);


    // Rectificads por direfencias  "Factura.RegistroFacturacion.FacturasRectificadas"
    if Factura.RegistroFacturacion.TipoRectificativa = ClaveTipoRectificativaType.I then
    Begin
      AgregarRelacionRectificadasPorDiferencias(DTFactura.Connection,TablaMaestra,IdFactura,Factura);
    End;


    // por sustitucion
    if Factura.RegistroFacturacion.TipoRectificativa = ClaveTipoRectificativaType.S then
    Begin
      AgregarRelacionRectificadasPorSustitucion(DTFactura.Connection,TablaMaestra,IdFactura,Factura);
    End;


  Factura.RegistroFacturacion.FechaOperacion := StringReplace(DTFactura.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',[rfReplaceAll, rfIgnoreCase]); // (dd-mm-yyyy)
  Factura.RegistroFacturacion.DescripcionOperacion := 'Venta';
  Factura.RegistroFacturacion.FacturaSimplificadaArticulos7_2_7_3 := SimplificadaCualificadaType.N; // Factura simplificada Articulo 7,2 Y 7,3 RD 1619/2012. 
//Si no se informa este campo se entenderá que tiene valor  “N , si l afacutra simplificada tiene nif i datos
  Factura.RegistroFacturacion.FacturaSinIdentifDestinatarioArticulo6_1_d := CompletaSinDestinatarioType.N; //si es simplificada N ordinaria S , por aclarar
  Factura.RegistroFacturacion.Macrodato := MacrodatoType.N; // S  Sí - N  No


  // Tervero No aplicamos ->
  // Factura.RegistroFacturacion.EmitidaPorTercerosODestinatario := ''; //TercerosODestinatarioType.D;
  //   Factura.RegistroFacturacion.Tercero

     { el ejemplo
    // Detalle
    var detalle := DetalleType.Create;
    detalle.CuotaRepercutida := '100';
    detalle.TipoImpositivo := '21';
    SetLength(arrayDetallesDesglose, 1);
    arrayDetallesDesglose[0] := detalle;



    // desglose
    var desglose: DesgloseType := DesgloseType.Create();
    SetLength(Desglose, 1);
    Desglose[0] := detalle;
    fact.RegistroFacturacion.Desglose := Desglose;
    }


  //Factura.RegistroFacturacion.Destinatarios := En simplificadas ?????

  // Destinatario
  var Destinatario := PersonaFisicaJuridicaType.Create;
  Destinatario.NombreRazon := DTFactura.FieldByName('NOMB').AsString;
  Destinatario.NIF         := DTFactura.FieldByName('NIF').AsString;

  Destinatario.IDOtro := IDOtroType.Create;
  //Destinatario.IDOtro.CodigoPais := '';

  //PersonaFisicaJuridicaIDTypeType ->
  //02  NIF-IVA
  //03  Pasaporte
  //04  Documento oficial de identificación expedido por el país o territorio de residencia
  //05  Certificado de residencia
  //06  Otro documento probatorio
  //07  No censado

  Destinatario.IDOtro.IdType := PersonaFisicaJuridicaIDTypeType._02;
  Destinatario.IDOtro.ID     := DTFactura.FieldByName('NIF').AsString;

  // Los destinatarios , la lista
  var ListaDestinatarios : Destinatarios := Destinatarios.Create();
  SetLength(ListaDestinatarios, 1);
  ListaDestinatarios[0] := Destinatario;
  Factura.RegistroFacturacion.Destinatarios := ListaDestinatarios;




  Factura.RegistroFacturacion.Cupon := CuponType.N;


//vamos por aqui




      // Desglose de IVAS
      var ListaDesglose : DesgloseType := DesgloseType.Create();
      var Orden := 0;
      while not DTDesgloseIvas.Eof do
      Begin

          var DetalleDesglose := DetalleType.Create;;

          DetalleDesglose.ClaveRegimen :=
          ClaveRegimenVerifactu(DTFactura.Connection,DTFactura.FieldByName('RegimenIva').AsInteger); //'L8';

          DetalleDesglose.CalificacionOperacion := TipoCalificacionOperacion; //L9

          // Si es exenta , motivo
          if (DetalleDesglose.CalificacionOperacion = CalificacionOperacionType.N1)
          or (DetalleDesglose.CalificacionOperacion = CalificacionOperacionType.N2) then
          DetalleDesglose.OperacionExenta := TipoOperacionExenta; //L10

          DetalleDesglose.TipoImpositivo := FormatFloat('0.00',DTDesgloseIvas.FieldByName('IVA').AsFloat);
          DetalleDesglose.BaseImponibleOimporteNoSujeto := FormatFloat('0.00',DTDesgloseIvas.FieldByName('BASIMP').AsFloat);;
          DetalleDesglose.BaseImponibleACoste := '0.00';
          DetalleDesglose.CuotaRepercutida := FormatFloat('0.00',DTDesgloseIvas.FieldByName('BASIVA').AsFloat);
          DetalleDesglose.TipoRecargoEquivalencia := FormatFloat('0.00',DTDesgloseIvas.FieldByName('REC').AsFloat);
          DetalleDesglose.CuotaRecargoEquivalencia := FormatFloat('0.00',DTDesgloseIvas.FieldByName('BASREC').AsFloat);

       DTDesgloseIvas.Next;

           // desglose

        SetLength(ListaDesglose, Orden+1);
        ListaDesglose[Orden] := DetalleDesglose ;


       Orden := Orden + 1;

      end;

      Factura.RegistroFacturacion.Desglose := ListaDesglose;


    Factura.RegistroFacturacion.ImporteTotal := FormatFloat('0.00',DTFactura.FieldByName('TOTA').AsCurrency);

    // EncadenamientoFacturaAnterior
    Factura.RegistroFacturacion.EncadenamientoRegistroAnterior := EncadenamientoFacturaAnteriorType.Create;
    //Factura.RegistroFacturacion.EncadenamientoRegistroAnterior.IDEmisorFacturaRegistroAnterior := '' ;
    Factura.RegistroFacturacion.EncadenamientoRegistroAnterior.NumSerieFacturaRegistroAnterior := '';
    Factura.RegistroFacturacion.EncadenamientoRegistroAnterior.FechaExpedicionFacturaRegistroAnterior := '';
    Factura.RegistroFacturacion.EncadenamientoRegistroAnterior.HuellaRegistroAnterior := '';



    Factura.RegistroFacturacion.SistemaInformatico := SistemaInformaticoType.Create;
    Factura.RegistroFacturacion.SistemaInformatico.NombreRazon := '';
    Factura.RegistroFacturacion.SistemaInformatico.NIF         := '';

    Factura.RegistroFacturacion.SistemaInformatico.IDOtro := IDOtroType.Create;
    //Factura.RegistroFacturacion.SistemaInformatico.IDOtro.CodigoPais
    Factura.RegistroFacturacion.SistemaInformatico.IDOtro.IDType := PersonaFisicaJuridicaIDTypeType._02;

    Factura.RegistroFacturacion.SistemaInformatico.NombreSistemaInformatico := '';
    Factura.RegistroFacturacion.SistemaInformatico.IdSistemaInformatico     := '';
    Factura.RegistroFacturacion.SistemaInformatico.Version                  := '';
    Factura.RegistroFacturacion.SistemaInformatico.NumeroInstalacion        := '';
    Factura.RegistroFacturacion.SistemaInformatico.TipoUsoPosibleSoloVerifactu := SiNoType.S;
    Factura.RegistroFacturacion.SistemaInformatico.TipoUsoPosibleOtros         := SiNoType.N;
    Factura.RegistroFacturacion.SistemaInformatico.TipoUsoPosibleMultiOT       := SiNoType.N;
    Factura.RegistroFacturacion.SistemaInformatico.NumeroOTAlta := '1';


    Factura.RegistroFacturacion.FechaGenRegistro := '';
    Factura.RegistroFacturacion.HoraGenRegistro  := '';
    Factura.RegistroFacturacion.HusoHorarioGenRegistro := HusoHorarioGenRegistroType._02; //L13 provisional
    Factura.RegistroFacturacion.NumRegistroAcuerdoFacturacion := '';
    Factura.RegistroFacturacion.IdAcuerdoSistemaInformatico   := '';


  DTFactura.DisposeOf;

  Showmessage('// Extraemos XML');

  var ARootNode,newNode : IXMLNode;
  var RefId,Swdsl : String;
  var XML : TXMLDocument;
  XML := TXMLDocument.Create(Fr_user);

  XML.Active := True;
  XML.Version:='1.0';
  XML.Encoding:='utf-8';


  ARootNode := XML.CreateNode('RegistroFacturacion');

  var MOPToSoapDomConvert : TOPtoSOAPDomConvert;
  MOPToSoapDomConvert := TOPtoSOAPDomConvert.Create(Fr_user);

  MOPToSoapDomConvert.Encoding := 'utf-8';

  MOPToSoapDomConvert.Options :=
  [TSOAPConvertOption.soSendMultiRefObj,
  TSOAPConvertOption.soTryAllSchema,
  TSOAPConvertOption.soRootRefNodesToBody,
  TSOAPConvertOption.soCacheMimeResponse,
  TSOAPConvertOption.soUTF8EncodeXML,
  TSOAPConvertOption.soSOAP12];

  try

   Swdsl := 'no puedo poner enlaces 2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SistemaFacturacion.wsdl';

   try
   newNode := Factura.RegistroFacturacion.ObjectToSOAP( ARootNode, ARootNode, MOPToSoapDomConvert, 'RegistroFacturacionType',
   Swdsl,'T',[ocoDontPrefixNode,ocoDontPutTypeAttr], RefId  ); //ocoDontPrefixNode

   XML.DocumentElement := ARootNode;
   XML.XML.SaveToFile('RegistroFacturacion.xml',TEncoding.UTF8);
   XML.Active := False;

   Except
   On E : Exception do
   Begin
    Showmessage(E.Message);
    XML.DocumentElement := ARootNode;
    XML.XML.SaveToFile('RegistroFacturacionError.xml',TEncoding.UTF8);
    XML.Active := False;
   End;

   end;

  finally
    XML.DisposeOf;
    MOPToSoapDomConvert.disposeOf;
    Factura.DisposeOf;

  end;


End;



function Trimestre(Dia:TDate):integer;
var mes,Trimestre : Integer;
begin

  Mes := monthof(dia);
  case mes of
  1 : Trimestre := 1;
  2 : Trimestre := 1;
  3 : Trimestre := 1;
  4 : Trimestre := 2;
  5 : Trimestre := 2;
  6 : Trimestre := 2;
  7 : Trimestre := 3;
  8 : Trimestre := 3;
  9 : Trimestre := 3;
  10: Trimestre := 4;
  11: Trimestre := 4;
  12: Trimestre := 4;
  end;


 result:= Trimestre;

end;

function TipoFacturaVerifactu(DTFactura : TGesAdoDataset) : ClaveTipoFacturaType;
var TipoVerifactu : ClaveTipoFacturaType;
var TablaMaestra : Integer;
Begin


  //F1  Factura (art. 6, 7.2 y 7.3 del RD 1619/2012)   // Factura ordinadia normal
  //F2  Factura Simplificada y Facturas sin identificación del destinatario art. 6.1.d) RD 1619/2012
  //F3  Factura emitida en sustitución de facturas simplificadas facturadas y declaradas // Canje i Recapitulativa?

  //R1  Factura Rectificativa (Error fundado en derecho y Art. 80 Uno Dos y Seis LIVA) // Resolucion Judicial
  //R2  Factura Rectificativa (Art. 80.3)   // Impago
  //R3  Factura Rectificativa (Art. 80.4)   // Impago
  //R4  Factura Rectificativa (Resto) // Lo normal , por error
  //R5  Factura Rectificativa en facturas simplificadas

  // A ver que de que tabla es la factura
  TablaMaestra :=
  f_devolver_valor_campo(0,DTFactura.Connection,'N','Tablas','Nombre','Codigo',DTFactura.TableName);

  // Ordinarias
  if TablaMaestra = 24 then
  Begin

    // Es rectificativa u Ordinaria
    if DTFactura.FieldByName('TipoRectificativo').AsInteger = 0 then
    TipoVerifactu := ClaveTipoFacturaType.F1
    else
    TipoVerifactu := ClaveTipoFacturaType.R4;

  End;

  // Simplificadas
  if TablaMaestra = 3 then
  Begin

    // SImplificada ordinaria
    if DTFactura.FieldByName('Tipo').AsInteger = 1 then
    TipoVerifactu := ClaveTipoFacturaType.F2;

    // Es rectificativa //R5  Factura Rectificativa en facturas simplificadas
    if DTFactura.FieldByName('Tipo').AsInteger = 6 then
    TipoVerifactu := ClaveTipoFacturaType.R5;

  End;



  //Factura de canje de simplificads y recapitulativas
  //F3  Factura emitida en sustitución de facturas simplificadas facturadas y declaradas // Canje i Recapitulativa?
  if (TablaMaestra = 252) or (TablaMaestra = 248) then
  Begin

    // Es rectificativa u Ordinaria
    if DTFactura.FieldByName('TipoRectificativo').AsInteger = 0 then
    TipoVerifactu := ClaveTipoFacturaType.F3
    else
    TipoVerifactu := ClaveTipoFacturaType.R4;

  End;




  Result := TipoVerifactu;

End;


function TipoRectificativaVerifactu(CorrectionMethod : String) : ClaveTipoRectificativaType;
var TipoVerifactu : ClaveTipoRectificativaType;
Begin

  //S  Por sustitución
  //I  Por diferencias

  // Si es rectificativa

    //Sustitucion
    if CorrectionMethod = '01' then TipoVerifactu := ClaveTipoRectificativaType.S;

    //Diferencias
    if CorrectionMethod = '02' then TipoVerifactu := ClaveTipoRectificativaType.I;


  Result := TipoVerifactu;

End;


procedure AgregarRelacionRectificadasPorDiferencias(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdFactura : String; Factura :FacturasEmitidasType);
var DTRectificadas : TGesAdoDataset;
var BaseRectificadas,IvaRectificadas,RecargoRectificadas : Currency;
var Orden : Integer;
var NombreTabla,NombreVista : String;
Begin

   //El fichero de lista de rectificadas por diferecnias
   DTRectificadas := f_crear_dataset(Conexion,DTRectificadas,'DTRectificadas','');

   try

   // Buscamos pro tabla
   NombreTabla := f_devolver_valor_campo(0,Conexion,'C','Tablas','Codigo','Nombre',TablaMaestra);
   NombreVista := 'Vista'+NombreTabla;

   DTRectificadas.Connection  :=  Conexion;
   DTRectificadas.TableName   := 'FacturasRectificadas';
   DTRectificadas.CommandText :=
   'Select * from '+NombreVista+' where Identificador in '+
   '(Select IdFacturaRectificada from FacturasRectificadas where (TablaFacturas = :TablaMaestra) and (IdFactura = :IdFactura)) ';

   f_valor_parametro_tabla(DTRectificadas,'TablaMaestra',TablaMaestra);
   f_valor_parametro_tabla(DTRectificadas,'IdFactura',IdFactura);

   f_open_adodataset(DTRectificadas,ltReadOnly);


   Orden := 0;
   BaseRectificadas    := 0;
   IvaRectificadas     := 0;
   RecargoRectificadas := 0;

   var ListaRectificadas : FacturasRectificadas := FacturasRectificadas.Create();
   while not DTRectificadas.Eof do
   Begin

    BaseRectificadas    := BaseRectificadas    + DTRectificadas.FieldByName('BASIMP').AsCurrency;
    IvaRectificadas     := IvaRectificadas     + DTRectificadas.FieldByName('BASIVA').AsCurrency;
    recargoRectificadas := RecargoRectificadas + DTRectificadas.FieldByName('BASREC').AsCurrency;

    // Añadimos la factura recitificada por diferencias
    var FacturaRectificada := IDFacturaARType.Create;
    FacturaRectificada.NumSerieFacturaEmisor        := DTRectificadas.FieldByName('ReferenciaDocumento').AsString;
    FacturaRectificada.FechaExpedicionFacturaEmisor := StringReplace(DTRectificadas.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',
 [rfReplaceAll, rfIgnoreCase]); // (dd-mm-yyyy)

    SetLength(ListaRectificadas, Orden+1);
    ListaRectificadas[Orden] := FacturaRectificada;

    Orden := Orden + 1;

    DTRectificadas.Next;
   End;
   f_close_adodataset(DTRectificadas);
   Factura.RegistroFacturacion.FacturasRectificadas := ListaRectificadas;

    // La Suma de las bases rectificads i/o sustituidas
    Factura.RegistroFacturacion.ImporteRectificacion := DesgloseRectificacionType.Create;
    Factura.RegistroFacturacion.ImporteRectificacion.BaseRectificada         := CurrToStr(BaseRectificadas);
    Factura.RegistroFacturacion.ImporteRectificacion.CuotaRectificada        := CurrToStr(IvaRectificadas);
    Factura.RegistroFacturacion.ImporteRectificacion.CuotaRecargoRectificado := CurrToStr(RecargoRectificadas);

  finally
   DTRectificadas.DisposeOf;
  end;

end;


procedure AgregarRelacionRectificadasPorSustitucion(Conexion : TAdoConnection ; TablaMaestra : Integer ; IdFactura : String; Factura :FacturasEmitidasType);
var DTRectificadas : TGesAdoDataset;
var BaseRectificadas,IvaRectificadas,RecargoRectificadas : Currency;
var Orden : Integer;
var NombreTabla,NombreVista : String;
Begin

  //El fichero de lista de rectificadas por Sustitucion
  DTRectificadas := f_crear_dataset(Conexion,DTRectificadas,'DTRectificadas','');

  try

   // Buscamos pro tabla
   NombreTabla := f_devolver_valor_campo(0,Conexion,'C','Tablas','Codigo','Nombre',TablaMaestra);
   NombreVista := 'Vista'+NombreTabla;


    //El fichero de lista de rectificadas por Sustitucion
    DTRectificadas.Connection  :=  Conexion;
    DTRectificadas.TableName   := 'FacturasRectificadas';
    DTRectificadas.CommandText :=
    'Select * from '+NombreVista+' where Identificador in '+
    '(Select IdFacturaRectificada from FacturasRectificadas where (TablaFacturas = :TablaMaestra) and (IdFactura = :IdFactura)) ';

    f_valor_parametro_tabla(DTRectificadas,'TablaMaestra',TablaMaestra);
    f_valor_parametro_tabla(DTRectificadas,'IdFactura',IdFactura);

    f_open_adodataset(DTRectificadas,ltReadOnly);


    // Cada factura Sustituida
    Orden := 0;
    BaseRectificadas    := 0;
    IvaRectificadas     := 0;
    RecargoRectificadas := 0;

    var ListaFacturasSustituidas : FacturasSustituidas := FacturasSustituidas.Create();
    while not DTRectificadas.Eof do
    Begin

     BaseRectificadas    := BaseRectificadas + DTRectificadas.FieldByName('BASIMP').AsCurrency;
     IvaRectificadas     := IvaRectificadas + DTRectificadas.FieldByName('BASIVA').AsCurrency;
     recargoRectificadas := RecargoRectificadas + DTRectificadas.FieldByName('BASREC').AsCurrency;

     // Añadimos la factura recitificada sustitutiva
     var FacturaSustitutiva := IDFacturaARType.Create;
     FacturaSustitutiva.NumSerieFacturaEmisor        := DTRectificadas.FieldByName('ReferenciaDocumento').AsString;
     FacturaSustitutiva.FechaExpedicionFacturaEmisor := StringReplace(DTRectificadas.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',
[rfReplaceAll, rfIgnoreCase]); // (dd-mm-yyyy)


     SetLength(ListaFacturasSustituidas, Orden+1);
     ListaFacturasSustituidas[Orden] := FacturaSustitutiva;


     Orden := Orden + 1;

     DTRectificadas.Next;

    End;
    f_close_adodataset(DTRectificadas);
    Factura.RegistroFacturacion.FacturasSustituidas := ListaFacturasSustituidas;

    // La Suma de las bases rectificads i/o sustituidas
    Factura.RegistroFacturacion.ImporteRectificacion := DesgloseRectificacionType.Create;
    Factura.RegistroFacturacion.ImporteRectificacion.BaseRectificada         := CurrToStr(BaseRectificadas);
    Factura.RegistroFacturacion.ImporteRectificacion.CuotaRectificada        := CurrToStr(IvaRectificadas);
    Factura.RegistroFacturacion.ImporteRectificacion.CuotaRecargoRectificado := CurrToStr(RecargoRectificadas);


  finally
   DTRectificadas.DisposeOf;
  end;



end;


function ClaveRegimenVerifactu(Conexion : TAdoConnection ; RegimenIva : Integer) : IdOperacionesTrascendenciaTributariaType;
var CodigoVerifactu : String;
var TypeRegimen : IdOperacionesTrascendenciaTributariaType;
Begin

  //'L8';

// 01  Operación de régimen general.
// 02  Exportación.
// 03  Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección.
// 04  Régimen especial del oro de inversión.
// 05  Régimen especial de las agencias de viajes.
// 06  Régimen especial grupo de entidades en IVA (Nivel Avanzado)
// 07  Régimen especial del criterio de caja.
// 08  Operaciones sujetas al IPSI  / IGIC (Impuesto sobre la Producción, los Servicios y la Importación  / Impuesto General Indirecto Canario).
// 09  Facturación de las prestaciones de servicios de agencias de viaje que actúan como mediadoras en nombre y por cuenta ajena (D.A.4ª RD1619/2012)
// 10  Cobros por cuenta de terceros de honorarios profesionales o de derechos derivados de la propiedad industrial, de autor u otros por cuenta de sus socios, 
// asociados o colegiados efectuados por sociedades, asociaciones, colegios profesionales u otras entidades que realicen estas funciones de cobro.
// 11  Operaciones de arrendamiento de local de negocio.
// 12  Factura con IVA pendiente de devengo en certificaciones de obra cuyo destinatario sea una Administración Pública.
// 13  Factura con IVA pendiente de devengo en operaciones de tracto sucesivo.
// 14  Régimen simplificado
// 15  Recargo de equivalencia.
// 16  Régimen especial de la agricultura


  // Falta ponde ren la carga inicial
  CodigoVerifactu := f_devolver_valor_campo(0,Conexion,'C','RegimenesIVA','Codigo','CodVerifactu',RegimenIva);


   Case IndexStr(CodigoVerifactu, ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16']) of
   0  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._01;
   1  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._02;
   2  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._03;
   3  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._04;
   4  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._05;
   5  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._06;
   6  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._07;
   7  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._08;
   8  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._09;
   9  : TypeRegimen := IdOperacionesTrascendenciaTributariaType._10;
   10 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._11;
   11 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._12;
   12 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._13;
   13 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._14;
   14 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._15;
   15 : TypeRegimen := IdOperacionesTrascendenciaTributariaType._16;
   else
   Begin
     TypeRegimen := IdOperacionesTrascendenciaTributariaType._01;
   End;
  end;

  Result := TypeRegimen;


End;


function TipoCalificacionOperacion : CalificacionOperacionType;
Begin

// L9

// S1  Operación Sujeta y No exenta - Sin inversión del sujeto pasivo.
// S2  Operación Sujeta y No exenta - Con Inversión del sujeto pasivo
// N1  Operación No Sujeta artículo 7, 14, otros.
// N2  Operación No Sujeta por Reglas de localización.

  Result := CalificacionOperacionType.S1;

End;


function TipoOperacionExenta : OperacionExentaType;
Begin

  //L10 - solo si exenta de IVA

// E0  Exenta sin especificar causa
// E1  Exenta por el artículo 20
// E2  Exenta por el artículo 21
// E3  Exenta por el artículo 22
// E4  Exenta por los artículos 23 y 24
// E5  Exenta por el artículo 25
// E6  Exenta por otros

  result := OperacionExentaType.E0;

End;


end.


Luego el código en bruto para recogerlo:

Código Delphi [-]
  XMLDocument1.XML.LoadFromFile('RegistroFacturacion.xml');
  XMLDocument1.Active := True;

  var fact2:FacturasEmitidasType;
  fact2 := FacturasEmitidasType.Create;
  fact2.RegistroFacturacion := RegistroFacturacionType.Create;

  ARootNode := XMLDocument1.DocumentElement;

  var MySOAPDomConv: TSOAPDomConv;
  MySOAPDomConv:= TSOAPDomConv.Create(Self);

  fact2.RegistroFacturacion.SOAPToObject(ARootNode.ChildNodes[0] , ARootNode.ChildNodes[0] , MySOAPDomConv);

  Showmessage('2 '+
  fact2.RegistroFacturacion.DescripcionOperacion+' '+
  fact2.RegistroFacturacion.IDFactura.NumSerieFacturaEmisor);



  fact2.DisposeOf;
  fact2.RegistroFacturacion.DisposeOf;
Responder Con Cita