- 00-auth-base.sql: Extracted auth.tenants+users from recreate-database.sh - 03b-core-companies.sql: DDL for auth.companies entity - 21b-inventory-extended.sql: 7 new tables for inventory entities without DDL - 24-invoices.sql: billing→operations schema to resolve duplication - 27/28/29-cfdi: Track existing CFDI DDL files - recreate-database.sh: Updated ddl_files array (17→43 entries) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
443 lines
17 KiB
SQL
443 lines
17 KiB
SQL
-- =============================================================
|
|
-- ARCHIVO: 28-cfdi-operations.sql
|
|
-- DESCRIPCION: Modulo CFDI - Operaciones: cancelaciones, logs,
|
|
-- complementos de pago
|
|
-- VERSION: 1.0.0
|
|
-- PROYECTO: ERP-Core V2
|
|
-- FECHA: 2026-02-03
|
|
-- DEPENDE DE: 27-cfdi-core.sql
|
|
-- =============================================================
|
|
|
|
-- =====================
|
|
-- TIPOS ENUMERADOS OPERACIONES
|
|
-- =====================
|
|
|
|
-- Motivo de cancelacion CFDI
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'cfdi_cancellation_reason') THEN
|
|
CREATE TYPE fiscal.cfdi_cancellation_reason AS ENUM (
|
|
'01', -- Comprobante emitido con errores con relacion
|
|
'02', -- Comprobante emitido con errores sin relacion
|
|
'03', -- No se llevo a cabo la operacion
|
|
'04' -- Operacion nominativa relacionada en factura global
|
|
);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Estado de solicitud de cancelacion
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'cancellation_request_status') THEN
|
|
CREATE TYPE fiscal.cancellation_request_status AS ENUM (
|
|
'pending', -- Pendiente de enviar
|
|
'submitted', -- Enviada al SAT
|
|
'accepted', -- Aceptada por el receptor
|
|
'rejected', -- Rechazada por el receptor
|
|
'in_process', -- En proceso (plazo de aceptacion)
|
|
'expired', -- Plazo expirado (cancelada automaticamente)
|
|
'cancelled', -- Cancelacion exitosa
|
|
'error' -- Error en el proceso
|
|
);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Tipo de operacion en log
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'cfdi_operation_type') THEN
|
|
CREATE TYPE fiscal.cfdi_operation_type AS ENUM (
|
|
'create', -- Creacion de CFDI
|
|
'stamp', -- Timbrado
|
|
'stamp_retry', -- Reintento de timbrado
|
|
'cancel_request', -- Solicitud de cancelacion
|
|
'cancel_accept', -- Aceptacion de cancelacion
|
|
'cancel_reject', -- Rechazo de cancelacion
|
|
'cancel_complete', -- Cancelacion completada
|
|
'validate', -- Validacion en SAT
|
|
'download', -- Descarga de XML/PDF
|
|
'email', -- Envio por email
|
|
'error' -- Error en operacion
|
|
);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Estado del complemento de pago
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'payment_complement_status') THEN
|
|
CREATE TYPE fiscal.payment_complement_status AS ENUM (
|
|
'draft', -- Borrador
|
|
'pending', -- Pendiente de timbrar
|
|
'stamped', -- Timbrado exitosamente
|
|
'cancelled', -- Cancelado
|
|
'error' -- Error
|
|
);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_cancellation_requests
|
|
-- Solicitudes de cancelacion de CFDI
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_cancellation_requests (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- CFDI a cancelar
|
|
cfdi_invoice_id UUID NOT NULL REFERENCES fiscal.cfdi_invoices(id) ON DELETE CASCADE,
|
|
cfdi_uuid VARCHAR(36) NOT NULL, -- UUID del CFDI a cancelar
|
|
|
|
-- Motivo de cancelacion
|
|
cancellation_reason fiscal.cfdi_cancellation_reason NOT NULL,
|
|
|
|
-- CFDI sustituto (para motivo 01)
|
|
substitute_uuid VARCHAR(36), -- UUID del CFDI que sustituye
|
|
substitute_cfdi_id UUID REFERENCES fiscal.cfdi_invoices(id),
|
|
|
|
-- Estado de la solicitud
|
|
status fiscal.cancellation_request_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Fechas del proceso
|
|
requested_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
submitted_at TIMESTAMPTZ, -- Fecha de envio al SAT
|
|
response_at TIMESTAMPTZ, -- Fecha de respuesta
|
|
expires_at TIMESTAMPTZ, -- Fecha limite para aceptacion (72h)
|
|
completed_at TIMESTAMPTZ, -- Fecha de cancelacion efectiva
|
|
|
|
-- Respuesta del SAT
|
|
sat_response_code VARCHAR(10),
|
|
sat_response_message TEXT,
|
|
sat_ack_xml TEXT, -- Acuse de cancelacion
|
|
|
|
-- Respuesta del receptor (si aplica)
|
|
receiver_response VARCHAR(20), -- accepted, rejected
|
|
receiver_response_at TIMESTAMPTZ,
|
|
receiver_response_reason TEXT,
|
|
|
|
-- Notas
|
|
reason_notes TEXT, -- Notas adicionales del motivo
|
|
internal_notes TEXT,
|
|
|
|
-- Errores
|
|
last_error TEXT,
|
|
error_details JSONB,
|
|
retry_count INTEGER DEFAULT 0,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
|
|
UNIQUE(cfdi_invoice_id)
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_cancellation_requests IS 'Solicitudes de cancelacion de CFDI segun proceso SAT 2022+';
|
|
COMMENT ON COLUMN fiscal.cfdi_cancellation_requests.cancellation_reason IS 'Motivo: 01=Con relacion, 02=Sin relacion, 03=No se realizo operacion, 04=Nominativa global';
|
|
COMMENT ON COLUMN fiscal.cfdi_cancellation_requests.expires_at IS 'Fecha limite para que el receptor acepte/rechace (72 horas habiles)';
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_operation_logs
|
|
-- Audit trail de todas las operaciones CFDI
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_operation_logs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- Referencia al CFDI
|
|
cfdi_invoice_id UUID REFERENCES fiscal.cfdi_invoices(id) ON DELETE SET NULL,
|
|
cfdi_uuid VARCHAR(36), -- Guardamos UUID por si se elimina el registro
|
|
|
|
-- Tipo de operacion
|
|
operation_type fiscal.cfdi_operation_type NOT NULL,
|
|
|
|
-- Estado antes y despues
|
|
status_before VARCHAR(50),
|
|
status_after VARCHAR(50),
|
|
|
|
-- Resultado
|
|
success BOOLEAN NOT NULL DEFAULT FALSE,
|
|
|
|
-- Detalles de la operacion
|
|
request_payload JSONB, -- Datos enviados
|
|
response_payload JSONB, -- Respuesta recibida
|
|
|
|
-- Error (si aplica)
|
|
error_code VARCHAR(50),
|
|
error_message TEXT,
|
|
error_details JSONB,
|
|
|
|
-- PAC utilizado
|
|
pac_code VARCHAR(20),
|
|
pac_transaction_id VARCHAR(100),
|
|
|
|
-- Tiempo de respuesta
|
|
duration_ms INTEGER, -- Duracion en milisegundos
|
|
|
|
-- IP y user agent (para auditorias)
|
|
ip_address INET,
|
|
user_agent VARCHAR(500),
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_operation_logs IS 'Log de todas las operaciones realizadas sobre CFDIs';
|
|
COMMENT ON COLUMN fiscal.cfdi_operation_logs.operation_type IS 'Tipo de operacion: stamp, cancel_request, validate, etc.';
|
|
COMMENT ON COLUMN fiscal.cfdi_operation_logs.duration_ms IS 'Tiempo de respuesta del PAC/SAT en milisegundos';
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_payment_complements
|
|
-- Complementos de pago (CFDI tipo P - REP)
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_payment_complements (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- Pago asociado
|
|
payment_id UUID REFERENCES billing.payments(id) ON DELETE SET NULL,
|
|
|
|
-- Identificadores CFDI
|
|
uuid VARCHAR(36), -- UUID del complemento de pago
|
|
serie VARCHAR(25),
|
|
folio VARCHAR(40),
|
|
|
|
-- Estado
|
|
status fiscal.payment_complement_status NOT NULL DEFAULT 'draft',
|
|
|
|
-- Certificado usado
|
|
certificate_id UUID REFERENCES fiscal.cfdi_certificates(id),
|
|
certificate_number VARCHAR(20),
|
|
|
|
-- Datos del emisor
|
|
issuer_rfc VARCHAR(13) NOT NULL,
|
|
issuer_name VARCHAR(300) NOT NULL,
|
|
issuer_fiscal_regime VARCHAR(10) NOT NULL,
|
|
|
|
-- Datos del receptor
|
|
receiver_rfc VARCHAR(13) NOT NULL,
|
|
receiver_name VARCHAR(300) NOT NULL,
|
|
receiver_fiscal_regime VARCHAR(10),
|
|
receiver_zip_code VARCHAR(5),
|
|
|
|
-- Lugar de expedicion
|
|
expedition_place VARCHAR(5) NOT NULL,
|
|
|
|
-- Datos del pago
|
|
payment_date DATE NOT NULL,
|
|
payment_form VARCHAR(10) NOT NULL, -- Forma de pago SAT
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(10, 6) DEFAULT 1,
|
|
total_amount DECIMAL(18, 6) NOT NULL,
|
|
|
|
-- Datos bancarios (si aplica)
|
|
payer_bank_rfc VARCHAR(13),
|
|
payer_bank_name VARCHAR(300),
|
|
payer_bank_account VARCHAR(50),
|
|
payee_bank_rfc VARCHAR(13),
|
|
payee_bank_account VARCHAR(50),
|
|
|
|
-- Cadena de pago (para transferencias)
|
|
payment_chain TEXT,
|
|
payment_certificate TEXT,
|
|
payment_stamp TEXT,
|
|
|
|
-- Operacion (efectivo, cheque, etc.)
|
|
operation_number VARCHAR(100),
|
|
|
|
-- XML y timbrado
|
|
xml_original TEXT,
|
|
xml_stamped TEXT,
|
|
stamp_date TIMESTAMPTZ,
|
|
stamp_sat_seal TEXT,
|
|
stamp_cfdi_seal TEXT,
|
|
stamp_original_chain TEXT,
|
|
sat_certificate_number VARCHAR(20),
|
|
|
|
-- PDF
|
|
pdf_url VARCHAR(500),
|
|
pdf_generated_at TIMESTAMPTZ,
|
|
|
|
-- Cancelacion
|
|
cancellation_request_id UUID REFERENCES fiscal.cfdi_cancellation_requests(id),
|
|
cancellation_date TIMESTAMPTZ,
|
|
|
|
-- Errores
|
|
last_error TEXT,
|
|
error_details JSONB,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
UNIQUE(tenant_id, uuid)
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_payment_complements IS 'Complementos de pago (CFDI tipo P - Recibo Electronico de Pago)';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complements.uuid IS 'UUID del timbre fiscal del complemento de pago';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complements.payment_form IS 'Forma de pago segun catalogo SAT c_FormaPago';
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_payment_complement_documents
|
|
-- Documentos relacionados en el complemento de pago
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_payment_complement_documents (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
payment_complement_id UUID NOT NULL REFERENCES fiscal.cfdi_payment_complements(id) ON DELETE CASCADE,
|
|
|
|
-- CFDI del documento relacionado
|
|
related_uuid VARCHAR(36) NOT NULL, -- IdDocumento - UUID de la factura pagada
|
|
related_cfdi_id UUID REFERENCES fiscal.cfdi_invoices(id),
|
|
|
|
-- Serie y folio del documento
|
|
serie VARCHAR(25),
|
|
folio VARCHAR(40),
|
|
|
|
-- Moneda del documento
|
|
document_currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
equivalence DECIMAL(18, 6) DEFAULT 1, -- Equivalencia DR (tipo cambio)
|
|
|
|
-- Numero de parcialidad
|
|
installment_number INTEGER NOT NULL DEFAULT 1,
|
|
|
|
-- Saldos
|
|
previous_balance DECIMAL(18, 6) NOT NULL, -- ImpSaldoAnt
|
|
amount_paid DECIMAL(18, 6) NOT NULL, -- ImpPagado
|
|
remaining_balance DECIMAL(18, 6) NOT NULL, -- ImpSaldoInsoluto
|
|
|
|
-- Objeto de impuesto
|
|
tax_object VARCHAR(2) DEFAULT '02', -- ObjetoImpDR
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_payment_complement_documents IS 'Documentos (facturas) incluidos en el complemento de pago';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complement_documents.related_uuid IS 'UUID de la factura que se esta pagando';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complement_documents.installment_number IS 'Numero de parcialidad (1, 2, 3...)';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complement_documents.previous_balance IS 'Saldo anterior antes de este pago';
|
|
COMMENT ON COLUMN fiscal.cfdi_payment_complement_documents.remaining_balance IS 'Saldo pendiente despues de este pago';
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_payment_complement_document_taxes
|
|
-- Impuestos por documento en complemento de pago
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_payment_complement_document_taxes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
payment_complement_document_id UUID NOT NULL REFERENCES fiscal.cfdi_payment_complement_documents(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo de impuesto
|
|
tax_type VARCHAR(20) NOT NULL, -- transferred o withheld
|
|
|
|
-- Impuesto
|
|
tax_code VARCHAR(10) NOT NULL, -- 001=ISR, 002=IVA, 003=IEPS
|
|
|
|
-- Factor
|
|
factor_type VARCHAR(10) NOT NULL, -- Tasa, Cuota, Exento
|
|
rate DECIMAL(10, 6),
|
|
|
|
-- Montos
|
|
base_amount DECIMAL(18, 6) NOT NULL,
|
|
tax_amount DECIMAL(18, 6) NOT NULL,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_payment_complement_document_taxes IS 'Impuestos por documento relacionado en el complemento de pago';
|
|
|
|
-- =====================
|
|
-- TABLA: cfdi_stamp_queue
|
|
-- Cola de timbrado para procesamiento asincrono
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS fiscal.cfdi_stamp_queue (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo de documento a timbrar
|
|
document_type VARCHAR(20) NOT NULL, -- invoice, payment_complement
|
|
document_id UUID NOT NULL, -- ID del documento
|
|
|
|
-- Prioridad
|
|
priority INTEGER DEFAULT 5, -- 1=urgente, 5=normal, 10=baja
|
|
|
|
-- Estado de la cola
|
|
queue_status VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending, processing, completed, failed
|
|
|
|
-- Intentos
|
|
attempts INTEGER DEFAULT 0,
|
|
max_attempts INTEGER DEFAULT 3,
|
|
next_retry_at TIMESTAMPTZ,
|
|
|
|
-- Resultado
|
|
completed_at TIMESTAMPTZ,
|
|
result_cfdi_uuid VARCHAR(36),
|
|
result_error TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE fiscal.cfdi_stamp_queue IS 'Cola de documentos pendientes de timbrar para procesamiento asincrono';
|
|
|
|
-- =====================
|
|
-- INDICES OPERACIONES
|
|
-- =====================
|
|
|
|
-- cfdi_cancellation_requests
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_tenant ON fiscal.cfdi_cancellation_requests(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_cfdi ON fiscal.cfdi_cancellation_requests(cfdi_invoice_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_uuid ON fiscal.cfdi_cancellation_requests(cfdi_uuid);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_status ON fiscal.cfdi_cancellation_requests(status);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_expires ON fiscal.cfdi_cancellation_requests(expires_at)
|
|
WHERE status IN ('submitted', 'in_process');
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_cancel_pending ON fiscal.cfdi_cancellation_requests(tenant_id, status)
|
|
WHERE status IN ('pending', 'submitted', 'in_process');
|
|
|
|
-- cfdi_operation_logs
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_tenant ON fiscal.cfdi_operation_logs(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_cfdi ON fiscal.cfdi_operation_logs(cfdi_invoice_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_uuid ON fiscal.cfdi_operation_logs(cfdi_uuid);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_type ON fiscal.cfdi_operation_logs(operation_type);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_date ON fiscal.cfdi_operation_logs(created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_success ON fiscal.cfdi_operation_logs(success);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_logs_errors ON fiscal.cfdi_operation_logs(tenant_id, operation_type, created_at)
|
|
WHERE success = FALSE;
|
|
|
|
-- cfdi_payment_complements
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_tenant ON fiscal.cfdi_payment_complements(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_payment ON fiscal.cfdi_payment_complements(payment_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_uuid ON fiscal.cfdi_payment_complements(uuid);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_status ON fiscal.cfdi_payment_complements(status);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_issuer ON fiscal.cfdi_payment_complements(issuer_rfc);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_receiver ON fiscal.cfdi_payment_complements(receiver_rfc);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_date ON fiscal.cfdi_payment_complements(payment_date);
|
|
|
|
-- cfdi_payment_complement_documents
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_docs_comp ON fiscal.cfdi_payment_complement_documents(payment_complement_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_docs_uuid ON fiscal.cfdi_payment_complement_documents(related_uuid);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_docs_cfdi ON fiscal.cfdi_payment_complement_documents(related_cfdi_id);
|
|
|
|
-- cfdi_payment_complement_document_taxes
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_pcomp_dtax_doc ON fiscal.cfdi_payment_complement_document_taxes(payment_complement_document_id);
|
|
|
|
-- cfdi_stamp_queue
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_queue_tenant ON fiscal.cfdi_stamp_queue(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_queue_status ON fiscal.cfdi_stamp_queue(queue_status);
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_queue_priority ON fiscal.cfdi_stamp_queue(priority, created_at)
|
|
WHERE queue_status = 'pending';
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_queue_retry ON fiscal.cfdi_stamp_queue(next_retry_at)
|
|
WHERE queue_status = 'failed' AND attempts < max_attempts;
|
|
CREATE INDEX IF NOT EXISTS idx_cfdi_queue_doc ON fiscal.cfdi_stamp_queue(document_type, document_id);
|
|
|
|
-- =====================
|
|
-- FIN DEL ARCHIVO
|
|
-- =====================
|