miércoles, 7 de octubre de 2015

Se termino

Finalizamos el proyecto designado de manera completa, creemos que fue un trabajo duro y de gran enseñanza, con altibajos y con difíciles palmadas al comienzo y al final.
Por parte del equipo se miro la dificultad de crear la base de datos y la pagina web la cual al final se tuvo que hacer en localhost ya que se venció la cuenta de azure donde se planeaba subir dicha pagina con su respectiva base de datos.

Se empezara el análisis punto por punto con los requerimientos del profesor:

+ Los SP de todas las actualizaciones (inserción, modificación y borrado de cada entidad) :

En este apartado no fue de mucha dificultad hacer todos los SP ya que no es difícil hacer un Update ni una inserción, lo que no se pude hacer del todo bien fue los SP de Eliminación ya que el profesor informo un después (ya toda la base de datos estaba diseñada y con datos almacenados y cargados) que este "delete" era de forma logica cambiando un bit que deberia existir en las tablas pero este no se pudo implementar por dichas razones.
Tiempo planeado: 2:5 horas
Tiempo real de implementacion: 1:30 horas

+ El SP que procesa los resultados de una carrera (la entrada es un archivo XML con la información de las posiciones y las sanciones), acumulando los puntos por posición para cada corredor, acumulando el tiempo, acumulando los puntos de sanción, y el cambio de estado de activo a expulsado.

Este Stored Procedure no fue muy difícil de crear pero si fue un poco tedioso ya que el archivo XML que brindaron los compañeros en sus inicios estaba mal, existían problemas en las posiciones y existían problemas en las sanciones, se logro hacer el insert masivo de dicho XML y se cree que la finalizacion de este XML no sera hasta la ultima hora de proyecto.
Tiempo estimado: 7 horas
Tiempo real: 9 horas (fue mas tiempo porque al ser un insert masivo era un poco mas complicado de escribir el SP ademas se tuvo problemas con las primeras versiones del XML)

+ El SP que lista el reporte de posiciones acumuladas al final de cada carrera

Este sección del proyecto fue de gran dificultad ya que se tuvieron que ingeniar técnicas y investigación de como hacer un cast o un convert de un dato para poder sumar los tiempos que hacen los atletas, después de mucho investigar se logro encontrar dicha forma usando una columna que se llamaba cast y lograba transformar el time en int el cual ya se podía acumular para poder hacer la suma.
Tiempo estimado: 4 horas
Tiempo real: 6:30 horas


+ El SP que lista los corredores expulsados o que faltaron a carreras

En la dicha parte del proyecto se presentaron problemas de como poder hacer un Inner Join Inverso (es decir que diera los datos no relacionados) pero con investigación y practica se encontró la función de Except la cual permitió que dicha tarea fuera un poco mas sencilla de hacer usando 2 consultas sencillas se puedo verificar este dato de manera sencilla, usando una consulta sobre que carreras había ido el corredor y otra consulta que determinaba cuantas carreras podía ir el corredor por campeonato y el except saca la intersección y asi determina a cuales carreras no fueron algunos corredores.
Tiempo estimado: 6 horas
Tiempo real: 4 horas

+ Los SP para cargar datos básicos (campeonatos, carreras, corredores, tipos de sanción, tipos de movimiento)  

Los Stored Procedure para dicha labor eran sencillos y se desarrollaron de manera rápida y eficaz los cuales fueron sencillos de realizar ya que eran inserciones y updates simples los cuales hacen la tarea fácil.
Tiempo Estimado: 7 horas
Tiempo Real: 4:30 horas

El código en capa lógica: 


+ La suscripción de corredores a un campeonato (debe ser una página web)

Por un momento esta seccion del proyecto fue duro ya que no se tenia muy claro de que tecnología se usaría (javascript, php, python o C#) al final se decidió manejar la pagina web en C# asp.net ya que da gran facilidad para integrar las bases de datos de sql server ya que son del mismo desarrollador.
Tiempo estimado: 12 horas
Tiempo real: 8 horas

+ El mantenimiento de campeonatos y carreras en campeonato.

Se pudo hacer esto de buena manera aunque existe un problema con el Update del corredor pero se llego a la conclusión de que C# esta teniendo un Bug ya que al hacer el Update desde capa de datos este se hace de manera correcta usando el mismo SP y a la hora de hacer dicho procedimiento en la capa logica este no funciona aunque por un error del programador de la pagina se encontró que el SP si funcionaba ya que confundió entre 2 textbox y los intercambio y en la capa de datos hubo un cambio.
Tiempo estimado: 7 horas
Tiempo real: 6 horas

+ La consulta de los corredores del reporte de posiciones y expulsados

Finalmente se dio unos grandes errores por parte de del C# ya que a veces no determina los datos de los gridview y esto era un poco molesto ya que muchas veces le daba un bug a la pagina web, con el tiempo se descubrió que el error podía ser solucionado si y solo si se usaba un panel el cual contendría al gridview y este asi dejaba de buggear de manera repetitiva, por lo demás la creación de los reportes es muy sencilla ya que se usaban SP ya creados y simplemente se incluían en un Gridview y listo. 
Tiempo estimado: 4:30
Tiempo real: 5:30

Moralejas del proyecto:
-Manejar mejor los datos desde código y no jalando botones ya que estos hacen que los sistemas sean menos flexibles y genera mucho código basura.

-Usar master page: En estos tiempos que el código se reutiliza mucho para hacer un ecosistema de paginas similares por lo general se copia muchas veces el codigo, gracias a las master page que ofrece C# se pudo hacer una plantilla la cual todas las paginas usan y ahorra mucho el trabajo en programar.

-Manejar inserts masivos es mucho mejor con alto volumen de datos, ya que en esta tarea se hizo un insert masivo y no se vio mucho la diferencia con un insert normal pero se sospecha que es mejor.

-Usar Variables tablas hace cómodo la modificación de datos los cuales no se quieren cambiar del todo.

Tiempo total del proyecto: 45 horas

Recta Final

Actualmente se crearon diferentes SP para hacer la conexion con la capa lógica mas sencilla.
Algunos códigos hechos para la conexión sencilla fueron:

El SP Addposition ayuda a que el usuario pueda ingresar de manera fácil la posición que quedo en la carrera, a su vez, facilmente se puede determinar el corredor y la carrera.
En la aplicación no se debe ingresar la posición del corredor ya que lo va auto incrementando
CREATE procedure [dbo].[addposition]
@Email varchar(50),
@Race varchar(50),
@time datetimeoffset(7)
as
begin
declare @ID int;
declare @IDRace int;
declare @IDRunner int;
declare @position int;
select @ID=max(P.ID)+1 from Positions P
select @IDRace=R.ID from Races R where R.Name=@Race
select @IDRunner=Ru.ID from Runners Ru where Ru.Email=@Email
select  @position=ISNULL(Max(P.Position),0)+1 from Positions P
inner join Races R on P.FK_Races=R.ID where R.ID=@IDRace

 INSERT INTO dbo.Positions(ID,ET_Time,FK_Races,FK_Runners,Position)
VALUES (@ID,@time,@IDRace,@IDRunner,@position)

end

GO
Tiempo de trabajo: 20 minutos

SP para determinar si un corredor esta descalificado:
CREATE PROCEDURE [dbo].[SP_Disqualify]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    UPDATE RunnersXChallenge
SET FK_Status = 1
WHERE AcumPunishPts > 30
END

GO
Tiempo de trabajo: 10 minutos

El Stored Procedure que muestra que concursante no asiste a diferentes carreras

CREATE procedure [dbo].[SP_ReportNotParticipate]
@Email varchar(50),
@Challenge varchar(50)
as
begin
declare @IDChallenge int;
select  @IDChallenge=C.ID from Challenge C where C.Name=@Challenge

select R.Name from Races R inner join Challenge C on R.FK_Challenge=C.ID where C.ID=@IDChallenge
EXCEPT
select   R.Name  from Races R inner join Positions P on R.ID=P.FK_Races
inner join Runners Ru on Ru.ID=P.FK_Runners where Ru.Email=@Email
end
GO
Tiempo de trabajo: 15 minutos
Link de referencia: https://msdn.microsoft.com/es-es/library/ms188055(v=sql.120).aspx

Stored Procedure el cual agrega un castigo a los corredores:
Create Procedure [dbo].[SP_PunishmentsADD]
 @NameRaces varchar(50),
 @NamePunish varchar(50),
 @Email varchar(50),
 @Points int
 as
 begin
 declare @ID int;
 declare @IDRace int;
 declare @IDRunner int;
 declare @IDPunish int;
 select @ID=max(Pu.ID)+1 from Punishments Pu
 select @IDRace=R.ID from Races R
 where R.Name=@NameRaces
 select @IDPunish=PuT.ID from PunishmentType PuT
 where PuT.Name=@NamePunish
 select @IDRunner=Ru.ID from Runners Ru
 where Ru.Email=@Email
 insert into Punishments (ID,Points,FK_Races,FK_PunishmentType,FK_Runners)
 Values (@ID,@Points,@IDRace,@IDPunish,@IDRunner)
 end
GO
Tiempo de trabajo: 20 minutos

Stored Procedure que determinaba que carreras podía acceder el corredor:

CREATE procedure [dbo].[SP_whatRace]
@Email varchar(50)
as
begin
select distinct R.name from Runners RU
inner join RunnersXChallenge RXC on RU.ID=RXC.FK_Runners
inner join Challenge C on C.ID=RXC.FK_Challenge
inner join Races R on R.FK_Challenge=C.ID
where RU.Email=@Email
end

GO
Tiempo de trabajo: 15 minutos

Stored Procedure el cual permitia inscribir a un corredor a los campeonatos:

CREATE procedure [dbo].[SP_enrollinChallenge]
 @Email varchar(50),
 @challenge varchar(50)
 as
 begin
declare @FK_Challenges int;
declare @FK_Runner int;
declare @MaxNumber int;
declare @MaxID int;

select DISTINCT @FK_Runner=R.ID from Runners R where R.Email=@Email
select DISTINCT @FK_Challenges=C.ID from Challenge C where C.Name=@challenge
select @MaxNumber=max(CONVERT(INT, RxC.Number))+1 from RunnersXChallenge RxC where RxC.FK_Challenge=@FK_Challenges
select @MaxID=MAX(RxC.ID)+1 from RunnersXChallenge RxC
INSERT INTO dbo.RunnersXChallenge(ID,Number,AcumTime,AcumPoints,AcumPunishPts,FK_Challenge,FK_Runners,FK_Status,AcumPointsAuthorized,AcumPunishPtsAuthorized)
VALUES (@MaxID,@MaxNumber,default,0,0, @FK_Challenges, @FK_Runner,0,0,0)
end

GO

Tiempo de trabajo: 20 minutos


Fallos y a poco tiempo

Actualmente tuvimos varios problemas en algunos Stored Procedure, el reporte de las penalizaciones, ya que no presenta ningún dato, tendremos que arreglar la base de datos o el Stored procedure para que funciones, a su empezó un problema a la hora de actualizar los datos de los corredores ya que no los deja actualizar aunque en la aplicación sin embargo si deja actualizar en el sql server, creo que debe ser un problema de  C# a la hora de manejar los Textbox ya que haciendo pruebas veo que los datos no cambian lo cual me llama la atención porque los datos de actualización de los campeonatos funcionan muy bien desde la aplicación, a su vez, se quiere terminar a tiempo pero hemos tenidos problemas con la base ya que uno de los compañeros de grupo tuvo que desinstalar el sql server ya producía un error -26 el cual no dejaba accesar a ninguna base de datos del sistema.

Tiempo invertido en "Arreglar" el error 45 minutos
 Link que podria ayudar a solucionar problema: https://technet.microsoft.com/es-es/library/ms156468(v=sql.105).aspx





domingo, 4 de octubre de 2015

Stored Procedure para CRUD

Hemos empezado hacer algunos Stored Procedure que funcionan para conectar y hacer solicitudes simples en la base de datos como el login y la inscripción de los corredores a los campeonatos:
Tiempo de trabajo: 1:00 hora

Stored Procedure para Login:

create procedure [dbo].[SP_LoginRunner]
@Email varchar(50)
as
Begin
set nocount off
select R.code from Runners R where R.Email=@Email
end

GO

Stored Procedure para Inscripcion:

CREATE procedure [dbo].[SP_enrollinChallenge]
 @Email varchar(50),
 @challenge varchar(50)
 as
 begin
declare @FK_Challenges int;
declare @FK_Runner int;
declare @MaxNumber int;
declare @MaxID int;

select DISTINCT @FK_Runner=R.ID from Runners R where R.Email=@Email
select DISTINCT @FK_Challenges=C.ID from Challenge C where C.Name=@challenge
select @MaxNumber=max(CONVERT(INT, RxC.Number))+1 from RunnersXChallenge RxC where RxC.FK_Challenge=@FK_Challenges
select @MaxID=MAX(RxC.ID)+1 from RunnersXChallenge RxC
INSERT INTO dbo.RunnersXChallenge(ID,Number,AcumTime,AcumPoints,AcumPunishPts,FK_Challenge,FK_Runners,FK_Status,AcumPointsAuthorized,AcumPunishPtsAuthorized)
VALUES (@MaxID,@MaxNumber,default,0,0, @FK_Challenges, @FK_Runner,0,0,0)
end

GO

También se hicieron algunas funciones para encapsular lógica y mostrar un código mas simple:

Función para transformar segundos en tiempo:
CREATE FUNCTION [dbo].[FN_Seconds2Time]
(
-- Add the parameters for the function here
@Seconds BIGINT
)
RETURNS time(7)
AS
BEGIN
-- Declare the return variable here
DECLARE @RT time(7)
SELECT @RT = CAST(@Seconds/3600 AS VARCHAR(1000))
      + RIGHT(try_CONVERT(CHAR(8),DATEADD(ss,@Seconds,0),108),6)
RETURN @RT
END

GO

Función para sumar todos los tiempos de un corredor:

CREATE FUNCTION [dbo].[FN_SumRunnerTimeByRace]
(
-- Add the parameters for the function here
@Runner INT
)
RETURNS TIME(7)
AS
BEGIN
-- Declare the return variable here
DECLARE @AcumTimeSecs BIGINT
DECLARE @AcumTime TIME(7)
DECLARE @TimeByRunner TABLE(ET_Time datetimeoffset(7),ET_Time_Seconds BIGINT)

INSERT INTO @TimeByRunner(ET_Time,ET_Time_Seconds)
SELECT P.ET_Time, dbo.FN_Time2Seconds(p.ET_Time)
FROM Positions P
WHERE P.FK_Runners = @Runner
-- Add the T-SQL statements to compute the return value here
SELECT @AcumTimeSecs = (SELECT SUM(ET_Time_Seconds) FROM @TimeByRunner)
SELECT @AcumTime = dbo.FN_Seconds2Time(@AcumTimeSecs);

-- Return the result of the function
RETURN @AcumTime
END

GO


Agregando SP update y otros.

Se crearon todos los Stored Procedure que actualizan las tablas, a su vez se duro 30 minutos en realizar todas los Updates:
Link guia para hacer update: https://www.youtube.com/watch?v=UgjVfhlk_QA


Para la tabla Challenge:
CREATE PROCEDURE [dbo].[SP_UpdateChallenge]
-- Add the parameters for the stored procedure here
@ID INT,
@Name VARCHAR(50),
@StartDate DATE,
@EndDate DATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.Challenge SET ID = @ID, Name = @Name, StartDate = @StartDate, EndDate = @EndDate
WHERE ID = @ID
END

GO

Para la Tabla Positions:
CREATE PROCEDURE [dbo].[SP_UpdatePositions]
-- Add the parameters for the stored procedure here
@ID INT,
@ET_Time TIME(7),
@FK_Races INT,
@FK_Runners INT,
@Position INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.Positions SET ID = @ID,ET_Time = @ET_Time,FK_Races = @FK_Races,FK_Runners = @FK_Runners,Position = @FK_Runners
WHERE ID = @ID
END

GO

Para tabla  punishments:

CREATE PROCEDURE [dbo].[SP_UpdatePunishments]
-- Add the parameters for the stored procedure here
@ID INT,
@Points INT,
@FK_Races INT,
@FK_PunishmentType INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.Punishments SET ID=@ID,Points=@Points,FK_Races=@FK_Races,FK_PunishmentType=@FK_PunishmentType
WHERE ID = @ID
END

GO

Para tabla Races:

CREATE PROCEDURE [dbo].[SP_UpdateRaces]
-- Add the parameters for the stored procedure here
@ID INT,
@Name VARCHAR(50),
@Description TEXT,
@pDate DATE,
@FK_Challenge int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.Races SET ID=@ID,Name=@Name,Description=@Description,Date=@pDate,FK_Challenge=@FK_Challenge
WHERE ID = @ID
END

Para tabla Runners:
CREATE PROCEDURE [dbo].[SP_UpdateRunners]
-- Add the parameters for the stored procedure here
@ID INT,
@Name VARCHAR(50),
@Genre INT,
@Email VARCHAR(50),
@Code VARCHAR(50),
@Aka VARCHAR(50),
@Bday DATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.Runners SET ID=@ID,Name=@Name,Genre=@Genre,Email=@Email,Code=@Code,Aka=@Aka,BirthDay=@Bday
WHERE ID = @ID
END

GO

Para tabla intermedia de RunnersByChanllenge:

CREATE PROCEDURE [dbo].[SP_UpdateRunnersByChallenge]
-- Add the parameters for the stored procedure here
@ID INT,
@Number VARCHAR(50),
@AcumTime time(7),
@AcumPoints INT,
@AcumPunishPts INT,
@FK_Challenge INT,
@FK_Runners INT,
@FK_Status INT,
@AcumTimeAuthosized TIME(7),
@AcumPointsAuthorized INT,
@AcumPunishPtsAuthorized INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

    -- Insert statements for procedure here
UPDATE dbo.RunnersXChallenge SET ID = @ID,Number = @Number,AcumTime = @AcumTime,AcumPoints = @AcumPoints,AcumPunishPts = @AcumPunishPts,
FK_Challenge= @FK_Challenge,FK_Runners =@FK_Runners,FK_Status = @FK_Status,AcumTimeAuthorized = @AcumTimeAuthosized,
AcumPointsAuthorized = @AcumPointsAuthorized,AcumPunishPtsAuthorized = @AcumPunishPtsAuthorized
WHERE ID = @ID
END

GO



viernes, 2 de octubre de 2015

Procesamiento de puntos y sanciones

Se concluye el proceso de desarrollo e implementación del Stored Procedure encargado de procesar debidamente los acumulados de saldo de puntos por corredor por campeonato, saldo de puntos de castigo y el acumulado total de tiempo corrido.
Para los saldos de puntos finales y puntos de castigo se implementó además un saldo autorizado o saldo comprometido, especialmente con fines ilustrativos, dicho atributo extra se tomo en cuenta al codificar la respectiva transacción responsable de las inserciones de movimientos, tanto pendientes como procesados (Aunque en realidad esto se ejecuta en una sola fase de manera inmediata a la inserción de movimientos pendientes).

 La siguiente metodología fue la utilizada para aplicar dichos movimientos:

  1. Se insertan los movimientos dentro de la tabla de movimientos pendientes, de manera que tal que anulen, aritméticamente hablando, el movimiento pendiente original ( o sea el inverso del monto especificado en el movimiento pendiente original. Ej: Crédito Pendiente de 1 punto, entonces se insertará en la tabla de Movimientos Pendientes un "Crédito Pendiente" de  -1 puntos  ) .
  2. Después se modifica el saldo No Aplicante (Autorizado o Comprometido).
  3. Después se añade  el movimiento pero a la tabla de Movimientos Procesados.
  4. Y se aplica el saldo final o aplicante.
En el siguiente código puede observarse la implementación del stored procedure correspondiente:


-- =============================================
-- Author: <Author: Vinicio Flores>
-- Create date: <Create Date: August 29th, 2015>
-- It inserts and process all the movements generated inside the database system
-- =============================================

ALTER PROCEDURE [dbo].[SP_ResultProcessing]
@Challenge INT,
@PostIn VARCHAR(50),
@PostDate DATE,
@PostBy VARCHAR(50)
-- Add the parameters for the stored procedure here


AS
BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRY
DECLARE @PositionsProc TABLE(ID INT IDENTITY(1,1),PosID INT PRIMARY KEY,FK_Races INT,FK_Runners INT,Position INT)
DECLARE @PunishProc TABLE(ID INT IDENTITY(1,1),PunID INT PRIMARY KEY,Amount INT,FK_Races INT,FK_PunishmentType INT,FK_Runners INT)
INSERT INTO @PositionsProc(PosID,FK_Races,FK_Runners,Position)
SELECT P.ID,P.FK_Races,P.FK_Runners,P.Position
FROM Positions P
WHERE (P.Position >= 1) AND (P.Position <= 20)



INSERT INTO @PunishProc(PunID,Amount,FK_Races,FK_PunishmentType,FK_Runners)
SELECT P.ID, P.Points,P.FK_Races,P.FK_PunishmentType,P.FK_Runners
FROM Punishments P
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
INSERT INTO dbo.PointsMovementPending(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT 20-Position, 1, dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),@PostIn,@PostDate,@PostBy
FROM @PositionsProc P
ORDER BY P.PosID
UPDATE dbo.RunnersXChallenge SET AcumTime = dbo.FN_SumRunnerTimeByRace(RC.ID)
-- update dbo.RunnersXChallenge SET AcumTime = '00:00:00'
FROM dbo.RunnersXChallenge RC
INNER JOIN @PositionsProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
WHERE RC.FK_Challenge = @Challenge
UPDATE dbo.RunnersXChallenge SET AcumPointsAuthorized = AcumPointsAuthorized + (20-PP.Position)
FROM dbo.RunnersXChallenge RC
INNER JOIN @PositionsProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PointsMovementPending(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT -(20-Position),2,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),@PostIn,@PostDate,@PostBy
FROM @PositionsProc P
ORDER BY P.PosID
UPDATE dbo.RunnersXChallenge SET AcumPointsAuthorized = AcumPointsAuthorized + -(20-PP.Position)
FROM dbo.RunnersXChallenge RC
INNER JOIN @PositionsProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PointsMovementProcessed(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT 20-Position, 1, dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),@PostIn,@PostDate,@PostBy
FROM @PositionsProc P
ORDER BY P.PosID
UPDATE dbo.RunnersXChallenge SET AcumPoints = AcumPoints + (20-PP.Position)
FROM dbo.RunnersXChallenge RC
INNER JOIN @PositionsProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)


 

-- Process the punish points movements tables
INSERT INTO dbo.PunishPtsMovementPending(Amount,FK_Punishments,FK_RunnersXChallenge,FK_TypePunishPtsMovement,PostIn,PostDate,PostBy)
SELECT Amount,P.FK_PunishmentType,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners) ,1 ,@PostIn,@PostDate,@PostBy
FROM @PunishProc P
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPunishPtsAuthorized = AcumPunishPtsAuthorized + Amount
FROM dbo.RunnersXChallenge RC
INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PunishPtsMovementPending(Amount,FK_Punishments,FK_RunnersXChallenge,FK_TypePunishPtsMovement,PostIn,PostDate,PostBy)
SELECT -Amount,P.FK_PunishmentType,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),2,@PostIn,@PostDate,@PostBy
FROM @PunishProc P
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPunishPtsAuthorized = AcumPunishPtsAuthorized + -Amount
FROM dbo.RunnersXChallenge RC
INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PunishPtsMovementProcessed(Amount,FK_Punishments,FK_RunnersXChallenge,FK_TypePunishPtsMovement,PostIn,PostDate,PostBy)
SELECT Amount,P.FK_PunishmentType,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),1,@PostIn,@PostDate,@PostBy
FROM @PunishProc P
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPunishPts = AcumPunishPts + Amount
FROM dbo.RunnersXChallenge RC
INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
--- Executes the substraction of the punishment points over the total points balance (acumpoints)
INSERT INTO dbo.PointsMovementPending(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT RC.AcumPunishPts,2,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners) ,@PostIn,@PostDate,@PostBy
FROM @PunishProc P INNER JOIN dbo.RunnersXChallenge RC ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners)
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPointsAuthorized = AcumPointsAuthorized + -RC.AcumPunishPts
FROM dbo.RunnersXChallenge RC INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PointsMovementPending(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT -RC.AcumPunishPts,1,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners),@PostIn,@PostDate,@PostBy
FROM @PunishProc P INNER JOIN dbo.RunnersXChallenge RC ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners)
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPointsAuthorized = AcumPointsAuthorized + RC.AcumPunishPts
FROM dbo.RunnersXChallenge RC INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
INSERT INTO dbo.PointsMovementProcessed(Amount,FK_TypeMovement,FK_RunnersXChallenge,PostIn,PostDate,PostBy)
SELECT RC.AcumPunishPts,2,dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners) ,@PostIn,@PostDate,@PostBy
FROM @PunishProc P INNER JOIN dbo.RunnersXChallenge RC ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,P.FK_Runners)
ORDER BY P.PunID
UPDATE dbo.RunnersXChallenge SET AcumPoints = AcumPoints + -RC.AcumPunishPts
FROM dbo.RunnersXChallenge RC INNER JOIN @PunishProc PP
ON RC.ID = dbo.FN_GetRunnerXChallengeByChallenge(@Challenge,PP.FK_Runners)
COMMIT
RETURN 1
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK
RETURN @@ERROR * -1
END CATCH


END