viernes, 31 de julio de 2020

30/7/2020 Reporte final 3ra parte

Base de datos:


Cambios y mejoras:

Se crearon los siguientes SPs:

  • SP_completarPagoRecibos: Si el usuario despues de ver el total de monto de los recibos decide pagar entonces se llama a este SP el cual simplemente cambia el estado de los recibos, crea un comprobante de pago y crea una relacion enre estas dos entidades:
                        CREATE PROC [dbo].[SP_completarPagoRecibos]
                            DECLARE @montoComprobante MONEY
BEGIN TRAN
--ACTUALIZA EL ESTADO A PAGADOS
UPDATE [dbo].[Recibos]
SET estado = 1
FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagar idRP ON R.id = idRP.idRecibo
--GUARDA EL MONTO TOTAL
SET @montoComprobante = (SELECT SUM(monto) 
FROM [dbo].[Recibos] R 
INNER JOIN ##idRecibosPagar idRP ON R.id                                 =idRP.idRecibo)
--CREA UN COMPROBANTE DE PAGO
INSERT INTO [dbo].[ComprobantePago](fecha,total,medioDePago)
SELECT GETDATE(),@montoComprobante,'Corriente'
--INSERTA LOS RECIBOS EN RECIBOS PAGADOS
INSERT INTO [dbo].[ReciboPagado](id_Recibo,id_Comprobante)
SELECT idRP.idRecibo,IDENT_CURRENT('[dbo].[ComprobantePago]')
FROM ##idRecibosPagar idRP
DROP TABLE ##idRecibosPagar

  • SP_pagarRecibos: Recibe un json(Se cambio despues por una tabla) con los id de los recibos que el usuario decidio pagar, se generan recibo moratorios si es que hay y se retornan para mostrarlos al usuario:
                            CREATE PROC [dbo].[SP_pagarRecibos] @inIdRecibos varchar(MAX)
                                DECLARE @idMenor INT, @idMayor INT, @montoRecibo MONEY, 
@montoMoratorio MONEY,@fechaOperacion DATE, @montoTotal MONEY,
@fechaVence DATE, @tasaMoratoria FLOAT,@idPropiedad int
CREATE TABLE ##idRecibosPagar (id INT IDENTITY(1,1),idRecibo INT);
--GUARDA LOS IDS DE LOS RECIBOS QUE QUIERO PAGAR
INSERT INTO ##idRecibosPagar(idRecibo)
SELECT id
FROM OPENJSON(@inIdRecibos)
WITH(id INT)

SET @montoTotal = 0

SELECT @idMenor = MIN([id]), @idMayor=MAX([id]) FROM ##idRecibosPagar--                                                                        SACA ID MAYOR Y MENOR PARA ITERAR LA TABLA
BEGIN TRAN
WHILE @idMenor<=@idMayor--RECORRE LOS RECIBOS
BEGIN
SET @montoMoratorio = 0
SET @fechaOperacion = GETDATE()
SET @idPropiedad = (SELECT id_Propiedad FROM [Recibos] R 
INNER JOIN ##idRecibosPagar idRP ON                                                                                                                                     idRP.idRecibo = R.id
WHERE @idMenor = idRP.id)
SET @fechaVence = (SELECT fechaVence FROM [dbo].[Recibos] R
   INNER JOIN ##idRecibosPagar idRP ON                                                                                                                                             idRP.idRecibo = R.id
   WHERE @idMenor = idRP.id)
SET @montoRecibo = (SELECT R.monto FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagar idRP ON R.id                                                                                                                                             = idRP.idRecibo
WHERE idRP.id = @idMenor)
IF @fechaVence < @fechaOperacion
BEGIN
--SACA LA TASA MORATORIA DEL RECIBO
SET @tasaMoratoria = (SELECT CC.tasaImpuestoMoratorio FROM                                                                                                                         [dbo].[ConceptoDeCobro] CC
INNER JOIN [dbo].[Recibos] R ON                                                                                                                                                     R.id_CC = CC.id 
INNER JOIN  ##idRecibosPagar idRP ON                                                                                                                                     idRP.idRecibo = R.id
WHERE idRP.id = @idMenor)

--AQUI CAMBIA EL MONTO MORATORIO YA QUE SI SE DEBE                                                        CREAR RECIBO MORATORIO
SET @montoMoratorio =                 (@montoRecibo*@tasaMoratoria/365)*ABS(DATEDIFF(d,@fechaVence,@fechaOperacion))
--CREA UN RECIBO DE TIPO MORATORIO
INSERT INTO [dbo].[Recibos](id_CC,monto,estado,id_Propiedad,fecha,fechaVence)
SELECT CC.id,@montoMoratorio,0,@idPropiedad,@fechaOperacion,DATEADD(d,CC.diasParaVencer,@fechaOperacion)
FROM [dbo].[ConceptoDeCobro] CC
WHERE CC.id = 11

--GUARDA ADEMAS LOS RECIBOS MORATORIOS A PAGAR
INSERT INTO ##idRecibosPagar(idRecibo)
SELECT IDENT_CURRENT('[dbo].[Recibos]')
END
SET @montoTotal += @montoMoratorio+@montoRecibo
SET @idMenor += 1
END
COMMIT
SELECT [id_CC],[monto],[fecha],[fechaVence] FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagar RP ON R.id = RP.idRecibo
  • SP_cancelarPagoRecibos: Si el usuario decide no pagar los recibos entonces los recibos moratorios que se generaron se anulan:
        CREATE PROC [dbo].[SP_cancelarPagoRecibos]
                            UPDATE [dbo].[Recibos]
SET estado = 2
FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagar AS idRP ON R.id = idRP.idRecibo
WHERE R.id_CC = 11
  • SP_ConsultarCuota: El cual saca la cuota dependiendo del monto de los recibos y de los metes  lo retorna.(inIdRecibos,inMeses)

CREATE PROC [dbo].[SP_ConsultarCuota] @inIdRecibos VARCHAR(MAX), @inMeses INT
        
    DECLARE @idMenor INT, @idMayor INT,@sumaRecibos MONEY=0, @cuota                                     MONEY, @tasaInteres FLOAT,@montoMoratorio MONEY,@fechaOperacion DATE,
@idPropiedad INT,@fechaVence DATE,@montoRecibo MONEY,@tasaMoratoria                                 FLOAT
CREATE TABLE ##idRecibosPagarAP (id INT IDENTITY(1,1),idRecibo INT);
--GUARDA LOS IDS DE LOS RECIBOS QUE QUIERO PAGAR
INSERT INTO ##idRecibosPagarAP(idRecibo)
SELECT id
FROM OPENJSON(@inIdRecibos)
WITH(id INT)
--SET @sumaRecibos = 0
SELECT @idMenor = MIN([id]), @idMayor=MAX([id]) FROM ##idRecibosPagarAP                                                                   --SACA ID MAYOR Y MENOR PARA ITERAR LA TABLA
BEGIN TRAN
WHILE @idMenor<=@idMayor--RECORRE LOS RECIBOS
BEGIN
SET @montoMoratorio = 0
SET @fechaOperacion = GETDATE()
SET @idPropiedad = (SELECT id_Propiedad FROM [Recibos] R 
INNER JOIN ##idRecibosPagarAP idRP ON                                                                                                                                         idRP.idRecibo = R.id
WHERE @idMenor = idRP.id)
SET @fechaVence = (SELECT fechaVence FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagarAP idRP ON                                                                                                                                             idRP.idRecibo = R.id
WHERE @idMenor = idRP.id)
SET @montoRecibo = (SELECT R.monto FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagarAP idRP ON R.id =                                                                                                                                                idRP.idRecibo
WHERE idRP.id = @idMenor)
IF @fechaVence < @fechaOperacion
BEGIN
--SACA LA TASA MORATORIA DEL RECIBO
SET @tasaMoratoria = (SELECT CC.tasaImpuestoMoratorio FROM [dbo].                                                                                                                                [ConceptoDeCobro] CC
INNER JOIN [dbo].[Recibos] R ON R.id_CC =                                                                                                                                                             CC.id 
INNER JOIN  ##idRecibosPagarAP idRP ON                                                                                                                                        idRP.idRecibo = R.id
WHERE idRP.id = @idMenor)

--AQUI CAMBIA EL MONTO MORATORIO YA QUE SI SE DEBE                                                                                                                             CREAR RECIBO MORATORIO
SET @montoMoratorio =             (@montoRecibo*@tasaMoratoria/365)*ABS(DATEDIFF(d,@fechaVence,@fechaOperacion))
--CREA UN RECIBO DE TIPO MORATORIO
INSERT INTO [dbo].[Recibos]                                                                                                                                                          (id_CC,monto,estado,id_Propiedad,fecha,fechaVence)
SELECT         CC.id,@montoMoratorio,0,@idPropiedad,@fechaOperacion,DATEADD(d,CC.diasParaVencer,@fech                                                                                                                                                   aOperacion)
FROM [dbo].[ConceptoDeCobro] CC
WHERE CC.id = 11

--GUARDA ADEMAS LOS RECIBOS MORATORIOS A PAGAR
INSERT INTO ##idRecibosPagarAP(idRecibo)
SELECT IDENT_CURRENT('[dbo].[Recibos]')
END
SET @sumaRecibos += @montoMoratorio+@montoRecibo
SET @idMenor += 1
END
SET @tasaInteres = convert(float,(SELECT valor FROM [dbo].[ValoresConfig]                                                                                                             WHERE nombre = 'TasaInteres AP'))
SET @cuota = @sumaRecibos*            ((@tasaInteres*POWER((1+@tasaInteres),@inMeses))/(POWER((1+@tasaInteres),@inMeses)-1))
SELECT @cuota

  • SP_CrearAP: Si el usuario desea pagar entonces llama a este SP el cual paga los recibos, genera un comprobante de pago para el ap, genera un AP y un movimiento de debito.(inMeses,inCuota)
        CREATE PROC [dbo].[SP_CrearAP] @inMeses INT, @inCuota MONEY
                
    DECLARE @montoAP MONEY, @idPropiedad INT, @idComprobante INT,@TasaInteresAnual FLOAT, @idAP INT
--SACA LA TASA ANUAL DE LA TABLA DE CONFIG
SET @TasaInteresAnual = convert(float,(SELECT valor FROM [dbo].[ValoresConfig] WHERE nombre = 'TasaInteres AP'))
--GUARDA EL ID DE LA PROPIEDAD
SET @idPropiedad = (SELECT DISTINCT id_Propiedad FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagarAP idRP ON R.id = idRP.idRecibo)
--GUARDA EL MONTO TOTAL
SET @montoAP = (SELECT SUM(monto) 
FROM [dbo].[Recibos] R 
INNER JOIN ##idRecibosPagarAP idRP ON R.id = idRP.idRecibo)
BEGIN TRAN
--ACTUALIZA EL ESTADO A PAGADOS
UPDATE [dbo].[Recibos]
SET estado = 1
FROM [dbo].[Recibos] R
INNER JOIN ##idRecibosPagarAP idRP ON R.id = idRP.idRecibo

--CREA UN COMPROBANTE DE PAGO
INSERT INTO [dbo].[ComprobantePago](fecha,total,medioDePago)
SELECT GETDATE(),@montoAP,'AP# '
SET @idComprobante = IDENT_CURRENT('[dbo].[ComprobantePago]')

--INSERTA LOS RECIBOS EN RECIBOS PAGADOS
INSERT INTO [dbo].[ReciboPagado](id_Recibo,id_Comprobante)
SELECT idRP.idRecibo,IDENT_CURRENT('[dbo].[ComprobantePago]')
FROM ##idRecibosPagarAP idRP
DROP TABLE ##idRecibosPagarAP

--CREA UN AP
INSERT INTO [dbo].[ArregloPago](IdPropiedad,IdComprobante,MontoOriginal,Saldo,TasaInteresAnual,PlazoOriginal,PlazoResta,Cuota,insertedAt,updatedAt)
SELECT @idPropiedad,@idComprobante,@montoAP,@montoAP,@TasaInteresAnual,@inMeses,@inMeses,@inCuota,GETDATE(),GETDATE()
SET @idAP = IDENT_CURRENT('[dbo].[ArregloPago]')

--ACTUALIZA EL COMPROBANTE DE PAGO CON EL ID DEL AP
UPDATE [dbo].[ComprobantePago]
SET medioDePago += @idAP

--GENERA UN MOVIMIENTO DE DEBITO, EL UNICO
INSERT INTO [dbo].[MovimientosAP](idAP,idTipoMov,Monto,interesDelMes,plazoResta,nuevoSaldo,fecha,insertedAt)
SELECT @idAP
,1
,@montoAP
,@montoAP*@TasaInteresAnual/12
,@inMeses
,@montoAP
,GETDATE()
,GETDATE()

  • SP_ProcesaAPs: Este SP procesa los nodos que vienen en el xml, recibe una finca y unos meses, entonces saca los recibos pendientes, los moratorios y genera un AP, aun estoy con dudas sobre como generar el AP, ya que ya existe un SP que lo genera.(APs,fechaOperacion)
            CREATE PROC [dbo].[SP_ProcesaAPs] @APs APTipo READONLY, @fechaOperacion DATE

                    SELECT @idMenor = min([id]), @idMayor=max([id]) FROM @APs
--PRIMERO ITERO POR LAS PROPIEDADES PARA GENERAR APS
WHILE @idMenor<=@idMayor
BEGIN
SET @montoAP = 0
SET @idPropiedad = (SELECT P.id
FROM @APs APs
INNER JOIN [dbo].[Propiedad] P ON P.numFinca = APs.numFinca 
WHERE APs.id = @idMenor)
SET @meses = (SELECT plazo 
FROM @APs
WHERE id = @idMenor)

--GUARDO TODOS LOS RECIBOS PENDIENTES
INSERT INTO @idRecibosAP(idRecibo,visitado)
SELECT R.id,0
FROM [dbo].[Recibos] R
WHERE R.estado = 0 AND R.id_Propiedad = @idPropiedad

--WHILE PARA RECORRER LOS RECIBOS Y VERIFICAR SI ES NECESARIO CREAR MORATORIOS
--SI ES NECESARIO ENTONCES LOS GUARDO EN LA TABLA DE IDS
WHILE EXISTS(SELECT * FROM @idRecibosAP WHERE visitado = 0)
BEGIN
--PONE EL RECIBO COMO VISITADO PORQUE LO ESTAMOS VISITANDO EN ESTE MOMENTO
UPDATE @idRecibosAP
SET visitado = 1
WHERE id = @indice

SET @fechaVence = (SELECT fechaVence FROM [dbo].[Recibos] R
   INNER JOIN @idRecibosAP idRAP ON idRAP.idRecibo = R.id
   WHERE @indice = idRAP.id AND idRAP.visitado = 0)
SET @montoRecibo = (SELECT R.monto FROM [dbo].[Recibos] R
INNER JOIN @idRecibosAP idRAP ON R.id = idRAP.idRecibo
WHERE @indice = idRAP.id AND idRAP.visitado = 0)
SET @montoAP += @montoRecibo
IF @fechaVence < @fechaOperacion
BEGIN
--SACA LA TASA MORATORIA DEL RECIBO
SET @tasaMoratoria = (SELECT CC.tasaImpuestoMoratorio FROM [dbo].[ConceptoDeCobro] CC
INNER JOIN [dbo].[Recibos] R ON R.id_CC = CC.id 
INNER JOIN  @idRecibosAP idRAP ON idRAP.idRecibo = R.id
WHERE @indice = idRAP.id AND idRAP.visitado = 0)

SET @montoMoratorio = (@montoRecibo*@tasaMoratoria/365)*ABS(DATEDIFF(d,@fechaVence,@fechaOperacion))
SET @montoAP += @montoMoratorio
--CREA UN RECIBO DE TIPO MORATORIO
INSERT INTO [dbo].[Recibos](id_CC,monto,estado,id_Propiedad,fecha,fechaVence)
SELECT CC.id,@montoMoratorio,0,@idPropiedad,@fechaOperacion,DATEADD(d,CC.diasParaVencer,@fechaOperacion)
FROM [dbo].[ConceptoDeCobro] CC
WHERE CC.id = 11

--GUARDA ADEMAS LOS RECIBOS MORATORIOS A PAGAR
INSERT INTO @idRecibosAP(idRecibo,visitado)
SELECT IDENT_CURRENT('[dbo].[Recibos]'),1
SET @indice += 1 --INCREMENTO EN INDICE PARA IR GUARANDO POR DONDE VOY 
END
END
--GENERO EL AP
SET @tasaInteres = convert(float,(SELECT valor FROM [dbo].[ValoresConfig] WHERE nombre = 'TasaInteres AP'))
SET @cuota = @montoAP*((@tasaInteres*POWER((1+@tasaInteres),@meses))/(POWER((1+@tasaInteres),@meses)-1))

--PODRIA LLAMAR AL SP PARA CREAR APs PERO TENDRIA QUE GUARDAR LOS IDS EN LA TABLA TEMPORAL

--CREAR EL AP AQUI MISMO 

SET @idMenor += 1

  • SP_GenerarRecibosAP: Genera los recibos de los Aps de manera diaria revisa si ese dia se deberia genrar un AP.(inFecha)
        CREATE PROC [dbo].[SP_GenerarRecibosAP] @inFecha DATE
        
    --GUARDA LOS IDS DE LOS APS QUE SE GENERARON ESTE DIA
INSERT INTO @idAPs(idAP)
SELECT id 
FROM [dbo].[ArregloPago]
WHERE DAY(insertedAt) = @dia AND PlazoResta != 0
--GUARDA LOS IDS MENOR Y MAYOR PARA ITERAR
SELECT @idMenor = MIN(id), @idMayor = MAX(id) FROM @idAPs
BEGIN TRAN
WHILE @idMenor<=@idMayor
BEGIN
SET @interesDelMes = (SELECT AP.Saldo 
FROM [dbo].[ArregloPago] AP
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor)*@TasaInteresAnual/12
SET @amortizacion = (SELECT AP.Cuota
FROM [dbo].[ArregloPago] AP
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor)-@interesDelMes
--SE ACTUALIZA EL AP
UPDATE [dbo].[ArregloPago]
SET Saldo = Saldo - @amortizacion,
PlazoResta = PlazoResta-1
FROM [dbo].[ArregloPago] AP 
INNER JOIN [dbo].[ValoresConfig] Config ON Config.nombre = 'TasaInteres AP' 
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor

SET @plazoRestante = (SELECT AP.PlazoResta 
FROM [dbo].[ArregloPago] AP
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor)
SET @nuevoSaldo = (SELECT AP.saldo
FROM [dbo].[ArregloPago] AP
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor )
--SE GENERA EL MOVIMIENTO
INSERT INTO [dbo].[MovimientosAP](idAP,idTipoMov,Monto,interesDelMes,plazoResta,nuevoSaldo,fecha,insertedAt)
SELECT AP.id,1,@amortizacion,@interesDelMes,@plazoRestante,@nuevoSaldo,@inFecha,@inFecha
FROM [dbo].[ArregloPago] AP
INNER JOIN @idAPs idAPs ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor
SET @idMov = IDENT_CURRENT('[dbo].[MovimientosAP]')

--SE GENERA EL RECIBOS DEL AP
INSERT INTO [dbo].[Recibos](id_CC,monto,estado,id_Propiedad,fecha,fechaVence)
SELECT CC.id,AP.Cuota,0,AP.IdPropiedad,@inFecha,DATEADD(D,CC.diasParaVencer,@inFecha)
FROM @idAPs idAPs 
INNER JOIN[dbo].[ConceptoDeCobro] CC ON CC.id = 12
INNER JOIN [ArregloPago] AP ON AP.id = idAPs.idAP
WHERE idAPs.id = @idMenor
SET @idRecibo = IDENT_CURRENT('[dbo].[Recibos]')

INSERT INTO [dbo].[RecibosAP](id,descripcion,idMovAP)
SELECT @idRecibo
,'Interes mensual:'+CAST(@interesDelMes AS VARCHAR(30))
+', amortizacion:'+CAST(@amortizacion AS VARCHAR(30))
+', plazo resta:'+CAST(@plazoRestante AS VARCHAR(30))
,@idMov
SET @idMenor += 1
END
COMMIT

  • SP_APdeUsuarioSelect: Retorna el arreglo de pago correspondiente a una propiedad.(@inNumFinca)
           CREATE PROCEDURE [dbo].[SP_APdeUsuarioSelect] @inNumFinca varchar(100)

            SELECT * 
FROM [dbo].[ArregloPago] AP
INNER JOIN [dbo].[Propiedad] P ON P.id = AP.IdPropiedad
WHERE P.numFinca = @inNumFinca

  • SP_MovDeAPSelect: Selecciona los movimientos en un Arreglo de Pago.(@inAPid)
            CREATE PROCEDURE [dbo].[SP_MovDeAPSelect] @inAPid varchar(100)

            SELECT * 
FROM [dbo].[MovimientosAP] MAP
INNER JOIN [dbo].[ArregloPago] AP ON MAP.idAP = AP.id
WHERE AP.id = @inAPid 
Se creo un view:

  • CCdePropiedadView: Muestra todos los atributos de todos los tipos de concepto de cobro.
                    REATE VIEW [CCdePropiedadView] AS
SELECT [dbo].[CCConsumo].[valorPorM3]
,[dbo].[ConceptoDeCobro].[esImpuesto]
,[dbo].[ConceptoDeCobro].[esRecurrente]
,[dbo].[ConceptoDeCobro].[esFijo]
,[dbo].[CCFijo].[Monto]
,[dbo].[ConceptoDeCobro].[nombre]
,[dbo].[ConceptoDeCobro].[tasaImpuestoMoratorio]
,[dbo].[ConceptoDeCobro].[id]
,[dbo].[ConceptoDeCobro].[diasParaVencer]
,[dbo].[ConceptoDeCobro].[diaDeCobro]
,[dbo].[CCPorcentaje].[valorPorcentual]
,[dbo].[CCDePropiedad].[id_Propiedad]
FROM   [dbo].[ConceptoDeCobro]
LEFT OUTER JOIN [dbo].[CCConsumo] ON [dbo].[ConceptoDeCobro].[id] = [dbo].[CCConsumo].[id]
LEFT OUTER JOIN [dbo].[CCFijo] ON [dbo].[ConceptoDeCobro].[id] = [dbo].[CCFijo].[id]
LEFT OUTER JOIN [dbo].[CCImpMoratorio] ON [ConceptoDeCobro].[id] = [dbo].[CCImpMoratorio].[id]
LEFT OUTER JOIN [dbo].[CCPorcentaje] ON [dbo].[ConceptoDeCobro].[id] = [dbo].[CCPorcentaje].[id]
INNER JOIN [dbo].[CCDePropiedad] ON [dbo].[CCDePropiedad].[id_CC] = [dbo].[ConceptoDeCobro].[id]
WHERE [dbo].[ConceptoDeCobro].[activo] = 1 AND [dbo].[CCDePropiedad].[activo] = 1;


Se crearon los siguientes tablas: 
  • ArregloPago: Se guardan los arreglos de pago que el usuario genera. (id, idPropiedad, idComprobante, MontoOriginal, Saldo, TasaInetersAnual, PlazoOriginal, PlazoResta, Cuota, insertedAt, updatedAt)
  • MovimientosAP: Se guardan todos los movimientos que se hacen en la tabla de arreglos de pago.(id, idAP, idTipoMov, Monto, interesDelMes, plazoResta, nuevoSaldo, fecha, insertedAt)
  • RecibosAP: heredan de recibos.(id, descripcion, idMovP)
  • tipoMovAP: me dice el tipo de movimiento que se esta haciendo en el arreglo.(id,nombre)
  • ValoresConfig: almacena configuraciones necesarias en calculos y demas.
  • TiposValoresConfig: Establece los tipos de datos que se usan en ValoresConfig.
  • idRecibosPagarTable: se guardan temporalmente los recibos que el usuario escoge pagar
  • idRecibosPagarAP: se guardan temporalmente los recibos que se pagan en AP.
Se alteraron SPs existentes:

  • getOperaciones: Se agrego el codigo para poder generar los recibos de ap y procesar los aps del xml:
        --GENERACION DE RECIBOS DE AP
EXEC [dbo].[SP_GenerarRecibosAP] @MinDate
--PROCESAMIENTO DE APS
DECLARE @APs APTipo
INSERT INTO @APs(numFinca,plazo) 
SELECT [NumFinca],[plazo]
FROM OPENXML (@hdoc, 'Operaciones_por_Dia/OperacionDia/AP',1)  
WITH ( [NumFinca] VARCHAR(30) '@NumFinca',  
[plazo] INT '@Plazo',
[fechaDeIngreso12] DATE '../@fecha')
WHERE [fechaDeIngreso12] = @MinDate
EXEC [dbo].[SP_ProcesaAPs] @APs,@MinDate
DELETE @APs

Problemas:
  • El problema que mas se nos complico en bases de datos fue que utilizábamos tablas temporales para los proceso en los que había que recibir una confirmación por parte del usuario, el problema de esto es que cuando se creaba la tabla temporal, y se realizaban acciones en la parte web y se volvía a la base de datos, la tabla temporal se eliminaba, ya que el scope de las tablas temporales se ve limitado cuando sucede esto, por lo que tuvimos que buscar una solución rápida la cual fue crear tablar normales las cuales serán utilizadas para almacenar datos temporales como los ids de los recibos que se deben pagar y así.
  • Mas que un problema fue un tema de pensar en donde implementar el view para que cumpliera la función de filtrar algunos datos de una tabla o mas bien juntar datos de ciertas tablas, finalmente lo aplicamos a la hora de mostrar los Conceptos de cobro de una propiedad, ya que mostramos los conceptos de cobro y todos los atributos de los hijos.
  • Nosotros solo retornábamos la cuota después de hacer el calculo de los recibos moratorias para el ap, aclarándonos nos dimos cuenta que habia que mostrar el detalle de los recibos, por lo que lo resolvimos retornando los recibos mas la cuota como columna extra.
Observaciones:

Para esta 3ra parte lo complicado y diferente a las anteriores fue tener que crear un proceso, guardar ciertos resultados y dependiendo de una respuesta del usuario saber que hacer, esto inicialmente lo resolvimos con tablas temporales pero a la hora de probarlo nos dimos cuenta de que se estaba borrando la tabla temporal cuando se iba a la base de datos, entonces lo que hicimos fue usar tablas normales que almacenan datos temporales.

Se trabajo por 16 horas en total aproximadamente en la base de datos

Parte Web

  • ¿Qué se implemento?
    • Se cambio el estilo de las tablas del usuario cliente. Ahora las tablas tienen una apariencia mucho más agradable.

      • Como se tenia poco conocimiento en css se busco un ejemplo que se pudiera usar como base, este ejemplo se simplifico, se quitaron varias librerías y funciones de js.
    • Las tablas también ahora se encuentran dentro de su propio div y cuando sobrepasan el tamaño de este aparece una barra para desplazarse. Esto se logro con el siguiente código:
                        .divTabla{
                            width: 75%;
                            display: inline-block;
                            overflow-y: scroll;
                            max-height: 90%;
                        }
      • Todos los div que contienen una tabla utilizan la misma clase, así no es necesario aplicar el estilo por separado.
    • En la tabla de recibos se añadió una nueva columna, la cual contiene un checkbox para que el usuario seleccione los recibos que quiere pagar. Esto se implemento de la siguiente manera:
                              <asp:TemplateField HeaderText="" ShowHeader="False">
                                  <ItemTemplate>
                                      <asp:CheckBox runat="server" ID="checkBoxRecibo"/>
                                  </ItemTemplate>
                                  <ItemStyle Width="3%"/>
                              </asp:TemplateField>
        • El código anterior se agrega dentro de la etiqueta de columnas del gridView.
      • El usuario usa estos checkboxs para seleccionar los recibos que quiere pagar, y abajo de la tabla aparece el botón de pagar, al hacer click en este se muestra una nueva tabla "flotante" donde se pueden ver tanto los recibos seleccionados, así como los moratorios que se generaron, además se muestra el total a pagar.
        • Para mostrar esta tabla flotante se hizo uso del siguiente codigo css.
                                     width: 70%;
                                     max-height: 70%;
                                     position: absolute;
                                     top: 70px;
                                     left: 19%;
                                     z-index: 10;
                                     background: white;
                                     -webkit-box-shadow: 6px 2px 54px -11px rgba(0,0,0,0.75);
                                     -moz-box-shadow: 6px 2px 54px -11px rgba(0,0,0,0.75);
                                     box-shadow: 6px 2px 54px -11px rgba(0,0,0,0.75);
        • Este css se aplica al div que se encuentra "flotando". Position:absolute permite que el div se coloque sobre otros elementos, y en z-index se le asigna un valor alto para asegurar que tenga prioridad respecto a los otros elementos en la pagina web. 
        • Los últimos tres atributos se encargan de añadir sombras al div, estas instrucciones se consiguieron usando una pagina web que permite visualizar la sombre y editarla en tiempo real hasta obtener la deseada. El link de la pagina es https://www.cssmatic.com/box-shadow.
    • Se añadió la opción para ver los arreglos de pagos, y dentro de esta opción también se pueden ver los movimientos del arreglo de pago.
    • En las tablas de recibos se añadió una nueva columna que se utiliza para mostrar la descripción de los recibos de arreglos de pago.
    • En la pagina web del usuario administrador se añadió una nueva opción para impersonar a un cliente. El administrador digita el nombre de usuario y da click en el botón para obtener una tabla de las propiedades del cliente. Acá puede ver los recibos pagados, pendientes y los arreglos de pago.
      • La mayor parte de esta sección fue una copia de la interfaz del usuario cliente, excepto en los recibos pendientes donde se tuvo que hacer varios cambios, como el texto de los botones, los SP a los que se llama y en lugar de mostrar el total a pagar se muestra la cuota.
      • Cuando el administrador se encuentra en los recibos pendientes, puede seleccionarlos y dar click en el botón para crear un arreglo de pago, esto igual que la interfaz del cliente, muestra una tabla "flotante" que contiene todos los recibos seleccionados, los moratorios y la cuota.
      •  Junto a la tabla de recibos pendientes también se muestra una lista desplegable para seleccionar el plazo del arreglo de pago.
      • En el div de confirmación también se muestra un botón para cancelar y uno para pagar, en caso de cancelar, los checkboxs se mantienen marcados para que el usuario pueda hacer cambios, también puede cambiar el plazo y volver a calcular la cuota.
    • Como se añadió esta nueva consulta, se hicieron cambios en el estilo de la pagina para que los cuadros de las consultas no se salieran de la pantalla.
                        #divConsultas {
                            display: flex;
                            flex-direction: row;
                            height: 100%;
                            margin-left: var(--div-width);
                            flex-wrap: wrap;
                        }

                        #divConsultas > div {
                            display: flex;
                            flex-direction: column;
                            margin: 20px 20px 20px 20px;
                            background-color: #474e5d;
                            border-style: solid;
                            padding: 5px 5px 5px 5px;
                            max-height: 300px;
                            width: 250px;
                        }
      • Al div que contiene las consultas se le dan los atributos "display: flex;" y "flex-direction: row;", estos hacen que el contenido del div se acomode en forma horizontal. El atributo "flex-wrap: wrap;" se encarga de distribuir los elementos dentro del div en varias líneas en caso de ocupar mas espacio que el grosor del div.
      • A cada div dentro del div padre se la da el atributo "flex-direction: column;" para que sus elementos se acomoden de manera vertical, también se les da un margen para que tengan espacios entre si y un valor de anchura fijo.
  • Problemas encontrados:
    • Para verificar que no se dejaran recibos intermedios sin pagar inicialmente se tenia una idea mas complicada la cual era solo activar el checkbox del recibo con fecha más vieja por cada concepto de cobro, y al seleccionarlo activar el siguiente checkbox y así sucesivamente. Al final la idea que se implemento es la siguiente:
      • La tabla se itera de la ultima fila hacia la primera.
      • Si la fila se marco para pagar se hacen dos cosas
        • Se inserta el id del recibo en la tabla que va a ser usada como parámetro del SP. Este se inserta siempre en posición 1. Esto para que no queden las filas invertidas.
        • Se guarda en un HashSet el id del concepto de cobro del recibo.
      • Si la fila no se encuentra marcada para pagar se realiza lo siguiente:
        • Se busca el id del concepto de cobro dentro del HashSet, en caso de encontrarlo se habilita un label con un mensaje de error y se termina la función.
        • En caso de no encontrar el id se continua con la función.
    • Algo que no se tenia claro era cuando usar el atributo class o cssclass, esto inicialmente causo varios problemas puesto que los estilos no se estaban aplicando, tras investigar un poco se encontró que el atributo cssclass solo se utilizan en los elementos propiamente de asp, como por ejemplo "<asp:Button>" o "<asp:Label>", inicialmente se creyó que todo elemento que tuviera el atributo "runat='server'" debía usar cssclass en lugar de class.
  • Se trabajó alrededor de 21 horas en la pagina web.