Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Registros de Facturacion y Eventos (XML) (https://www.clubdelphi.com/foros/forumdisplay.php?f=67)
-   -   Clase para generar huella en Delphi 12 (https://www.clubdelphi.com/foros/showthread.php?t=97602)

Neftali [Germán.Estévez] 24-07-2025 08:37:39

Clase para generar huella en Delphi 12
 
Buenas, os comparto una clase para la generación de la huella en Delphi 12, teniendo en cuenta facturas F1 y de anulación, y si estamos en la península o en canarias.
Este código es autoría de [Eduardo Infante]. Me ha comentado que lo publicara en el club si lo veía útil.

Código Delphi [-]
unit uGenerarHuellaVerifactu;

interface

uses
    System.SysUtils, System.DateUtils, System.Hash;

type
    TTipoVerifactu = (tpAlta, tpAnulacion);

    TGenerarHuellaVerifactu = class
    public
        function GenerarHuellaVerifactu(const Tipo: TTipoVerifactu; const IDEmisor, NumSerie: string; 
                         const FechaExpedicion, FechaHora: TDateTime; const HuellaAnterior: string; const EsCanarias: Boolean; 
                         const TipoFactura: string = ''; const CuotaTotal: Double = 0.0; const ImporteTotal: Double = 0.0): string;
    end;

implementation

function TGenerarHuellaVerifactu.GenerarHuellaVerifactu(const Tipo: TTipoVerifactu; const IDEmisor, NumSerie: string; 
                         const FechaExpedicion, FechaHora: TDateTime; const HuellaAnterior: string; const EsCanarias: Boolean; 
                         const TipoFactura: string; const CuotaTotal: Double; const ImporteTotal: Double): string;
var
    InputStr: string;

    function FloatStr(Value: Double): string;
    var
        FS: TFormatSettings;
    begin
        FS := TFormatSettings.Create;
        FS.DecimalSeparator := '.';
        Result := FloatToStr(Value, FS);
    end;

    function FechaStr(const Fecha: TDateTime): string;
    begin
        Result := FormatDateTime('dd-mm-yyyy', Fecha);
    end;

    function FechaHoraStr(const FechaHora: TDateTime): string;
    var
        LocalHora: TDateTime;
        OffsetStr: string;
    begin
        if EsCanarias then begin
            LocalHora := FechaHora;
            OffsetStr := '+00:00';
        end
        else begin
            LocalHora := FechaHora + OneHour;
            OffsetStr := '+01:00';
        end;
        Result := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss', LocalHora) + OffsetStr;
    end;

begin
    case Tipo of
        tpAlta:
            InputStr := 'IDEmisorFactura=' + Trim(IDEmisor) + '&' + 'NumSerieFactura=' + Trim(NumSerie) + '&' + 'FechaExpedicionFactura=' + 
                             FechaStr(FechaExpedicion) + '&' + 'TipoFactura=' + Trim(TipoFactura) + '&' + 'CuotaTotal=' + FloatStr(CuotaTotal) + '&' + 
                              'ImporteTotal=' + FloatStr(ImporteTotal) + '&' + 'Huella=' + Trim(HuellaAnterior) + '&' + 'FechaHoraHusoGenRegistro=' + 
                             FechaHoraStr(FechaHora);
        tpAnulacion:
            InputStr := 'IDEmisorFacturaAnulada=' + Trim(IDEmisor) + '&' + 'NumSerieFacturaAnulada=' + Trim(NumSerie) + '&' + 
                             'FechaExpedicionFacturaAnulada=' + FechaStr(FechaExpedicion) + '&' + 'Huella=' + Trim(HuellaAnterior) + '&' + 
                             'FechaHoraHusoGenRegistro=' + FechaHoraStr(FechaHora);
    else
        raise Exception.Create('Tipo de operación no soportado');
    end;

    Result := UpperCase(THashSHA2.GetHashString(InputStr, THashSHA2.TSHA2Version.SHA256));
end;

end.

Neftali [Germán.Estévez] 24-07-2025 08:40:05

Y sobre el pdf publicado de verifactu del calculo de huella, un ejemplo con los mismos datos para comprobar que la información sale correcta.

Código Delphi [-]
{$APPTYPE CONSOLE}

uses
    System.SysUtils,
    System.DateUtils,
    uGenerarHuellaVerifactu in 'F:\AutofirmaCLI\uGenerarHuellaVerifactu.pas';

var
    Generador: TGenerarHuellaVerifactu;
    h1, h2, h3: string;
    f1, f2, f3: TDateTime;
    FechaExpedicion: TDateTime;

begin
    try
        Generador := TGenerarHuellaVerifactu.Create;
        try
            FechaExpedicion := EncodeDate(2024, 1, 1);  //01-01-2024

            // === Caso 1: primer registro de alta (sin huella anterior) ===
            f1 := EncodeDateTime(2024, 1, 1, 18, 20, 30, 0);  //2024-01-01T19:20:30+01:00
            h1 := Generador.GenerarHuellaVerifactu(tpAlta, '89890001K', '12345678/G33', FechaExpedicion, f1, '', // Huella anterior vacía
                    False, // Península
                    'F1', // TipoFactura
                    12.35, 123.45);
            Writeln('Huella 1:');
            Writeln(h1);
            Writeln;

            // === Caso 2: segundo registro de alta (con huella anterior) ===
            f2 := EncodeDateTime(2024, 1, 1, 18, 20, 35, 0);   //01-01-2024
            h2 := Generador.GenerarHuellaVerifactu(tpAlta, '89890001K', '12345679/G34', FechaExpedicion, f2, h1, // Huella del registro anterior
                    False, // Península
                    'F1', // TipoFactura
                    12.35, 123.45);
            Writeln('Huella 2:');
            Writeln(h2);
            Writeln;

            // === Caso 3: anulación (sin campos financieros) ===
            f3 := EncodeDateTime(2024, 1, 1, 18, 20, 40, 0);
            h3 := Generador.GenerarHuellaVerifactu(tpAnulacion, '89890001K', '12345679/G34', FechaExpedicion, f3, h2, // Huella del registro anterior
                    False // península
                    // No se pasan TipoFactura, CuotaTotal ni ImporteTotal
                    );
            Writeln('Huella 3:');
            Writeln(h3);
            Writeln;

            Readln;
        finally
            Generador.Free;
        end;
    except
        on E: Exception do
            Writeln('Error: ', E.Message);
    end;

end.

Espero que sea útil.

Neftali [Germán.Estévez] 24-07-2025 08:46:54

Actualizo el mensaje#2 recopilatorio de códigos útiles.

ElKurgan 25-07-2025 19:11:02

Muchas gracias por el aporte

^\||/^\||/^\||/


La franja horaria es GMT +2. Ahora son las 16:23:01.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi