Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Envío de registros y sus respuestas (https://www.clubdelphi.com/foros/forumdisplay.php?f=66)
-   -   ¿que hacer si se cae veri*factu? (https://www.clubdelphi.com/foros/showthread.php?t=97530)

victor03 16-06-2025 14:48:26

¿que hacer si se cae veri*factu?
 
Pues eso, esta el error '4134 = Servicio no activo.'

a mi me suena que este tema ya salió en el foro pero como no lo encuentro vuelvo a preguntar ¿que hacer si se cae ver*factu?
En mi programa no tengo implementado NoVerifactu así que según se generan las facturas se van enviando a la aeAt pero aquí esta el caso de que el servidor de la AEAt se caiga y otro caso que se podría dar es que se me caiga internet.


en estos casos ¿Qué debo hacer?, en mi programa la factura ya estaría creada en la BD pero asta que no recibo una respuesta de veri*factu esa factura no se puede ni imprimir, ni enviar ni añadir vencimientos etc.

gcqZW 16-06-2025 14:49:43

Acumulas facturas hasta que puedas enviarlas, y las envías en bloque marcando incidencia a "S".

victor03 16-06-2025 14:57:54

Cita:

Empezado por gcqZW (Mensaje 565548)
Acumulas facturas hasta que puedas enviarlas, y las envías en bloque marcando incidencia a "S".

y en el caso de las tiendas que tienen que entregar una factura al momento, en esos casos no se pueden permitir parar por ese tipo de error

gcqZW 16-06-2025 15:00:26

Paras los envíos, no tienes por que dejar de imprimir las facturas/tickets

duilioisola 16-06-2025 17:30:42

La emisión de facturas y el reporte del registro verifactu a Hacienda son dos cosas distintas.
Deberían ser hechos de forma inmediata pero si hay inconvenientes puedes seguir si remitir la información a Hacienda.

Si cae Hacienda o Internet o alguna otra cosa, podrás seguir vendiendo y emitiendo facturas.
El QR que se imprime no indica datos de encadenamiento.

Neftali [Germán.Estévez] 17-06-2025 08:30:53

Cita:

Empezado por victor03 (Mensaje 565549)
y en el caso de las tiendas que tienen que entregar una factura al momento, en esos casos no se pueden permitir parar por ese tipo de error

Si tu sistema no puede generar e imprimir facturas sin enviarlas, es que tienes el flujo mal diseñado.
Como han dicho otros compañeros, el sistema está pensado (y así lo ha especificado la AEAT desde el principio) para que tu programa de facturación no tenga que detenerse, aunque pierdas la conexión a internet (error desde tu lado) o los servidores de la AEAT se caigan (error desde su lado).

CarlosArjonomia 17-06-2025 08:46:05

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 565560)
Si tu sistema no puede generar e imprimir facturas sin enviarlas, es que tienes el flujo mal diseñado.
Como han dicho otros compañeros, el sistema está pensado (y así lo ha especificado la AEAT desde el principio) para que tu programa de facturación no tenga que detenerse, aunque pierdas la conexión a internet (error desde tu lado) o los servidores de la AEAT se caigan (error desde su lado).

Ya, pero no solo es verifactu, hay comprobación de horas y fecha antes de la generación del RF, así como comprobaciones de NIF/CIF etc. Sin conexión a internet y sin estas validaciones te la pueden liar parda.

duilioisola 17-06-2025 09:39:06

La comprobación de hora se hace durante el envío y si no has podido enviarla a tiempo solo debes marcar "Incidencia".
La comprobación de NIF básica la puedes hacer tu mismo.
Si por alguna razón, el NIF estuviera dado de baja en Hacienda, podrás hacer una corrección cuando rechacen o acepten con errores la factura.

Hay ejemplos de código para verificar esto.
Yo lo hago en la base de datos al insertar el dato.

Te dejo como ejemplo el código que utilizo para documentos españoles.
Código SQL [-]
create or alter procedure verifica_documento_esp_nif (
    numero_documento varchar(20))
returns (
    valido smallint,
    mensaje_error varchar(100))
AS
declare variable digito_verificador varchar(1);
declare variable digito_documento varchar(1);
declare variable aux varchar(20);
declare variable letra_principio varchar(1);
declare variable letra_final varchar(1);
declare variable numero varchar(20);
declare variable contador integer;
declare variable fin_contador integer;
declare variable sumatoria integer;
declare variable resto integer;
begin
    /*
    Verificacion de CIF, NIF, DNI, NIE.
    Se verifica que el numero de documento cumpla la condicion ESCnnnnnnnC o CnnnnnnC
    (n son numeros y C es el digito de control).
    */

    -- Inicializamos variables
    valido = 1;
    mensaje_error = '';

    if (char_length(numero_documento) > 0) then
    begin
        -- Limpieza de documento (solo letras y numeros)
        numero_documento = upper(numero_documento);
        contador = 1;
        aux = '';
        while (contador <= char_length(numero_documento)) do
        begin
            digito_documento = substring(numero_documento from contador for 1);
            if ((digito_documento between 'A' and 'Z') or
                ((digito_documento between '0' and '9'))) then
                aux = aux || digito_documento;

            contador = contador + 1;
        end
        numero_documento = aux;

        if (char_length(numero_documento) > 0) then
        begin
            if (substring(numero_documento from 1 for 2) = 'ES') then
                numero_documento = substring(numero_documento from 3 for char_length(numero_documento));

            letra_principio = substring(numero_documento from 1 for 1);
            letra_final = substring(numero_documento from char_length(numero_documento) for 1);
            if (letra_principio between '0' and '9') then
                letra_principio = '';
            if (letra_final between '0' and '9') then
                letra_final = '';

            if (letra_principio = '') then
                contador = 1;
            else
                contador = 2;

            if (letra_final = '') then
                fin_contador = char_length(numero_documento);
            else
                fin_contador = char_length(numero_documento) - 1;

            numero = '';
            while (contador <= fin_contador) do
            begin
                digito_documento = substring(numero_documento from contador for 1);
                if (digito_documento between '0' and '9') then
                    numero = numero || digito_documento;
                else
                begin
                    valido = 0;
                    mensaje_error = '(1) El formato del numero es incorrecto';
                end

                contador = contador + 1;
            end

            if ((valido = 1) and
                (char_length(numero_documento) = 9)) then
            begin
                if ((letra_principio = '') or
                    ((letra_principio in ('X', 'Y', 'Z')))) then
                begin
                    -- Es un NIE. (Numero de identificacion de extranjero)
                    if (letra_principio = 'X') then
                        numero = '0' || numero;
                    if (letra_principio = 'Y') then
                        numero = '1' || numero;
                    if (letra_principio = 'Z') then
                        numero = '2' || numero;

                    resto = numero - (trunc(numero / 23) * 23);
                    digito_verificador = substring('TRWAGMYFPDXBNJZSQVHLCKET' from 1 + resto for 1);

                    if (digito_verificador <> letra_final) then
                    begin
                        valido = 0;
                        mensaje_error = '(3) NIE no valido' || ' - ' || digito_verificador || '<>' || letra_final;
                    end
                end
                else
                if (letra_principio in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
                                        'L', 'M', 'N', 'P', 'Q', 'S', 'U', 'V', 'W', 'R')) then
                begin
                    -- Es un NIF (Numero de identificacion fiscal
                    if (letra_final > '') then
                    begin
                        if (letra_final in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J')) then
                            -- Convierte la letra final en un numero (es el dig. control)
                            letra_final = substring('0123456789' from position(letra_final, 'JABCDEFGHI') for 1);
                        else
                        begin
                            valido = 0;
                            mensaje_error = '(4) NIF no valido';
                        end
                    end
                    else
                    begin
                        letra_final = substring(numero_documento from char_length(numero_documento) for 1);
                        numero_documento = substring(numero_documento from 1 for char_length(numero_documento) - 1);
                    end
                    if (valido = 1) then
                    begin
                        -- Sumamos posiciones pares
                        sumatoria = substring(numero_documento from 3 for 1) + substring(numero_documento from 5 for 1) + substring(numero_documento from 7 for 1);

                        contador = substring(numero_documento from 2 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 4 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 6 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 8 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        if (sumatoria > 9) then
                            sumatoria = substring(sumatoria from 2 for 1);

                        sumatoria = 10 - sumatoria;

                        if (sumatoria = 10) then
                            sumatoria = 0;

                        if (sumatoria <> letra_final) then
                        begin
                            valido = 0;
                            mensaje_error = '(5) NIF no valido';
                        end
                    end
                end
                else
                begin
                    valido = 0;
                    mensaje_error = '(6) Letra inicial invalida';
                end
            end
            else
            begin
                valido = 0;
                mensaje_error = '(2) Longitud incorrecta';
            end
        end
    end

    suspend;
end

novatico 17-06-2025 10:02:02

Cita:

Empezado por duilioisola (Mensaje 565562)
La comprobación de hora se hace durante el envío y si no has podido enviarla a tiempo solo debes marcar "Incidencia".
La comprobación de NIF básica la puedes hacer tu mismo.
Si por alguna razón, el NIF estuviera dado de baja en Hacienda, podrás hacer una corrección cuando rechacen o acepten con errores la factura.

Hay ejemplos de código para verificar esto.
Yo lo hago en la base de datos al insertar el dato.

Te dejo como ejemplo el código que utilizo para documentos españoles.
Código SQL [-]
create or alter procedure verifica_documento_esp_nif (
    numero_documento varchar(20))
returns (
    valido smallint,
    mensaje_error varchar(100))
AS
declare variable digito_verificador varchar(1);
declare variable digito_documento varchar(1);
declare variable aux varchar(20);
declare variable letra_principio varchar(1);
declare variable letra_final varchar(1);
declare variable numero varchar(20);
declare variable contador integer;
declare variable fin_contador integer;
declare variable sumatoria integer;
declare variable resto integer;
begin
    /*
    Verificacion de CIF, NIF, DNI, NIE.
    Se verifica que el numero de documento cumpla la condicion ESCnnnnnnnC o CnnnnnnC
    (n son numeros y C es el digito de control).
    */

    -- Inicializamos variables
    valido = 1;
    mensaje_error = '';

    if (char_length(numero_documento) > 0) then
    begin
        -- Limpieza de documento (solo letras y numeros)
        numero_documento = upper(numero_documento);
        contador = 1;
        aux = '';
        while (contador <= char_length(numero_documento)) do
        begin
            digito_documento = substring(numero_documento from contador for 1);
            if ((digito_documento between 'A' and 'Z') or
                ((digito_documento between '0' and '9'))) then
                aux = aux || digito_documento;

            contador = contador + 1;
        end
        numero_documento = aux;

        if (char_length(numero_documento) > 0) then
        begin
            if (substring(numero_documento from 1 for 2) = 'ES') then
                numero_documento = substring(numero_documento from 3 for char_length(numero_documento));

            letra_principio = substring(numero_documento from 1 for 1);
            letra_final = substring(numero_documento from char_length(numero_documento) for 1);
            if (letra_principio between '0' and '9') then
                letra_principio = '';
            if (letra_final between '0' and '9') then
                letra_final = '';

            if (letra_principio = '') then
                contador = 1;
            else
                contador = 2;

            if (letra_final = '') then
                fin_contador = char_length(numero_documento);
            else
                fin_contador = char_length(numero_documento) - 1;

            numero = '';
            while (contador <= fin_contador) do
            begin
                digito_documento = substring(numero_documento from contador for 1);
                if (digito_documento between '0' and '9') then
                    numero = numero || digito_documento;
                else
                begin
                    valido = 0;
                    mensaje_error = '(1) El formato del numero es incorrecto';
                end

                contador = contador + 1;
            end

            if ((valido = 1) and
                (char_length(numero_documento) = 9)) then
            begin
                if ((letra_principio = '') or
                    ((letra_principio in ('X', 'Y', 'Z')))) then
                begin
                    -- Es un NIE. (Numero de identificacion de extranjero)
                    if (letra_principio = 'X') then
                        numero = '0' || numero;
                    if (letra_principio = 'Y') then
                        numero = '1' || numero;
                    if (letra_principio = 'Z') then
                        numero = '2' || numero;

                    resto = numero - (trunc(numero / 23) * 23);
                    digito_verificador = substring('TRWAGMYFPDXBNJZSQVHLCKET' from 1 + resto for 1);

                    if (digito_verificador <> letra_final) then
                    begin
                        valido = 0;
                        mensaje_error = '(3) NIE no valido' || ' - ' || digito_verificador || '<>' || letra_final;
                    end
                end
                else
                if (letra_principio in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
                                        'L', 'M', 'N', 'P', 'Q', 'S', 'U', 'V', 'W', 'R')) then
                begin
                    -- Es un NIF (Numero de identificacion fiscal
                    if (letra_final > '') then
                    begin
                        if (letra_final in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J')) then
                            -- Convierte la letra final en un numero (es el dig. control)
                            letra_final = substring('0123456789' from position(letra_final, 'JABCDEFGHI') for 1);
                        else
                        begin
                            valido = 0;
                            mensaje_error = '(4) NIF no valido';
                        end
                    end
                    else
                    begin
                        letra_final = substring(numero_documento from char_length(numero_documento) for 1);
                        numero_documento = substring(numero_documento from 1 for char_length(numero_documento) - 1);
                    end
                    if (valido = 1) then
                    begin
                        -- Sumamos posiciones pares
                        sumatoria = substring(numero_documento from 3 for 1) + substring(numero_documento from 5 for 1) + substring(numero_documento from 7 for 1);

                        contador = substring(numero_documento from 2 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 4 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 6 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        contador = substring(numero_documento from 8 for 1) * 2;
                        if (contador > 9) then
                            contador = substring(contador from 1 for 1) + substring(contador from 2 for 1);
                        sumatoria = sumatoria + contador;

                        if (sumatoria > 9) then
                            sumatoria = substring(sumatoria from 2 for 1);

                        sumatoria = 10 - sumatoria;

                        if (sumatoria = 10) then
                            sumatoria = 0;

                        if (sumatoria <> letra_final) then
                        begin
                            valido = 0;
                            mensaje_error = '(5) NIF no valido';
                        end
                    end
                end
                else
                begin
                    valido = 0;
                    mensaje_error = '(6) Letra inicial invalida';
                end
            end
            else
            begin
                valido = 0;
                mensaje_error = '(2) Longitud incorrecta';
            end
        end
    end

    suspend;
end


Sólo hay una cosa con la que no estoy de acuerdo, donde dices: "La comprobación de hora se hace durante el envío".

Realmente, cuando generas el Registro de Facturación, que ha de ser obligatoriamente en el mismo momento de generar la factura, uno de los datos que has de grabar es la FechaHoraHusoGenRegistro, y lo ideal es tomarla de Internet, porque si la tomas del ordenador, el usuario podría cambiarla. De hecho yo tengo clientes que lo hacen habitualmente.

Neftali [Germán.Estévez] 17-06-2025 12:50:52

Cita:

Empezado por CarlosArjonomia (Mensaje 565561)
Ya, pero no solo es verifactu, hay comprobación de horas y fecha antes de la generación del RF, así como comprobaciones de NIF/CIF etc. Sin conexión a internet y sin estas validaciones te la pueden liar parda.

Pero eso ya es un tema no relacionado con veri*factu.
Esos temas ya te los debes plantear tú, si quieres/puedes hacer que sin internet tu sistema funcione o no.


La franja horaria es GMT +2. Ahora son las 06:45:15.

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