Procedimiento de Revisión Quincenal de Comprobantes Electrónicos

Periodo evaluado: últimos 15 días (prior 15 days)


1. Objetivo

Establecer un procedimiento detallado y sistemático para la revisión quincenal de comprobantes electrónicos emitidos desde el sistema POS, con el fin de identificar incongruencias entre:

La revisión permite detectar errores operativos, inconsistencias de estado, problemas de emisión, cancelación y facturación, y dejar trazabilidad clara para su posterior corrección.


2. Alcance

Este procedimiento aplica a:

⚠️ Este procedimiento es de revisión y validación.
Las correcciones pueden requerir acciones manuales y/o aprobación del cliente.


3. Responsabilidad


4. Fuentes de Información


5. Procedimiento General de Revisión

La revisión se realiza siguiendo los pasos descritos a continuación, en el orden indicado.


6. Revisión de Comprobantes No Enviados al PSE (Waiting)

Descripción

Corresponde a comprobantes que no llegaron a enviarse al PSE, generalmente por:

Obtención de la información

Query de referencia:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SET @DATE_CHECK := '2026-01-01 05:00:00';

-- PENDING BILLS
select o.name,
       s.name,
       eb.order_uuid,
       eb.uuid,
       eb.type,
       eb.series,
       eb.number,
       eb.date_of_issue,
       eb.link          as LINK,
       eb.latest_status AS ESTADO,
       eb.retry_count,
       SUBSTRING_INDEX(eb.errors, '\n', -2),
       payload,
       eb.organization_uuid,
       eb.created_at,
       eb.updated_at
from electronic_bills eb
         left join stores s on eb.venue_uuid = s.uuid
         left join organizations o on eb.organization_uuid = o.uuid
where eb.created_at >= @DATE_CHECK
  AND (eb.latest_status = 'waiting'  || eb.latest_status = 'pending' )
  AND eb.deleted_at IS NULL
AND s.uses_system = 1
order by eb.updated_at;


-- INVALID
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SET @DATE_CHECK := '2026-01-01 05:00:00';

-- NON VALID VOUCHERS
CREATE TEMPORARY TABLE IF NOT EXISTS NonValidVouchers AS (select eb.uuid,
                                                                 eb.type,
                                                                 eb.series,
                                                                 eb.number,
                                                                 eb.link,
                                                                 eb.date_of_issue,
                                                                 eb.latest_status,
                                                                 eb.order_uuid,
                                                                 eb.retry_count,
                                                                 eb.errors,
                                                                 eb.payload,
                                                                 eb.created_at,
                                                                 eb.updated_at,
                                                                 eb.deleted_at,
                                                                 eb.venue_uuid
                                                          from electronic_bills eb
                                                          where (link = 'https://idbiperu.pse.pe' or link = '')
                                                            and eb.created_at >= @DATE_CHECK and eb.deleted_at is null);

-- NON VALID VOUCHERS
SELECT o.name as organization, s.name as store, JSON_EXTRACT(eb.payload, "$.total") as total,  eb.*
FROM NonValidVouchers eb
         LEFT JOIN stores s ON eb.venue_uuid = s.uuid AND s.uses_system = 1
         LEFT JOIN organizations o ON s.owner_uuid = o.uuid
WHERE s.uuid IS NOT NULL
ORDER BY eb.updated_at;

DROP TEMPORARY TABLE NonValidVouchers;

Acción


7. Revisión de Comprobantes Pendientes de Cancelación

Descripción

Comprobantes que deberían estar cancelados pero no cuentan con ticket de cancelación registrado en el sistema.

Obtención de la información

Query de referencia:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    SET @DATE_CHECK := '2025-10-01 05:00:00';

    -- PENDING CANCELED BILLS
    select o.name,
           s.name,
           eb.uuid,
           eb.series,
           eb.number,
           eb.link          as LINK,
           eb.latest_status AS ESTADO,
           eb.cancel_ticket AS TICKET,
           eb.created_at,
           eb.updated_at
    from electronic_bills eb FORCE INDEX (idx_electronic_bills_created_status_cancel_deleted)
             left join stores s on eb.venue_uuid = s.uuid
             left join organizations o on eb.organization_uuid = o.uuid and o.enabled = 1
    where eb.created_at BETWEEN @DATE_CHECK AND DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 1 DAY), INTERVAL 5 HOUR)
      AND eb.latest_status = 'canceled'
      AND eb.cancel_ticket IS NULL
      AND eb.deleted_at IS NULL
      AND s.uses_system = 1
    and o.name IS NOT NULL
    order by eb.updated_at;

Casos posibles

  1. El comprobante fue emitido pero la cancelación no se completó.
  2. El comprobante no fue enviado aún, por lo que:
    • Debe emitirse primero.
    • Luego proceder con la cancelación.

Acción


8. Revisión de Saltos de Correlativo

Descripción

Casos donde se detectan saltos o discontinuidades en el correlativo de comprobantes.

Obtención de la información

Query de referencia:

-ET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SET @DATE_CHECK := '2026-01-01 05:00:00';

-- MISSING
WITH NumberedDocuments AS (SELECT created_at                                                              as Fecha,
                                  venue_uuid                                                              as Venue,
                                  organization_uuid                                                       as Organization,
                                  type                                                                    as TipoDocumento,
                                  series                                                                  as GroupPrefix,
                                  number                                                                  as DocumentNumberPart,
                                  LAG(number)
                                      OVER (PARTITION BY organization_uuid, type, series ORDER BY number) as PreviousDocumentNumberPart
                           FROM electronic_bills
                           WHERE created_at > @DATE_CHECK and deleted_at is null),
     MissingDocuments AS (SELECT Fecha,
                                 Venue,
                                 Organization,
                                 TipoDocumento,
                                 GroupPrefix,
                                 PreviousDocumentNumberPart + 1 as MissingFrom,
                                 DocumentNumberPart - 1         as MissingTo
                          FROM NumberedDocuments
                          WHERE PreviousDocumentNumberPart IS NOT NULL
                            AND DocumentNumberPart - PreviousDocumentNumberPart > 1)
SELECT o.uuid,
       o.name                      as Name,
       v.uuid                      AS VID,
       v.name                      as Venue,
       Fecha,
       TipoDocumento,
       GroupPrefix,
       MissingFrom,
       MissingTo,
       MissingTo - MissingFrom + 1 as MissingCount
FROM MissingDocuments
         LEFT JOIN venues v ON MissingDocuments.Venue = v.uuid
         LEFT JOIN organizations o ON MissingDocuments.Organization = o.uuid
ORDER BY GroupPrefix, MissingFrom, MissingTo;

Acción


9. Revisión de Comprobantes Duplicados

Descripción

Casos donde existen dos o más comprobantes asociados indebidamente, ya sea por reintentos o errores del sistema.

Obtención de la información

Query de referencia:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SET @DATE_CHECK := '2026-01-01 05:00:00';

create temporary table temp_electronic_bills as
select *
from electronic_bills
where created_at >= @DATE_CHECK
  and deleted_at is null;


alter table temp_electronic_bills
    add index idx_venue_uuid_series_number (venue_uuid, serial_number, number);

-- DUPLICATED RECORDS
WITH cte AS (SELECT *
                  , COUNT(*) OVER (PARTITION BY venue_uuid,type, serial_number, number)                     AS num_of_duplicates_group
                  , ROW_NUMBER() OVER (PARTITION BY venue_uuid, type, serial_number, number ORDER BY number) AS pos_in_group
             FROM temp_electronic_bills)
SELECT v.uuid,
       v.name,
       date_of_issue,
       qr_code,
       o.total,
       cte.uuid,
       cte.latest_status,
       cte.latest_status_id,
       type,
       serial_number,
       number,
       CONCAT('OV-', o.correlative),
       o.uuid,
       num_of_duplicates_group,
       pos_in_group
FROM cte
         left join venues v on cte.venue_uuid = v.uuid
         left join orders o on cte.order_uuid = o.uuid
WHERE num_of_duplicates_group > 1
  and number is not null
  and cte.deleted_at is null;

DROP TEMPORARY TABLE temp_electronic_bills;

Acción


10. Revisión de Inconsistencias POS vs PSE

Descripción

Comparación entre:

Herramienta

Comparación de montos

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));

-- Q_COMPARE_OPTIMAL
WITH SELECTED AS (SELECT o.uuid                               as order_id,
                         o.correlative,
                         o.payable_amount + o.delivery_amount AS order_total,
                         s.name                               as store_name,
                         s.uuid                               as store_id
                  FROM orders o
                           LEFT JOIN stores s ON o.store_uuid = s.uuid
                  WHERE o.created_at >= @DATE_CHECK
                    AND o.deleted_at IS NULL),
     TOTAL_BILLED AS (SELECT *
                      FROM electronic_bills eb
                               JOIN SELECTED s ON eb.order_uuid = s.order_id
                      WHERE eb.latest_status IN ('sent', 'sent_inoperative')
                        AND eb.deleted_at IS NULL),
     AMOUNTS AS (SELECT order_id,
                        CONCAT('OV-', correlative)                                    as correlative,
                        store_id,
                        store_name,
                        order_total,
                        IF(type = 1 or type = 2, JSON_EXTRACT(payload, '$.total'), 0) AS POSITIVE,
                        IF(type = 3, JSON_EXTRACT(payload, '$.total'), 0)             AS NEGATIVE,
                        JSON_EXTRACT(payload, '$.')
                 FROM TOTAL_BILLED),
     FINAL AS (SELECT order_id,
                      correlative,
                      store_id,
                      store_name,
                      order_total,
                      SUM(POSITIVE)            AS POSITIVE,
                      SUM(NEGATIVE)            AS NEGATIVE,
                      SUM(POSITIVE - NEGATIVE) AS TOTAL,
                      IFNULL(SUM(a.amount), 0) AS ANTICIPO
               FROM AMOUNTS f
                        LEFT JOIN advance_order ao ON ao.order_uuid = f.order_id
                        LEFT JOIN advances a ON a.uuid = ao.advance_uuid
               GROUP BY order_id)
SELECT order_id,
       correlative,
       store_id,
       store_name,
       order_total,
       POSITIVE,
       NEGATIVE,
       TOTAL,
       ANTICIPO,
       ABS(order_total - ANTICIPO - TOTAL) AS DIFF
FROM FINAL f
         LEFT JOIN advance_order ao ON ao.order_uuid = f.order_id
         LEFT JOIN advances a ON a.uuid = ao.advance_uuid
WHERE order_total - TOTAL != 0
GROUP BY order_id 

Ejecución


11. Validaciones Manuales sobre el CSV

Durante la revisión del CSV se debe validar:

Cada inconsistencia debe:


12. Aprobaciones del Cliente

Algunas correcciones requieren aprobación explícita del cliente, especialmente cuando:

La aprobación debe quedar documentada y referenciada en el registro de la revisión.


13. Registro de la Revisión

Al finalizar la revisión quincenal se debe dejar constancia de:


14. Consideraciones Finales


Responsable del procedimiento:
Equipo técnico / Infraestructura

Última actualización: 16/01/2026