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
Suscripción de noticias RSS para comentarios de esta entrada.