Impedir facturas con saldos en negativo

Hola Estimad@s.

 

En esta ocasión les tengo un artículo interesante para los usuarios de SAE que tengan la base de datos traducida a SQL Server. Cuántas veces no hemos visto como nuestras facturas tienen saldos en negativo, ya sea porque se les aplicó un pago de más o porque ya estando saldadas perfectamente, alguien nos aplica una nota de crédito. Operativamente esto es un problema y la única forma de solucionarlo es cancelando el pago o la nota de crédito lo que hace que "toquemos" los movimientos de cuentas x cobrar ocasionando un verdadero problema.

Lo que les vengo a mostrar es cómo mediante un trigger en SQL Server podemos impedir que esto suceda. Para esto, debemos saber los querys que nos indican si una factura está perfectamente saldada o no, esto lo vemos con el siguiente query.

 

SELECT CARGOS.DOCTO, (CARGOS.IMPORTE * CARGOS.SIGNO) + SUM(COALESCE(ABONOS.IMPORTE, 0) * COALESCE(ABONOS.SIGNO,0))
FROM CUEN_M01 CARGOS 
LEFT JOIN CUEN_DET01 ABONOS ON ABONOS.CVE_CLIE = CARGOS.CVE_CLIE AND ABONOS.REFER = CARGOS.REFER AND ABONOS.NUM_CARGO = CARGOS.NUM_CARGO 
AND ABONOS.ID_MOV = CARGOS.NUM_CPTO 
GROUP BY CARGOS.IMPORTE, CARGOS.SIGNO
having  ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) >= 0.01 OR ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) < -0.01 
 

Este query nos indica por documento cuál es el saldo restante del mismo. Si cuando guardamos el movimiento de CxC detectamos si el saldo se vuelve negativo, nos daríamos cuenta que el error está pasando y podriamos mandar un correo, guardar una bitácora o en el ejemplo que mostraré enviar un mensaje de error.

Para esto, crearemos un trigger en la tabla cuen_det01 solo corriendo este script en su base de datos

 

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:	CyberAdmin
-- Create date: 20150427
-- Description:<No deja insertar un valor cuen_det01 para que la factura quede con saldo negativo en CxC>
-- =============================================
CREATE TRIGGER TriggerCuen_Det01
   ON  Cuen_Det01
   AFTER INSERT
AS 
BEGIN
SET NOCOUNT ON;
declare @CVE_CLIE varchar(10)
declare @REFER varchar(20)
declare @NUM_CARGO int
declare @ID_MOV int
declare @Saldo money
declare @Texto as varchar(1024)
 
select @CVE_CLIE = cve_clie, @REFER = refer, @NUM_CARGO = num_cargo, @ID_MOV = id_mov FROM inserted
 
SELECT @Saldo = (CARGOS.IMPORTE * CARGOS.SIGNO) + SUM(COALESCE(ABONOS.IMPORTE, 0) * COALESCE(ABONOS.SIGNO,0))
FROM CUEN_M01 CARGOS 
LEFT JOIN CUEN_DET01 ABONOS ON ABONOS.CVE_CLIE = CARGOS.CVE_CLIE AND ABONOS.REFER = CARGOS.REFER AND ABONOS.NUM_CARGO = CARGOS.NUM_CARGO 
AND ABONOS.ID_MOV = CARGOS.NUM_CPTO 
WHERE ABONOS.CVE_CLIE = @CVE_CLIE and ABONOS.REFER = @REFER AND abonos.num_cargo = @NUM_CARGO AND ABONOS.ID_MOV = @ID_MOV
GROUP BY CARGOS.IMPORTE, CARGOS.SIGNO
having  ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) >= 0.01 OR ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) < -0.01 
 
if @saldo is not null
BEGIN
if @Saldo < -.01
BEGIN
rollback transaction
set @Texto = 'Se pretende aplicar un movimiento de CxC que dajaría con saldo negativo el documento (' + CAST(@Saldo as varchar(15)) + ')'
raiserror (@Texto, 16,1)
END
END
END
GO


Viendo el código a detalle, vemos que se obtienen las 4 llaves de la tabla CUEN_M01 que es donde se guardan los cargos de CxC

select @CVE_CLIE = cve_clie, @REFER = refer, @NUM_CARGO = num_cargo, @ID_MOV = id_mov FROM inserted

Esto es porque deberemos de buscar en la tabla CUEN_DET01 (Abonos de CxC) la sumatoria para saber del importe de la factura cuánto se ha pagado.

 

SELECT @Saldo = (CARGOS.IMPORTE * CARGOS.SIGNO) + SUM(COALESCE(ABONOS.IMPORTE, 0) * COALESCE(ABONOS.SIGNO,0))
FROM CUEN_M01 CARGOS 
LEFT JOIN CUEN_DET01 ABONOS ON ABONOS.CVE_CLIE = CARGOS.CVE_CLIE AND ABONOS.REFER = CARGOS.REFER AND ABONOS.NUM_CARGO = CARGOS.NUM_CARGO 
AND ABONOS.ID_MOV = CARGOS.NUM_CPTO 
WHERE ABONOS.CVE_CLIE = @CVE_CLIE and ABONOS.REFER = @REFER AND abonos.num_cargo = @NUM_CARGO AND ABONOS.ID_MOV = @ID_MOV
GROUP BY CARGOS.IMPORTE, CARGOS.SIGNO
having  ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) >= 0.01 OR ((CARGOS.IMPORTE * CARGOS.SIGNO) + CASE WHEN SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) IS NULL THEN 0 ELSE SUM((ABONOS.IMPORTE) * ABONOS.SIGNO) END) < -0.01 


Lo último ya es el control de errores, gracias a esto, cuando el usuario quiera guardar una nota de crédito, aplicación de pagos o cualquier otra cosa que afecte el saldo de una factura, si eso implica dejarla en negativo, mostrará el error claramente en el SAE

Juzguen por ustedes mismos si este tipo de mensajes les es útil. En lo particular nos ha ahorrado muchísimo tiempo de revisiones. Pedirle esto a Aspel nos saldría en un ojo de la cara, los ahorros son significativos.




Nos vemos pronto

 

Comentarios   

0 #1 R 24-11-2017 23:31
Este trigger está buenísimo , además es bastante conciso !!! He querido hacer cosas como ésta. Gracias ...

No tienes derecho suficientes para publicar contenido