unit UVerifactu;
interface
Uses
System.SysUtils,
Xml.xmldom,
Xml.XMLIntf,
Xml.XMLDoc,
Data.Win.ADODB,
System.DateUtils,
Vcl.Dialogs,
Udatam, System.hash,
System.StrUtils,
GesAdoDataset, 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;
function GenerarHashRegistroVerifactu(CadenaVerifactu : String) : String;
Begin
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
NombreTabla := f_devolver_valor_campo(0,Conexion,'C','Tablas','Codigo','Nombre',TablaMaestra);
NombreVista := 'Vista'+NombreTabla;
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;
var Factura :FacturasEmitidasType;
Factura := FacturasEmitidasType.Create;
Factura.RegistroFacturacion := RegistroFacturacionType.Create;
Factura.DatosControl := DatosControlType.Create;
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]);
Factura.RegistroFacturacion.NombreRazonEmisor := Datam.TBEmpresa.FieldByName('C_EMPRESA').AsString;
Factura.RegistroFacturacion.TipoRegistroSIF := TipoRegistroSIFType.S0; Factura.RegistroFacturacion.TipoFactura := TipoFacturaVerifactu(DTFactura);
if Length(Trim(DTFactura.FieldByName('CorrectionMethod1').AsString)) > 0 then
Factura.RegistroFacturacion.TipoRectificativa := TipoRectificativaVerifactu(DTFactura.FieldByName('CorrectionMethod1').AsString);
if Factura.RegistroFacturacion.TipoRectificativa = ClaveTipoRectificativaType.I then
Begin
AgregarRelacionRectificadasPorDiferencias(DTFactura.Connection,TablaMaestra,IdFactura,Factura);
End;
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]); Factura.RegistroFacturacion.DescripcionOperacion := 'Venta';
Factura.RegistroFacturacion.FacturaSimplificadaArticulos7_2_7_3 := SimplificadaCualificadaType.N; Factura.RegistroFacturacion.FacturaSinIdentifDestinatarioArticulo6_1_d := CompletaSinDestinatarioType.N; Factura.RegistroFacturacion.Macrodato := MacrodatoType.N;
var Destinatario := PersonaFisicaJuridicaType.Create;
Destinatario.NombreRazon := DTFactura.FieldByName('NOMB').AsString;
Destinatario.NIF := DTFactura.FieldByName('NIF').AsString;
Destinatario.IDOtro := IDOtroType.Create;
Destinatario.IDOtro.IdType := PersonaFisicaJuridicaIDTypeType._02;
Destinatario.IDOtro.ID := DTFactura.FieldByName('NIF').AsString;
var ListaDestinatarios : Destinatarios := Destinatarios.Create();
SetLength(ListaDestinatarios, 1);
ListaDestinatarios[0] := Destinatario;
Factura.RegistroFacturacion.Destinatarios := ListaDestinatarios;
Factura.RegistroFacturacion.Cupon := CuponType.N;
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);
DetalleDesglose.CalificacionOperacion := TipoCalificacionOperacion;
if (DetalleDesglose.CalificacionOperacion = CalificacionOperacionType.N1)
or (DetalleDesglose.CalificacionOperacion = CalificacionOperacionType.N2) then
DetalleDesglose.OperacionExenta := TipoOperacionExenta;
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;
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);
Factura.RegistroFacturacion.EncadenamientoRegistroAnterior := EncadenamientoFacturaAnteriorType.Create;
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.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; 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 );
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
TablaMaestra :=
f_devolver_valor_campo(0,DTFactura.Connection,'N','Tablas','Nombre','Codigo',DTFactura.TableName);
if TablaMaestra = 24 then
Begin
if DTFactura.FieldByName('TipoRectificativo').AsInteger = 0 then
TipoVerifactu := ClaveTipoFacturaType.F1
else
TipoVerifactu := ClaveTipoFacturaType.R4;
End;
if TablaMaestra = 3 then
Begin
if DTFactura.FieldByName('Tipo').AsInteger = 1 then
TipoVerifactu := ClaveTipoFacturaType.F2;
if DTFactura.FieldByName('Tipo').AsInteger = 6 then
TipoVerifactu := ClaveTipoFacturaType.R5;
End;
if (TablaMaestra = 252) or (TablaMaestra = 248) then
Begin
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
if CorrectionMethod = '01' then TipoVerifactu := ClaveTipoRectificativaType.S;
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
DTRectificadas := f_crear_dataset(Conexion,DTRectificadas,'DTRectificadas','');
try
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;
var FacturaRectificada := IDFacturaARType.Create;
FacturaRectificada.NumSerieFacturaEmisor := DTRectificadas.FieldByName('ReferenciaDocumento').AsString;
FacturaRectificada.FechaExpedicionFacturaEmisor := StringReplace(DTRectificadas.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',
[rfReplaceAll, rfIgnoreCase]);
SetLength(ListaRectificadas, Orden+1);
ListaRectificadas[Orden] := FacturaRectificada;
Orden := Orden + 1;
DTRectificadas.Next;
End;
f_close_adodataset(DTRectificadas);
Factura.RegistroFacturacion.FacturasRectificadas := ListaRectificadas;
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
DTRectificadas := f_crear_dataset(Conexion,DTRectificadas,'DTRectificadas','');
try
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 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;
var FacturaSustitutiva := IDFacturaARType.Create;
FacturaSustitutiva.NumSerieFacturaEmisor := DTRectificadas.FieldByName('ReferenciaDocumento').AsString;
FacturaSustitutiva.FechaExpedicionFacturaEmisor := StringReplace(DTRectificadas.FieldByName('FECH').AsString,FormatSettings.DateSeparator,'-',
[rfReplaceAll, rfIgnoreCase]);
SetLength(ListaFacturasSustituidas, Orden+1);
ListaFacturasSustituidas[Orden] := FacturaSustitutiva;
Orden := Orden + 1;
DTRectificadas.Next;
End;
f_close_adodataset(DTRectificadas);
Factura.RegistroFacturacion.FacturasSustituidas := ListaFacturasSustituidas;
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
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
Result := CalificacionOperacionType.S1;
End;
function TipoOperacionExenta : OperacionExentaType;
Begin
result := OperacionExentaType.E0;
End;
end.