jueves, 21 de noviembre de 2019

Creación del modelo físico

Hora Inicio: 9:23 p.m

Actividades


- Se hace el SP para reiniciar las tablas de carga de datos. En este se eliminan las tablas 
- Realizar la primera conexión de todas las entidades con base en el modelo conceptual hecho en clase. El diagrama resultante es el siguiente:














Enlace al repositorio GitHub: SP_ReiniciarTablas.sql

Hora Fin: 10:40 p.m

Horas totales: 1:16 h

lunes, 18 de noviembre de 2019

Inicio de Proyecto Final

Reunión proyecto final: (Austin y Antony)

Hora Inicio: 1:40 p.m

Actividades:
- Creación preliminar de todas las tablas que van a ser necesarias, no hubo problemas con esta parte porque teníamos la guía del modelo conceptual realizado en clase.
- Inicio del desarrollo de sp de simulación. Se realiza únicamente la carga de los archivos de simulación.
- Apertura de un repositorio en GitHub para control de versiones del proyecto. Se crean 3 ramas: master, Austin y Antony para manejar en las ramas de nuestros nombres los cambios que hacemos individualmente y el master para mantener la versión funcional más actual.
- Análisis de diagrama conceptual de la base de datos para la creación de la base de datos física.
- Se inicia la carga de archivos (Deducción, etc)



Hora Fin: 4:44 p.m

Total de horas trabajadas: 3:04 h

miércoles, 6 de noviembre de 2019

Realización de la primera consulta y segunda consulta.

Para la primera consulta se decidió hacer uso de una vista. En este caso primero se intentó encontrar una forma de usar la función agregada DATEADD y restar los resultados para calcular la cantidad de depósitos realizados y los que que se hubieran realizado si el saldo no hubiera quedado negativo, esto estaba generando problemas, sin embargo investigando se descubrió la función agregada DATEDIFF que simplificó mucho más el proceso. Para aprender a usar las vistas fue de gran ayuda este video: https://www.youtube.com/watch?v=MK_dWEcltWY
Además para este caso de puso como criterio de filtración que la fecha inicio de las cuentas objetivo por analizar fueran iguales o menores al 2018-05-31 ya que el último día del archivo de simulación es el 2018-06-30 y como lo indica la sección DOS de la tercera tarea programada los ahorros en la CO son mensuales por lo que esta sería la última fecha posible para hacer un ahorro mensual. Idealmente se incluiría una consulta que calcula este fecha con base en la última fecha del archivo de simulación.

Este es el código resultante de la primera consulta:

CREATE OR ALTER VIEW [dbo].[Vista_CuentasObjetivoQuePerdieronRetirosPorSaldoNegativo]
AS
SELECT CO.Numero_Cuenta,
  CO.id as ID_de_la_Cuenta_Objetivo,
  CO.Descripcion,
  DATEDIFF(MONTH,Fecha_Proximo_Credito,Fecha_Final) as Cantidad_de_depósitos_realizados,
  DATEDIFF(MONTH,Fecha_Inicio, Fecha_Final) as Cantidad_de_depósitos_si_se_hubieran_realizado_todos_los_depósitos,
  CO.Monto_Ahorro * DATEDIFF(MONTH,Fecha_Proximo_Credito,Fecha_Final) as Monto_debitado_real,
  CO.Monto_Ahorro * DATEDIFF(MONTH,Fecha_Inicio, Fecha_Final) as Monto_debitado_si_se_hubieran_realizado_todos_los_depósitos
FROM CuentaObjetivo CO
WHERE CO.Saldo = 0 and CO.Fecha_Proximo_Credito != Fecha_Final and Fecha_Inicio <= '2018-05-31'
GO

Para la segunda consulta, se decidió utilizar un stored procedure. Para realizar esta consulta se tuvo que hacer modificaciones al archivo XML de simulación (Simulación2.xml), puesto a que no sucedía ningún caso en el que una cuenta tuviera 5 multas por exceso de retiros en cajero humano. Por lo tanto en la prueba realizada solo se muestra sobre 1 cuenta la consulta para mostrar que funciona, ya que hacerlo para todas habría tomado mucho tiempo. También sucedió que con las pruebas se descubrió que puede haber más de un mes y más de un año con la mayor cantidad de retiros, por lo que se pasó de usar una variable entera para guardar este valor a usar tablas variables para guardar todos los años y meses donde la cantidad de retiros fue la mayor. Uno de los principales problemas enfrentados fue el de obtener el primer día del mes siguiente a cualquier fecha, para lograrlo se hizo uso de una función encontrada en internet: DATEADD(m,1,DATEADD(m,datediff(m,0,@Fecha_Buscar),0))

Al final lo que faltó de la consulta fue calcular el promedio de retiros por mes.

El código de la segunda consulta es el siguiente

USE [Sistema_Banco]
GO
/****** Object:  StoredProcedure [dbo].[SP_CuentasMultaExcCH_Min5_UltimosNDias]    Script Date: 11/14/2019 5:05:38 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Austin Hakanson>
-- Create date: <11-06-2019>
-- Description: <SP para ejecutar consulta de cuentas que tienen multas por exceso de retiros en cajero humano
-- y lo han hecho al menos 5 veces en los últimos N días>
-- =============================================
ALTER PROCEDURE [dbo].[SP_CuentasMultaExcCH_Min5_UltimosNDias]
-- Parametros
@Dias int
AS
BEGIN
SET NOCOUNT ON;

-- DESCRIPCION
-- Se consultan los id de las cuentas y el numero de apariciones de dicho id en la tabla movimento
-- para todas las cuentas que hayan tenido movimientos del tipo 'multSaldMin' en fechas posteriores
-- a la fecha de busqueda

-- Se declara una tabla variable para cargar las fechas de operacion
SET Language Spanish
DECLARE @Fechas TABLE
(
sec int primary key identity(1,1),
fecha date
)

DECLARE @UltimaFechaDeOperacion date
DECLARE @PrimeraFechaDeOperacion date
DECLARE @MesesDeOperacion int

DECLARE @DocHandle int, @XmlDocument xml
-- Se cargan los datos del XML a la variable XML
SELECT @XmlDocument = F
FROM OPENROWSET (Bulk '\\Mac\Home\Documents\Ing. Computación\IV Semestre\Bases de datos I\IIITP\Simulacion2.xml',Single_BLOB) AS Fechas(F)
-- Se crea una representacion interna del documento XML
EXEC sp_xml_preparedocument @DocHandle OUTPUT, @XmlDocument
-- Execute a SELECT statement using OPENXML rowset provider.
INSERT INTO @Fechas
SELECT fecha
FROM OPENXML (@DocHandle, '/xml/Simulacion/FechaOperacion',1) -- El uno al final indica que la lectura es <atribute-centric>
      WITH (fecha date)
EXEC sp_xml_removedocument @DocHandle

SELECT @UltimaFechaDeOperacion = max(fecha) FROM @Fechas
SELECT @PrimeraFechaDeOperacion = min(fecha) FROM @Fechas
SELECT @UltimaFechaDeOperacion = DATEADD(DAY,1,@UltimaFechaDeOperacion) -- Para que ajustar el total de meses de operacion si es el ultimo dia del mes
SELECT @MesesDeOperacion = DATEDIFF(MONTH,@PrimeraFechaDeOperacion,@UltimaFechaDeOperacion)

-- Se selecciona la ultima fecha de operacion del xml de simulacion
DECLARE @Fecha_Buscar date = DATEADD(DAY,-@Dias,@UltimaFechaDeOperacion)

-- Se insertan las cuentas con multa de exceso de retiros en cajero humano
DECLARE @Cuentas_Con_Multa_Exceso_CH_En_Fecha_Solicitada TABLE
(
idCuenta int,
Frecuencia int
)
INSERT INTO @Cuentas_Con_Multa_Exceso_CH_En_Fecha_Solicitada
SELECT [idCuenta]
  ,COUNT(idCuenta)
FROM [Sistema_Banco].[dbo].[Movimiento]
WHERE Tipo_Movimiento = 'multExcCH' and Fecha > @Fecha_Buscar
GROUP BY idCuenta

-- CANTIDAD PROMEDIO DE RETIROS

-- Se inserta en una tabla todos los movimientos de retiro

DECLARE @TodosLosMovimientosRetiro TABLE
( sec int identity(1,1),
 idCuenta int,
 Fecha date,
 Tipo_Movimiento nvarchar(50)
)
INSERT INTO @TodosLosMovimientosRetiro
SELECT M.idCuenta,
  M.Fecha,
  M.Tipo_Movimiento
FROM Movimiento M
WHERE M.Tipo_Movimiento = 'retiroCH' or M.Tipo_Movimiento = 'retiroCA'

-- Variables para el procesamiento del promedio
DECLARE @Fecha_LimiteInferior date = @PrimeraFechaDeOperacion
DECLARE @Fecha_LimiteSuperior date = DATEADD(MONTH,1,@PrimeraFechaDeOperacion)
SET @Fecha_LimiteSuperior = DATEADD(DAY,-1,@Fecha_LimiteSuperior)
DECLARE @Promedio float
DECLARE @Total float
DECLARE @CantidadMesesSimulacion int
DECLARE @MesConMasRetiros int = 0
DECLARE @MayorCantidadRetiros int  = 0
DECLARE @AnioConMasRetiros int

-- Ciclo para sacar los retiros mensuales de las cuentas con mas de 5 multas

DECLARE @Retiros_En_El_Mes int
DECLARE @Retiros_En_El_Anio int
DECLARE @MesesConMasRetiros TABLE
(
sec int identity(1,1),
mes int,
cantidad int,
nombre nvarchar(20)
)
DECLARE @AniosConMasRetiros TABLE
(
sec int identity(1,1),
anio int,
cantidad int
)

SELECT @Fecha_Buscar as Fecha_A_Buscar
-- Se definen los limites de fecha para hacer los calculos mensuales
SET @Fecha_LimiteInferior = @Fecha_Buscar
SET @Fecha_LimiteSuperior = DATEADD(m,1,DATEADD(m,datediff(m,0,@Fecha_Buscar),0)) -- Se selecciona el primer dia del siguiente mes
SET @Fecha_LimiteSuperior = DATEADD(DAY,-1,@Fecha_LimiteSuperior) -- Se acomoda para que sea el final del mes
SET @UltimaFechaDeOperacion = DATEADD(DAY,-1, @UltimaFechaDeOperacion)

WHILE @Fecha_LimiteSuperior <= @UltimaFechaDeOperacion
BEGIN

-- Se seleccionan el numero de retiros y el id de las cuentas que tienen movimientos de retiroCH o retiraCA Y que tienen al menos 5 multas por exceso de retiros
SELECT @Fecha_LimiteInferior as Fecha_LimiteInferior, @Fecha_LimiteSuperior as Fecha_LimiteSuperior, M.idCuenta, COUNT(M.idCuenta) Numero_Retiros_En_El_Mes
FROM Movimiento M
WHERE M.idCuenta IN (SELECT idCuenta FROM @Cuentas_Con_Multa_Exceso_CH_En_Fecha_Solicitada WHERE Frecuencia >= 5) -- Se seleccionan solo las cuentas con mas de 5 multas por exceso de retiros
 and M.Fecha BETWEEN @Fecha_LimiteInferior and @Fecha_LimiteSuperior -- Se seleccionan solo los
 and (M.Tipo_Movimiento = 'retiroCH' or M.Tipo_Movimiento = 'retiroCA')
GROUP BY idCuenta

-- Se guarda el numero de retiros en el mes
SELECT @Retiros_En_El_Mes = COUNT(M.idCuenta)
FROM Movimiento M
WHERE M.idCuenta IN (SELECT idCuenta FROM @Cuentas_Con_Multa_Exceso_CH_En_Fecha_Solicitada WHERE Frecuencia >= 5) -- Se seleccionan solo las cuentas con mas de 5 multas por exceso de retiros
 and M.Fecha BETWEEN @Fecha_LimiteInferior and @Fecha_LimiteSuperior -- Se seleccionan solo los
 and (M.Tipo_Movimiento = 'retiroCH' or M.Tipo_Movimiento = 'retiroCA')
GROUP BY idCuenta

SET @Retiros_En_El_Anio = @Retiros_En_El_Mes

IF (@Retiros_En_El_Mes >= @MayorCantidadRetiros)
BEGIN
SET @MayorCantidadRetiros = @Retiros_En_El_Mes
SET @MesConMasRetiros = DATEPART(MONTH,@Fecha_LimiteInferior)
SET @AnioConMasRetiros = DATEPART(YEAR,@Fecha_LimiteInferior)

IF (@MesConMasRetiros NOT IN (SELECT mes FROM @MesesConMasRetiros)) -- Si el mes no esta ya
BEGIN
-- Se eliminan los meses que tengan menor o igual cantidad
IF (@Retiros_En_El_Mes > (SELECT max(cantidad) FROM @MesesConMasRetiros))
BEGIN
DELETE @MesesConMasRetiros
END
-- Se inserta el nuevo mes
INSERT INTO @MesesConMasRetiros
VALUES
(
@MesConMasRetiros,
@Retiros_En_El_Mes,
DATENAME(MONTH,@Fecha_LimiteInferior)
)
END
ELSE
BEGIN
UPDATE @MesesConMasRetiros
SET cantidad = @MayorCantidadRetiros
WHERE mes = @MesConMasRetiros
END

IF (@AnioConMasRetiros NOT IN (SELECT anio FROM @AniosConMasRetiros))
BEGIN
-- Se eliminan los anios que tengan menor o igual cantidad
IF (@Retiros_En_El_Anio > (SELECT max(anio) FROM @AniosConMasRetiros))
BEGIN
DELETE @AniosConMasRetiros
END
-- Se inserta el nuevo anio
INSERT INTO @AniosConMasRetiros
VALUES
(
@AnioConMasRetiros,
@Retiros_En_El_Mes
)
END
ELSE
BEGIN
UPDATE @AniosConMasRetiros
SET cantidad = @MayorCantidadRetiros
WHERE anio = @AnioConMasRetiros
END
END

SET @Fecha_LimiteInferior = DATEADD(m,1,DATEADD(m,datediff(m,0,@Fecha_LimiteInferior),0)) -- Se selecciona el primer dia del siguiente mes
SET @Fecha_LimiteSuperior = DATEADD(MONTH,1,@Fecha_LimiteInferior) -- Se selecciona el primer dia del siguiente mes
SET @Fecha_LimiteSuperior = DATEADD(DAY,-1,@Fecha_LimiteSuperior)
----------------------------------------------------------------------------
END

SELECT  @MesConMasRetiros as MesConMasRetiros, @AnioConMasRetiros as AnioConMasRetiros
SELECT * FROM @MesesConMasRetiros
SELECT * FROM @AniosConMasRetiros
END

Horas de trabajo: Primera Consulta (1:30 h) Segunda Consulta: (2h)

martes, 5 de noviembre de 2019

Resumen y autoevaluacion III Parte

  • Administración del tiempo
Para esta tercera parte hubo una administración del tiempo deficiente, en su mayor parte porque esta tercera parte de la tarea programada se realizó prácticamente a finales del semestre y todo el mundo ya estaba siendo inundado de trabajos, así que el tiempo que se le podía dedicar al proyecto de Bases de datos era muy limitado ya que por la naturaleza de la malla curricular de la carrera de Ingenieria en Computacion, normalmente se llevan al menos dos cursos que realizan proyectos programados grandes. Por ello creo que la administracion del tiempo fue complicada y la limitante de la falta de tiempo por tener que invertirla en otros proyectos o tareas no ayuda para nada a la administracion del tiempo. En todo caso, se logró realizar bastante de la tarea programada.
  • Conocimientos sobre triggers, tipo XML de SQl server, manejo de fechas, etc
Los conocimientos adquiridos en este periodo de la tercera parte de la tarea programada fuerona bastante simples, con respecto a lo aprendido sobre el tipo de dato XML de SQL server es algo simple, lo unico esque hay que enterder que comandos utilizar ya que hay comandos por ejemplo si se quiere guardar mas de un alemento o registro de una tabla, el XML va a estar mal colocado si no se le agrega una raiz, ya que en un XML no puede haber mas de un registro en el "primer nivel" por asi decirlo, asi que si no se usa el comando ROOT("NombreDeRaiz") entonces el XML va a tener un error de sintaxis y si se quisiera utilizar para otras operaciones mas adelante, va a haber errores.

En cuanto a los triggers, ya se habian utilizado para la segunda parte de la tarea programada, pero solo se habia utilizado triggers de insercion, en cambio en esta tercera parte se utilizaron de insercion y actualizacion (de eliminacion no, pues nosotros enrealidad NO eliminamos, sino que "desactivamos" un campo en especifico y eso ya significa que el elemento fue eliminado; por eso el trigger de eliminacion es enrealidad de actualizacion), asi que en esta tarea se aprendio sobre los trigger de actualizacion y que enrealidad es como si se hiciera una eliminacion y luego un insercion, al menos al nivel del elemento actualizado. Ya que para obtener la informacion del elemento antes de la actualizacion, hay que usar la palabra recervada "deleted" y para obtener datos de la nueva informacion del elemento se usa la palabra reservada "inserted".

Se aprendió sobre el manejo y el cálculo de fechas por medio de las funciones agregadas, DATEADD() y DATEDIFF() para realizar actualizaciones y cambios en periodos de tiempo.

También se aprendió sobre el uso de las vistas como una manera de seleccionar y filtrar datos que se quieren consultar, ocultando al usuario final los detalles que pueden no ser relevantes.
  • Comunicación, liderazgo y trabajo en equipo
En esta tarea programada hubo una mejor distribución de las tareas, mientras que Austin se encargaba de corregir errores de la 2da tarea programada y realizar las consultas, Antony se enfocó en los triggers para la realización de la bitácora de eventos. Se inició con un poco más de antelación a realizar el trabajo, sin embargo no se pudo completar por completo todo lo solicitado en la tarea.

Horas totales de trabajo: 13.75 h

sábado, 2 de noviembre de 2019

Corrección de los intereses desde la segunda tarea programada

Se recordó que desde la 2da tarea programada había que corregir un error en el cálculo de los intereses y también que se necesitaba agregar los movimientos de multa por incumplimiento del saldo mínimo y multa por exceso de retiros en cajero humano a la tabla de movimientos.

El código resultante fue el siguiente:

Modificación el cálculo de los intereses.

Viejo:

DECLARE @MontoIntereses int
SELECT @MontoIntereses = TCA.Tasa_Interes * @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar/@Cargos_Servicio_Cuenta_Cerrar

Nuevo:

@MontoIntereses = (TCA.Tasa_Interes_Mensual * 0.01 * @saldoMinimoEC_Cerrar)/12

Se tomaron todas las declaraciones de variables y se colocaron al inicio de la simulación (fuera del while) para evitar una "redeclaración" de la variables


Ejemplo de código viejo

-- Se selecciona el id de la cuenta que debe ser procesada
DECLARE @idCuentaCerrarEC int
SELECT @idCuentaCerrarEC = C.idCuenta
FROM @CuentasCerrarEC C
WHERE C.sec = @lo 

-- Se obtiene el id del ultimo estado de cuenta de la cuenta que esta siendo procesada
DECLARE @idUltimoEC_CuentaCerrar int
SELECT @idUltimoEC_CuentaCerrar = max(EC.id)
FROM EstadoCuenta EC
WHERE EC.idCuenta = @idCuentaCerrarEC and EC.Fecha_Final = @fechaIteracion

-- Se obtiene el saldo minimo mantenido durante la vigencia del ultimo estado de cuenta
DECLARE @saldoMinimoEC_Cerrar money
SELECT @saldoMinimoEC_Cerrar = EC.Saldo_Minimo
FROM EstadoCuenta EC
WHERE EC.id = @idCuentaCerrarEC

-- Se obtiene la cantidad de retiros en cajero humano hechos durante la vigencia del ultimo estado de cuenta
DECLARE @QRCH_EC_Cerrar int
SELECT @QRCH_EC_Cerrar = EC.QRCH
FROM EstadoCuenta EC
WHERE EC.id = @idCuentaCerrarEC

-- Se obtiene el id del tipo de cuenta de la cuenta en iteracion
DECLARE @idTCA_Cuenta_Cerrar int
SELECT @idTCA_Cuenta_Cerrar = CA.idTipoCuentaAhorro
FROM Cuenta_Ahorro CA
WHERE CA.id = @idCuentaCerrarEC

-- Se obtiene el maximo de retiros en cajero humano para el tipo de cuenta de la cuenta en iteracion
DECLARE @MaxRCH_Cuenta_Cerrar int
SELECT @MaxRCH_Cuenta_Cerrar = TCA.Maximo_Retiros_Cajero_Humano
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se obtiene el saldo minimo para el tipo de cuenta de la cuenta en iteracion
DECLARE @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar money
SELECT @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar = TCA.Saldo_Minimo
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se obtiene la multa por exceder el maximo de retiros en cajero humano, segun el tipo de cuenta de la cuenta en iteracion
DECLARE @Multa_MaxRCH_Cuenta_Cerrar money
SELECT @Multa_MaxRCH_Cuenta_Cerrar = TCA.Multa_Exceso_Retiro_Cajero
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se obtiene la multa por incumplir el saldo minimo, segun el tipo de cuenta de la cuenta en iteracion
DECLARE @Multa_Saldo_Minimo_Cuenta_Cerrar money
SELECT @Multa_Saldo_Minimo_Cuenta_Cerrar = TCA.Multa_Saldo_Minimo
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se obtiene los cargos de servicio segun el tipo de cuenta de la cuenta en iteracion
DECLARE @Cargos_Servicio_Cuenta_Cerrar money
SELECT @Cargos_Servicio_Cuenta_Cerrar = TCA.Monto_Mensual_Cargos_Servicio
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se calculan intereses
DECLARE @MontoIntereses int
SELECT @MontoIntereses = TCA.Tasa_Interes * @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar/@Cargos_Servicio_Cuenta_Cerrar
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

-- Se obtiene el saldo actual de la cuenta en iteracion
DECLARE @SaldoActual_CuentaCerrar money
SELECT @SaldoActual_CuentaCerrar = CA.Saldo
FROM Cuenta_Ahorro CA
WHERE CA.id = @idCuentaCerrarEC

Ejemplo de código nuevo


-- Se selecciona el id de la cuenta que debe ser procesada
SELECT @idCuentaCerrarEC = C.idCuenta
FROM @CuentasCerrarEC C
WHERE C.sec = @lo 

-- Se obtiene el id del ultimo estado de cuenta de la cuenta que esta siendo procesada
SELECT @idUltimoEC_CuentaCerrar = max(EC.id)
FROM EstadoCuenta EC
WHERE EC.idCuenta = @idCuentaCerrarEC and EC.Fecha_Final = @fechaIteracion

-- Se obtiene el saldo minimo mantenido durante la vigencia del ultimo estado de cuenta
-- Se obtiene la cantidad de retiros en cajero humano hechos durante la vigencia del ultimo estado de cuenta
SELECT @saldoMinimoEC_Cerrar = EC.Saldo_Minimo, 
  @QRCH_EC_Cerrar = EC.QRCH
FROM EstadoCuenta EC
WHERE EC.idCuenta = @idCuentaCerrarEC and EC.Fecha_Final = @fechaIteracion

-- Se obtiene el id del tipo de cuenta de la cuenta en iteracion
-- Se obtiene el saldo actual de la cuenta en iteracion
SELECT @idTCA_Cuenta_Cerrar = CA.idTipoCuentaAhorro,
  @SaldoActual_CuentaCerrar = CA.Saldo
FROM Cuenta_Ahorro CA
WHERE CA.id = @idCuentaCerrarEC

-- Se obtiene el maximo de retiros en cajero humano para el tipo de cuenta de la cuenta en iteracion
-- Se obtiene el saldo minimo para el tipo de cuenta de la cuenta en iteracion
-- Se obtiene la multa por exceder el maximo de retiros en cajero humano, segun el tipo de cuenta de la cuenta en iteracion
-- Se obtiene la multa por incumplir el saldo minimo, segun el tipo de cuenta de la cuenta en iteracion
-- Se obtiene los cargos de servicio segun el tipo de cuenta de la cuenta en iteracion
-- Se calculan los intereses
SELECT @MaxRCH_Cuenta_Cerrar = TCA.Maximo_Retiros_Cajero_Humano, 
  @Multa_MaxRCH_Cuenta_Cerrar = TCA.Multa_Exceso_Retiros_Cajero,
  @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar = TCA.Saldo_Minimo,
  @Multa_Saldo_Minimo_Cuenta_Cerrar = TCA.Multa_Saldo_Minimo,
  @Cargos_Servicio_Cuenta_Cerrar = TCA.Monto_Mensual_Cargos_Servicio,
  @MontoIntereses = (TCA.Tasa_Interes_Mensual * 0.01 * @saldoMinimoEC_Cerrar)/12
FROM TipoCuentaAhorro TCA
WHERE TCA.id = @idTCA_Cuenta_Cerrar

Inserción de los movimientos por multa e intereses

Multa por saldo mínimo


-- Si se incumplio con el saldo minimo se aplica la multa correspondiente
IF (@saldoMinimoEC_Cerrar < @SaldoMinimo_Segun_Tipo_Cuenta_Cerrar)
BEGIN
SET @SaldoActual_CuentaCerrar = @SaldoActual_CuentaCerrar - @Multa_Saldo_Minimo_Cuenta_Cerrar

-- Si el saldo despues de aplicar los intereses y multas queda negativo, se deja en cero
IF (@SaldoActual_CuentaCerrar < 0)
BEGIN 
SET @SaldoActual_CuentaCerrar = 0
END
-- Se inserta el movimiento de multa a la tabla de movimientos
INSERT dbo.Movimiento
SELECT @idCuentaCerrarEC, TM.id, 'multSaldMin',
  @fechaIteracion, @Multa_Saldo_Minimo_Cuenta_Cerrar, 
  @SaldoActual_CuentaCerrar, 'Aplicacion de multa por incumplir el saldo minimo'
FROM TipoMovimiento TM 
WHERE TM.Nombre = 'multSaldMin'
END

Multa por saldo exceso de retiros en cajero humano


-- Si se excedio el maximo de retiros en cajero humano se aplica la multa correspondiente
IF (@QRCH_EC_Cerrar > @MaxRCH_Cuenta_Cerrar)
BEGIN
SET @SaldoActual_CuentaCerrar = @SaldoActual_CuentaCerrar - @Multa_MaxRCH_Cuenta_Cerrar

-- Se inserta el movimiento de multa a la tabla de movimientos
INSERT dbo.Movimiento
SELECT @idCuentaCerrarEC, TM.id, 'multExcCH',
  @fechaIteracion, @Multa_MaxRCH_Cuenta_Cerrar, 
  @SaldoActual_CuentaCerrar, 'Aplicacion de multa por exceder el maximo de retiros permitidos en cajero humano'
FROM TipoMovimiento TM 
WHERE TM.Nombre = 'multExcCH'
END

Horas trabajadas: 1.5 h

jueves, 31 de octubre de 2019

Resolucion de problemas anteriores y algunos triggers


Este día resolví lo de XMLAntes y XMLDespues que podían ser vacíos y lo hice haciendo que los campos de XMLAntes y XMLDespues puedan contener nulos ya que no o no existe o simplemente no encontré ninguna forma de crear un XML que fuera vacío, por lo que los XML vacíos son en realidad nulos.

Además realice algunos triggers algunos trigger y pare allí ya que en esta semana estoy hasta la cebolla de trabajos.

A continuación un poco del código que se programó:

CREATE TRIGGER  [dbo].[COInsertados] ON [dbo].[CuentaObjeto]
   AFTER INSERT
AS
BEGIN
                -- SET NOCOUNT ON added to prevent extra result sets from
                -- interfering with SELECT statements.
                SET NOCOUNT ON;

                               --Variables para buscar id de otros elementos
    declare @TipoEvento nvarchar(100) = N'Insertar CO';
                declare @Numero_de_Cuenta nvarchar(50);                                                  --Numero cuenta para buscar el idUsuario
                              
                               --Elementos para el nuevo elemento
                declare @idUsuario int;    --El id del usuario
                declare @Fecha date = GETDATE();
                declare @idTipoEvento int;   --El id del tipo evento
                declare @IP int = 0;
                declare @XMLAntes xml;
                declare @XMLDespues xml;

                Select @Numero_de_Cuenta = NewCO.Numero_Cuenta,                        --Determina NumeroCuenta y idTipoEvento
                                               @idTipoEvento = TE.id                
                from inserted NewCO, TipoEvento TE
                where TE.nombre = @TipoEvento;

                Select @idUsuario = CA.idCliente                           --Id del usuario
                from CuentaAhorro CA
                where CA.Numero_Cuenta = @Numero_de_Cuenta; 

               
                declare @TablaXml TABLE (  --Tabla variable para sacar XML del evento
                               id int NOT NULL,
                               idCuenta int NOT NULL,
                               Saldo money NOT NULL,
                               Fecha_Inicio date NOT NULL,
                               Fecha_Final date NOT NULL,
                               Monto_Ahorro money NOT NULL,
                               Numero_Cuenta nvarchar(50) NOT NULL
                )

                insert into @TablaXml  --Insercion del Evento en tabla variable
                select newCo.id, newCo.idCuenta, newCo.Saldo, newCo.Fecha_Inicio,
                                               newCo.Fecha_Final, newCo.Monto_Ahorro, newCo.Numero_Cuenta
                from inserted newCo

                set @XMLDespues = (Select * from @TablaXml as TablaXml for xml Auto, ELEMENTS XSINIL);  --XML del Evento

                insert into Evento (idTipoEvento, idUser, _IP, Fecha, XMLAntes, XMLDespues)  --Insercion final al evento
                values(@idTipoEvento, @idUsuario, @IP, @Fecha, @XMLAntes, @XMLDespues);

END

Este día solo invertí el proyecto como 1,5 horas.
Tarde tanto porque al principio estaba haciendo malísimo la tabla que se usa para crear el XML