/* Pagos y Convenios - procedimientos y dependencias. NO EJECUTADO. Preparado sobre la BD y los procedimientos consultados el 22/09/2026. Incluye 25 PAs nuevos, 24 PAs adaptados y la vista existente Vta_SaldosFavor. INSTALACIÓN COORDINADA PENDIENTE: 1. Estructura_20260922.sql. 2. Este archivo. 3. Configuracion_20260922.sql. El instalador debe usar la MISMA conexión y transacción para todos los lotes, detenerse ante cualquier error y confirmar sólo con la aplicación compatible. GO separa lotes; no ejecutar con un cliente que continúe después de errores. El SQL no inicia, confirma ni revierte transacciones. CONTRATO CON LOS SERVICIOS (pendientes de adaptar en la siguiente entrega): - TransactionLogic para todas las mutaciones, incluidas bitácora y PA_Tra_SolicitudProcesoActualizar para las solicitudes afectadas. - Si cualquier PA devuelve Return=0, abandonar y revertir toda la operación. - Validar permisos y acceso cliente en el servicio; nunca confiar en un CveCliente o PermitirDisminucion enviado por el navegador. - Pagos.RegistrarAbono: registro/aplicación/cancelación de abonos. Pagos.CambiarRequerido: excepción con observación obligatoria. Pagos.AdministrarDocumentosFiscales: carga/validación/vinculación fiscal. Convenios.Crear/Modificar/Cancelar y Convenios.DisminuirImporte. Permisos particulares: sólo SuperUsuario en catálogo de usuarios. - Guardar/aplicar/cancelar abono y convenio obtiene un bloqueo transaccional común para impedir sobregiros concurrentes. No hay saldos persistidos. - GenerarPorSolicitud exige vencimiento explícito; no decide el plazo. - Importes de obligación/plantilla son finales. Los parámetros de captura anterior de precio NETO conservan su cálculo fiscal en PagoDetalleSave. La captura nueva usa PrecioUnitarioFinal y no cambia el catálogo de costos. - Abonos son recibidos/confirmados; valores y equivalencias no se actualizan. ImporteAplicado está en la unidad de la obligación. ImportePagoConsumido, en la unidad del abono. AplicacionesJson identifica producto y parcialidad. - Un traslado a convenio no cuenta como dinero pagado. La UI debe usar SaldoPendiente, ImporteAbonado e ImporteConvenido, no sólo TienePago. - Edición de convenio sin movimientos: capturar antes/después en bitácora; con aplicaciones o traslados posteriores se conserva su detalle histórico. - CFDI externo: captura manual, no parser, ZIP, asociación automática ni PAC. Servicio almacena XML/PDF y resuelve rutas con protección de documentos. Documento fiscal no crea pagos. El listado pendiente requiere XML, PDF, timbrado y validación del importe; conserva visible documentación parcial. - Ventas y condiciones fiscales siguen independientes de las obligaciones. Modificar una venta no reescribe los importes históricos de la deuda. La generación anterior de venta se conserva sólo para MXN y total coincidente. - Catálogo ProductosServicios y Conta_Cuentas se reutilizan; no se inventa cuenta ni producto genérico Convenio, usuario o equivalencia. PENDIENTE DE PRUEBA DE INTEGRACIÓN: instalación en base de pruebas y conexión de repositorios/servicios/pantallas. No publicar esta migración aisladamente. */ SET NOCOUNT ON; SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; IF DB_NAME() <> N'SIG_PlataformaDesarolladores' THROW 51390, N'La base seleccionada no corresponde a la revisada.', 1; IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51391, N'Se requiere una transacción activa del instalador.', 1; IF OBJECT_ID(N'dbo.Tra_TiposTramitePagos', N'U') IS NULL OR COL_LENGTH(N'dbo.Tra_Pagos', N'ValorConversion') IS NULL THROW 51392, N'Instale primero la estructura de Pagos y Convenios.', 1; GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoListar @CveSolicitudPago INT=NULL, @CveCliente INT=NULL, @CveFraccionamiento INT=NULL, @CveSolicitud INT=NULL, @CveTipoTramite INT=NULL, @CveTipoSolicitudPago INT=NULL, @EstadoAdministrativo VARCHAR (20)=NULL, @SoloPendientes BIT=NULL, @SoloVencidos BIT=0, @Desde DATE=NULL, @Hasta DATE=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @Hoy AS DATE = CONVERT (DATE, GETDATE()); DECLARE @Vencimientos TABLE ( CveSolicitudPago INT PRIMARY KEY, PrimerVencimiento DATE, ImporteVencido DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) INSERT INTO @Vencimientos SELECT CveSolicitudPago, MIN(CASE WHEN SaldoPendiente > 0 THEN VencimientoEfectivo END), SUM(CASE WHEN SaldoPendiente > 0 AND VencimientoEfectivo < @Hoy THEN SaldoPendiente ELSE 0 END) FROM SaldosParcialidades GROUP BY CveSolicitudPago; WITH Aplicaciones AS (SELECT A.CveSolicitudPago, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPago), Traslados AS (SELECT O.CveSolicitudPagoOrigen, SUM(O.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY O.CveSolicitudPagoOrigen), Saldos AS (SELECT S.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, S.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPago AS S LEFT OUTER JOIN Aplicaciones AS A ON A.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoOrigen = S.CveSolicitudPago) SELECT S.*, C.Nombre AS Cliente, F.Fraccionamiento, E.Etapa, T.TipoTramite, U.Codigo AS UnidadCobro, TS.TipoSolicitudPago, V.PrimerVencimiento, ISNULL(V.ImporteVencido, 0) AS ImporteVencido, CONVERT (BIT, CASE WHEN ISNULL(V.ImporteVencido, 0) > 0 AND S.EstadoAdministrativo = 'ACTIVO' THEN 1 ELSE 0 END) AS EstaVencido, CASE WHEN S.ImporteAbonado >= S.Importe THEN 'Pagado' WHEN S.ImporteAbonado > 0 THEN 'Parcialmente pagado' ELSE 'Pendiente' END AS EstatusFinanciero FROM Saldos AS S INNER JOIN dbo.Clientes AS C ON C.CveCliente = S.CveCliente INNER JOIN dbo.Fraccionamientos AS F ON F.CveFraccionamiento = S.CveFraccionamiento LEFT OUTER JOIN dbo.FraccionamientosEtapas AS E ON E.CveFraccionamientoEtapa = S.CveFraccionamientoEtapa LEFT OUTER JOIN dbo.Tra_TiposTramite AS T ON T.CveTipoTramite = S.CveTipoTramite INNER JOIN dbo.Tra_TiposSolicitudPago AS TS ON TS.CveTipoSolicitudPago = S.CveTipoSolicitudPago INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = S.CveUnidadCobro LEFT OUTER JOIN @Vencimientos AS V ON V.CveSolicitudPago = S.CveSolicitudPago WHERE (@CveSolicitudPago IS NULL OR S.CveSolicitudPago = @CveSolicitudPago) AND (@CveCliente IS NULL OR S.CveCliente = @CveCliente) AND (@CveFraccionamiento IS NULL OR S.CveFraccionamiento = @CveFraccionamiento) AND (@CveTipoTramite IS NULL OR S.CveTipoTramite = @CveTipoTramite) AND (@CveTipoSolicitudPago IS NULL OR S.CveTipoSolicitudPago = @CveTipoSolicitudPago) AND (@EstadoAdministrativo IS NULL OR S.EstadoAdministrativo = @EstadoAdministrativo) AND (@Desde IS NULL OR S.FechaGeneracion >= @Desde) AND (@Hasta IS NULL OR CONVERT (DATE, S.FechaGeneracion) <= @Hasta) AND (@SoloPendientes IS NULL OR (@SoloPendientes = 1 AND S.SaldoPendiente > 0) OR (@SoloPendientes = 0 AND S.SaldoPendiente = 0)) AND (@SoloVencidos = 0 OR (V.ImporteVencido > 0 AND S.EstadoAdministrativo = 'ACTIVO')) AND (@CveSolicitud IS NULL OR S.CveSolicitud = @CveSolicitud OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS A ON A.CveSolicitudPago = O.CveSolicitudPagoOrigen WHERE O.CveSolicitudPagoConvenio = S.CveSolicitudPago AND A.CveSolicitud = @CveSolicitud)) ORDER BY CASE WHEN V.ImporteVencido > 0 AND S.EstadoAdministrativo = 'ACTIVO' THEN 0 ELSE 1 END, V.PrimerVencimiento, S.CveSolicitudPago DESC; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoObtener @CveSolicitudPago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WHERE CveSolicitudPago = @CveSolicitudPago) BEGIN SELECT @ErrorMostrar = 'La obligación no existe.', @ErrorTipo = 2, @Return = 0; RETURN; END EXECUTE dbo.PA_Tra_SolicitudPagoListar @CveSolicitudPago = @CveSolicitudPago, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; WITH Abonos AS (SELECT A.CveSolicitudPagoDetalle, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoDetalle), Traslados AS (SELECT D.CveSolicitudPagoDetalleOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoDetalleOrigen) SELECT D.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoDetalle AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalle LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoDetalleOrigen = D.CveSolicitudPagoDetalle WHERE D.CveSolicitudPago = @CveSolicitudPago ORDER BY D.CveSolicitudPagoDetalle; WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) SELECT *, CONVERT (BIT, CASE WHEN SaldoPendiente > 0 AND VencimientoEfectivo < CONVERT (DATE, GETDATE()) THEN 1 ELSE 0 END) AS EstaVencida FROM SaldosParcialidades WHERE CveSolicitudPago = @CveSolicitudPago ORDER BY NumeroParcialidad; SELECT A.*, P.FechaPago, P.Referencia, P.EsActivo, P.Autorizado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE A.CveSolicitudPago = @CveSolicitudPago ORDER BY P.FechaPago DESC, A.CvePagoAplicacion DESC; SELECT * FROM dbo.Tra_SolicitudesPagoConvenio WHERE CveSolicitudPago = @CveSolicitudPago; SELECT * FROM dbo.Tra_SolicitudesPagoConvenioOrigen WHERE CveSolicitudPagoConvenio = @CveSolicitudPago OR CveSolicitudPagoOrigen = @CveSolicitudPago; SELECT * FROM dbo.Tra_SolicitudesPagoRequeridoBitacora WHERE CveSolicitudPago = @CveSolicitudPago ORDER BY CveSolicitudPagoRequeridoBitacora DESC; SELECT D.CveConvenioOrigenDetalle, D.CveConvenioOrigen, D.CveSolicitudPagoOrigen, D.CveSolicitudPagoDetalleOrigen, D.CveSolicitudPagoParcialidadOrigen, D.ImporteSaldoOriginal, D.ImporteTomadoConvenio, P.Descripcion AS Producto, V.NumeroParcialidad AS Parcialidad, COALESCE(V.FechaProrroga, V.FechaVencimiento) AS Vencimiento FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPagoDetalle AS P ON P.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalleOrigen INNER JOIN dbo.Tra_SolicitudesPagoParcialidades AS V ON V.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidadOrigen WHERE O.CveSolicitudPagoConvenio = @CveSolicitudPago ORDER BY D.CveSolicitudPagoOrigen, D.CveSolicitudPagoDetalleOrigen, V.NumeroParcialidad; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoObtener'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_ConvenioListar @CveCliente INT=NULL, @SoloPendientes BIT=1, @SoloVencidos BIT=0, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @Tipo AS INT = (SELECT CveTipoSolicitudPago FROM dbo.Tra_TiposSolicitudPago WHERE Codigo = 'CONVENIO'); IF @Tipo IS NULL BEGIN SELECT @ErrorMostrar = 'No se encontró el tipo de solicitud Convenio.', @ErrorTipo = 2, @Return = 0; RETURN; END EXECUTE dbo.PA_Tra_SolicitudPagoListar @CveCliente = @CveCliente, @CveTipoSolicitudPago = @Tipo, @EstadoAdministrativo = 'ACTIVO', @SoloPendientes = @SoloPendientes, @SoloVencidos = @SoloVencidos, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_ConvenioListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_ConvenioOrigenListar @CveCliente INT, @CveSolicitudPago INT=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY EXECUTE dbo.PA_Tra_SolicitudPagoListar @CveCliente = @CveCliente, @CveSolicitudPago = @CveSolicitudPago, @SoloPendientes = 1, @EstadoAdministrativo = 'ACTIVO', @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; IF @CveSolicitudPago IS NOT NULL BEGIN WITH Abonos AS (SELECT A.CveSolicitudPagoDetalle, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoDetalle), Traslados AS (SELECT D.CveSolicitudPagoDetalleOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoDetalleOrigen) SELECT D.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoDetalle AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalle LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoDetalleOrigen = D.CveSolicitudPagoDetalle WHERE D.CveSolicitudPago = @CveSolicitudPago AND D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) > 0 AND EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago AS S WHERE S.CveSolicitudPago = D.CveSolicitudPago AND S.CveCliente = @CveCliente) ORDER BY D.CveSolicitudPagoDetalle; WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) SELECT * FROM SaldosParcialidades WHERE CveSolicitudPago = @CveSolicitudPago AND SaldoPendiente > 0 AND EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago AS S WHERE S.CveSolicitudPago = @CveSolicitudPago AND S.CveCliente = @CveCliente) ORDER BY VencimientoEfectivo, NumeroParcialidad; END SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_ConvenioOrigenListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoGuardar @CveSolicitudPago INT=NULL OUTPUT, @CveTipoSolicitudPago INT, @CveCliente INT, @CveFraccionamiento INT, @CveFraccionamientoEtapa INT=NULL, @CveSolicitud INT=NULL, @CveTipoTramite INT=NULL, @CveTramitePago INT=NULL, @Descripcion VARCHAR (1000), @Importe DECIMAL (19, 6), @CveUnidadCobro INT, @EsRequerido BIT, @FechaGeneracion DATETIME2 (0), @DetalleJson NVARCHAR (MAX), @ParcialidadesJson NVARCHAR (MAX), @DevolverResultado BIT=1, @EsOperacionConvenio BIT=0, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Importe IS NULL OR @Importe < 0 OR @FechaGeneracion IS NULL OR NULLIF (LTRIM(RTRIM(@Descripcion)), '') IS NULL OR @EsRequerido IS NULL BEGIN SELECT @ErrorMostrar = 'Capture descripción, importe y fecha de generación.', @ErrorTipo = 2, @Return = 0; RETURN; END IF ISNULL(ISJSON(@DetalleJson), 0) <> 1 OR ISNULL(ISJSON(@ParcialidadesJson), 0) <> 1 OR LEFT(LTRIM(@DetalleJson), 1) <> '[' OR LEFT(LTRIM(@ParcialidadesJson), 1) <> '[' BEGIN SELECT @ErrorMostrar = 'El detalle y las parcialidades no tienen un formato válido.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Detalle TABLE ( CvePS INT, Descripcion VARCHAR (1000), Cantidad DECIMAL (18, 4), PrecioUnitario DECIMAL (19, 6), Importe DECIMAL (19, 6)); INSERT INTO @Detalle SELECT CvePS, Descripcion, Cantidad, PrecioUnitario, Importe FROM OPENJSON (@DetalleJson) WITH (CvePS INT, Descripcion VARCHAR (1000), Cantidad DECIMAL (18, 4), PrecioUnitario DECIMAL (19, 6), Importe DECIMAL (19, 6)); DECLARE @Parcialidades TABLE ( NumeroParcialidad INT, FechaVencimiento DATE, Importe DECIMAL (19, 6), FechaProrroga DATE); INSERT INTO @Parcialidades SELECT NumeroParcialidad, FechaVencimiento, Importe, FechaProrroga FROM OPENJSON (@ParcialidadesJson) WITH (NumeroParcialidad INT, FechaVencimiento DATE, Importe DECIMAL (19, 6), FechaProrroga DATE); IF NOT EXISTS (SELECT 1 FROM @Detalle) OR NOT EXISTS (SELECT 1 FROM @Parcialidades) OR EXISTS (SELECT 1 FROM @Detalle WHERE CvePS IS NULL OR Cantidad IS NULL OR Cantidad <= 0 OR PrecioUnitario IS NULL OR PrecioUnitario < 0 OR Importe IS NULL OR Importe < 0 OR NULLIF (LTRIM(RTRIM(Descripcion)), '') IS NULL OR ABS(ROUND(Cantidad * PrecioUnitario, 6) - Importe) > (Cantidad * 0.0000005 + 0.000001)) OR EXISTS (SELECT 1 FROM @Parcialidades WHERE NumeroParcialidad IS NULL OR NumeroParcialidad <= 0 OR FechaVencimiento IS NULL OR Importe IS NULL OR Importe < 0 OR FechaProrroga < FechaVencimiento) OR EXISTS (SELECT NumeroParcialidad FROM @Parcialidades GROUP BY NumeroParcialidad HAVING COUNT(*) > 1) OR (SELECT SUM(Importe) FROM @Detalle) <> @Importe OR (SELECT SUM(Importe) FROM @Parcialidades) <> @Importe BEGIN SELECT @ErrorMostrar = 'Los productos y las parcialidades deben ser válidos y sumar exactamente el importe de la obligación.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Fraccionamientos WHERE CveFraccionamiento = @CveFraccionamiento AND CveCliente = @CveCliente) OR (@CveFraccionamientoEtapa IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.FraccionamientosEtapas WHERE CveFraccionamientoEtapa = @CveFraccionamientoEtapa AND CveFraccionamiento = @CveFraccionamiento)) OR (@CveSolicitud IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes WHERE CveSolicitud = @CveSolicitud AND CveCliente = @CveCliente AND CveFraccionamiento = @CveFraccionamiento AND (@CveFraccionamientoEtapa IS NULL OR CveFraccionamientoEtapa = @CveFraccionamientoEtapa))) OR (@CveTramitePago IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @CveTramitePago AND CveTipoTramite = @CveTipoTramite AND CveUnidadCobro = @CveUnidadCobro)) BEGIN SELECT @ErrorMostrar = 'El cliente, fraccionamiento, etapa o trámite no corresponden a la obligación.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro AND Activo = 1) OR NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposSolicitudPago WHERE CveTipoSolicitudPago = @CveTipoSolicitudPago AND Activo = 1) BEGIN SELECT @ErrorMostrar = 'Seleccione un tipo y unidad de cobro disponibles.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @EsOperacionConvenio = 0 AND EXISTS (SELECT 1 FROM dbo.Tra_TiposSolicitudPago WHERE CveTipoSolicitudPago = @CveTipoSolicitudPago AND Codigo = 'CONVENIO') BEGIN SELECT @ErrorMostrar = 'Guarde el convenio desde su operación completa, incluyendo los adeudos de origen.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @CveSolicitudPago = NULLIF (@CveSolicitudPago, 0); IF @CveSolicitudPago IS NOT NULL BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WHERE CveSolicitudPago = @CveSolicitudPago AND EstadoAdministrativo = 'ACTIVO' AND CveCliente = @CveCliente AND CveTipoSolicitudPago = @CveTipoSolicitudPago) BEGIN SELECT @ErrorMostrar = 'La obligación no está disponible para modificar.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_PagosAplicaciones WHERE CveSolicitudPago = @CveSolicitudPago) OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenioOrigen WHERE CveSolicitudPagoOrigen = @CveSolicitudPago) OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoDetalle WHERE CveSolicitudPago = @CveSolicitudPago AND CveVentaDetalleOrigen IS NOT NULL) BEGIN SELECT @ErrorMostrar = 'La obligación tiene historia financiera. Sus importes y productos deben conservarse.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WHERE CveSolicitudPago = @CveSolicitudPago AND EsRequerido <> @EsRequerido) BEGIN SELECT @ErrorMostrar = 'Cambie requerido desde la operación que solicita observación.', @ErrorTipo = 2, @Return = 0; RETURN; END DELETE dbo.Tra_SolicitudesPagoDetalle WHERE CveSolicitudPago = @CveSolicitudPago; DELETE dbo.Tra_SolicitudesPagoParcialidades WHERE CveSolicitudPago = @CveSolicitudPago; UPDATE dbo.Tra_SolicitudesPago SET CveFraccionamiento = @CveFraccionamiento, CveFraccionamientoEtapa = @CveFraccionamientoEtapa, CveSolicitud = @CveSolicitud, CveTipoTramite = @CveTipoTramite, CveTramitePago = @CveTramitePago, Descripcion = @Descripcion, Importe = @Importe, CveUnidadCobro = @CveUnidadCobro, FechaGeneracion = @FechaGeneracion, CveUsuarioModificacion = @CveUsuarioEjecuta, FechaModificacion = SYSDATETIME() WHERE CveSolicitudPago = @CveSolicitudPago; END ELSE BEGIN INSERT INTO dbo.Tra_SolicitudesPago (CveTipoSolicitudPago, CveCliente, CveFraccionamiento, CveFraccionamientoEtapa, CveSolicitud, CveTipoTramite, CveTramitePago, Descripcion, Importe, CveUnidadCobro, EsRequerido, FechaGeneracion, FechaAlta, CveUsuario) VALUES (@CveTipoSolicitudPago, @CveCliente, @CveFraccionamiento, @CveFraccionamientoEtapa, @CveSolicitud, @CveTipoTramite, @CveTramitePago, @Descripcion, @Importe, @CveUnidadCobro, @EsRequerido, @FechaGeneracion, SYSDATETIME(), @CveUsuarioEjecuta); SET @CveSolicitudPago = CONVERT (INT, SCOPE_IDENTITY()); END INSERT INTO dbo.Tra_SolicitudesPagoDetalle (CveSolicitudPago, CvePS, Descripcion, Cantidad, PrecioUnitario, CveUnidadCobro, Importe) SELECT @CveSolicitudPago, CvePS, Descripcion, Cantidad, PrecioUnitario, @CveUnidadCobro, Importe FROM @Detalle; INSERT INTO dbo.Tra_SolicitudesPagoParcialidades (CveSolicitudPago, NumeroParcialidad, FechaVencimiento, Importe, CveUnidadCobro, FechaProrroga) SELECT @CveSolicitudPago, NumeroParcialidad, FechaVencimiento, Importe, @CveUnidadCobro, FechaProrroga FROM @Parcialidades; IF @DevolverResultado = 1 SELECT @CveSolicitudPago AS CveSolicitudPago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoGuardar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoGenerarPorSolicitud @CveSolicitud INT, @FechaVencimiento DATE, @CveTramitePago INT=NULL, @DevolverResultado BIT=1, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @FechaVencimiento IS NULL BEGIN SELECT @ErrorMostrar = 'Indique la fecha de vencimiento; no se asigna una fecha implícita.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Cliente AS INT, @Fraccionamiento AS INT, @Etapa AS INT, @TipoTramite AS INT, @Tipo AS INT; SELECT @Cliente = CveCliente, @Fraccionamiento = CveFraccionamiento, @Etapa = CveFraccionamientoEtapa, @TipoTramite = CveTipoTramite FROM dbo.Tra_Solicitudes WHERE CveSolicitud = @CveSolicitud; SET @Tipo = (SELECT CveTipoSolicitudPago FROM dbo.Tra_TiposSolicitudPago WHERE Codigo = 'NORMAL'); IF @Cliente IS NULL OR @Tipo IS NULL BEGIN SELECT @ErrorMostrar = 'La solicitud o el tipo Normal no están disponibles.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Pendientes TABLE ( CveTramitePago INT PRIMARY KEY); INSERT INTO @Pendientes SELECT CveTramitePago FROM dbo.Tra_TiposTramitePagos WHERE CveTipoTramite = @TipoTramite AND EsActivo = 1 AND (@CveTramitePago IS NULL OR CveTramitePago = @CveTramitePago); DECLARE @Generadas TABLE ( CveSolicitudPago INT); WHILE EXISTS (SELECT 1 FROM @Pendientes) BEGIN DECLARE @Plantilla AS INT = (SELECT MIN(CveTramitePago) FROM @Pendientes); DECLARE @Clave AS INT = (SELECT CveSolicitudPago FROM dbo.Tra_SolicitudesPago WHERE CveSolicitud = @CveSolicitud AND CveTramitePago = @Plantilla); IF @Clave IS NULL BEGIN DECLARE @Descripcion AS VARCHAR (1000), @Importe AS DECIMAL (19, 6), @Unidad AS INT, @Requerido AS BIT, @Detalle AS NVARCHAR (MAX), @Parcialidades AS NVARCHAR (MAX); DECLARE @Fecha AS DATETIME2 (0) = SYSDATETIME(); SELECT @Descripcion = Nombre, @Importe = Importe, @Unidad = CveUnidadCobro, @Requerido = EsRequerido FROM dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @Plantilla; SET @Detalle = (SELECT CvePS, Descripcion, Cantidad, PrecioUnitario, Importe FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @Plantilla ORDER BY CveTramitePagoDetalle FOR JSON PATH); SET @Parcialidades = (SELECT 1 AS NumeroParcialidad, @FechaVencimiento AS FechaVencimiento, @Importe AS Importe FOR JSON PATH); EXECUTE dbo.PA_Tra_SolicitudPagoGuardar @CveSolicitudPago = @Clave OUTPUT, @CveTipoSolicitudPago = @Tipo, @CveCliente = @Cliente, @CveFraccionamiento = @Fraccionamiento, @CveFraccionamientoEtapa = @Etapa, @CveSolicitud = @CveSolicitud, @CveTipoTramite = @TipoTramite, @CveTramitePago = @Plantilla, @Descripcion = @Descripcion, @Importe = @Importe, @CveUnidadCobro = @Unidad, @EsRequerido = @Requerido, @FechaGeneracion = @Fecha, @DetalleJson = @Detalle, @ParcialidadesJson = @Parcialidades, @DevolverResultado = 0, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; END INSERT INTO @Generadas VALUES (@Clave); DELETE @Pendientes WHERE CveTramitePago = @Plantilla; END IF @DevolverResultado = 1 SELECT CveSolicitudPago FROM @Generadas; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoGenerarPorSolicitud'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoCambiarRequerido @CveSolicitudPago INT, @EsRequerido BIT, @Observacion VARCHAR (2000), @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @EsRequerido IS NULL OR NULLIF (LTRIM(RTRIM(@Observacion)), '') IS NULL BEGIN SELECT @ErrorMostrar = 'Capture una observación para cambiar requerido.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Anterior AS BIT; SELECT @Anterior = EsRequerido FROM dbo.Tra_SolicitudesPago WHERE CveSolicitudPago = @CveSolicitudPago; IF @Anterior IS NULL BEGIN SELECT @ErrorMostrar = 'La obligación no existe.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Anterior <> @EsRequerido BEGIN UPDATE dbo.Tra_SolicitudesPago SET EsRequerido = @EsRequerido, CveUsuarioModificacion = @CveUsuarioEjecuta, FechaModificacion = SYSDATETIME() WHERE CveSolicitudPago = @CveSolicitudPago; INSERT INTO dbo.Tra_SolicitudesPagoRequeridoBitacora (CveSolicitudPago, ValorAnterior, ValorNuevo, Observacion, CveUsuarioRegistro) VALUES (@CveSolicitudPago, @Anterior, @EsRequerido, @Observacion, @CveUsuarioEjecuta); END SELECT CONVERT (BIT, 1) AS Guardado; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoCambiarRequerido'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoCancelar @CveSolicitudPago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WHERE CveSolicitudPago = @CveSolicitudPago) BEGIN SELECT @ErrorMostrar = 'La obligación no existe.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE A.CveSolicitudPago = @CveSolicitudPago AND P.EsActivo = 1) OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE O.CveSolicitudPagoOrigen = @CveSolicitudPago AND C.EstadoAdministrativo <> 'CANCELADO') BEGIN SELECT @ErrorMostrar = 'La obligación tiene abonos o saldo trasladado a un convenio vigente.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Tra_SolicitudesPago SET EstadoAdministrativo = 'CANCELADO', CveUsuarioModificacion = @CveUsuarioEjecuta, FechaModificacion = SYSDATETIME() WHERE CveSolicitudPago = @CveSolicitudPago; SELECT CONVERT (BIT, 1) AS Cancelado; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoCancelar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_ConvenioCancelar @CveSolicitudPago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenio WHERE CveSolicitudPago = @CveSolicitudPago) BEGIN SELECT @ErrorMostrar = 'El convenio no existe.', @ErrorTipo = 2, @Return = 0; RETURN; END EXECUTE dbo.PA_Tra_SolicitudPagoCancelar @CveSolicitudPago = @CveSolicitudPago, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_ConvenioCancelar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoRegistrar @CvePago INT=NULL OUTPUT, @CveCliente INT, @FechaPago DATETIME, @Importe DECIMAL (19, 6), @CveUnidadCobro INT, @CveFormaPago TINYINT, @CveBancoCuenta INT=NULL, @Referencia VARCHAR (200)=NULL, @Observaciones VARCHAR (300)=NULL, @DevolverResultado BIT=1, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @CvePago IS NOT NULL AND @CvePago <> 0 BEGIN SELECT @ErrorMostrar = 'Un abono registrado conserva su importe y conversión; no puede sobrescribirse.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Importe IS NULL OR @Importe <= 0 OR @FechaPago IS NULL BEGIN SELECT @ErrorMostrar = 'Capture un importe positivo y la fecha del pago.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveMoneda AS INT, @RequiereConversion AS BIT, @ValorConversion AS DECIMAL (19, 8), @CveUnidadCobroValor AS INT, @ImporteMXN AS DECIMAL (19, 6); SELECT @CveMoneda = CveMoneda, @RequiereConversion = RequiereConversion FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro AND Activo = 1; IF @RequiereConversion IS NULL BEGIN SELECT @ErrorMostrar = 'Seleccione una unidad de cobro disponible.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @RequiereConversion = 0 SET @ValorConversion = 1; ELSE SELECT TOP (1) @CveUnidadCobroValor = CveUnidadCobroValor, @ValorConversion = ValorMXN FROM dbo.Gral_UnidadesCobroValores WHERE CveUnidadCobro = @CveUnidadCobro AND FechaVigencia <= CONVERT (DATE, @FechaPago) ORDER BY FechaVigencia DESC; IF @ValorConversion IS NULL OR @ValorConversion <= 0 BEGIN SELECT @ErrorMostrar = 'Falta registrar la equivalencia vigente en la fecha del pago.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @ImporteMXN = CONVERT (DECIMAL (19, 6), ROUND(@Importe * @ValorConversion, 6)); IF @ImporteMXN <= 0 BEGIN SELECT @ErrorMostrar = 'El importe convertido debe ser mayor a cero.', @ErrorTipo = 2, @Return = 0; RETURN; END INSERT INTO dbo.Tra_Pagos (CveCliente, CveFormaPago, CveMoneda, FechaPago, Importe, Referencia, EsSaldoFavor, EsActivo, FechaAlta, CveUsuario, CveBancoCuenta, Observaciones, Autorizado, FechaAutorizacion, CveUsuarioAutoriza, CveUnidadCobro, CveUnidadCobroValor, ValorConversion, ImporteMXN) VALUES (@CveCliente, @CveFormaPago, @CveMoneda, @FechaPago, @Importe, @Referencia, 0, 1, SYSDATETIME(), @CveUsuarioEjecuta, @CveBancoCuenta, @Observaciones, 1, SYSDATETIME(), @CveUsuarioEjecuta, @CveUnidadCobro, @CveUnidadCobroValor, @ValorConversion, @ImporteMXN); SET @CvePago = CONVERT (INT, SCOPE_IDENTITY()); IF @DevolverResultado = 1 SELECT @CvePago AS CvePago, @ValorConversion AS ValorConversion, @ImporteMXN AS ImporteMXN; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoRegistrar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoListar @CvePago INT=NULL, @CveCliente INT=NULL, @CveFraccionamiento INT=NULL, @CveSolicitud INT=NULL, @Desde DATE=NULL, @Hasta DATE=NULL, @EsActivo BIT=NULL, @SoloPendientesFacturar BIT=0, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY WITH Aplicado AS (SELECT CvePago, SUM(ImportePagoConsumido) AS ImporteAplicado, SUM(ImporteAplicadoMXN) AS ImporteAplicadoMXN FROM dbo.Tra_PagosAplicaciones GROUP BY CvePago), Documentado AS (SELECT V.CvePago, SUM(V.ImporteVinculadoMXN) AS ImporteDocumentadoMXN FROM dbo.Tra_PagosCfdi AS V INNER JOIN dbo.Fac_CfdiDocumentos AS D ON D.CveCfdiDocumento = V.CveCfdiDocumento LEFT OUTER JOIN dbo.Fac_CfdiTimbrados AS T ON T.CveCfdiTimbrado = D.CveCfdiTimbradoVigente WHERE D.Estado = 'TIMBRADO' AND D.ImporteValidado = 1 AND D.RutaPdf IS NOT NULL AND ((D.OrigenRegistro = 'EXTERNO' AND D.RutaXmlExterno IS NOT NULL AND D.UuidExterno IS NOT NULL) OR (D.OrigenRegistro = 'INTERNO' AND T.Exitoso = 1 AND T.XmlTimbrado IS NOT NULL)) GROUP BY V.CvePago) SELECT P.CvePago, P.CveCliente, C.Nombre AS Cliente, P.FechaPago, P.Importe, P.CveUnidadCobro, U.Codigo AS UnidadCobro, P.ValorConversion, P.ImporteMXN, P.Referencia, P.Observaciones, P.CveFormaPago, P.CveBancoCuenta, P.EsActivo, P.Autorizado, P.CveUsuario, P.FechaAlta, ISNULL(A.ImporteAplicado, 0) AS ImporteAplicado, P.Importe - ISNULL(A.ImporteAplicado, 0) AS ImporteSinAplicar, P.ImporteMXN - ISNULL(A.ImporteAplicadoMXN, 0) AS ImporteSinAplicarMXN, ISNULL(D.ImporteDocumentadoMXN, 0) AS ImporteDocumentadoMXN, P.ImporteMXN - ISNULL(D.ImporteDocumentadoMXN, 0) AS ImportePendienteFacturarMXN FROM dbo.Tra_Pagos AS P INNER JOIN dbo.Clientes AS C ON C.CveCliente = P.CveCliente INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = P.CveUnidadCobro LEFT OUTER JOIN Aplicado AS A ON A.CvePago = P.CvePago LEFT OUTER JOIN Documentado AS D ON D.CvePago = P.CvePago WHERE (@CvePago IS NULL OR P.CvePago = @CvePago) AND (@CveCliente IS NULL OR P.CveCliente = @CveCliente) AND (@Desde IS NULL OR P.FechaPago >= @Desde) AND (@Hasta IS NULL OR CONVERT (DATE, P.FechaPago) <= @Hasta) AND (@EsActivo IS NULL OR P.EsActivo = @EsActivo) AND (@SoloPendientesFacturar = 0 OR (P.EsActivo = 1 AND P.Autorizado = 1 AND P.ImporteMXN > ISNULL(D.ImporteDocumentadoMXN, 0))) AND ((@CveFraccionamiento IS NULL AND @CveSolicitud IS NULL) OR EXISTS (SELECT 1 FROM dbo.Tra_PagosAplicaciones AS X INNER JOIN dbo.Tra_SolicitudesPago AS S ON S.CveSolicitudPago = X.CveSolicitudPago WHERE X.CvePago = P.CvePago AND (@CveFraccionamiento IS NULL OR S.CveFraccionamiento = @CveFraccionamiento) AND (@CveSolicitud IS NULL OR S.CveSolicitud = @CveSolicitud))) ORDER BY P.FechaPago DESC, P.CvePago DESC; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoObtener @CvePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF NOT EXISTS (SELECT 1 FROM dbo.Tra_Pagos WHERE CvePago = @CvePago) BEGIN SELECT @ErrorMostrar = 'No se encontró el pago.', @ErrorTipo = 2, @Return = 0; RETURN; END EXECUTE dbo.PA_Tra_PagoListar @CvePago = @CvePago, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SELECT A.*, S.Descripcion, P.NumeroParcialidad, D.Descripcion AS Producto FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_SolicitudesPago AS S ON S.CveSolicitudPago = A.CveSolicitudPago INNER JOIN dbo.Tra_SolicitudesPagoParcialidades AS P ON P.CveSolicitudPagoParcialidad = A.CveSolicitudPagoParcialidad INNER JOIN dbo.Tra_SolicitudesPagoDetalle AS D ON D.CveSolicitudPagoDetalle = A.CveSolicitudPagoDetalle WHERE A.CvePago = @CvePago ORDER BY A.CvePagoAplicacion; SELECT V.CvePagoCfdi, V.CveCfdiDocumento, V.ImporteVinculadoMXN, D.Serie, D.Folio, D.Total, D.Moneda, D.Estado, D.ImporteValidado, COALESCE (CONVERT (VARCHAR (36), D.UuidExterno), T.Uuid) AS Uuid, CONVERT (BIT, CASE WHEN D.RutaPdf IS NOT NULL THEN 1 ELSE 0 END) AS TienePdf, CONVERT (BIT, CASE WHEN D.RutaXmlExterno IS NOT NULL OR T.XmlTimbrado IS NOT NULL THEN 1 ELSE 0 END) AS TieneXml FROM dbo.Tra_PagosCfdi AS V INNER JOIN dbo.Fac_CfdiDocumentos AS D ON D.CveCfdiDocumento = V.CveCfdiDocumento LEFT OUTER JOIN dbo.Fac_CfdiTimbrados AS T ON T.CveCfdiTimbrado = D.CveCfdiTimbradoVigente WHERE V.CvePago = @CvePago ORDER BY V.CvePagoCfdi; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoObtener'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoPendienteFacturarListar @CveCliente INT=NULL, @Desde DATE=NULL, @Hasta DATE=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY EXECUTE dbo.PA_Tra_PagoListar @CveCliente = @CveCliente, @Desde = @Desde, @Hasta = @Hasta, @SoloPendientesFacturar = 1, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoPendienteFacturarListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Conservar aplicaciones y documentos como historia; las consultas de saldo excluyen abonos cancelados. CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoCancelar @CvePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Tra_Pagos WHERE CvePago = @CvePago) BEGIN SELECT @ErrorMostrar = 'No se encontró el pago.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Tra_Pagos SET EsActivo = 0 WHERE CvePago = @CvePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoCancelar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoAplicar @CvePago INT, @AplicacionesJson NVARCHAR (MAX), @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF ISNULL(ISJSON(@AplicacionesJson), 0) <> 1 OR LEFT(LTRIM(@AplicacionesJson), 1) <> '[' BEGIN SELECT @ErrorMostrar = 'Las aplicaciones no tienen un formato válido.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveCliente AS INT, @UnidadPago AS INT, @FechaPago AS DATE, @FactorPago AS DECIMAL (19, 8), @Disponible AS DECIMAL (19, 6), @DisponibleMXN AS DECIMAL (19, 6); SELECT @CveCliente = P.CveCliente, @UnidadPago = P.CveUnidadCobro, @FechaPago = CONVERT (DATE, P.FechaPago), @FactorPago = P.ValorConversion, @Disponible = P.Importe - ISNULL((SELECT SUM(ImportePagoConsumido) FROM dbo.Tra_PagosAplicaciones WHERE CvePago = P.CvePago), 0), @DisponibleMXN = P.ImporteMXN - ISNULL((SELECT SUM(ImporteAplicadoMXN) FROM dbo.Tra_PagosAplicaciones WHERE CvePago = P.CvePago), 0) FROM dbo.Tra_Pagos AS P WHERE P.CvePago = @CvePago AND P.EsActivo = 1 AND P.Autorizado = 1; IF @CveCliente IS NULL BEGIN SELECT @ErrorMostrar = 'Seleccione un abono recibido y vigente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Aplicaciones TABLE ( CveSolicitudPagoDetalle INT, CveSolicitudPagoParcialidad INT, ImporteAplicado DECIMAL (19, 6), CveSolicitudPago INT, CveUnidadCobro INT, Factor DECIMAL (19, 8), ImporteMXN DECIMAL (19, 6), ImporteConsumido DECIMAL (19, 6)); INSERT INTO @Aplicaciones (CveSolicitudPagoDetalle, CveSolicitudPagoParcialidad, ImporteAplicado) SELECT CveSolicitudPagoDetalle, CveSolicitudPagoParcialidad, ImporteAplicado FROM OPENJSON (@AplicacionesJson) WITH (CveSolicitudPagoDetalle INT, CveSolicitudPagoParcialidad INT, ImporteAplicado DECIMAL (19, 6)); IF NOT EXISTS (SELECT 1 FROM @Aplicaciones) OR EXISTS (SELECT 1 FROM @Aplicaciones WHERE CveSolicitudPagoDetalle IS NULL OR CveSolicitudPagoParcialidad IS NULL OR ImporteAplicado IS NULL OR ImporteAplicado <= 0) OR EXISTS (SELECT CveSolicitudPagoDetalle, CveSolicitudPagoParcialidad FROM @Aplicaciones GROUP BY CveSolicitudPagoDetalle, CveSolicitudPagoParcialidad HAVING COUNT(*) > 1) BEGIN SELECT @ErrorMostrar = 'Seleccione aplicaciones positivas, sin destinos repetidos.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE A SET CveSolicitudPago = S.CveSolicitudPago, CveUnidadCobro = S.CveUnidadCobro FROM @Aplicaciones AS A INNER JOIN dbo.Tra_SolicitudesPagoDetalle AS D ON D.CveSolicitudPagoDetalle = A.CveSolicitudPagoDetalle INNER JOIN dbo.Tra_SolicitudesPagoParcialidades AS P ON P.CveSolicitudPagoParcialidad = A.CveSolicitudPagoParcialidad AND P.CveSolicitudPago = D.CveSolicitudPago INNER JOIN dbo.Tra_SolicitudesPago AS S ON S.CveSolicitudPago = D.CveSolicitudPago WHERE S.CveCliente = @CveCliente AND S.EstadoAdministrativo = 'ACTIVO'; IF EXISTS (SELECT 1 FROM @Aplicaciones WHERE CveSolicitudPago IS NULL) BEGIN SELECT @ErrorMostrar = 'Las parcialidades y productos deben pertenecer a obligaciones vigentes del cliente del pago.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM @Aplicaciones AS A INNER JOIN dbo.Tra_PagosAplicaciones AS X ON X.CvePago = @CvePago AND X.CveSolicitudPagoDetalle = A.CveSolicitudPagoDetalle AND X.CveSolicitudPagoParcialidad = A.CveSolicitudPagoParcialidad) BEGIN SELECT @ErrorMostrar = 'Este pago ya tiene una aplicación a ese destino; conserve el movimiento registrado.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE A SET Factor = CASE WHEN A.CveUnidadCobro = @UnidadPago THEN @FactorPago WHEN U.RequiereConversion = 0 THEN 1 ELSE (SELECT TOP (1) V.ValorMXN FROM dbo.Gral_UnidadesCobroValores AS V WHERE V.CveUnidadCobro = A.CveUnidadCobro AND V.FechaVigencia <= @FechaPago ORDER BY V.FechaVigencia DESC) END FROM @Aplicaciones AS A INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = A.CveUnidadCobro; IF EXISTS (SELECT 1 FROM @Aplicaciones WHERE Factor IS NULL OR Factor <= 0) BEGIN SELECT @ErrorMostrar = 'Falta la equivalencia de una obligación en la fecha del pago.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE @Aplicaciones SET ImporteMXN = CONVERT (DECIMAL (19, 6), ROUND(ImporteAplicado * Factor, 6)), ImporteConsumido = CASE WHEN CveUnidadCobro = @UnidadPago THEN ImporteAplicado ELSE CONVERT (DECIMAL (19, 6), ROUND(ImporteAplicado * Factor / @FactorPago, 6)) END; IF EXISTS (SELECT 1 FROM @Aplicaciones WHERE ImporteMXN <= 0 OR ImporteConsumido <= 0) OR (SELECT SUM(ImporteConsumido) FROM @Aplicaciones) > @Disponible OR (SELECT SUM(ImporteMXN) FROM @Aplicaciones) > @DisponibleMXN BEGIN SELECT @ErrorMostrar = 'Las aplicaciones exceden el saldo disponible del abono o requieren ajustar el redondeo.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @SaldosDetalle TABLE ( CveSolicitudPagoDetalle INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoDetalle, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoDetalle), Traslados AS (SELECT D.CveSolicitudPagoDetalleOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoDetalleOrigen) INSERT INTO @SaldosDetalle SELECT D.CveSolicitudPagoDetalle, D.CveSolicitudPago, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) FROM dbo.Tra_SolicitudesPagoDetalle AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalle LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoDetalleOrigen = D.CveSolicitudPagoDetalle; DECLARE @SaldosParcialidades TABLE ( CveSolicitudPagoParcialidad INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) INSERT INTO @SaldosParcialidades SELECT CveSolicitudPagoParcialidad, CveSolicitudPago, SaldoPendiente FROM SaldosParcialidades; IF EXISTS (SELECT A.CveSolicitudPagoDetalle FROM @Aplicaciones AS A INNER JOIN @SaldosDetalle AS D ON D.CveSolicitudPagoDetalle = A.CveSolicitudPagoDetalle GROUP BY A.CveSolicitudPagoDetalle, D.SaldoPendiente HAVING SUM(A.ImporteAplicado) > D.SaldoPendiente) OR EXISTS (SELECT A.CveSolicitudPagoParcialidad FROM @Aplicaciones AS A INNER JOIN @SaldosParcialidades AS P ON P.CveSolicitudPagoParcialidad = A.CveSolicitudPagoParcialidad GROUP BY A.CveSolicitudPagoParcialidad, P.SaldoPendiente HAVING SUM(A.ImporteAplicado) > P.SaldoPendiente) BEGIN SELECT @ErrorMostrar = 'Las aplicaciones exceden el saldo de un producto o parcialidad.', @ErrorTipo = 2, @Return = 0; RETURN; END INSERT INTO dbo.Tra_PagosAplicaciones (CvePago, CveSolicitudPago, CveSolicitudPagoParcialidad, CveSolicitudPagoDetalle, CveUnidadCobro, ImporteAplicado, ValorConversionObligacion, ImporteAplicadoMXN, ImportePagoConsumido, CveUsuarioRegistro, FechaRegistro) SELECT @CvePago, CveSolicitudPago, CveSolicitudPagoParcialidad, CveSolicitudPagoDetalle, CveUnidadCobro, ImporteAplicado, Factor, ImporteMXN, ImporteConsumido, @CveUsuarioEjecuta, SYSDATETIME() FROM @Aplicaciones; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoAplicar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- El servicio obtiene PermitirDisminucion del permiso Convenios.DisminuirImporte. -- Nunca tomar ese valor directamente de un campo enviado por el navegador. -- Al editar se excluye el traslado propio, sin alterar el historial antes de validar. CREATE OR ALTER PROCEDURE dbo.PA_Tra_ConvenioGuardar @CveSolicitudPago INT=NULL OUTPUT, @CveCliente INT, @CveFraccionamiento INT, @CveFraccionamientoEtapa INT=NULL, @Descripcion VARCHAR (1000), @Importe DECIMAL (19, 6), @CveUnidadCobro INT, @EsRequerido BIT, @FechaGeneracion DATETIME2 (0), @Observaciones VARCHAR (2000)=NULL, @DetalleJson NVARCHAR (MAX), @ParcialidadesJson NVARCHAR (MAX), @OrigenesJson NVARCHAR (MAX), @PermitirDisminucion BIT=0, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @CveSolicitudPago = NULLIF (@CveSolicitudPago, 0); IF ISNULL(ISJSON(@OrigenesJson), 0) <> 1 OR LEFT(LTRIM(@OrigenesJson), 1) <> '[' BEGIN SELECT @ErrorMostrar = 'Los adeudos de origen no tienen un formato válido.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @CveSolicitudPago IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenio WHERE CveSolicitudPago = @CveSolicitudPago) BEGIN SELECT @ErrorMostrar = 'No se encontró el convenio que desea modificar.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Origenes TABLE ( CveSolicitudPagoOrigen INT, CveSolicitudPagoDetalleOrigen INT, CveSolicitudPagoParcialidadOrigen INT, ImporteTomadoConvenio DECIMAL (19, 6)); INSERT INTO @Origenes SELECT CveSolicitudPagoOrigen, CveSolicitudPagoDetalleOrigen, CveSolicitudPagoParcialidadOrigen, ImporteTomadoConvenio FROM OPENJSON (@OrigenesJson) WITH (CveSolicitudPagoOrigen INT, CveSolicitudPagoDetalleOrigen INT, CveSolicitudPagoParcialidadOrigen INT, ImporteTomadoConvenio DECIMAL (19, 6)); IF NOT EXISTS (SELECT 1 FROM @Origenes) OR EXISTS (SELECT 1 FROM @Origenes WHERE CveSolicitudPagoOrigen IS NULL OR CveSolicitudPagoDetalleOrigen IS NULL OR CveSolicitudPagoParcialidadOrigen IS NULL OR ImporteTomadoConvenio IS NULL OR ImporteTomadoConvenio <= 0 OR CveSolicitudPagoOrigen = @CveSolicitudPago) OR EXISTS (SELECT CveSolicitudPagoDetalleOrigen, CveSolicitudPagoParcialidadOrigen FROM @Origenes GROUP BY CveSolicitudPagoDetalleOrigen, CveSolicitudPagoParcialidadOrigen HAVING COUNT(*) > 1) BEGIN SELECT @ErrorMostrar = 'Seleccione saldos positivos sin repetir productos y parcialidades de origen.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM @Origenes AS O LEFT OUTER JOIN dbo.Tra_SolicitudesPago AS S ON S.CveSolicitudPago = O.CveSolicitudPagoOrigen LEFT OUTER JOIN dbo.Tra_SolicitudesPagoDetalle AS D ON D.CveSolicitudPagoDetalle = O.CveSolicitudPagoDetalleOrigen AND D.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN dbo.Tra_SolicitudesPagoParcialidades AS P ON P.CveSolicitudPagoParcialidad = O.CveSolicitudPagoParcialidadOrigen AND P.CveSolicitudPago = S.CveSolicitudPago WHERE S.CveSolicitudPago IS NULL OR D.CveSolicitudPagoDetalle IS NULL OR P.CveSolicitudPagoParcialidad IS NULL OR S.EstadoAdministrativo <> 'ACTIVO' OR S.CveCliente <> @CveCliente OR S.CveFraccionamiento <> @CveFraccionamiento OR S.CveUnidadCobro <> @CveUnidadCobro) BEGIN SELECT @ErrorMostrar = 'Los adeudos deben corresponder al cliente, fraccionamiento y unidad del convenio.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @SaldosDetalle TABLE ( CveSolicitudPagoDetalle INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoDetalle, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoDetalle), Traslados AS (SELECT D.CveSolicitudPagoDetalleOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' AND (@CveSolicitudPago IS NULL OR C.CveSolicitudPago <> @CveSolicitudPago) GROUP BY D.CveSolicitudPagoDetalleOrigen) INSERT INTO @SaldosDetalle SELECT D.CveSolicitudPagoDetalle, D.CveSolicitudPago, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) FROM dbo.Tra_SolicitudesPagoDetalle AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalle LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoDetalleOrigen = D.CveSolicitudPagoDetalle; DECLARE @SaldosParcialidades TABLE ( CveSolicitudPagoParcialidad INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' AND (@CveSolicitudPago IS NULL OR C.CveSolicitudPago <> @CveSolicitudPago) GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) INSERT INTO @SaldosParcialidades SELECT CveSolicitudPagoParcialidad, CveSolicitudPago, SaldoPendiente FROM SaldosParcialidades; IF EXISTS (SELECT O.CveSolicitudPagoDetalleOrigen FROM @Origenes AS O INNER JOIN @SaldosDetalle AS D ON D.CveSolicitudPagoDetalle = O.CveSolicitudPagoDetalleOrigen GROUP BY O.CveSolicitudPagoDetalleOrigen, D.SaldoPendiente HAVING SUM(O.ImporteTomadoConvenio) > D.SaldoPendiente) OR EXISTS (SELECT O.CveSolicitudPagoParcialidadOrigen FROM @Origenes AS O INNER JOIN @SaldosParcialidades AS P ON P.CveSolicitudPagoParcialidad = O.CveSolicitudPagoParcialidadOrigen GROUP BY O.CveSolicitudPagoParcialidadOrigen, P.SaldoPendiente HAVING SUM(O.ImporteTomadoConvenio) > P.SaldoPendiente) BEGIN SELECT @ErrorMostrar = 'El saldo seleccionado excede el disponible en un producto o parcialidad.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @SaldoConvenido AS DECIMAL (19, 6) = (SELECT SUM(ImporteTomadoConvenio) FROM @Origenes), @CveTipoSolicitudPago AS INT; IF ISNULL(@PermitirDisminucion, 0) = 0 AND @Importe < @SaldoConvenido BEGIN SELECT @ErrorMostrar = 'El importe del convenio no puede ser menor al saldo seleccionado.', @ErrorTipo = 2, @Return = 0; RETURN; END SELECT @CveTipoSolicitudPago = CveTipoSolicitudPago FROM dbo.Tra_TiposSolicitudPago WHERE Codigo = 'CONVENIO'; EXECUTE dbo.PA_Tra_SolicitudPagoGuardar @CveSolicitudPago = @CveSolicitudPago OUTPUT, @CveTipoSolicitudPago = @CveTipoSolicitudPago, @CveCliente = @CveCliente, @CveFraccionamiento = @CveFraccionamiento, @CveFraccionamientoEtapa = @CveFraccionamientoEtapa, @Descripcion = @Descripcion, @Importe = @Importe, @CveUnidadCobro = @CveUnidadCobro, @EsRequerido = @EsRequerido, @FechaGeneracion = @FechaGeneracion, @DetalleJson = @DetalleJson, @ParcialidadesJson = @ParcialidadesJson, @DevolverResultado = 0, @EsOperacionConvenio = 1, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenio WHERE CveSolicitudPago = @CveSolicitudPago) UPDATE dbo.Tra_SolicitudesPagoConvenio SET ImporteSaldoConvenido = @SaldoConvenido, Observaciones = @Observaciones WHERE CveSolicitudPago = @CveSolicitudPago; ELSE INSERT INTO dbo.Tra_SolicitudesPagoConvenio (CveSolicitudPago, ImporteSaldoConvenido, Observaciones, CveUsuarioRegistro, FechaRegistro) VALUES (@CveSolicitudPago, @SaldoConvenido, @Observaciones, @CveUsuarioEjecuta, SYSDATETIME()); DELETE D FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen WHERE O.CveSolicitudPagoConvenio = @CveSolicitudPago; DELETE dbo.Tra_SolicitudesPagoConvenioOrigen WHERE CveSolicitudPagoConvenio = @CveSolicitudPago; INSERT INTO dbo.Tra_SolicitudesPagoConvenioOrigen (CveSolicitudPagoConvenio, CveSolicitudPagoOrigen, ImporteSaldoOriginal, ImporteTomadoConvenio, CveUnidadCobro) SELECT @CveSolicitudPago, O.CveSolicitudPagoOrigen, (SELECT SUM(D.SaldoPendiente) FROM @SaldosDetalle AS D WHERE D.CveSolicitudPago = O.CveSolicitudPagoOrigen), SUM(O.ImporteTomadoConvenio), @CveUnidadCobro FROM @Origenes AS O GROUP BY O.CveSolicitudPagoOrigen; INSERT INTO dbo.Tra_SolicitudesPagoConvenioOrigenDetalle (CveConvenioOrigen, CveSolicitudPagoOrigen, CveSolicitudPagoDetalleOrigen, CveSolicitudPagoParcialidadOrigen, ImporteSaldoOriginal, ImporteTomadoConvenio) SELECT C.CveConvenioOrigen, O.CveSolicitudPagoOrigen, O.CveSolicitudPagoDetalleOrigen, O.CveSolicitudPagoParcialidadOrigen, CASE WHEN D.SaldoPendiente < P.SaldoPendiente THEN D.SaldoPendiente ELSE P.SaldoPendiente END, O.ImporteTomadoConvenio FROM @Origenes AS O INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS C ON C.CveSolicitudPagoConvenio = @CveSolicitudPago AND C.CveSolicitudPagoOrigen = O.CveSolicitudPagoOrigen INNER JOIN @SaldosDetalle AS D ON D.CveSolicitudPagoDetalle = O.CveSolicitudPagoDetalleOrigen INNER JOIN @SaldosParcialidades AS P ON P.CveSolicitudPagoParcialidad = O.CveSolicitudPagoParcialidadOrigen; SELECT @CveSolicitudPago AS CveSolicitudPago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_ConvenioGuardar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_UnidadCobroListar @SoloActivas BIT=1, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT CveUnidadCobro, Codigo, Nombre, EsMoneda, RequiereConversion, CveMoneda, Activo FROM dbo.Gral_UnidadesCobro WHERE @SoloActivas = 0 OR Activo = 1 ORDER BY Nombre; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_UnidadCobroListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_UnidadCobroGuardar @CveUnidadCobro INT=NULL OUTPUT, @Codigo VARCHAR (10), @Nombre VARCHAR (100), @EsMoneda BIT, @RequiereConversion BIT, @CveMoneda INT=NULL, @Activo BIT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @CveUnidadCobro = NULLIF (@CveUnidadCobro, 0); SET @Codigo = UPPER(LTRIM(RTRIM(@Codigo))); IF NULLIF (@Codigo, '') IS NULL OR NULLIF (LTRIM(RTRIM(@Nombre)), '') IS NULL OR @EsMoneda IS NULL OR @RequiereConversion IS NULL OR @Activo IS NULL BEGIN SELECT @ErrorMostrar = 'Capture código, nombre y características de la unidad.', @ErrorTipo = 2, @Return = 0; RETURN; END IF (@EsMoneda = 1 AND @CveMoneda IS NULL) OR (@EsMoneda = 0 AND @CveMoneda IS NOT NULL) OR (@Codigo = 'MXN' AND (@EsMoneda <> 1 OR @RequiereConversion <> 0)) OR (@Codigo <> 'MXN' AND @RequiereConversion = 0) BEGIN SELECT @ErrorMostrar = 'La unidad base MXN no requiere conversión; las demás unidades sí. Relacione las monedas con el catálogo existente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE Codigo = @Codigo AND (@CveUnidadCobro IS NULL OR CveUnidadCobro <> @CveUnidadCobro)) BEGIN SELECT @ErrorMostrar = 'Ya existe una unidad con ese código.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @CveUnidadCobro IS NULL BEGIN INSERT INTO dbo.Gral_UnidadesCobro (Codigo, Nombre, EsMoneda, RequiereConversion, CveMoneda, Activo) VALUES (@Codigo, @Nombre, @EsMoneda, @RequiereConversion, @CveMoneda, @Activo); SET @CveUnidadCobro = CONVERT (INT, SCOPE_IDENTITY()); END ELSE BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro) BEGIN SELECT @ErrorMostrar = 'No se encontró la unidad.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro AND (Codigo <> @Codigo OR EsMoneda <> @EsMoneda OR RequiereConversion <> @RequiereConversion OR ISNULL(CveMoneda, 0) <> ISNULL(@CveMoneda, 0))) AND (EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobroValores WHERE CveUnidadCobro = @CveUnidadCobro) OR EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagos WHERE CveUnidadCobro = @CveUnidadCobro) OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WHERE CveUnidadCobro = @CveUnidadCobro) OR EXISTS (SELECT 1 FROM dbo.Tra_Pagos WHERE CveUnidadCobro = @CveUnidadCobro)) BEGIN SELECT @ErrorMostrar = 'La unidad tiene registros relacionados; conserve su código y características de conversión.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Gral_UnidadesCobro SET Codigo = @Codigo, Nombre = @Nombre, EsMoneda = @EsMoneda, RequiereConversion = @RequiereConversion, CveMoneda = @CveMoneda, Activo = @Activo WHERE CveUnidadCobro = @CveUnidadCobro; END SELECT @CveUnidadCobro AS CveUnidadCobro; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_UnidadCobroGuardar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_UnidadCobroValoresListar @CveUnidadCobro INT, @FechaHasta DATE=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT V.CveUnidadCobroValor, V.CveUnidadCobro, U.Codigo AS UnidadCobro, V.FechaVigencia, V.ValorMXN, V.Fuente, V.FechaRegistro, V.CveUsuarioRegistro FROM dbo.Gral_UnidadesCobroValores AS V INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = V.CveUnidadCobro WHERE V.CveUnidadCobro = @CveUnidadCobro AND (@FechaHasta IS NULL OR V.FechaVigencia <= @FechaHasta) ORDER BY V.FechaVigencia DESC; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_UnidadCobroValoresListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_UnidadCobroValorAgregar @CveUnidadCobro INT, @FechaVigencia DATE, @ValorMXN DECIMAL (19, 8), @Fuente VARCHAR (500), @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @FechaVigencia IS NULL OR @ValorMXN IS NULL OR @ValorMXN <= 0 OR NULLIF (LTRIM(RTRIM(@Fuente)), '') IS NULL BEGIN SELECT @ErrorMostrar = 'Capture vigencia, valor positivo y fuente de la equivalencia.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro AND RequiereConversion = 1) BEGIN SELECT @ErrorMostrar = 'La unidad seleccionada no requiere equivalencias.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobroValores WHERE CveUnidadCobro = @CveUnidadCobro AND FechaVigencia = @FechaVigencia) BEGIN SELECT @ErrorMostrar = 'Ya existe un valor para esa vigencia; el histórico no se sobrescribe.', @ErrorTipo = 2, @Return = 0; RETURN; END INSERT INTO dbo.Gral_UnidadesCobroValores (CveUnidadCobro, FechaVigencia, ValorMXN, Fuente, CveUsuarioRegistro, FechaRegistro) VALUES (@CveUnidadCobro, @FechaVigencia, @ValorMXN, @Fuente, @CveUsuarioEjecuta, SYSDATETIME()); SELECT CONVERT (INT, SCOPE_IDENTITY()) AS CveUnidadCobroValor; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_UnidadCobroValorAgregar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Acceso a esta operación: servicio del catálogo de usuarios, sólo SuperUsuario. CREATE OR ALTER PROCEDURE dbo.PA_Sis_UsuarioPermisosListar @CveUsuario INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT P.CvePermiso, P.CodigoPermiso, P.NombrePermiso, P.Descripcion, U.Permitido AS PermisoUsuario, R.Permitido AS PermisoRol, CONVERT (BIT, COALESCE (U.Permitido, R.Permitido, 0)) AS PermitidoEfectivo FROM dbo.Sis_Permisos AS P INNER JOIN dbo.Sis_Usuarios AS S ON S.CveUsuario = @CveUsuario LEFT OUTER JOIN dbo.Sis_UsuariosPermisos AS U ON U.CveUsuario = S.CveUsuario AND U.CvePermiso = P.CvePermiso LEFT OUTER JOIN dbo.Sis_RolesPermisos AS R ON R.CveRol = S.CveRol AND R.CvePermiso = P.CvePermiso WHERE P.Activo = 1 ORDER BY P.NombrePermiso; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Sis_UsuarioPermisosListar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- El servicio verifica SuperUsuario. NULL restaura herencia, 0 deniega y 1 permite. CREATE OR ALTER PROCEDURE dbo.PA_Sis_UsuarioPermisosGuardar @CveUsuario INT, @CvePermiso INT, @Permitido BIT=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Permitido IS NULL DELETE dbo.Sis_UsuariosPermisos WHERE CveUsuario = @CveUsuario AND CvePermiso = @CvePermiso; ELSE IF EXISTS (SELECT 1 FROM dbo.Sis_UsuariosPermisos WHERE CveUsuario = @CveUsuario AND CvePermiso = @CvePermiso) UPDATE dbo.Sis_UsuariosPermisos SET Permitido = @Permitido WHERE CveUsuario = @CveUsuario AND CvePermiso = @CvePermiso; ELSE INSERT INTO dbo.Sis_UsuariosPermisos (CveUsuario, CvePermiso, Permitido, FechaCreacion) VALUES (@CveUsuario, @CvePermiso, @Permitido, SYSDATETIME()); SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Sis_UsuarioPermisosGuardar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Los metadatos son captura manual. El servicio guarda archivos en almacenamiento protegido. CREATE OR ALTER PROCEDURE dbo.PA_Fac_CfdiExternoGuardar @CveCfdiDocumento BIGINT=NULL OUTPUT, @CveCliente INT, @VersionCfdi VARCHAR (5), @Moneda VARCHAR (3), @Total DECIMAL (19, 6), @TipoCambio DECIMAL (19, 6)=NULL, @Uuid UNIQUEIDENTIFIER=NULL, @Serie VARCHAR (25)=NULL, @Folio VARCHAR (40)=NULL, @FechaEmision DATETIME2 (0)=NULL, @FechaTimbrado DATETIME2 (0)=NULL, @RutaXml VARCHAR (500)=NULL, @HashXml BINARY (32)=NULL, @RutaPdf VARCHAR (500)=NULL, @HashPdf BINARY (32)=NULL, @ImporteValidado BIT=0, @MarcarTimbrado BIT=0, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @CveCfdiDocumento = NULLIF (@CveCfdiDocumento, 0); SET @Moneda = UPPER(LTRIM(RTRIM(@Moneda))); IF @Total IS NULL OR @Total <= 0 OR NULLIF (LTRIM(RTRIM(@VersionCfdi)), '') IS NULL OR NULLIF (@Moneda, '') IS NULL OR (@Moneda <> 'MXN' AND ISNULL(@TipoCambio, 0) <= 0) BEGIN SELECT @ErrorMostrar = 'Capture importe, versión, moneda y equivalencia del documento cuando corresponda.', @ErrorTipo = 2, @Return = 0; RETURN; END IF (@RutaXml IS NULL AND @HashXml IS NOT NULL) OR (@RutaXml IS NOT NULL AND @HashXml IS NULL) OR (@RutaPdf IS NULL AND @HashPdf IS NOT NULL) OR (@RutaPdf IS NOT NULL AND @HashPdf IS NULL) BEGIN SELECT @ErrorMostrar = 'Los archivos deben incluir su huella de integridad.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @MarcarTimbrado = 1 AND (@Uuid IS NULL OR @RutaXml IS NULL OR @RutaPdf IS NULL OR ISNULL(@ImporteValidado, 0) = 0 OR @FechaTimbrado IS NULL) BEGIN SELECT @ErrorMostrar = 'Para marcar timbrado capture UUID, fecha, XML, PDF y valide el importe.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Uuid IS NOT NULL AND (EXISTS (SELECT 1 FROM dbo.Fac_CfdiDocumentos WHERE UuidExterno = @Uuid AND (@CveCfdiDocumento IS NULL OR CveCfdiDocumento <> @CveCfdiDocumento)) OR EXISTS (SELECT 1 FROM dbo.Fac_CfdiTimbrados WHERE TRY_CONVERT (UNIQUEIDENTIFIER, Uuid) = @Uuid)) BEGIN SELECT @ErrorMostrar = 'El UUID ya está registrado. Utilice el documento existente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @CveCfdiDocumento IS NOT NULL BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Fac_CfdiDocumentos WHERE CveCfdiDocumento = @CveCfdiDocumento AND OrigenRegistro = 'EXTERNO') BEGIN SELECT @ErrorMostrar = 'El documento no corresponde a una carga externa.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_PagosCfdi WHERE CveCfdiDocumento = @CveCfdiDocumento) BEGIN SELECT @ErrorMostrar = 'El documento está vinculado a pagos. Sus metadatos validados deben conservarse.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Fac_CfdiDocumentos SET CveCliente = @CveCliente, VersionCfdi = @VersionCfdi, Moneda = @Moneda, Total = @Total, TipoCambio = CASE WHEN @Moneda = 'MXN' THEN 1 ELSE @TipoCambio END, UuidExterno = @Uuid, Serie = @Serie, Folio = @Folio, FechaEmision = @FechaEmision, FechaTimbradoExterno = @FechaTimbrado, RutaXmlExterno = @RutaXml, HashXmlExterno = @HashXml, RutaPdf = @RutaPdf, HashPdf = @HashPdf, ImporteValidado = @ImporteValidado, CveUsuarioValida = CASE WHEN @ImporteValidado = 1 THEN @CveUsuarioEjecuta END, FechaValidacion = CASE WHEN @ImporteValidado = 1 THEN SYSDATETIME() END, Estado = CASE WHEN @MarcarTimbrado = 1 THEN 'TIMBRADO' ELSE 'BORRADOR' END, FechaModificacion = SYSDATETIME() WHERE CveCfdiDocumento = @CveCfdiDocumento; END ELSE BEGIN INSERT INTO dbo.Fac_CfdiDocumentos (CveEmpresa, TipoComprobante, Exportacion, LugarExpedicion, Subtotal, Descuento, TotalImpuestosTrasladados, TotalImpuestosRetenidos, RfcEmisor, NombreEmisor, RegimenFiscalEmisor, RfcReceptor, NombreReceptor, DomicilioFiscalReceptor, RegimenFiscalReceptor, UsoCfdi, XmlSinTimbrar, HashXmlSinTimbrar, IdentificadorDocumento, CveCliente, VersionCfdi, Moneda, Total, TipoCambio, UuidExterno, Serie, Folio, FechaEmision, FechaTimbradoExterno, RutaXmlExterno, HashXmlExterno, RutaPdf, HashPdf, ImporteValidado, CveUsuarioValida, FechaValidacion, Estado, OrigenRegistro, FechaAlta, CveUsuario) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NEWID(), @CveCliente, @VersionCfdi, @Moneda, @Total, CASE WHEN @Moneda = 'MXN' THEN 1 ELSE @TipoCambio END, @Uuid, @Serie, @Folio, @FechaEmision, @FechaTimbrado, @RutaXml, @HashXml, @RutaPdf, @HashPdf, @ImporteValidado, CASE WHEN @ImporteValidado = 1 THEN @CveUsuarioEjecuta END, CASE WHEN @ImporteValidado = 1 THEN SYSDATETIME() END, CASE WHEN @MarcarTimbrado = 1 THEN 'TIMBRADO' ELSE 'BORRADOR' END, 'EXTERNO', SYSDATETIME(), @CveUsuarioEjecuta); SET @CveCfdiDocumento = CONVERT (BIGINT, SCOPE_IDENTITY()); END SELECT @CveCfdiDocumento AS CveCfdiDocumento; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Fac_CfdiExternoGuardar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoCfdiVincular @CvePago INT, @CveCfdiDocumento BIGINT, @ImporteVinculadoMXN DECIMAL (19, 6), @ImporteDocumentoValidado DECIMAL (19, 6), @RutaPdf VARCHAR (500)=NULL, @HashPdf BINARY (32)=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @ClientePago AS INT, @ClienteDocumento AS INT, @ImportePago AS DECIMAL (19, 6), @TotalDocumento AS DECIMAL (19, 6), @TotalDocumentoMXN AS DECIMAL (19, 6); SELECT @ClientePago = CveCliente, @ImportePago = ImporteMXN FROM dbo.Tra_Pagos WHERE CvePago = @CvePago AND EsActivo = 1 AND Autorizado = 1; SELECT @ClienteDocumento = D.CveCliente, @TotalDocumento = D.Total, @TotalDocumentoMXN = CONVERT (DECIMAL (19, 6), ROUND(D.Total * CASE WHEN D.Moneda = 'MXN' THEN 1 ELSE D.TipoCambio END, 6)) FROM dbo.Fac_CfdiDocumentos AS D WHERE D.CveCfdiDocumento = @CveCfdiDocumento AND D.Estado = 'TIMBRADO'; IF @ClientePago IS NULL OR @ClienteDocumento IS NULL OR @ClientePago <> @ClienteDocumento BEGIN SELECT @ErrorMostrar = 'Seleccione un pago recibido y un documento timbrado del mismo cliente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @ImporteDocumentoValidado IS NULL OR @ImporteDocumentoValidado <> @TotalDocumento OR @TotalDocumentoMXN IS NULL OR @TotalDocumentoMXN <= 0 BEGIN SELECT @ErrorMostrar = 'El importe capturado no coincide con el documento o falta su equivalencia a MXN.', @ErrorTipo = 2, @Return = 0; RETURN; END IF ISNULL(@ImporteVinculadoMXN, 0) <= 0 OR @ImporteVinculadoMXN + ISNULL((SELECT SUM(ImporteVinculadoMXN) FROM dbo.Tra_PagosCfdi WHERE CvePago = @CvePago), 0) > @ImportePago OR @ImporteVinculadoMXN + ISNULL((SELECT SUM(ImporteVinculadoMXN) FROM dbo.Tra_PagosCfdi WHERE CveCfdiDocumento = @CveCfdiDocumento), 0) > @TotalDocumentoMXN BEGIN SELECT @ErrorMostrar = 'El importe a vincular excede el disponible en el pago o documento.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_PagosCfdi WHERE CvePago = @CvePago AND CveCfdiDocumento = @CveCfdiDocumento) BEGIN SELECT @ErrorMostrar = 'El documento ya está vinculado a este pago.', @ErrorTipo = 2, @Return = 0; RETURN; END IF (@RutaPdf IS NULL AND @HashPdf IS NOT NULL) OR (@RutaPdf IS NOT NULL AND @HashPdf IS NULL) BEGIN SELECT @ErrorMostrar = 'El archivo PDF debe incluir su huella de integridad.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Fac_CfdiDocumentos SET ImporteValidado = 1, CveUsuarioValida = @CveUsuarioEjecuta, FechaValidacion = SYSDATETIME(), RutaPdf = COALESCE (@RutaPdf, RutaPdf), HashPdf = COALESCE (@HashPdf, HashPdf), FechaModificacion = SYSDATETIME() WHERE CveCfdiDocumento = @CveCfdiDocumento; INSERT INTO dbo.Tra_PagosCfdi (CvePago, CveCfdiDocumento, ImporteVinculadoMXN, CveUsuarioRegistro, FechaRegistro) VALUES (@CvePago, @CveCfdiDocumento, @ImporteVinculadoMXN, @CveUsuarioEjecuta, SYSDATETIME()); SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoCfdiVincular'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- El servicio valida el acceso del cliente y resuelve rutas dentro del almacén protegido. CREATE OR ALTER PROCEDURE dbo.PA_Fac_CfdiArchivoObtener @CveCfdiDocumento BIGINT, @TipoArchivo VARCHAR (3), @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @TipoArchivo IS NULL OR UPPER(@TipoArchivo) NOT IN ('XML', 'PDF') BEGIN SELECT @ErrorMostrar = 'Seleccione XML o PDF.', @ErrorTipo = 2, @Return = 0; RETURN; END SELECT D.CveCfdiDocumento, D.CveCliente, D.OrigenRegistro, CASE WHEN UPPER(@TipoArchivo) = 'PDF' THEN D.RutaPdf ELSE D.RutaXmlExterno END AS RutaProtegida, CASE WHEN UPPER(@TipoArchivo) = 'XML' AND D.OrigenRegistro = 'INTERNO' THEN T.XmlTimbrado END AS Contenido, CASE WHEN UPPER(@TipoArchivo) = 'PDF' THEN D.HashPdf WHEN D.OrigenRegistro = 'EXTERNO' THEN D.HashXmlExterno ELSE T.HashXmlTimbrado END AS HuellaArchivo, CASE WHEN UPPER(@TipoArchivo) = 'PDF' THEN 'application/pdf' ELSE 'application/xml' END AS TipoContenido FROM dbo.Fac_CfdiDocumentos AS D LEFT OUTER JOIN dbo.Fac_CfdiTimbrados AS T ON T.CveCfdiTimbrado = D.CveCfdiTimbradoVigente AND T.Exitoso = 1 WHERE D.CveCfdiDocumento = @CveCfdiDocumento; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Fac_CfdiArchivoObtener'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Adaptación de objetos existentes; conservar sus nombres para los repositorios. CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDelete @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago) BEGIN SELECT @ErrorMostrar = 'El pago tiene conceptos registrados. Elimine primero sus conceptos.', @ErrorTipo = 2; RETURN; END DELETE dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @CveTramitePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al eliminar el pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoDelete'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDetalleDelete @CveTramitePagoDetalle INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveTramitePago AS INT; SELECT @CveTramitePago = CveTramitePago FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle; DELETE dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle; UPDATE dbo.Tra_TiposTramitePagos SET Importe = ISNULL((SELECT SUM(Importe) FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago), 0), FechaModificacion = SYSDATETIME(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePago = @CveTramitePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoDetalleDelete'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDetalleGet @CveTramitePagoDetalle INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT D.CveTramitePagoDetalle, D.CveTramitePago, P.Nombre AS Pago, D.CvePS, PS.Codigo, PS.PS, D.CveUM, UM.UnidadMedida, UM.Abreviatura, D.Cantidad, D.CveUnidadCobro, D.Descripcion, D.PrecioUnitario, D.Importe AS ImporteFinal, CONVERT (DECIMAL (18, 2), PS.Precio) AS PrecioProducto, CONVERT (DECIMAL (18, 2), COALESCE (Costo.Importe, PS.Precio)) AS Importe, COALESCE (Costo.CveObjetoImpuesto, PS.CveObjetoImpuesto) AS CveObjetoImpuesto, OI.CodigoObjetoImpuesto, OI.CodigoObjetoImpuesto COLLATE Modern_Spanish_CS_AS + ' - ' + OI.ObjetoImpuesto AS ObjetoImpuesto, CONVERT (DECIMAL (9, 6), COALESCE (ImpuestoIVA.TasaOCuota, CASE WHEN PS.CveObjetoImpuesto = 1 THEN 0 WHEN PS.IVA IS NULL OR PS.IVA = -1 THEN 0.16 ELSE PS.IVA END)) AS PorcentajeIVA, Costo.FechaInicioVigencia, Costo.FechaFinVigencia, CONVERT (DECIMAL (18, 2), ROUND(D.Cantidad * COALESCE (Costo.Importe, PS.Precio) * COALESCE (ImpuestoIVA.TasaOCuota, 0), 2)) AS ImporteIVA, D.Importe AS Total FROM dbo.Tra_TiposTramitePagosDetalle AS D INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = D.CveTramitePago INNER JOIN dbo.ProductosServicios AS PS ON PS.CvePS = D.CvePS LEFT OUTER JOIN dbo.UnidadesMedida AS UM ON UM.CveUnidadMedida = D.CveUM OUTER APPLY (SELECT TOP (1) CT.CveCostoTramite, CT.Importe, CT.CveObjetoImpuesto, CT.FechaInicioVigencia, CT.FechaFinVigencia FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = P.CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, GETDATE())) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, GETDATE())) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC) AS Costo OUTER APPLY (SELECT TOP (1) CTI.TasaOCuota FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = Costo.CveCostoTramite AND CTI.EsRetencion = 0 AND CTI.Impuesto = '002' AND CTI.TipoFactor = 'Tasa') AS ImpuestoIVA INNER JOIN dbo.Gral_SAT_ObjetoImpuesto AS OI ON OI.CveObjetoImpuesto = COALESCE (Costo.CveObjetoImpuesto, PS.CveObjetoImpuesto) WHERE D.CveTramitePagoDetalle = @CveTramitePagoDetalle; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al consultar el concepto del pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoDetalleGet'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDetalleList @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT D.CveTramitePagoDetalle, D.CveTramitePago, P.Nombre AS Pago, D.CvePS, PS.Codigo, PS.PS, D.CveUM, UM.UnidadMedida, UM.Abreviatura, D.Cantidad, D.CveUnidadCobro, D.Descripcion, D.PrecioUnitario, D.Importe AS ImporteFinal, CONVERT (DECIMAL (18, 2), PS.Precio) AS PrecioProducto, CONVERT (DECIMAL (18, 2), COALESCE (Costo.Importe, PS.Precio)) AS Importe, COALESCE (Costo.CveObjetoImpuesto, PS.CveObjetoImpuesto) AS CveObjetoImpuesto, OI.CodigoObjetoImpuesto, OI.CodigoObjetoImpuesto COLLATE Modern_Spanish_CS_AS + ' - ' + OI.ObjetoImpuesto AS ObjetoImpuesto, CONVERT (DECIMAL (9, 6), COALESCE (ImpuestoIVA.TasaOCuota, CASE WHEN PS.CveObjetoImpuesto = 1 THEN 0 WHEN PS.IVA IS NULL OR PS.IVA = -1 THEN 0.16 ELSE PS.IVA END)) AS PorcentajeIVA, Costo.FechaInicioVigencia, Costo.FechaFinVigencia, CONVERT (DECIMAL (18, 2), ROUND(D.Cantidad * COALESCE (Costo.Importe, PS.Precio) * COALESCE (ImpuestoIVA.TasaOCuota, 0), 2)) AS ImporteIVA, D.Importe AS Total FROM dbo.Tra_TiposTramitePagosDetalle AS D INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = D.CveTramitePago INNER JOIN dbo.ProductosServicios AS PS ON PS.CvePS = D.CvePS LEFT OUTER JOIN dbo.UnidadesMedida AS UM ON UM.CveUnidadMedida = D.CveUM OUTER APPLY (SELECT TOP (1) CT.CveCostoTramite, CT.Importe, CT.CveObjetoImpuesto, CT.FechaInicioVigencia, CT.FechaFinVigencia FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = P.CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, GETDATE())) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, GETDATE())) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC) AS Costo OUTER APPLY (SELECT TOP (1) CTI.TasaOCuota FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = Costo.CveCostoTramite AND CTI.EsRetencion = 0 AND CTI.Impuesto = '002' AND CTI.TipoFactor = 'Tasa') AS ImpuestoIVA INNER JOIN dbo.Gral_SAT_ObjetoImpuesto AS OI ON OI.CveObjetoImpuesto = COALESCE (Costo.CveObjetoImpuesto, PS.CveObjetoImpuesto) WHERE D.CveTramitePago = @CveTramitePago ORDER BY D.CveTramitePagoDetalle; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al consultar los conceptos del pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoDetalleList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Compatibilidad con captura anterior de precio neto e impuestos. CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDetalleSave @CveTramitePagoDetalle INT=NULL, @CveTramitePago INT, @CvePS INT, @CveUM INT, @Cantidad DECIMAL (18, 4), @Importe DECIMAL (18, 2)=NULL, @CveObjetoImpuesto TINYINT, @PorcentajeIVA DECIMAL (9, 6), @FechaInicioVigencia DATE=NULL, @PrecioUnitarioFinal DECIMAL (19, 6)=NULL, @DescripcionFinal VARCHAR (1000)=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @UnidadPlantilla AS INT; SELECT @UnidadPlantilla = CveUnidadCobro FROM dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @CveTramitePago; IF @PrecioUnitarioFinal IS NOT NULL BEGIN IF @Cantidad IS NULL OR @Cantidad <= 0 OR @PrecioUnitarioFinal < 0 OR @UnidadPlantilla IS NULL BEGIN SELECT @ErrorMostrar = 'Capture cantidad, precio final y plantilla válidos.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @DescripcionFinal = COALESCE (NULLIF (LTRIM(RTRIM(@DescripcionFinal)), ''), (SELECT PS FROM dbo.ProductosServicios WHERE CvePS = @CvePS)); SET @CveTramitePagoDetalle = NULLIF (@CveTramitePagoDetalle, 0); IF @CveTramitePagoDetalle IS NULL BEGIN INSERT INTO dbo.Tra_TiposTramitePagosDetalle (CveTramitePago, CvePS, CveUM, Cantidad, FechaAlta, CveUsuario, Descripcion, PrecioUnitario, CveUnidadCobro, Importe) VALUES (@CveTramitePago, @CvePS, @CveUM, @Cantidad, SYSDATETIME(), @CveUsuarioEjecuta, @DescripcionFinal, @PrecioUnitarioFinal, @UnidadPlantilla, ROUND(@Cantidad * @PrecioUnitarioFinal, 6)); SET @CveTramitePagoDetalle = CONVERT (INT, SCOPE_IDENTITY()); END ELSE BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle AND CveTramitePago = @CveTramitePago) BEGIN SELECT @ErrorMostrar = 'No se encontró el concepto en la plantilla.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Tra_TiposTramitePagosDetalle SET CvePS = @CvePS, CveUM = @CveUM, Cantidad = @Cantidad, Descripcion = @DescripcionFinal, PrecioUnitario = @PrecioUnitarioFinal, Importe = ROUND(@Cantidad * @PrecioUnitarioFinal, 6), FechaModificacion = SYSDATETIME(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle; END UPDATE dbo.Tra_TiposTramitePagos SET Importe = (SELECT SUM(Importe) FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago), FechaModificacion = SYSDATETIME(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePago = @CveTramitePago; SELECT @CveTramitePagoDetalle AS CveTramitePagoDetalle; SET @Return = 1; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @UnidadPlantilla AND Codigo = 'MXN') BEGIN SELECT @ErrorMostrar = 'Para esta unidad capture el precio final de la plantilla.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveTipoTramite AS INT, @CveMoneda AS INT, @Descripcion AS VARCHAR (300), @PrecioProducto AS DECIMAL (18, 2), @CveCostoVigente AS INT, @CveCostoObjetivo AS INT, @FechaInicioVigente AS DATE, @ImporteVigente AS DECIMAL (18, 2), @CveObjetoImpuestoVigente AS TINYINT, @PorcentajeIVAVigente AS DECIMAL (9, 6); SELECT @CveTipoTramite = P.CveTipoTramite FROM dbo.Tra_TiposTramitePagos AS P WHERE P.CveTramitePago = @CveTramitePago; SELECT @PrecioProducto = CONVERT (DECIMAL (18, 2), PS.Precio), @Descripcion = LEFT(PS.PS, 300) FROM dbo.ProductosServicios AS PS WHERE PS.CvePS = @CvePS AND PS.Estado = 1; SELECT TOP (1) @CveMoneda = M.CveMoneda FROM dbo.Gral_Monedas AS M WHERE M.AbreviaturaSAT = 'MXN' ORDER BY M.CveMoneda; SET @Importe = ISNULL(@Importe, @PrecioProducto); SET @FechaInicioVigencia = ISNULL(@FechaInicioVigencia, CONVERT (DATE, GETDATE())); IF @CveTipoTramite IS NULL OR @PrecioProducto IS NULL OR @CveMoneda IS NULL BEGIN SELECT @ErrorMostrar = 'El pago, producto o moneda seleccionados no están disponibles.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.UnidadesMedida WHERE CveUnidadMedida = @CveUM AND Estado = 1) BEGIN SELECT @ErrorMostrar = 'Seleccione una unidad de medida vigente.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Gral_SAT_ObjetoImpuesto WHERE CveObjetoImpuesto = @CveObjetoImpuesto) BEGIN SELECT @ErrorMostrar = 'Seleccione un objeto de impuesto válido.', @ErrorTipo = 2; RETURN; END IF @Cantidad <= 0 OR @Importe < 0 OR @PorcentajeIVA < 0 OR @PorcentajeIVA > 1 BEGIN SELECT @ErrorMostrar = 'Capture cantidad, importe y porcentaje de IVA válidos.', @ErrorTipo = 2; RETURN; END IF @CveObjetoImpuesto = 1 SET @PorcentajeIVA = 0; SET @CveTramitePagoDetalle = NULLIF (@CveTramitePagoDetalle, 0); IF @CveTramitePagoDetalle IS NULL BEGIN INSERT dbo.Tra_TiposTramitePagosDetalle (CveTramitePago, CvePS, CveUM, Cantidad, FechaAlta, CveUsuario, Descripcion, PrecioUnitario, CveUnidadCobro, Importe) VALUES (@CveTramitePago, @CvePS, @CveUM, @Cantidad, GETDATE(), @CveUsuarioEjecuta, @Descripcion, @Importe, @UnidadPlantilla, ROUND(@Cantidad * @Importe, 6)); SET @CveTramitePagoDetalle = CONVERT (INT, SCOPE_IDENTITY()); END ELSE BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle AND CveTramitePago = @CveTramitePago) BEGIN SELECT @ErrorMostrar = 'El concepto de pago seleccionado no existe.', @ErrorTipo = 2; RETURN; END UPDATE dbo.Tra_TiposTramitePagosDetalle SET CvePS = @CvePS, CveUM = @CveUM, Cantidad = @Cantidad, FechaModificacion = GETDATE(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle; END SELECT TOP (1) @CveCostoVigente = CT.CveCostoTramite, @FechaInicioVigente = CT.FechaInicioVigencia, @ImporteVigente = CT.Importe, @CveObjetoImpuestoVigente = CT.CveObjetoImpuesto, @PorcentajeIVAVigente = IVA.TasaOCuota FROM dbo.Tra_CostosTramite AS CT OUTER APPLY (SELECT TOP (1) CTI.TasaOCuota FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = CT.CveCostoTramite AND CTI.EsRetencion = 0 AND CTI.Impuesto = '002' AND CTI.TipoFactor = 'Tasa') AS IVA WHERE CT.CveTipoTramite = @CveTipoTramite AND CT.CvePS = @CvePS AND CT.EsActivo = 1 AND CT.FechaFinVigencia IS NULL ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC; IF @CveCostoVigente IS NULL BEGIN INSERT dbo.Tra_CostosTramite (CveTipoTramite, CvePS, CveMoneda, Descripcion, Importe, CveObjetoImpuesto, FechaInicioVigencia, FechaFinVigencia, EsActivo, CveUsuario) VALUES (@CveTipoTramite, @CvePS, @CveMoneda, @Descripcion, @Importe, @CveObjetoImpuesto, @FechaInicioVigencia, NULL, 1, @CveUsuarioEjecuta); SET @CveCostoObjetivo = CONVERT (INT, SCOPE_IDENTITY()); END ELSE IF @FechaInicioVigente IS NOT NULL AND @FechaInicioVigencia < @FechaInicioVigente BEGIN SELECT @ErrorMostrar = 'La nueva vigencia no puede iniciar antes de la vigencia actual.', @ErrorTipo = 2; RETURN; END ELSE IF @FechaInicioVigente = @FechaInicioVigencia BEGIN UPDATE dbo.Tra_CostosTramite SET CveMoneda = @CveMoneda, Descripcion = @Descripcion, Importe = @Importe, CveObjetoImpuesto = @CveObjetoImpuesto, FechaInicioVigencia = @FechaInicioVigencia, FechaModificacion = GETDATE(), CveUsuario = @CveUsuarioEjecuta WHERE CveCostoTramite = @CveCostoVigente; SET @CveCostoObjetivo = @CveCostoVigente; END ELSE IF @ImporteVigente <> @Importe OR @CveObjetoImpuestoVigente <> @CveObjetoImpuesto OR ISNULL(@PorcentajeIVAVigente, 0) <> @PorcentajeIVA BEGIN UPDATE dbo.Tra_CostosTramite SET FechaFinVigencia = DATEADD(day, -1, @FechaInicioVigencia), FechaModificacion = GETDATE(), CveUsuario = @CveUsuarioEjecuta WHERE CveCostoTramite = @CveCostoVigente; INSERT dbo.Tra_CostosTramite (CveTipoTramite, CvePS, CveMoneda, Descripcion, Importe, CveObjetoImpuesto, FechaInicioVigencia, FechaFinVigencia, EsActivo, CveUsuario) VALUES (@CveTipoTramite, @CvePS, @CveMoneda, @Descripcion, @Importe, @CveObjetoImpuesto, @FechaInicioVigencia, NULL, 1, @CveUsuarioEjecuta); SET @CveCostoObjetivo = CONVERT (INT, SCOPE_IDENTITY()); INSERT dbo.Tra_CostosTramiteImpuestos (CveCostoTramite, EsRetencion, Impuesto, TipoFactor, TasaOCuota, FechaAlta, CveUsuario) SELECT @CveCostoObjetivo, CTI.EsRetencion, CTI.Impuesto, CTI.TipoFactor, CTI.TasaOCuota, GETDATE(), @CveUsuarioEjecuta FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = @CveCostoVigente AND NOT (CTI.EsRetencion = 0 AND CTI.Impuesto = '002'); END ELSE BEGIN SET @CveCostoObjetivo = @CveCostoVigente; END DELETE dbo.Tra_CostosTramiteImpuestos WHERE CveCostoTramite = @CveCostoObjetivo AND EsRetencion = 0 AND Impuesto = '002'; IF @CveObjetoImpuesto <> 1 AND @PorcentajeIVA > 0 BEGIN INSERT dbo.Tra_CostosTramiteImpuestos (CveCostoTramite, EsRetencion, Impuesto, TipoFactor, TasaOCuota, FechaAlta, CveUsuario) VALUES (@CveCostoObjetivo, 0, '002', 'Tasa', @PorcentajeIVA, GETDATE(), @CveUsuarioEjecuta); END UPDATE D SET Descripcion = @Descripcion, Importe = ROUND(@Cantidad * @Importe, 2) + ISNULL((SELECT SUM(CASE WHEN I.EsRetencion = 1 THEN -1 ELSE 1 END * CASE WHEN I.TipoFactor = 'Exento' THEN 0 WHEN I.TipoFactor = 'Cuota' THEN ROUND(@Cantidad * I.TasaOCuota, 2) ELSE ROUND(@Cantidad * @Importe * I.TasaOCuota, 2) END) FROM dbo.Tra_CostosTramiteImpuestos AS I WHERE I.CveCostoTramite = @CveCostoObjetivo), 0), CveUnidadCobro = @UnidadPlantilla FROM dbo.Tra_TiposTramitePagosDetalle AS D WHERE D.CveTramitePagoDetalle = @CveTramitePagoDetalle; UPDATE dbo.Tra_TiposTramitePagosDetalle SET PrecioUnitario = ROUND(Importe / Cantidad, 6) WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle; UPDATE dbo.Tra_TiposTramitePagos SET Importe = (SELECT SUM(Importe) FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago), FechaModificacion = SYSDATETIME(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePago = @CveTramitePago; SELECT @CveTramitePagoDetalle AS CveTramitePagoDetalle; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al guardar el concepto del pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoDetalleSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoGet @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT P.CveTramitePago, P.CveTipoTramite, T.TipoTramite, P.Nombre, P.Notas, P.EsRequerido, P.Orden, P.EsActivo, P.CveUnidadCobro, U.Codigo AS UnidadCobro, P.Importe AS Total, (SELECT COUNT(*) FROM dbo.Tra_TiposTramitePagosDetalle AS D WHERE D.CveTramitePago = P.CveTramitePago) AS NumeroConceptos FROM dbo.Tra_TiposTramitePagos AS P INNER JOIN dbo.Tra_TiposTramite AS T ON T.CveTipoTramite = P.CveTipoTramite INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = P.CveUnidadCobro WHERE P.CveTramitePago = @CveTramitePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoGet'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoList @CveTipoTramite INT, @IncluirInactivos BIT=1, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY SELECT P.CveTramitePago, P.CveTipoTramite, T.TipoTramite, P.Nombre, P.Notas, P.EsRequerido, P.Orden, P.EsActivo, P.CveUnidadCobro, U.Codigo AS UnidadCobro, P.Importe AS Total, (SELECT COUNT(*) FROM dbo.Tra_TiposTramitePagosDetalle AS D WHERE D.CveTramitePago = P.CveTramitePago) AS NumeroConceptos FROM dbo.Tra_TiposTramitePagos AS P INNER JOIN dbo.Tra_TiposTramite AS T ON T.CveTipoTramite = P.CveTipoTramite INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = P.CveUnidadCobro WHERE P.CveTipoTramite = @CveTipoTramite AND (@IncluirInactivos = 1 OR P.EsActivo = 1) ORDER BY P.Orden, P.CveTramitePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoSave @CveTramitePago INT=NULL, @CveTipoTramite INT, @Nombre VARCHAR (200), @Notas VARCHAR (1000)=NULL, @EsRequerido BIT, @EsActivo BIT, @CveUnidadCobro INT=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END SET @CveTramitePago = NULLIF (@CveTramitePago, 0); IF @CveUnidadCobro IS NULL AND @CveTramitePago IS NOT NULL SELECT @CveUnidadCobro = CveUnidadCobro FROM dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @CveTramitePago; IF @CveUnidadCobro IS NULL SELECT @CveUnidadCobro = CveUnidadCobro FROM dbo.Gral_UnidadesCobro WHERE Codigo = 'MXN'; IF NOT EXISTS (SELECT 1 FROM dbo.Gral_UnidadesCobro WHERE CveUnidadCobro = @CveUnidadCobro AND Activo = 1) BEGIN SELECT @ErrorMostrar = 'Seleccione una unidad de cobro disponible.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago AND CveUnidadCobro <> @CveUnidadCobro) BEGIN SELECT @ErrorMostrar = 'La plantilla tiene productos; conserve su unidad de cobro.', @ErrorTipo = 2, @Return = 0; RETURN; END SELECT @Nombre = LTRIM(RTRIM(@Nombre)), @Notas = NULLIF (LTRIM(RTRIM(@Notas)), ''); IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramite WHERE CveTipoTramite = @CveTipoTramite) BEGIN SELECT @ErrorMostrar = 'Seleccione un tipo de trámite válido.', @ErrorTipo = 2; RETURN; END IF NULLIF (@Nombre, '') IS NULL BEGIN SELECT @ErrorMostrar = 'Capture el nombre del pago.', @ErrorTipo = 2; RETURN; END IF @CveTramitePago IS NULL BEGIN DECLARE @Orden AS INT = ISNULL((SELECT MAX(Orden) FROM dbo.Tra_TiposTramitePagos WHERE CveTipoTramite = @CveTipoTramite), 0) + 1; INSERT dbo.Tra_TiposTramitePagos (CveTipoTramite, Nombre, Notas, EsRequerido, Orden, EsActivo, CveUsuario, CveUnidadCobro, Importe) VALUES (@CveTipoTramite, @Nombre, @Notas, @EsRequerido, @Orden, @EsActivo, @CveUsuarioEjecuta, @CveUnidadCobro, 0); SET @CveTramitePago = CONVERT (INT, SCOPE_IDENTITY()); END ELSE BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagos WHERE CveTramitePago = @CveTramitePago AND CveTipoTramite = @CveTipoTramite) BEGIN SELECT @ErrorMostrar = 'El pago seleccionado no pertenece al tipo de trámite.', @ErrorTipo = 2; RETURN; END UPDATE dbo.Tra_TiposTramitePagos SET Nombre = @Nombre, CveUnidadCobro = @CveUnidadCobro, Notas = @Notas, EsRequerido = @EsRequerido, EsActivo = @EsActivo, FechaModificacion = GETDATE(), CveUsuario = @CveUsuarioEjecuta WHERE CveTramitePago = @CveTramitePago; END SELECT @CveTramitePago AS CveTramitePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al guardar el pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_PagoSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_FraccionamientoPagoPendienteList @CveFraccionamiento INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY WITH Aplicaciones AS (SELECT A.CveSolicitudPago, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPago), Traslados AS (SELECT O.CveSolicitudPagoOrigen, SUM(O.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY O.CveSolicitudPagoOrigen), Saldos AS (SELECT S.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, S.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPago AS S LEFT OUTER JOIN Aplicaciones AS A ON A.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoOrigen = S.CveSolicitudPago) SELECT S.CveSolicitudPago, S.CveSolicitud, S.CveTramitePago, S.CveVenta, CONVERT (BIT, CASE WHEN S.CveVenta IS NOT NULL THEN 1 ELSE 0 END) AS VentaGenerada, T.Folio AS FolioSolicitud, E.Etapa, TT.TipoTramite, S.Descripcion AS NombrePago, (SELECT COUNT(*) FROM dbo.Tra_SolicitudesPagoDetalle AS D WHERE D.CveSolicitudPago = S.CveSolicitudPago) AS NumeroConceptos, CONVERT (DECIMAL (19, 6), V.SubTotal) AS SubTotal, CONVERT (DECIMAL (19, 6), V.IVA) AS IVA, S.Importe AS Total, S.ImporteAbonado, S.ImporteConvenido, S.SaldoPendiente, S.CveUnidadCobro, U.Codigo AS UnidadCobro FROM Saldos AS S INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = S.CveUnidadCobro LEFT OUTER JOIN dbo.Tra_Solicitudes AS T ON T.CveSolicitud = S.CveSolicitud LEFT OUTER JOIN dbo.FraccionamientosEtapas AS E ON E.CveFraccionamientoEtapa = S.CveFraccionamientoEtapa LEFT OUTER JOIN dbo.Tra_TiposTramite AS TT ON TT.CveTipoTramite = S.CveTipoTramite LEFT OUTER JOIN dbo.Ventas AS V ON V.CveVenta = S.CveVenta WHERE S.CveFraccionamiento = @CveFraccionamiento AND S.EstadoAdministrativo = 'ACTIVO' AND S.SaldoPendiente > 0 ORDER BY E.Orden, S.CveSolicitudPago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_FraccionamientoPagoPendienteList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_FraccionamientoPagoRealizadoList @CveFraccionamiento INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY WITH Aplicaciones AS (SELECT CvePago, CveSolicitudPago, SUM(ImporteAplicado) AS ImporteAplicado, SUM(ImporteAplicadoMXN) AS ImporteAplicadoMXN FROM dbo.Tra_PagosAplicaciones GROUP BY CvePago, CveSolicitudPago) SELECT S.CveSolicitudPago, S.CveSolicitud, S.CveTramitePago, S.CveVenta, P.CvePago, V.SerieFolio, V.Fecha, P.FechaPago, P.Referencia, T.Folio AS FolioSolicitud, E.Etapa, TT.TipoTramite, S.Descripcion AS NombrePago, CONVERT (DECIMAL (19, 6), NULL) AS SubTotal, CONVERT (DECIMAL (19, 6), NULL) AS IVA, A.ImporteAplicado AS Total, A.ImporteAplicadoMXN, S.CveUnidadCobro, U.Codigo AS UnidadCobro FROM Aplicaciones AS A INNER JOIN dbo.Tra_SolicitudesPago AS S ON S.CveSolicitudPago = A.CveSolicitudPago INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = S.CveUnidadCobro LEFT OUTER JOIN dbo.Tra_Solicitudes AS T ON T.CveSolicitud = S.CveSolicitud LEFT OUTER JOIN dbo.FraccionamientosEtapas AS E ON E.CveFraccionamientoEtapa = S.CveFraccionamientoEtapa LEFT OUTER JOIN dbo.Tra_TiposTramite AS TT ON TT.CveTipoTramite = S.CveTipoTramite LEFT OUTER JOIN dbo.Ventas AS V ON V.CveVenta = S.CveVenta WHERE S.CveFraccionamiento = @CveFraccionamiento AND P.EsActivo = 1 AND P.Autorizado = 1 ORDER BY P.FechaPago DESC, P.CvePago DESC, S.CveSolicitudPago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_FraccionamientoPagoRealizadoList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteConceptoDelete @CveSolicitud INT, @CveTramitePago INT, @CveVentaDetalle INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveVenta AS INT; SELECT @CveVenta = V.CveVenta FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NULL BEGIN SELECT @ErrorMostrar = 'Primero debe generar la venta del trámite.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Ventas WHERE CveVenta = @CveVenta AND SeTimbro = 1) BEGIN SELECT @ErrorMostrar = 'No se pueden modificar los conceptos de una venta timbrada.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.VentasDetalle WHERE CveVentaDetalle = @CveVentaDetalle AND CveVenta = @CveVenta) BEGIN SELECT @ErrorMostrar = 'El concepto seleccionado no pertenece a la venta.', @ErrorTipo = 2; RETURN; END IF (SELECT COUNT(*) FROM dbo.VentasDetalle WHERE CveVenta = @CveVenta) <= 1 BEGIN SELECT @ErrorMostrar = 'La venta debe conservar al menos un concepto.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoDetalle WHERE CveVentaDetalleOrigen = @CveVentaDetalle) BEGIN SELECT @ErrorMostrar = 'El concepto forma parte del origen histórico de una obligación y debe conservarse.', @ErrorTipo = 2, @Return = 0; RETURN; END DELETE dbo.VentasDetalleImpuestos WHERE CveVentaDetalle = @CveVentaDetalle; DELETE dbo.VentasDetalle WHERE CveVentaDetalle = @CveVentaDetalle AND CveVenta = @CveVenta; EXECUTE dbo.PA_Vta_TramiteVentaTotalesUpdate @CveVenta = @CveVenta, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al eliminar el concepto de la venta; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteConceptoDelete'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteConceptoList @CveSolicitud INT, @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @CveVenta AS INT; DECLARE @PorcentajeIVA AS DECIMAL (9, 6) = 0.16; SELECT @CveVenta = SP.CveVenta FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NOT NULL BEGIN SELECT VD.CveVentaDetalle, CONVERT (INT, 0) AS CveTramitePagoDetalle, VD.CvePS, UM.CveUnidadMedida AS CveUM, CASE WHEN NULLIF (LTRIM(RTRIM(UM.Abreviatura)), '') IS NULL THEN UM.UnidadMedida COLLATE DATABASE_DEFAULT ELSE UM.UnidadMedida COLLATE DATABASE_DEFAULT + ' (' + UM.Abreviatura COLLATE DATABASE_DEFAULT + ')' END AS UnidadMedida, C.CveClasificacion, CASE WHEN NULLIF (LTRIM(RTRIM(C.Codigo)), '') IS NULL THEN C.Clasificacion COLLATE DATABASE_DEFAULT ELSE C.Codigo COLLATE DATABASE_DEFAULT + ' - ' + C.Clasificacion COLLATE DATABASE_DEFAULT END AS Clasificacion, CASE WHEN NULLIF (LTRIM(RTRIM(PS.Codigo)), '') IS NULL THEN PS.PS COLLATE DATABASE_DEFAULT ELSE PS.Codigo COLLATE DATABASE_DEFAULT + ' - ' + PS.PS COLLATE DATABASE_DEFAULT END AS ProductoServicio, VD.Cantidad, VD.PrecioUnitario, VD.Descuento, VD.IVA, VD.Importe FROM dbo.VentasDetalle AS VD INNER JOIN dbo.ProductosServicios AS PS ON PS.CvePS = VD.CvePS INNER JOIN dbo.UnidadesMedida AS UM ON UM.CveUnidadMedida = PS.CveUnidadMedida INNER JOIN dbo.Clasificaciones AS C ON C.CveClasificacion = PS.CveClasificacion WHERE VD.CveVenta = @CveVenta ORDER BY VD.CveVentaDetalle; END ELSE BEGIN SELECT CONVERT (INT, 0) AS CveVentaDetalle, D.CveTramitePagoDetalle, D.CvePS, D.CveUM, CASE WHEN NULLIF (LTRIM(RTRIM(UM.Abreviatura)), '') IS NULL THEN UM.UnidadMedida COLLATE DATABASE_DEFAULT ELSE UM.UnidadMedida COLLATE DATABASE_DEFAULT + ' (' + UM.Abreviatura COLLATE DATABASE_DEFAULT + ')' END AS UnidadMedida, C.CveClasificacion, CASE WHEN NULLIF (LTRIM(RTRIM(C.Codigo)), '') IS NULL THEN C.Clasificacion COLLATE DATABASE_DEFAULT ELSE C.Codigo COLLATE DATABASE_DEFAULT + ' - ' + C.Clasificacion COLLATE DATABASE_DEFAULT END AS Clasificacion, CASE WHEN NULLIF (LTRIM(RTRIM(PS.Codigo)), '') IS NULL THEN PS.PS COLLATE DATABASE_DEFAULT ELSE PS.Codigo COLLATE DATABASE_DEFAULT + ' - ' + PS.PS COLLATE DATABASE_DEFAULT END AS ProductoServicio, CONVERT (DECIMAL (18, 4), 1) AS Cantidad, CONVERT (DECIMAL (18, 2), Costo.Importe) AS PrecioUnitario, CONVERT (DECIMAL (18, 2), 0) AS Descuento, CONVERT (DECIMAL (18, 2), ROUND(Costo.Importe * @PorcentajeIVA, 2)) AS IVA, CONVERT (DECIMAL (18, 2), ROUND(Costo.Importe, 2)) AS Importe FROM dbo.Tra_Solicitudes AS S INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = @CveTramitePago AND P.CveTipoTramite = S.CveTipoTramite AND P.EsActivo = 1 INNER JOIN dbo.Tra_TiposTramitePagosDetalle AS D ON D.CveTramitePago = P.CveTramitePago INNER JOIN dbo.ProductosServicios AS PS ON PS.CvePS = D.CvePS CROSS APPLY (SELECT TOP (1) CT.Importe FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = S.CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, GETDATE())) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, GETDATE())) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC) AS Costo INNER JOIN dbo.UnidadesMedida AS UM ON UM.CveUnidadMedida = D.CveUM INNER JOIN dbo.Clasificaciones AS C ON C.CveClasificacion = PS.CveClasificacion WHERE S.CveSolicitud = @CveSolicitud ORDER BY D.CveTramitePagoDetalle; END SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al consultar los conceptos de la venta; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteConceptoList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteConceptoSave @CveSolicitud INT, @CveTramitePago INT, @CveVentaDetalle INT=NULL, @CvePS INT, @Cantidad DECIMAL (18, 4), @PrecioUnitario DECIMAL (18, 2), @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveVenta AS INT, @CveTipoTramite AS INT, @CveCostoTramite AS INT, @CveObjetoImpuesto AS TINYINT, @Descuento AS DECIMAL (18, 2) = 0, @IVA AS DECIMAL (18, 2), @Importe AS DECIMAL (18, 2), @Fecha AS DATETIME = GETDATE(); SELECT @CveVenta = V.CveVenta, @CveTipoTramite = S.CveTipoTramite FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta INNER JOIN dbo.Tra_Solicitudes AS S ON S.CveSolicitud = SP.CveSolicitud WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NULL BEGIN SELECT @ErrorMostrar = 'Primero debe generar la venta del trámite.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Ventas WHERE CveVenta = @CveVenta AND SeTimbro = 1) BEGIN SELECT @ErrorMostrar = 'No se pueden modificar los conceptos de una venta timbrada.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.ProductosServicios WHERE CvePS = @CvePS AND Estado = 1) OR @Cantidad <= 0 OR @PrecioUnitario < 0 BEGIN SELECT @ErrorMostrar = 'Capture un producto activo, cantidad y precio unitario válidos.', @ErrorTipo = 2; RETURN; END SELECT TOP (1) @CveCostoTramite = CT.CveCostoTramite, @CveObjetoImpuesto = CT.CveObjetoImpuesto FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = @CveTipoTramite AND CT.CvePS = @CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, @Fecha)) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, @Fecha)) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC; IF @CveCostoTramite IS NULL BEGIN SELECT @ErrorMostrar = 'El producto seleccionado no tiene un costo vigente para este trámite.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Gral_SAT_ObjetoImpuesto WHERE CveObjetoImpuesto = @CveObjetoImpuesto AND CodigoObjetoImpuesto = '02') AND NOT EXISTS (SELECT 1 FROM dbo.Tra_CostosTramiteImpuestos WHERE CveCostoTramite = @CveCostoTramite) BEGIN SELECT @ErrorMostrar = 'El costo es objeto de impuesto y no tiene impuestos configurados.', @ErrorTipo = 2; RETURN; END IF @CveVentaDetalle IS NOT NULL BEGIN SELECT @Descuento = Descuento FROM dbo.VentasDetalle WHERE CveVentaDetalle = @CveVentaDetalle AND CveVenta = @CveVenta; END SET @Importe = CONVERT (DECIMAL (18, 2), ROUND(@Cantidad * @PrecioUnitario, 2)); IF @Descuento > @Importe BEGIN SELECT @ErrorMostrar = 'El descuento del concepto no puede ser mayor que su importe.', @ErrorTipo = 2; RETURN; END IF @CveVentaDetalle IS NULL BEGIN INSERT dbo.VentasDetalle (CveVenta, CvePS, CveSolicitud, CveCostoTramite, Cantidad, PrecioUnitario, Descuento, IVA, Importe, CveObjetoImpuesto, EsFondoInicial, FechaAlta, CveUsuario) VALUES (@CveVenta, @CvePS, @CveSolicitud, @CveCostoTramite, @Cantidad, @PrecioUnitario, 0, 0, @Importe, @CveObjetoImpuesto, 0, @Fecha, @CveUsuarioEjecuta); SET @CveVentaDetalle = CONVERT (INT, SCOPE_IDENTITY()); END ELSE BEGIN IF NOT EXISTS (SELECT 1 FROM dbo.VentasDetalle WHERE CveVentaDetalle = @CveVentaDetalle AND CveVenta = @CveVenta) BEGIN SELECT @ErrorMostrar = 'El concepto seleccionado no pertenece a la venta.', @ErrorTipo = 2; RETURN; END DELETE dbo.VentasDetalleImpuestos WHERE CveVentaDetalle = @CveVentaDetalle; UPDATE dbo.VentasDetalle SET CvePS = @CvePS, CveCostoTramite = @CveCostoTramite, Cantidad = @Cantidad, PrecioUnitario = @PrecioUnitario, IVA = 0, Importe = @Importe, CveObjetoImpuesto = @CveObjetoImpuesto, CveUsuario = @CveUsuarioEjecuta WHERE CveVentaDetalle = @CveVentaDetalle; END INSERT dbo.VentasDetalleImpuestos (CveVentaDetalle, EsRetencion, Base, Impuesto, TipoFactor, TasaOCuota, Importe, FechaAlta, CveUsuario) SELECT @CveVentaDetalle, CTI.EsRetencion, CONVERT (DECIMAL (19, 6), @Importe - @Descuento), CTI.Impuesto, CTI.TipoFactor, CTI.TasaOCuota, CONVERT (DECIMAL (18, 2), CASE WHEN CTI.TipoFactor = 'Exento' THEN 0 WHEN CTI.TipoFactor = 'Cuota' THEN ROUND(@Cantidad * CTI.TasaOCuota, 2) ELSE ROUND((@Importe - @Descuento) * CTI.TasaOCuota, 2) END), @Fecha, @CveUsuarioEjecuta FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = @CveCostoTramite; SELECT @IVA = ISNULL(SUM(VDI.Importe), 0) FROM dbo.VentasDetalleImpuestos AS VDI WHERE VDI.CveVentaDetalle = @CveVentaDetalle AND VDI.EsRetencion = 0 AND VDI.Impuesto = '002'; UPDATE dbo.VentasDetalle SET IVA = @IVA WHERE CveVentaDetalle = @CveVentaDetalle; EXECUTE dbo.PA_Vta_TramiteVentaTotalesUpdate @CveVenta = @CveVenta, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SELECT @CveVentaDetalle AS CveVentaDetalle; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al guardar el concepto de la venta; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteConceptoSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteCondicionesPagoSave @CveSolicitud INT, @CveTramitePago INT, @CveMetodoPago INT, @CveFormaPago TINYINT, @FechaVencimiento DATE, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveVenta AS INT; SELECT @CveVenta = V.CveVenta FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NULL BEGIN SELECT @ErrorMostrar = 'Primero debe generar la venta del trámite.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Ventas WHERE CveVenta = @CveVenta AND SeTimbro = 1) BEGIN SELECT @ErrorMostrar = 'Las condiciones de una venta timbrada no se pueden modificar.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Vta_MetodoPago WHERE CveMetodoPago = @CveMetodoPago) BEGIN SELECT @ErrorMostrar = 'Seleccione un método de pago válido.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Vta_FormaPago WHERE CveFormaPago = @CveFormaPago) BEGIN SELECT @ErrorMostrar = 'Seleccione una forma de pago válida.', @ErrorTipo = 2; RETURN; END IF @FechaVencimiento IS NULL BEGIN SELECT @ErrorMostrar = 'Capture una fecha de vencimiento válida.', @ErrorTipo = 2; RETURN; END UPDATE dbo.Ventas SET CveMetodoPago = @CveMetodoPago, CveMetodoPago33 = @CveMetodoPago, FormaPago = @CveFormaPago, CveFormaPago33 = @CveFormaPago, FechaVencimiento2 = @FechaVencimiento, CveUsuarioModifico = @CveUsuarioEjecuta WHERE CveVenta = @CveVenta; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al actualizar las condiciones de pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteCondicionesPagoSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteContextoGet @CveSolicitud INT, @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @CveSubProyecto AS INT = (SELECT TOP (1) CveSubProyecto FROM dbo.SubProyectos WHERE Estatus = 1 ORDER BY CASE WHEN Serie = 'TRA' THEN 0 ELSE 1 END, CveSubProyecto); IF NOT EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes AS S INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = @CveTramitePago AND P.CveTipoTramite = S.CveTipoTramite AND P.EsActivo = 1 INNER JOIN dbo.Tra_TiposTramitePagosDetalle AS D ON D.CveTramitePago = P.CveTramitePago WHERE S.CveSolicitud = @CveSolicitud) BEGIN SELECT @ErrorMostrar = 'El pago seleccionado no corresponde al trámite o no tiene conceptos activos.', @ErrorTipo = 2; RETURN; END SELECT S.CveSolicitud, P.CveTramitePago, SP.CveVenta, VP.CvePago, CONVERT (BIT, CASE WHEN SP.CveSolicitudPago IS NOT NULL AND V.CveVenta IS NOT NULL THEN 1 ELSE 0 END) AS VentaGenerada, CONVERT (BIT, CASE WHEN SP.CveSolicitudPago IS NOT NULL AND ISNULL(VP.ImportePagado, 0) >= SP.Importe THEN 1 ELSE 0 END) AS VentaPagada, Documento.CveCfdiDocumento, CONVERT (BIT, CASE WHEN V.SeTimbro = 1 OR Documento.Estado = 'TIMBRADO' THEN 1 ELSE 0 END) AS VentaTimbrada, CONVERT (BIT, CASE WHEN Documento.Estado = 'CANCELADO' THEN 1 ELSE 0 END) AS TimbreCancelado, Documento.Uuid AS UuidTimbre, S.CveFraccionamiento, F.Fraccionamiento, F.CveCliente, C.Nombre AS Cliente, C.RFC, CONCAT(C.Direccion, CASE WHEN NULLIF (LTRIM(RTRIM(C.NoExt)), '') IS NULL THEN '' ELSE CONCAT(' ', C.NoExt) END, CASE WHEN NULLIF (LTRIM(RTRIM(C.NoInt)), '') IS NULL THEN '' ELSE CONCAT(' Int. ', C.NoInt) END) AS Direccion, C.Colonia, CONCAT(C.Ciudad, ', ', C.Estado) AS CiudadEstado, C.CP, C.Telefono, C.Mail, S.Folio AS FolioSolicitud, E.Etapa, TT.TipoTramite, P.Nombre AS NombrePago, N'Remisión' AS TipoDocumento, ISNULL(V.Serie, 'TRA') AS Serie, ISNULL(V.Folio, ISNULL((SELECT MAX(Venta.Folio) + 1 FROM dbo.Ventas AS Venta WHERE Venta.TipoDocto = 'Rem' AND Venta.Serie = 'TRA' AND Venta.CveSubProyecto = @CveSubProyecto), 1)) AS Folio, ISNULL(V.Fecha, GETDATE()) AS Fecha FROM dbo.Tra_Solicitudes AS S INNER JOIN dbo.Fraccionamientos AS F ON F.CveFraccionamiento = S.CveFraccionamiento INNER JOIN dbo.FraccionamientosEtapas AS E ON E.CveFraccionamientoEtapa = S.CveFraccionamientoEtapa INNER JOIN dbo.Tra_TiposTramite AS TT ON TT.CveTipoTramite = S.CveTipoTramite INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = @CveTramitePago AND P.CveTipoTramite = S.CveTipoTramite INNER JOIN dbo.Clientes AS C ON C.CveCliente = F.CveCliente LEFT OUTER JOIN dbo.Tra_SolicitudesPago AS SP ON SP.CveSolicitud = S.CveSolicitud AND SP.CveTramitePago = P.CveTramitePago LEFT OUTER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta OUTER APPLY (SELECT MAX(Pago.CvePago) AS CvePago, SUM(A.ImporteAplicado) AS ImportePagado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS Pago ON Pago.CvePago = A.CvePago WHERE A.CveSolicitudPago = SP.CveSolicitudPago AND Pago.EsActivo = 1 AND Pago.Autorizado = 1) AS VP OUTER APPLY (SELECT TOP (1) D.CveCfdiDocumento, D.Estado, T.Uuid FROM dbo.Fac_CfdiDocumentos AS D LEFT OUTER JOIN dbo.Fac_CfdiTimbrados AS T ON T.CveCfdiTimbrado = D.CveCfdiTimbradoVigente WHERE D.TipoOrigen = 'VENTA' AND D.CveOrigen = V.CveVenta AND D.Estado IN ('TIMBRADO', 'CANCELADO') ORDER BY D.CveCfdiDocumento DESC) AS Documento WHERE S.CveSolicitud = @CveSolicitud; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al consultar la venta del trámite; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteContextoGet'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramitePagoOpcionesList @CveSolicitud INT, @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @CveVenta AS INT; SELECT @CveVenta = V.CveVenta FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NULL BEGIN SELECT @ErrorMostrar = 'Primero debe generar la venta del trámite.', @ErrorTipo = 2; RETURN; END SELECT @CveVenta AS CveVenta, CONCAT('TRA-', RIGHT(REPLICATE('0', 10) + CONVERT (VARCHAR (10), @CveVenta), 10)) AS ReferenciaPago; SELECT FP.CveFormaPago, FP.ClaveFormaPagoSAT, CASE WHEN NULLIF (LTRIM(RTRIM(FP.ClaveFormaPagoSAT)), '') IS NULL THEN FP.FormaPago ELSE FP.ClaveFormaPagoSAT COLLATE Modern_Spanish_CS_AS + ' - ' + FP.FormaPago COLLATE Modern_Spanish_CS_AS END AS FormaPago, CONVERT (BIT, CASE WHEN FP.ClaveFormaPagoSAT = '04' THEN 0 ELSE 1 END) AS Disponible FROM dbo.Vta_FormaPago AS FP WHERE FP.ClaveFormaPagoSAT IN ('01', '03', '04') ORDER BY FP.ClaveFormaPagoSAT COLLATE Modern_Spanish_CS_AS, FP.FormaPago COLLATE Modern_Spanish_CS_AS, FP.CveFormaPago; SELECT BC.CveBancoCuenta, B.Banco, BC.NumCuenta AS NumeroCuenta, BC.CLABE, B.Banco COLLATE Modern_Spanish_CS_AS + ' - ' + BC.NumCuenta COLLATE Modern_Spanish_CS_AS + CASE WHEN NULLIF (LTRIM(RTRIM(BC.CLABE)), '') IS NULL THEN '' ELSE ' (CLABE ' + BC.CLABE COLLATE Modern_Spanish_CS_AS + ')' END AS CuentaBancaria FROM dbo.Banc_BancosCuentas AS BC INNER JOIN dbo.Banc_Bancos AS B ON B.CveBanco = BC.CveBanco WHERE BC.Estatus = 1 AND B.Estatus = 1 AND NULLIF (LTRIM(RTRIM(BC.CLABE)), '') IS NOT NULL ORDER BY B.Banco COLLATE Modern_Spanish_CS_AS, BC.NumCuenta COLLATE Modern_Spanish_CS_AS, BC.CveBancoCuenta; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al consultar las opciones de pago; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramitePagoOpcionesList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- Compatibilidad: reparto proporcional por productos pendientes, vencimientos más antiguos primero. CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramitePagoSave @CveSolicitud INT, @CveTramitePago INT, @Referencia VARCHAR (200)=NULL, @Importe DECIMAL (19, 6)=NULL, @FechaPago DATETIME=NULL, @CveFormaPago TINYINT=NULL, @CveBancoCuenta INT=NULL, @Observaciones VARCHAR (300)=NULL, @AplicacionesJson NVARCHAR (MAX)=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @Importe IS NULL OR @Importe <= 0 OR @FechaPago IS NULL OR @CveFormaPago IS NULL BEGIN SELECT @ErrorMostrar = 'Capture importe recibido, fecha y forma de pago.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Obligacion AS INT, @Cliente AS INT, @Unidad AS INT, @Pago AS INT, @Pendiente AS DECIMAL (19, 6); WITH Aplicaciones AS (SELECT A.CveSolicitudPago, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPago), Traslados AS (SELECT O.CveSolicitudPagoOrigen, SUM(O.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY O.CveSolicitudPagoOrigen), Saldos AS (SELECT S.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, S.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPago AS S LEFT OUTER JOIN Aplicaciones AS A ON A.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoOrigen = S.CveSolicitudPago) SELECT @Obligacion = CveSolicitudPago, @Cliente = CveCliente, @Unidad = CveUnidadCobro, @Pendiente = SaldoPendiente FROM Saldos WHERE CveSolicitud = @CveSolicitud AND CveTramitePago = @CveTramitePago AND EstadoAdministrativo = 'ACTIVO'; IF @Obligacion IS NULL OR @Importe > @Pendiente BEGIN SELECT @ErrorMostrar = 'Genere la obligación y capture un abono que no exceda su saldo pendiente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF @AplicacionesJson IS NULL BEGIN DECLARE @SaldosDetalle TABLE ( CveSolicitudPagoDetalle INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoDetalle, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoDetalle), Traslados AS (SELECT D.CveSolicitudPagoDetalleOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoDetalleOrigen) INSERT INTO @SaldosDetalle SELECT D.CveSolicitudPagoDetalle, D.CveSolicitudPago, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) FROM dbo.Tra_SolicitudesPagoDetalle AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoDetalle = D.CveSolicitudPagoDetalle LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoDetalleOrigen = D.CveSolicitudPagoDetalle; DECLARE @SaldosParcialidades TABLE ( CveSolicitudPagoParcialidad INT PRIMARY KEY, CveSolicitudPago INT, SaldoPendiente DECIMAL (19, 6)); WITH Abonos AS (SELECT A.CveSolicitudPagoParcialidad, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPagoParcialidad), Traslados AS (SELECT D.CveSolicitudPagoParcialidadOrigen, SUM(D.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigenDetalle AS D INNER JOIN dbo.Tra_SolicitudesPagoConvenioOrigen AS O ON O.CveConvenioOrigen = D.CveConvenioOrigen INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY D.CveSolicitudPagoParcialidadOrigen), SaldosParcialidades AS (SELECT D.*, COALESCE (D.FechaProrroga, D.FechaVencimiento) AS VencimientoEfectivo, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, D.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPagoParcialidades AS D LEFT OUTER JOIN Abonos AS A ON A.CveSolicitudPagoParcialidad = D.CveSolicitudPagoParcialidad LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoParcialidadOrigen = D.CveSolicitudPagoParcialidad) INSERT INTO @SaldosParcialidades SELECT CveSolicitudPagoParcialidad, CveSolicitudPago, SaldoPendiente FROM SaldosParcialidades; DECLARE @Distribucion TABLE ( CveSolicitudPagoDetalle INT, CveSolicitudPagoParcialidad INT, ImporteAplicado DECIMAL (19, 6)); DECLARE @Productos TABLE ( CveSolicitudPagoDetalle INT PRIMARY KEY, Importe DECIMAL (19, 6)); INSERT INTO @Productos SELECT CveSolicitudPagoDetalle, CONVERT (DECIMAL (19, 6), ROUND(@Importe * SaldoPendiente / @Pendiente, 6, 1)) FROM @SaldosDetalle WHERE CveSolicitudPago = @Obligacion AND SaldoPendiente > 0; DECLARE @Resto AS DECIMAL (19, 6) = @Importe - (SELECT SUM(Importe) FROM @Productos); WHILE @Resto > 0 BEGIN DECLARE @ProductoAjuste AS INT, @Ajuste AS DECIMAL (19, 6); SELECT TOP (1) @ProductoAjuste = P.CveSolicitudPagoDetalle, @Ajuste = CASE WHEN D.SaldoPendiente - P.Importe < @Resto THEN D.SaldoPendiente - P.Importe ELSE @Resto END FROM @Productos AS P INNER JOIN @SaldosDetalle AS D ON D.CveSolicitudPagoDetalle = P.CveSolicitudPagoDetalle WHERE D.SaldoPendiente > P.Importe ORDER BY P.CveSolicitudPagoDetalle; UPDATE @Productos SET Importe = Importe + @Ajuste WHERE CveSolicitudPagoDetalle = @ProductoAjuste; SET @Resto = @Resto - @Ajuste; END WHILE EXISTS (SELECT 1 FROM @Productos WHERE Importe > 0) BEGIN DECLARE @Detalle AS INT, @Parcialidad AS INT, @MontoProducto AS DECIMAL (19, 6), @MontoParcialidad AS DECIMAL (19, 6), @Monto AS DECIMAL (19, 6); SELECT TOP (1) @Detalle = CveSolicitudPagoDetalle, @MontoProducto = Importe FROM @Productos WHERE Importe > 0 ORDER BY CveSolicitudPagoDetalle; SELECT TOP (1) @Parcialidad = P.CveSolicitudPagoParcialidad, @MontoParcialidad = P.SaldoPendiente FROM @SaldosParcialidades AS P INNER JOIN dbo.Tra_SolicitudesPagoParcialidades AS D ON D.CveSolicitudPagoParcialidad = P.CveSolicitudPagoParcialidad WHERE P.CveSolicitudPago = @Obligacion AND P.SaldoPendiente > 0 ORDER BY COALESCE (D.FechaProrroga, D.FechaVencimiento), D.NumeroParcialidad; SET @Monto = CASE WHEN @MontoProducto < @MontoParcialidad THEN @MontoProducto ELSE @MontoParcialidad END; INSERT INTO @Distribucion VALUES (@Detalle, @Parcialidad, @Monto); UPDATE @Productos SET Importe = Importe - @Monto WHERE CveSolicitudPagoDetalle = @Detalle; UPDATE @SaldosParcialidades SET SaldoPendiente = SaldoPendiente - @Monto WHERE CveSolicitudPagoParcialidad = @Parcialidad; END SET @AplicacionesJson = (SELECT * FROM @Distribucion FOR JSON PATH); END EXECUTE dbo.PA_Tra_PagoRegistrar @CvePago = @Pago OUTPUT, @CveCliente = @Cliente, @FechaPago = @FechaPago, @Importe = @Importe, @CveUnidadCobro = @Unidad, @CveFormaPago = @CveFormaPago, @CveBancoCuenta = @CveBancoCuenta, @Referencia = @Referencia, @Observaciones = @Observaciones, @DevolverResultado = 0, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; EXECUTE dbo.PA_Tra_PagoAplicar @CvePago = @Pago, @AplicacionesJson = @AplicacionesJson, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SELECT @Pago AS CvePago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramitePagoSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteVentaDatosCfdiGet @CveSolicitud INT, @CveTramitePago INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @CveVenta AS INT; SELECT @CveVenta = V.CveVenta FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago; IF @CveVenta IS NULL BEGIN SELECT @ErrorMostrar = 'Primero debe generar la venta del trámite.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Ventas AS V WHERE V.CveVenta = @CveVenta AND (V.SeTimbro = 1 OR EXISTS (SELECT 1 FROM dbo.Fac_CfdiDocumentos AS D WHERE D.TipoOrigen = 'VENTA' AND D.CveOrigen = V.CveVenta AND D.Estado = 'TIMBRADO' AND D.CveCfdiTimbradoVigente IS NOT NULL))) BEGIN SELECT @ErrorMostrar = 'La venta ya se encuentra timbrada.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Fac_CfdiDocumentos WHERE TipoOrigen = 'VENTA' AND CveOrigen = @CveVenta AND Estado = 'REVISAR') BEGIN SELECT @ErrorMostrar = 'Existe un intento de timbrado con resultado indeterminado; debe revisarse antes de volver a timbrar.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.VentasDetalle AS VD INNER JOIN dbo.Gral_SAT_ObjetoImpuesto AS OI ON OI.CveObjetoImpuesto = VD.CveObjetoImpuesto WHERE VD.CveVenta = @CveVenta AND OI.CodigoObjetoImpuesto = '02' AND NOT EXISTS (SELECT 1 FROM dbo.VentasDetalleImpuestos AS VDI WHERE VDI.CveVentaDetalle = VD.CveVentaDetalle)) BEGIN SELECT @ErrorMostrar = 'Uno o más conceptos son objeto de impuesto y no tienen impuestos registrados.', @ErrorTipo = 2; RETURN; END SELECT V.CveVenta, Borrador.CveCfdiDocumento, V.CveCliente, V.Serie, V.Folio, V.Fecha, FP.ClaveFormaPagoSAT AS FormaPago, MP.ClaveMetodoPagoSAT AS MetodoPago, M.AbreviaturaSAT AS Moneda, CONVERT (DECIMAL (19, 6), V.TipoCambio) AS TipoCambio FROM dbo.Ventas AS V LEFT OUTER JOIN dbo.Vta_FormaPago AS FP ON FP.CveFormaPago = V.FormaPago LEFT OUTER JOIN dbo.Vta_MetodoPago AS MP ON MP.CveMetodoPago = V.CveMetodoPago INNER JOIN dbo.Gral_Monedas AS M ON M.CveMoneda = V.CveMoneda OUTER APPLY (SELECT TOP (1) D.CveCfdiDocumento FROM dbo.Fac_CfdiDocumentos AS D WHERE D.TipoOrigen = 'VENTA' AND D.CveOrigen = V.CveVenta AND D.CveCfdiTimbradoVigente IS NULL AND D.Estado IN ('BORRADOR', 'LISTO', 'ERROR') ORDER BY D.CveCfdiDocumento DESC) AS Borrador WHERE V.CveVenta = @CveVenta; SELECT VD.CveVentaDetalle, SATPS.SATClavePS AS ClaveProductoServicio, PS.Codigo AS NumeroIdentificacion, VD.Cantidad, SATUM.SATClaveUnidadMedida AS ClaveUnidad, UM.UnidadMedida AS Unidad, PS.PS AS Descripcion, VD.PrecioUnitario AS ValorUnitario, VD.PrecioUnitario AS PU, VD.Importe AS Total, VD.Descuento, OI.CodigoObjetoImpuesto AS ObjetoImpuesto FROM dbo.VentasDetalle AS VD INNER JOIN dbo.ProductosServicios AS PS ON PS.CvePS = VD.CvePS INNER JOIN dbo.UnidadesMedida AS UM ON UM.CveUnidadMedida = PS.CveUnidadMedida LEFT OUTER JOIN dbo.Gral_SAT_ProductosServicios AS SATPS ON SATPS.CveSATPS = PS.CveSATPS LEFT OUTER JOIN dbo.Gral_SAT_UnidadesMedida AS SATUM ON SATUM.CveSATUnidadMedida = UM.CveSATUnidadMedida INNER JOIN dbo.Gral_SAT_ObjetoImpuesto AS OI ON OI.CveObjetoImpuesto = VD.CveObjetoImpuesto WHERE VD.CveVenta = @CveVenta ORDER BY VD.CveVentaDetalle; SELECT VDI.CveVentaDetalle, VDI.EsRetencion, VDI.Base, VDI.Impuesto, VDI.TipoFactor, VDI.TasaOCuota, VDI.Importe FROM dbo.VentasDetalleImpuestos AS VDI INNER JOIN dbo.VentasDetalle AS VD ON VD.CveVentaDetalle = VDI.CveVentaDetalle WHERE VD.CveVenta = @CveVenta ORDER BY VDI.CveVentaDetalle, VDI.EsRetencion, VDI.Impuesto, VDI.CveVentaDetalleImpuesto; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al preparar los datos fiscales de la venta; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteVentaDatosCfdiGet'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteVentaGenerar @CveSolicitud INT, @CveTramitePago INT, @Observaciones VARCHAR (2000)=NULL, @FechaVencimiento DATE=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago AS SP INNER JOIN dbo.Ventas AS V ON V.CveVenta = SP.CveVenta WHERE SP.CveSolicitud = @CveSolicitud AND SP.CveTramitePago = @CveTramitePago) BEGIN SELECT @ErrorMostrar = 'La venta del trámite ya fue generada.', @ErrorTipo = 2; RETURN; END EXECUTE dbo.PA_Vta_TramiteVentaSave @CveSolicitud = @CveSolicitud, @CveTramitePago = @CveTramitePago, @Observaciones = @Observaciones, @FechaVencimiento = @FechaVencimiento, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al generar la venta del trámite; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteVentaGenerar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Vta_TramiteVentaSave @CveSolicitud INT, @CveTramitePago INT, @Observaciones VARCHAR (2000)=NULL, @FechaVencimiento DATE=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @Obligacion AS INT; SELECT @Obligacion = CveSolicitudPago FROM dbo.Tra_SolicitudesPago WHERE CveSolicitud = @CveSolicitud AND CveTramitePago = @CveTramitePago; IF @Obligacion IS NULL BEGIN EXECUTE dbo.PA_Tra_SolicitudPagoGenerarPorSolicitud @CveSolicitud = @CveSolicitud, @FechaVencimiento = @FechaVencimiento, @CveTramitePago = @CveTramitePago, @DevolverResultado = 0, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; SELECT @Obligacion = CveSolicitudPago FROM dbo.Tra_SolicitudesPago WHERE CveSolicitud = @CveSolicitud AND CveTramitePago = @CveTramitePago; END IF NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago AS S INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = S.CveUnidadCobro WHERE S.CveSolicitudPago = @Obligacion AND S.EstadoAdministrativo = 'ACTIVO' AND U.Codigo = 'MXN') BEGIN SELECT @ErrorMostrar = 'La venta anterior requiere una obligación vigente en MXN. Para otras unidades utilice los documentos del pago.', @ErrorTipo = 2, @Return = 0; RETURN; END DECLARE @CveVendedor AS INT = 1, @CveCliente AS INT, @CveTipoTramite AS INT, @CveSubProyecto AS INT, @CveEstatusFactura AS INT, @CveVenta AS INT, @Folio AS INT, @Fecha AS DATETIME = GETDATE(); SELECT @CveCliente = F.CveCliente, @CveTipoTramite = S.CveTipoTramite FROM dbo.Tra_Solicitudes AS S INNER JOIN dbo.Fraccionamientos AS F ON F.CveFraccionamiento = S.CveFraccionamiento INNER JOIN dbo.Tra_TiposTramitePagos AS P ON P.CveTramitePago = @CveTramitePago AND P.CveTipoTramite = S.CveTipoTramite AND P.EsActivo = 1 WHERE S.CveSolicitud = @CveSolicitud; IF @CveCliente IS NULL BEGIN SELECT @ErrorMostrar = 'El pago seleccionado no corresponde al trámite.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Vta_Vendedores WHERE CveVendedor = @CveVendedor) BEGIN SELECT @ErrorMostrar = 'No se encuentra configurado el vendedor predeterminado 1.', @ErrorTipo = 2; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveTramitePago = @CveTramitePago) BEGIN SELECT @ErrorMostrar = 'El pago seleccionado no tiene conceptos para vender.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle AS D WHERE D.CveTramitePago = @CveTramitePago AND NOT EXISTS (SELECT 1 FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = @CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, @Fecha)) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, @Fecha)))) BEGIN SELECT @ErrorMostrar = 'Uno o más conceptos no tienen un costo vigente configurado.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle AS D CROSS APPLY (SELECT TOP (1) CT.CveCostoTramite, CT.CveObjetoImpuesto FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = @CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, @Fecha)) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, @Fecha)) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC) AS Costo INNER JOIN dbo.Gral_SAT_ObjetoImpuesto AS OI ON OI.CveObjetoImpuesto = Costo.CveObjetoImpuesto WHERE D.CveTramitePago = @CveTramitePago AND OI.CodigoObjetoImpuesto = '02' AND NOT EXISTS (SELECT 1 FROM dbo.Tra_CostosTramiteImpuestos AS CTI WHERE CTI.CveCostoTramite = Costo.CveCostoTramite)) BEGIN SELECT @ErrorMostrar = 'Uno o más costos son objeto de impuesto y no tienen impuestos configurados.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago WITH (UPDLOCK, HOLDLOCK) WHERE CveSolicitud = @CveSolicitud AND CveTramitePago = @CveTramitePago AND CveVenta IS NOT NULL) BEGIN SELECT @ErrorMostrar = 'La venta de la obligación ya fue generada.', @ErrorTipo = 2; RETURN; END SELECT TOP (1) @CveSubProyecto = CveSubProyecto FROM dbo.SubProyectos WHERE Estatus = 1 ORDER BY CASE WHEN Serie = 'TRA' THEN 0 ELSE 1 END, CveSubProyecto; SELECT TOP (1) @CveEstatusFactura = CveEstatusFactura FROM dbo.EstatusFactura WHERE TipoDocto = 'Rem' AND Estado = 1 ORDER BY CveEstatusFactura; IF @CveSubProyecto IS NULL OR @CveEstatusFactura IS NULL BEGIN SELECT @ErrorMostrar = 'La configuración mínima de ventas no está disponible; favor de contactar a Sistemas.', @ErrorTipo = 2; RETURN; END SELECT @Folio = ISNULL(MAX(Folio), 0) + 1 FROM dbo.Ventas WITH (UPDLOCK, HOLDLOCK) WHERE CveSubProyecto = @CveSubProyecto AND TipoDocto = 'Rem' AND Serie = 'TRA'; INSERT dbo.Ventas (TipoDocto, Serie, Folio, Fecha, CveCliente, CveVendedor, CveMetodoPago, CondicionesPago, FormaPago, SubTotal, Descuento, IVA, IEPS, RetIVA, RetISR, Total, Observaciones, CveEstatusFactura, FechaEjecucion, CveSubProyecto, CveUsuario, CveFormaPago33, CveMetodoPago33, FechaIng, FechaVencimiento2, Ref, DescripcionVenta, FechaParaSurtir) VALUES ('Rem', 'TRA', @Folio, @Fecha, @CveCliente, @CveVendedor, 2, 0, 99, 0, 0, 0, 0, 0, 0, 0, ISNULL(@Observaciones, ''), @CveEstatusFactura, @Fecha, @CveSubProyecto, @CveUsuarioEjecuta, 99, 2, @Fecha, CONVERT (DATE, @Fecha), CONVERT (VARCHAR (50), @CveSolicitud), 'Pago de trámite', @Fecha); SET @CveVenta = CONVERT (INT, SCOPE_IDENTITY()); INSERT dbo.VentasDetalle (CveVenta, CvePS, CveSolicitud, CveCostoTramite, Cantidad, PrecioUnitario, Descuento, IVA, Importe, CveObjetoImpuesto, EsFondoInicial, FechaAlta, CveUsuario) SELECT @CveVenta, D.CvePS, @CveSolicitud, Costo.CveCostoTramite, D.Cantidad, CONVERT (DECIMAL (18, 2), Costo.Importe), CONVERT (DECIMAL (18, 2), 0), CONVERT (DECIMAL (18, 2), 0), CONVERT (DECIMAL (18, 2), ROUND(D.Cantidad * Costo.Importe, 2)), Costo.CveObjetoImpuesto, 0, @Fecha, @CveUsuarioEjecuta FROM dbo.Tra_TiposTramitePagosDetalle AS D CROSS APPLY (SELECT TOP (1) CT.CveCostoTramite, CT.Importe, CT.CveObjetoImpuesto FROM dbo.Tra_CostosTramite AS CT WHERE CT.CveTipoTramite = @CveTipoTramite AND CT.CvePS = D.CvePS AND CT.EsActivo = 1 AND (CT.FechaInicioVigencia IS NULL OR CT.FechaInicioVigencia <= CONVERT (DATE, @Fecha)) AND (CT.FechaFinVigencia IS NULL OR CT.FechaFinVigencia >= CONVERT (DATE, @Fecha)) ORDER BY ISNULL(CT.FechaInicioVigencia, CONVERT (DATE, '19000101')) DESC, CT.CveCostoTramite DESC) AS Costo WHERE D.CveTramitePago = @CveTramitePago; INSERT dbo.VentasDetalleImpuestos (CveVentaDetalle, EsRetencion, Base, Impuesto, TipoFactor, TasaOCuota, Importe, FechaAlta, CveUsuario) SELECT VD.CveVentaDetalle, CTI.EsRetencion, CONVERT (DECIMAL (19, 6), VD.Importe - VD.Descuento), CTI.Impuesto, CTI.TipoFactor, CTI.TasaOCuota, CONVERT (DECIMAL (18, 2), CASE WHEN CTI.TipoFactor = 'Exento' THEN 0 WHEN CTI.TipoFactor = 'Cuota' THEN ROUND(VD.Cantidad * CTI.TasaOCuota, 2) ELSE ROUND((VD.Importe - VD.Descuento) * CTI.TasaOCuota, 2) END), @Fecha, @CveUsuarioEjecuta FROM dbo.VentasDetalle AS VD INNER JOIN dbo.Tra_CostosTramiteImpuestos AS CTI ON CTI.CveCostoTramite = VD.CveCostoTramite WHERE VD.CveVenta = @CveVenta; UPDATE VD SET IVA = ISNULL(ImpuestoIVA.Importe, 0) FROM dbo.VentasDetalle AS VD OUTER APPLY (SELECT SUM(VDI.Importe) AS Importe FROM dbo.VentasDetalleImpuestos AS VDI WHERE VDI.CveVentaDetalle = VD.CveVentaDetalle AND VDI.EsRetencion = 0 AND VDI.Impuesto = '002') AS ImpuestoIVA WHERE VD.CveVenta = @CveVenta; EXECUTE dbo.PA_Vta_TramiteVentaTotalesUpdate @CveVenta = @CveVenta, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @ErrorMostrar OUTPUT, @ErrorTipo = @ErrorTipo OUTPUT, @Return = @Return OUTPUT; IF @Return = 0 RETURN; IF EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPago AS S INNER JOIN dbo.Ventas AS V ON V.CveVenta = @CveVenta WHERE S.CveSolicitudPago = @Obligacion AND S.Importe <> V.Total) BEGIN SELECT @ErrorMostrar = 'El total de venta no coincide con la obligación. Revise los conceptos e impuestos antes de vincularla.', @ErrorTipo = 2, @Return = 0; RETURN; END UPDATE dbo.Tra_SolicitudesPago SET CveVenta = @CveVenta, CveUsuarioModificacion = @CveUsuarioEjecuta, FechaModificacion = SYSDATETIME() WHERE CveSolicitudPago = @Obligacion; SELECT @CveVenta AS CveVenta; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'Ocurrió un error al registrar la venta del trámite; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Vta_TramiteVentaSave'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_ProductoServicioDelete @CvePS INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.ProductosServicios WHERE CvePS = @CvePS) BEGIN SELECT @ErrorMostrar = 'El producto o servicio seleccionado no existe.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.Tra_CostosTramite WHERE CvePS = @CvePS) OR EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CvePS = @CvePS) OR EXISTS (SELECT 1 FROM dbo.VentasDetalle WHERE CvePS = @CvePS) OR EXISTS (SELECT 1 FROM dbo.ProductosServicios WHERE CvePS <> @CvePS AND (CvePSAdicional = @CvePS OR CveCompuesto = @CvePS)) BEGIN SELECT @ErrorMostrar = 'El producto o servicio tiene trámites, pagos, ventas o productos relacionados y no puede eliminarse.', @ErrorTipo = 2; RETURN; END DELETE dbo.ProductosServicios WHERE CvePS = @CvePS; SET @Return = 1; END TRY BEGIN CATCH IF ERROR_NUMBER() = 547 BEGIN SELECT @ErrorMostrar = 'El producto o servicio tiene información relacionada y no puede eliminarse.', @ErrorTipo = 2, @Return = 0; RETURN; END SELECT @ErrorMostrar = 'Ocurrió un error al eliminar el producto o servicio; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_ProductoServicioDelete'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Gral_UnidadMedidaDelete @CveUnidadMedida INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @@TRANCOUNT = 0 OR XACT_STATE() <> 1 THROW 51300, 'La operación requiere la transacción del servicio.', 1; DECLARE @ResultadoBloqueo AS INT; EXECUTE @ResultadoBloqueo = sys.sp_getapplock @Resource = N'PagosConvenios', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 5000; IF @ResultadoBloqueo < 0 BEGIN SELECT @ErrorMostrar = 'Hay otra operación de pagos en curso. Intente nuevamente.', @ErrorTipo = 2, @Return = 0; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.UnidadesMedida WHERE CveUnidadMedida = @CveUnidadMedida) BEGIN SELECT @ErrorMostrar = 'La unidad de medida seleccionada no existe.', @ErrorTipo = 2; RETURN; END IF EXISTS (SELECT 1 FROM dbo.ProductosServicios WHERE CveUnidadMedida = @CveUnidadMedida) OR EXISTS (SELECT 1 FROM dbo.Tra_TiposTramitePagosDetalle WHERE CveUM = @CveUnidadMedida) BEGIN SELECT @ErrorMostrar = 'La unidad de medida tiene productos, servicios o pagos relacionados y no puede eliminarse.', @ErrorTipo = 2; RETURN; END DELETE dbo.UnidadesMedida WHERE CveUnidadMedida = @CveUnidadMedida; SET @Return = 1; END TRY BEGIN CATCH IF ERROR_NUMBER() = 547 BEGIN SELECT @ErrorMostrar = 'La unidad de medida tiene información relacionada y no puede eliminarse.', @ErrorTipo = 2, @Return = 0; RETURN; END SELECT @ErrorMostrar = 'Ocurrió un error al eliminar la unidad de medida; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Gral_UnidadMedidaDelete'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudPagoList @CveSolicitud INT, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY WITH Aplicaciones AS (SELECT A.CveSolicitudPago, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPago), Traslados AS (SELECT O.CveSolicitudPagoOrigen, SUM(O.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY O.CveSolicitudPagoOrigen), Saldos AS (SELECT S.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, S.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPago AS S LEFT OUTER JOIN Aplicaciones AS A ON A.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoOrigen = S.CveSolicitudPago) SELECT @CveSolicitud AS CveSolicitud, S.CveSolicitudPago, S.CveTramitePago, S.Descripcion AS NombrePago, S.EsRequerido, CONVERT (BIT, CASE WHEN S.EstadoAdministrativo = 'ACTIVO' THEN 1 ELSE 0 END) AS EsActivo, CONVERT (BIT, CASE WHEN S.ImporteAbonado >= S.Importe THEN 1 ELSE 0 END) AS TienePago, S.Importe AS Total, S.ImporteAbonado AS ImportePagado, S.ImporteConvenido, S.SaldoPendiente, S.CveUnidadCobro, U.Codigo AS UnidadCobro FROM Saldos AS S INNER JOIN dbo.Gral_UnidadesCobro AS U ON U.CveUnidadCobro = S.CveUnidadCobro WHERE (S.CveSolicitud = @CveSolicitud OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS R ON R.CveSolicitudPago = O.CveSolicitudPagoOrigen WHERE O.CveSolicitudPagoConvenio = S.CveSolicitudPago AND R.CveSolicitud = @CveSolicitud)) ORDER BY S.FechaGeneracion, S.CveSolicitudPago; SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible completar la operación. Contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudPagoList'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO -- La configuración particular sustituye completamente la general. -- Sólo obligaciones generadas, requeridas y con saldo cobrable. -- Consulta las condiciones al PA existente, sin duplicar sus reglas. -- El estatus Autorizado tiene prioridad; el rechazo precede a faltantes/vencidos. -- Autorizados/cancelados no presentan tareas por atender en el panel. CREATE OR ALTER PROCEDURE dbo.PA_Tra_SolicitudProcesoActualizar @CveSolicitud INT=NULL, @CveFraccionamientoEtapa INT=NULL, @CveUsuarioEjecuta INT, @ErrorMostrar VARCHAR (MAX) OUTPUT, @ErrorTipo INT OUTPUT, @Return BIT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY IF @CveSolicitud IS NULL AND @CveFraccionamientoEtapa IS NULL BEGIN SET @ErrorMostrar = 'Seleccione una solicitud o etapa para actualizar.'; SET @ErrorTipo = 2; RETURN; END DECLARE @Hoy AS DATE = CONVERT (DATE, SYSDATETIMEOFFSET() AT TIME ZONE 'US Mountain Standard Time'); SELECT S.CveSolicitud, S.CveTipoTramite, S.CveFraccionamientoEtapa, ES.Codigo AS CodigoEstatus INTO #Solicitudes FROM dbo.Tra_Solicitudes AS S INNER JOIN dbo.Tra_EstatusSolicitud AS ES ON ES.CveEstatusSolicitud = S.CveEstatusSolicitud WHERE (@CveSolicitud IS NULL OR S.CveSolicitud = @CveSolicitud) AND (@CveFraccionamientoEtapa IS NULL OR S.CveFraccionamientoEtapa = @CveFraccionamientoEtapa); CREATE UNIQUE CLUSTERED INDEX IX_Solicitudes ON #Solicitudes(CveSolicitud); SELECT S.CveSolicitud, G.CveTipoDocumento, G.EsRequerido, G.EsCliente, G.TieneVigencia, G.EsActivo INTO #Configuracion FROM #Solicitudes AS S INNER JOIN dbo.Tra_TiposTramiteDocumento AS G ON G.CveTipoTramite = S.CveTipoTramite WHERE NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudDocumentoConfiguracion AS P WHERE P.CveSolicitud = S.CveSolicitud AND P.CveTipoDocumento = G.CveTipoDocumento) UNION ALL SELECT P.CveSolicitud, P.CveTipoDocumento, P.EsRequerido, P.EsCliente, P.TieneVigencia, P.EsActivo FROM dbo.Tra_SolicitudDocumentoConfiguracion AS P INNER JOIN #Solicitudes AS S ON S.CveSolicitud = P.CveSolicitud; CREATE TABLE #Acciones ( CveSolicitud INT NOT NULL, TipoAccion VARCHAR (30) COLLATE Modern_Spanish_CI_AS NOT NULL, CveReferencia INT NOT NULL, Descripcion NVARCHAR (1000) COLLATE Modern_Spanish_CS_AS NOT NULL, VisibleCliente BIT NOT NULL, Orden INT NOT NULL, PRIMARY KEY (CveSolicitud, TipoAccion, CveReferencia) ); INSERT INTO #Acciones (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT C.CveSolicitud, 'DocumentoFaltante', C.CveTipoDocumento, CONCAT(N'Cargar documento: ', COALESCE (NULLIF (T.Descripcion, ''), T.TipoDocumento)), C.EsCliente, 10 FROM #Configuracion AS C INNER JOIN dbo.Tra_TiposDocumento AS T ON T.CveTipoDocumento = C.CveTipoDocumento WHERE C.EsActivo = 1 AND C.EsRequerido = 1 AND T.EsActivo = 1 AND NOT EXISTS (SELECT 1 FROM dbo.Tra_DocumentosSolicitud AS D WHERE D.CveSolicitud = C.CveSolicitud AND D.CveTipoDocumento = C.CveTipoDocumento AND D.EsActivo = 1 AND NULLIF (LTRIM(RTRIM(D.NombreArchivo)), '') IS NOT NULL AND NULLIF (LTRIM(RTRIM(D.RutaArchivo)), '') IS NOT NULL); INSERT INTO #Acciones (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT D.CveSolicitud, 'DocumentoRechazado', D.CveDocumentoSolicitud, CONCAT(N'Corregir documento no autorizado: ', COALESCE (NULLIF (T.Descripcion, ''), T.TipoDocumento)), ISNULL(C.EsCliente, 0), 20 FROM dbo.Tra_DocumentosSolicitud AS D INNER JOIN #Solicitudes AS S ON S.CveSolicitud = D.CveSolicitud INNER JOIN dbo.Tra_TiposDocumento AS T ON T.CveTipoDocumento = D.CveTipoDocumento LEFT OUTER JOIN #Configuracion AS C ON C.CveSolicitud = D.CveSolicitud AND C.CveTipoDocumento = D.CveTipoDocumento WHERE D.EsActivo = 1 AND D.EsAprobado = 0; INSERT INTO #Acciones (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT D.CveSolicitud, 'DocumentoVencido', D.CveDocumentoSolicitud, CONCAT(N'Renovar documento vencido: ', COALESCE (NULLIF (T.Descripcion, ''), T.TipoDocumento), N' (', CONVERT (CHAR (10), D.FechaVencimiento, 103), N')'), ISNULL(C.EsCliente, 0), 30 FROM dbo.Tra_DocumentosSolicitud AS D INNER JOIN #Solicitudes AS S ON S.CveSolicitud = D.CveSolicitud INNER JOIN dbo.Tra_TiposDocumento AS T ON T.CveTipoDocumento = D.CveTipoDocumento LEFT OUTER JOIN #Configuracion AS C ON C.CveSolicitud = D.CveSolicitud AND C.CveTipoDocumento = D.CveTipoDocumento WHERE D.EsActivo = 1 AND D.FechaVencimiento < @Hoy AND ISNULL(C.TieneVigencia, 1) = 1; WITH Aplicaciones AS (SELECT A.CveSolicitudPago, SUM(A.ImporteAplicado) AS Abonado FROM dbo.Tra_PagosAplicaciones AS A INNER JOIN dbo.Tra_Pagos AS P ON P.CvePago = A.CvePago WHERE P.EsActivo = 1 AND P.Autorizado = 1 GROUP BY A.CveSolicitudPago), Traslados AS (SELECT O.CveSolicitudPagoOrigen, SUM(O.ImporteTomadoConvenio) AS Convenido FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS C ON C.CveSolicitudPago = O.CveSolicitudPagoConvenio WHERE C.EstadoAdministrativo <> 'CANCELADO' GROUP BY O.CveSolicitudPagoOrigen), Saldos AS (SELECT S.*, ISNULL(A.Abonado, 0) AS ImporteAbonado, ISNULL(T.Convenido, 0) AS ImporteConvenido, S.Importe - ISNULL(A.Abonado, 0) - ISNULL(T.Convenido, 0) AS SaldoPendiente FROM dbo.Tra_SolicitudesPago AS S LEFT OUTER JOIN Aplicaciones AS A ON A.CveSolicitudPago = S.CveSolicitudPago LEFT OUTER JOIN Traslados AS T ON T.CveSolicitudPagoOrigen = S.CveSolicitudPago) INSERT INTO #Acciones (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT DISTINCT R.CveSolicitud, 'PagoPendiente', S.CveSolicitudPago, CONCAT(N'Pagar saldo: ', S.Descripcion), 1, 40 FROM Saldos AS S INNER JOIN #Solicitudes AS R ON R.CveSolicitud = S.CveSolicitud OR EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesPagoConvenioOrigen AS O INNER JOIN dbo.Tra_SolicitudesPago AS P ON P.CveSolicitudPago = O.CveSolicitudPagoOrigen WHERE O.CveSolicitudPagoConvenio = S.CveSolicitudPago AND P.CveSolicitud = R.CveSolicitud) WHERE S.EstadoAdministrativo = 'ACTIVO' AND S.EsRequerido = 1 AND S.SaldoPendiente > 0; DECLARE @SolicitudCondicion AS INT; DECLARE @TipoTramite AS INT; DECLARE @Etapa AS INT; DECLARE @Condiciones TABLE ( CveCondicionMostrar INT, CondicionMostrar VARCHAR (100)); DECLARE @Correcto AS BIT; DECLARE @TipoError AS INT; DECLARE @Mensaje AS VARCHAR (MAX); DECLARE condiciones CURSOR LOCAL FAST_FORWARD FOR SELECT CveSolicitud, CveTipoTramite, CveFraccionamientoEtapa FROM #Solicitudes ORDER BY CveSolicitud; OPEN condiciones; FETCH NEXT FROM condiciones INTO @SolicitudCondicion, @TipoTramite, @Etapa; WHILE @@FETCH_STATUS = 0 BEGIN DELETE @Condiciones; INSERT INTO @Condiciones EXECUTE dbo.PA_Tra_MostrarCondicionesporTramite @CveTipoTramite = @TipoTramite, @CveFraccionamientoEtapa = @Etapa, @CveUsuarioEjecuta = @CveUsuarioEjecuta, @ErrorMostrar = @Mensaje OUTPUT, @ErrorTipo = @TipoError OUTPUT, @Return = @Correcto OUTPUT; IF ISNULL(@Correcto, 0) = 0 BEGIN SET @ErrorMostrar = @Mensaje; SET @ErrorTipo = ISNULL(NULLIF (@TipoError, 0), 1); CLOSE condiciones; DEALLOCATE condiciones; RETURN; END INSERT INTO #Acciones (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT @SolicitudCondicion, 'CondicionPendiente', C.CveCondicionMostrar, CONCAT(N'Capturar condición: ', C.CondicionMostrar), 0, 50 FROM @Condiciones AS C INNER JOIN dbo.FraccionamientosEtapas AS E ON E.CveFraccionamientoEtapa = @Etapa WHERE CASE C.CveCondicionMostrar WHEN 1 THEN E.Aprobado_Prefactibilidad WHEN 2 THEN E.RequiereObrasExternas WHEN 3 THEN E.TipoDeObra WHEN 4 THEN E.LiberacionMacromedidor WHEN 5 THEN E.Relotificacion WHEN 6 THEN E.LiberacionDeLotes WHEN 7 THEN E.LiberacionDePagosDeDerechos END IS NULL; FETCH NEXT FROM condiciones INTO @SolicitudCondicion, @TipoTramite, @Etapa; END CLOSE condiciones; DEALLOCATE condiciones; UPDATE S SET EstatusProceso = CASE WHEN B.CodigoEstatus = 'Autorizado' THEN 4 WHEN EXISTS (SELECT 1 FROM #Acciones AS A WHERE A.CveSolicitud = S.CveSolicitud AND A.TipoAccion = 'DocumentoRechazado') THEN 2 WHEN EXISTS (SELECT 1 FROM #Acciones AS A WHERE A.CveSolicitud = S.CveSolicitud AND A.TipoAccion IN ('DocumentoFaltante', 'DocumentoVencido')) THEN 1 WHEN B.CodigoEstatus = 'Revisando' THEN 3 WHEN B.CodigoEstatus <> 'Sin Procesar' OR EXISTS (SELECT 1 FROM dbo.Tra_DocumentosSolicitud AS D WHERE D.CveSolicitud = S.CveSolicitud AND D.EsActivo = 1) OR EXISTS (SELECT 1 FROM dbo.Tra_ComentariosSolicitud AS C WHERE C.CveSolicitud = S.CveSolicitud) THEN 1 ELSE 0 END FROM dbo.Tra_Solicitudes AS S INNER JOIN #Solicitudes AS B ON B.CveSolicitud = S.CveSolicitud; DELETE A FROM #Acciones AS A INNER JOIN #Solicitudes AS S ON S.CveSolicitud = A.CveSolicitud WHERE S.CodigoEstatus IN ('Autorizado', 'Cancelado'); DELETE A FROM dbo.Tra_SolicitudesAccionesPendientes AS A INNER JOIN #Solicitudes AS S ON S.CveSolicitud = A.CveSolicitud WHERE NOT EXISTS (SELECT 1 FROM #Acciones AS N WHERE N.CveSolicitud = A.CveSolicitud AND N.TipoAccion = A.TipoAccion AND N.CveReferencia = A.CveReferencia); UPDATE A SET Descripcion = N.Descripcion, VisibleCliente = N.VisibleCliente, Orden = N.Orden FROM dbo.Tra_SolicitudesAccionesPendientes AS A INNER JOIN #Acciones AS N ON N.CveSolicitud = A.CveSolicitud AND N.TipoAccion = A.TipoAccion AND N.CveReferencia = A.CveReferencia; INSERT INTO dbo.Tra_SolicitudesAccionesPendientes (CveSolicitud, TipoAccion, CveReferencia, Descripcion, VisibleCliente, Orden) SELECT N.CveSolicitud, N.TipoAccion, N.CveReferencia, N.Descripcion, N.VisibleCliente, N.Orden FROM #Acciones AS N WHERE NOT EXISTS (SELECT 1 FROM dbo.Tra_SolicitudesAccionesPendientes AS A WHERE A.CveSolicitud = N.CveSolicitud AND A.TipoAccion = N.TipoAccion AND A.CveReferencia = N.CveReferencia); SET @Return = 1; END TRY BEGIN CATCH SELECT @ErrorMostrar = 'No fue posible actualizar o consultar el seguimiento de solicitudes; contacte a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @ErrorTecnico AS NVARCHAR (2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', COALESCE (ERROR_PROCEDURE(), 'PA_Tra_SolicitudProcesoActualizar'), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR (N'%s', 10, 1, @ErrorTecnico); END CATCH END GO CREATE OR ALTER VIEW [dbo].[Vta_SaldosFavor] AS SELECT P.[CvePago], P.[CveCliente], P.[CveVenta], P.[CveMoneda], P.[Importe] AS [ImporteRecibido], ISNULL(SUM(CASE WHEN A.[EsActivo] = (1) THEN A.[Importe] ELSE (0) END), (0)) AS [ImporteAplicado], P.[Importe] - ISNULL(SUM(CASE WHEN A.[EsActivo] = (1) THEN A.[Importe] ELSE (0) END), (0)) AS [SaldoDisponible] FROM [dbo].[Tra_Pagos] AS P LEFT OUTER JOIN [dbo].[Vta_AplicacionesSaldoFavor] AS A ON A.[CvePagoOrigen] = P.[CvePago] WHERE P.[EsSaldoFavor] = (1) AND P.[EsActivo] = (1) GROUP BY P.[CvePago], P.[CveCliente], P.[CveVenta], P.[CveMoneda], P.[Importe]; GO