Primero se creó la tabla variable @CuentasObjetivoPorAcreditar donde se almacenan los id de las cuentas objetivo activas cuya fecha de próximo crédito es igual a la fecha de interacción. De esta tabla se obtiene un @lo y @hi para iterar sobre ella.
Seguidamente, con estas cuentas seleccionadas se inicia una transacción donde se realizan los siguientes procesos:
- Se debita el monto que indica la cuenta objetivo que se ahorra mensualmente a la cuenta de ahorro a la que está asociada. Pero ANTES de hacerlo se verifica si el saldo de la cuenta de ahorro queda negativo, porque si es así entonces NO se realiza el movimiento de dinero.
- Si el saldo no queda negativo se hace un UPDATE sobre la tabla Cuenta_Ahorro para actualizar el saldo.
- Se inserta el movimiento de CO en la tabla de movimientos de la cuenta objetivo
- Una vez debitado el monto de la cuenta de ahorro, se acredita dicho monto a la cuenta objetivo. Para ello se verifica primero si la fecha de próximo crédito aún no ha alcanzado la fecha final de la cuenta objetivo.
- Si la fecha de próximo crédito alcanzó a la fecha final de la CO entonces se procesa el último movimiento, se desactiva la cuenta objetivo de manera lógica (se pone en 0 el campo "Activo") y se transfiere todo el saldo ahorrado de la cuenta objetivo a la cuenta de ahorro.
-- Procesar depositos en cuentas objetivo
DECLARE @CuentasObjetivoPorAcreditar TABLE
(
sec int identity(1,1),
idCuentaObjetivo int
)
IF EXISTS(SELECT CO.id FROM CuentaObjetivo CO WHERE CO.Fecha_Proximo_Credito = @fechaIteracion and CO.Activo = 1)
BEGIN
SET @lo = (SELECT COUNT(CO.sec) FROM @CuentasObjetivoPorAcreditar CO ) + 1
INSERT INTO @CuentasObjetivoPorAcreditar
SELECT CO.id
FROM CuentaObjetivo CO
WHERE CO.Fecha_Proximo_Credito = @fechaIteracion
SET @hi = (SELECT COUNT(CO.sec) FROM @CuentasObjetivoPorAcreditar CO )
BEGIN TRY
IF @@TRANCOUNT = 0
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION ProcesarCuentasObjetivo
SET @InicioTran = 1
END
WHILE @lo <= @hi
BEGIN
-- SE DEBITA EL MONTO A AHORRAR EN LA CUENTA OBJETIVO DE LA CUENTA DE AHORRO
-- Se seleccionan algunas variables que se necesitan para el proceso
SELECT @Monto_Ahorro = CO.Monto_Ahorro,
@Numero_Cuenta_CO = CO.Numero_Cuenta
FROM CuentaObjetivo CO
INNER JOIN @CuentasObjetivoPorAcreditar C ON CO.id = C.idCuentaObjetivo and C.sec = @lo
SELECT @SaldoCuenta_Debitar = CA.Saldo
FROM Cuenta_Ahorro CA
WHERE CA.Numero_Cuenta = @Numero_Cuenta_CO
-- Se verifica primero si el saldo de la cuenta queda negativo al restar el monto de ahorro
-- Si el saldo de la cuenta de ahorro no queda negativo se realiza la transaccion a la cuenta objetivo
IF ((@SaldoCuenta_Debitar - @Monto_Ahorro) > 0)
BEGIN
UPDATE Cuenta_Ahorro
SET Saldo = Saldo - @Monto_Ahorro
WHERE Numero_Cuenta = @Numero_Cuenta_CO
-- Se registra en la tabla de movimientos de CO la transaccion
INSERT INTO MovimientoCO
SELECT CO.id, TCO.id, @fechaIteracion, CO.Monto_Ahorro, CO.Descripcion
FROM @CuentasObjetivoPorAcreditar C
INNER JOIN CuentaObjetivo CO ON CO.id = C.idCuentaObjetivo
INNER JOIN TipoMovimientoCO TCO ON TCO.Nombre = 'Depósito'
WHERE C.sec = @lo
-- UNA VEZ REDUCIDO EL MONTO AHORRAR DE LA CUENTA DE AHORRO,
-- SE ACREDITA EL MONTO A LA CUENTA OBJETIVO CORRESPONDIENTE
-- Se selecciona la fecha del ultimo credito y la fecha final
SELECT @Fecha_Proximo_Credito = CO.Fecha_Proximo_Credito,
@Fecha_Final_CO = CO.Fecha_Final
FROM CuentaObjetivo CO
WHERE CO.id = (SELECT C.idCuentaObjetivo FROM @CuentasObjetivoPorAcreditar C WHERE C.sec = @lo)
IF (@Fecha_Proximo_Credito < @Fecha_Final_CO)
BEGIN
UPDATE CuentaObjetivo
SET Saldo = (Saldo + Monto_Ahorro),
Fecha_Proximo_Credito = DATEADD(MONTH,1,Fecha_Proximo_Credito)
WHERE id = (SELECT C.idCuentaObjetivo FROM @CuentasObjetivoPorAcreditar C WHERE C.sec = @lo)
END
ELSE
BEGIN
UPDATE CuentaObjetivo
SET Saldo = (Saldo + Monto_Ahorro)
WHERE id = (SELECT C.idCuentaObjetivo FROM @CuentasObjetivoPorAcreditar C WHERE C.sec = @lo)
-- Si entra aqui significa que llego a la fecha final de la cuenta objetivo
-- por lo que se procede a procesar la redencion en cuentas objetivo
IF (@Fecha_Proximo_Credito = @Fecha_Final_CO)
BEGIN
-- Se acredita la cuenta de ahorro
UPDATE Cuenta_Ahorro
SET Saldo = Saldo + (SELECT CO.Saldo
FROM CuentaObjetivo CO
INNER JOIN @CuentasObjetivoPorAcreditar C ON CO.id = C.idCuentaObjetivo and C.sec = @lo)
WHERE id = (SELECT CO.idCuenta
FROM CuentaObjetivo CO
INNER JOIN @CuentasObjetivoPorAcreditar C ON CO.id = C.idCuentaObjetivo and C.sec = @lo)
-- Se debita la cuenta objetivo y se desactiva
UPDATE CuentaObjetivo
SET Saldo = 0,
Activo = 0
WHERE id = (SELECT C.idCuentaObjetivo FROM @CuentasObjetivoPorAcreditar C WHERE C.sec = @lo)
END
END
END
-- Si al hacer la transaccion el saldo quedaba negativo en la cuenta de ahorro
ELSE
BEGIN
INSERT INTO @CuentasObjetivo_CasoDeSaldoNegativo
SELECT CO.Numero_Cuenta, CO.Fecha_Inicio, CO.Fecha_Final, CO.Fecha_Proximo_Credito
FROM CuentaObjetivo CO
WHERE CO.id = (SELECT C.idCuentaObjetivo FROM @CuentasObjetivoPorAcreditar C WHERE C.sec = @lo)
END
SET @lo = @lo + 1
END
IF (@InicioTran = 1)
BEGIN
COMMIT TRANSACTION ProcesarCuentasObjetivo
SET @InicioTran = 0
END
END TRY
BEGIN CATCH
IF @InicioTran = 1
BEGIN
ROLLBACK TRANSACTION ProcesarCuentasObjetivo
SELECT 'Hubo un error al procesar las cuentas objetivo'
Return -100007
END
END CATCH
END
Horas trabajadas: 3:30 h
No hay comentarios:
Publicar un comentario