domingo, 27 de octubre de 2019

Procesamiento de las cuentas objetivo (depósitos)

Se saca la tarde del domingo para realizar el procesamiento de los depósitos en las cuentas objetivo.

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:

  1. 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.
  2. Si el saldo no queda negativo se hace un UPDATE sobre la tabla Cuenta_Ahorro para actualizar el saldo.
  3. Se inserta el movimiento de CO en la tabla de movimientos de la cuenta objetivo
  4. 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. 
  5. 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