--Hash:D74EF222D6FD5165A89C34E7E7A93F82

-- Bloqueo exclusivo por base de datos
--//
SET NOCOUNT ON;

DECLARE @__ZiurDbScriptLockResource NVARCHAR(200) = N'ZiurSoft:DbScriptLock:' + CAST(DB_ID() AS NVARCHAR(20));
DECLARE @__ZiurDbScriptLockResult INT;
EXEC @__ZiurDbScriptLockResult = sp_getapplock
    @Resource = @__ZiurDbScriptLockResource,
    @LockMode = N'Exclusive',
    @LockOwner = N'Session',
    @LockTimeout = 600000; -- 10 min

IF (@__ZiurDbScriptLockResult < 0)
BEGIN
    RAISERROR(N'No se pudo obtener el bloqueo exclusivo de actualizacion para esta base de datos.', 16, 1);
    SET NOEXEC ON;
END

/* Idempotencia a nivel de script: si la version ya existe, no ejecutar nada. */
IF EXISTS (SELECT 1 FROM dbo.ZiurVersiones WHERE NumVersion = 940)
BEGIN
    PRINT N'Scripts_940.sql: la version 940 ya esta aplicada. Se omite ejecucion.';
    EXEC sp_releaseapplock @Resource = @__ZiurDbScriptLockResource, @LockOwner = N'Session';
    SET NOEXEC ON;
END

SET XACT_ABORT ON;
GO

SET DATEFORMAT mdy;

--Validar que no existan scripts que no se hayan ejecutado
--//
IF EXISTS
(
	SELECT a.NumVersion + 1 AS HuecoInicio
	FROM ZiurVersiones a
	LEFT JOIN ZiurVersiones b ON a.NumVersion + 1 = b.NumVersion
	WHERE a.NumVersion>830 AND b.NumVersion IS NULL
	AND a.NumVersion + 1 < 940
)
RAISERROR('Error : hay un script que no se ejecuto , debe ejecutarlo manualmente.', 20, -1) with log
--//

--Colocar contenido de script diferencial aqui (Ziur.Database.publish.sql)

/*
 Plantilla de script anterior a la implementación							
--------------------------------------------------------------------------------------
 Este archivo contiene instrucciones de SQL que se ejecutarán antes del script de compilación	
 Use la sintaxis de SQLCMD para incluir un archivo en el script anterior a la implementación			
 Ejemplo:      :r .\miArchivo.sql								
 Use la sintaxis de SQLCMD para hacer referencia a una variable en el script anterior a la implementación		
 Ejemplo:      :setvar TableName miTabla							
               SELECT * FROM [$(TableName)]					
--------------------------------------------------------------------------------------
*/
GO

GO
PRINT N'Altering Procedure [dbo].[GetLiquidarNomina]...';


GO
IF OBJECT_ID(N'dbo.GetLiquidarNomina', N'P') IS NULL
    EXEC(N'CREATE PROCEDURE dbo.GetLiquidarNomina AS RETURN 0;');
GO
ALTER PROCEDURE [dbo].[GetLiquidarNomina]

	@IdMoneda INT,
	@Fecha datetime,
	@FechaIni datetime,
	@FechaFin datetime,
	@IdEmpresa INT,
	@NumDocumento INT,
	@IdCliente1 INT,
	@EsAnulado BIT,
	@EsBloqueado BIT,
	@EsRevisado BIT,
	@EsImpreso BIT,
	@InfoUsuario NVARCHAR(100),
	@Cantidad NUMERIC(28,6),
	@IdEncab INT,
	@IdEmpleado NVARCHAR(max),
	@ValorBase NUMERIC(28,6),
	@AuxTransport NUMERIC(28,6),
	@DiasLiquidados NVARCHAR(MAX) = '',
	@EsFondoSolid BIT=0,
	@EsAuxTransportDed BIT=0,
	@EsHorasExtas BIT=0,
	@EsNew BIT=0,
	@Exito INT = 0 output,
	@IdEncabNuevo INT = 0 output
As

BEGIN

DECLARE 

@salarioMin NUMERIC(28,6),
@AuxTrans NUMERIC(28,6),
@EmpleadoHoras int=0,
@FechaCorte DATETIME,
@FechaIniT DATETIME,
@IdDocumento int=0,
@IdEmpleadoCurrent INT=0,
@hMes INT,
@hValorDiv NUMERIC(28,6)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

	--Información Usuario
	exec CrearContextoUsuario @InfoUsuario
	
	-- Salario Mínimo y Auxilio de transporte
	SET @salarioMin=(SELECT Valor FROM dbo.Nomina_Valores WHERE IdTipo=1 AND EsActivo=1)
	SET @AuxTrans=(SELECT Valor FROM dbo.Nomina_Valores WHERE IdTipo=2 AND EsActivo=1)
	
	IF @IdEncab is null
		INSERT INTO Encabezados(IdEmpresa,IdDocumento,NumDocumento,Fecha,FechaIni,FechaFin,IdCliente1,IdMoneda,EsAnulado,EsBloqueado,EsRevisado,EsImpreso,IdTipo)
		VALUES (@IdEmpresa,20,@NumDocumento,@Fecha,@FechaIni,@FechaFin,@IdCliente1,@IdMoneda,@EsAnulado,@EsBloqueado,@EsRevisado,@EsImpreso,1)
		
	SET @IdEncabNuevo=IsNull(@IdEncab,IDENT_CURRENT('Encabezados'))
	
	--Fecha de corte para el calculo de Aux de Transporte
	SET @FechaCorte= DATEADD(dd,-(DATEPART(dd,@FechaIni)-1),@FechaIni)
	
	SET @FechaIniT = CAST(CONVERT(DATETIME, @FechaIni, 103) + ' 23:59:59' AS DATETIME)

	--Definir horas en el mes
	--//
	SELECT @hMes = CAST(ValParametro AS INT) FROM Parametros WHERE CodParametro = 47
    SET @hMes = COALESCE(@hMes,240)
	--//
	
	SET @hValorDiv = 30 * CAST(@hMes AS FLOAT)/ CAST(240 AS FLOAT)

	select @IdDocumento=IdDocumento
	from Encabezados
	where IdEncab=@IdEncabNuevo

	--Eliminar registros de sueldo
	IF @EsNew=1
		DELETE FROM Nomina_Movimientos
		WHERE IdEncab=IsNull(@IdEncabNuevo,0) and IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado)) 
		and (EsVisible=0 or IdItem in(
		select IdItem
		from dbo.Nomina_Items
		where IdClasif in(1)
		))
	
	--Eliminar registros de Aux de transporte
	DELETE FROM Nomina_Movimientos
	WHERE IdEncab=IsNull(@IdEncabNuevo,0) and IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado)) 
	and (EsVisible=0 or IdItem in(
	select IdItem
	from dbo.Nomina_Items
	where IdClasif = 3 -- in(3)
	))
	
	IF @EsFondoSolid=1
		--Eliminar registros de fondo de solidaridad
		DELETE FROM Nomina_Movimientos
		WHERE IdEncab=IsNull(@IdEncabNuevo,0) and IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado)) 
		and IdItem=199

	
	--Recalcular Item de sueldo
	IF @EsNew=1

		IF @DiasLiquidados = ''

			INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente,IdContrato,IdItem, Cantidad, IdTiempo, ValorBase, ValorUnit,ValorUnitInferior,IdCentroCosto)
			select @IdEncabNuevo,q.IdCliente,q.IdCOntrato,min(q.IdItem),case when @IdDocumento=49 then @Cantidad else q.Cantidad end,1,q.ValorBase,q.ValorUnit,q.ValorDiv,q.IdCentroCosto
		
			from
			(	
					SELECT cont.IdCliente,IdContrato,item.IdItem,
					CASE WHEN FechaIni>@FechaIni AND FechaRetiro<@FechaFin THEN DATEDIFF(day,FechaIni,FechaRetiro)+1 ELSE
					CASE WHEN FechaIni>@FechaIni THEN DATEDIFF(day,FechaIni,@FechaFin)+1 ELSE
					CASE WHEN FechaRetiro<@FechaFin THEN DATEDIFF(day,@FechaIni,FechaRetiro)+1 ELSE @Cantidad END END END AS Cantidad,
					IsNull(@ValorBase,SueldoIni)ValorBase,IsNull(@ValorBase,SueldoIni)ValorUnit,@hValorDiv ValorDiv,cliEmp.IdCentroCosto
					FROM  dbo.Nomina_Contratos cont inner join Nomina_Configuracion confi 
					on cont.IdPlantilla=confi.IdPlantilla inner join Nomina_Items item
					on confi.IdItem=item.IdItem inner join dbo.Clientes_Empleados as cliEmp
					on cliEmp.IdCliente=cont.IdCliente
					WHERE cont.EsActivo=1 and @FechaFin>=IsNull(FechaIni,@FechaFin) and @FechaIni<=IsNull(FechaRetiro,@FechaIni)and cont.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
					and item.IdClasif=1 and IsNull(cont.IdEmpresa,@IdEmpresa)=@IdEmpresa
			) AS q
			group by q.IdCliente,q.IdCOntrato,q.Cantidad,q.ValorBase,q.ValorUnit,q.ValorDiv,q.IdCentroCosto

		ELSE
		
			INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente,IdContrato,IdItem, Cantidad, 
						IdTiempo, ValorBase, ValorUnit,ValorUnitInferior,IdCentroCosto)
			SELECT @IdEncabNuevo,q.IdCliente,q.IdCOntrato,min(q.IdItem),case when @IdDocumento=49 then @Cantidad else q.Cantidad end,
					1,q.ValorBase,q.ValorUnit,q.ValorDiv,q.IdCentroCosto
		
			FROM
			(	
					--- NEW CASE --- 
					SELECT cont.IdCliente, cont.IdContrato, item.IdItem,
					DiasLiquidar.DiasLiquidar AS Cantidad,
					IsNull(@ValorBase,SueldoIni)ValorBase,IsNull(@ValorBase,SueldoIni)ValorUnit,@hValorDiv ValorDiv,cliEmp.IdCentroCosto
					FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ID,
							number AS IdEmpleado 
							FROM iter$simple_intlist_to_tbl(@IdEmpleado)
						 ) AS IdEmpleado
					INNER JOIN (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ID,
								(CAST((CAST(number AS NUMERIC(28,6)) / 1000000) AS NUMERIC(28,6))) AS DiasLiquidar
								FROM iter$simple_intlist_to_tbl(@DiasLiquidados)
								) AS DiasLiquidar ON DiasLiquidar.ID = IdEmpleado.ID
					INNER JOIN dbo.Nomina_Contratos cont ON cont.IdCliente = IdEmpleado.IdEmpleado
					INNER JOIN Nomina_Configuracion confi ON cont.IdPlantilla=confi.IdPlantilla 
					INNER JOIN Nomina_Items item ON confi.IdItem=item.IdItem 
					INNER JOIN dbo.Clientes_Empleados AS cliEmp ON cliEmp.IdCliente=cont.IdCliente
					WHERE cont.EsActivo=1 
					AND @FechaFin>=IsNull(FechaIni,@FechaFin) AND @FechaIni<=IsNull(FechaRetiro,@FechaIni)
					AND cont.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
					AND item.IdClasif=1
					AND IsNull(cont.IdEmpresa,@IdEmpresa)=@IdEmpresa
			) AS q
			GROUP BY q.IdCliente,q.IdCOntrato,q.Cantidad,q.ValorBase,q.ValorUnit,q.ValorDiv,q.IdCentroCosto
		
	IF @EsNew=0 and @ValorBase is not null
		UPDATE dbo.Nomina_Movimientos
		SET ValorBase=@ValorBase,
		ValorUnit=@ValorBase
		WHERE Nomina_Movimientos.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
		  and IdEncab=@IdEncabNuevo and Iditem in (100,101,102)

  IF @EsFondoSolid=1
--Recalcular Fondo de Solidaridad
	INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente, IdItem,IdContrato, Cantidad, IdTiempo,ValorUnit,ValorUnitInferior,IdCentroCosto)
	select @IdEncabNuevo,q1.IdCliente,199,q1.IdContrato,1,1,max(Valor1)-MAX(ValorUnit),1,q1.IdCentroCosto
	from
	(	
	select 
	q.IdCliente,q.IdContrato,
	(Valor*IsNull(config.DivParteSuperior,1)/IsNull(config.DivParteInferior,1))*IsNull(PorcTarifa,0)/100 as Valor1,
	case when mov.IdItem=199 then ValorUnit else 0 end ValorUnit,
	cliEmp.IdCentroCosto
	from
		(
	select IdCliente,IdContrato,
			sum((ValorUnit/ValorUnitInferior)*cantidad) as Valor
			from dbo.Nomina_Movimientos mov inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem
			inner join dbo.Encabezados as enc on mov.IdEncab=enc.IdEncab
			where EsFondoSolid=1 and (IsNull (Mov.FactorMov, 1) = 1)
			and enc.FechaIni between @FechaCorte and @FechaIniT and EsAnulado=0
			group by IdCliente,IdContrato) as q inner join dbo.Nomina_Movimientos mov on q.IdCliente=mov.IdCliente and q.IdContrato=mov.IdContrato
			inner join dbo.Encabezados as enc on mov.IdEncab=enc.IdEncab
		inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem inner join dbo.Clientes_Empleados as cliEmp
		on cliEmp.IdCliente=q.IdCliente
		inner join Nomina_Contratos con on q.IdContrato=con.IdContrato left join [dbo].[Nomina_Configuracion] config on con.IdPlantilla=config.IdPlantilla and config.IdItem=199
		 left join  dbo.Nomina_Rangos nomRan on ((Valor*IsNull(config.DivParteSuperior,1)/IsNull(config.DivParteInferior,1))/@salarioMin) between nomRan.RangoIni and nomRan.RangoFin and nomRan.IdTipo='4'
		where  enc.FechaIni between @FechaCorte and  @FechaIniT and EsAnulado=0
		and (Valor/@salarioMin)>4 and q.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
		and ((item.IdClasif=1 and mov.IdEncab=@IdEncabNuevo) or mov.IdItem=199)) q1
		group by q1.IdCliente,q1.IdContrato,q1.IdCentroCosto
	
		
	--Recalcular Horas Extras	
IF (select count(number) from iter$simple_intlist_to_tbl(@IdEmpleado)) = 1 AND @EsHorasExtas=1
	BEGIN
		set @EmpleadoHoras=(select min(number) from iter$simple_intlist_to_tbl(@IdEmpleado))
		EXEC	RecalcNominaHorasExtra
 				      @EmpleadoHoras,
 				      @IdEncabNuevo,
 				      null,
 				      @Exito
     END
     
 	
 	--Recalcular aux de Transporte (Por ley)			      			      	
	IF @AuxTransport=-1	
	BEGIN

	;with tempPlantillas(IdPlantilla,IdItem,FactorPlantilla)
	as
	(
		select IdPlantilla,IdItem,max((isnull(DivParteSuperior,1)/isnull(DivParteInferior,1)))as FactorPlantilla
			from Nomina_Configuracion
			where IdItem=110
			group by IdPlantilla,IdItem
	)

	INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente, IdItem,IdContrato,Cantidad, IdTiempo,ValorUnit,ValorUnitInferior,IdCentroCosto)
		select @IdEncabNuevo,q.IdCliente,110,q.IdContrato,sum(mov.Cantidad),1,@AuxTrans*ISNULL(FactorPlantilla,1),@hValorDiv,cliEmp.IdCentroCosto
		from
		(select IdCliente,IdContrato,
			case when count(distinct enc.IdEncab)=1 then sum (case when IdClasif=1 then (ValorBase * EsValorBase) else (ValorUnit/ValorUnitInferior)*cantidad end)
			else sum((ValorUnit/ValorUnitInferior)*cantidad)end as Valor,
			max(cantidad) as cantidad
			from dbo.Nomina_Movimientos mov inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem
			inner join dbo.Encabezados as enc on mov.IdEncab=enc.IdEncab
			where EsAuxTransp=1 and (COALESCE (Mov.FactorMov, 1) = 1)
			and enc.FechaIni between @FechaCorte and @FechaIniT and EsAnulado=0
			group by IdCliente,IdContrato)as q inner join dbo.Nomina_Movimientos mov on q.IdCliente=mov.IdCliente and q.IdContrato=mov.IdContrato
		inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem inner join dbo.Clientes_Empleados as cliEmp
		on cliEmp.IdCliente=q.IdCliente inner join Nomina_Contratos contrato
		on contrato.IdContrato=q.IdContrato inner join tempPlantillas plantilla on contrato.IdPlantilla=plantilla.IdPlantilla 
		where Valor<=(@salarioMin*2)	and q.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
		and item.IdClasif=1 and item.EsAuxTranspDias=1 and mov.IdEncab=@IdEncabNuevo
		group by q.IdCliente,q.IdContrato,cliEmp.IdCentroCosto,FactorPlantilla

     END


	    IF @EsAuxTransportDed=1	
		--Calcular descuento del Auxilio de Transporte
		BEGIN
		
		DELETE FROM Nomina_Movimientos
		WHERE IdEncab=IsNull(@IdEncabNuevo,0) and IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
		AND IdItem=217 
		
		INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente, IdItem, IdContrato, Cantidad, IdTiempo,ValorUnit,ValorUnitInferior,IdCentroCosto)
		select @IdEncabNuevo,q.IdCliente,217,q.IdContrato,1,1,(@AuxTrans*mov.Cantidad/@hValorDiv),1,cliEmp.IdCentroCosto
		from
		(select IdCliente,IdContrato,
			sum((ValorUnit/ValorUnitInferior)*cantidad)as Valor,
			max(cantidad) as cantidad
			from dbo.Nomina_Movimientos mov inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem
			inner join dbo.Encabezados as enc on mov.IdEncab=enc.IdEncab
			where EsAuxTransp=1 and (IsNull (Mov.FactorMov, 1) = 1)
			and enc.FechaIni between @FechaCorte and @FechaIniT and EsAnulado=0
			group by IdCliente,IdContrato)as q inner join dbo.Nomina_Movimientos mov on q.IdCliente=mov.IdCliente and q.IdContrato=mov.IdContrato
		inner join dbo.Nomina_Items item on mov.IdItem=item.IdItem inner join dbo.Clientes_Empleados as cliEmp
		on cliEmp.IdCliente=q.IdCliente inner join dbo.Encabezados as enc on mov.IdEncab=enc.IdEncab
		where Valor>(@salarioMin*2)	and q.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
		and item.IdItem=110 and enc.FechaIni between @FechaCorte and @FechaIniT and EsAnulado=0
		END
	  
	--Recalcular Aux de Transporte Personalizado
	IF @AuxTransport>0
	INSERT INTO dbo.Nomina_Movimientos(IdEncab, IdCliente, IdItem,IdContrato,Cantidad, IdTiempo,ValorUnit,ValorUnitInferior,IdCentroCosto)
	SELECT @IdEncabNuevo,IsNull(@IdEmpleado,cont.IdCliente),110,cont.IdContrato,@Cantidad,1,@AuxTransport,@hValorDiv,cliEmp.IdCentroCosto
	FROM  dbo.Nomina_Contratos cont inner join Nomina_Configuracion confi 
	on cont.IdPlantilla=confi.IdPlantilla inner join Nomina_Items item
	on confi.IdItem=item.IdItem inner join dbo.Clientes_Empleados as cliEmp
	on cliEmp.IdCliente=cont.IdCliente
	WHERE cont.EsActivo=1 and cont.IdCliente IN(select number from iter$simple_intlist_to_tbl(@IdEmpleado))
	and item.IdClasif=3 and IsNull(cont.IdEmpresa,@IdEmpresa)=@IdEmpresa
	      
   --Insert de los registros hijos(Visible=0)--
	EXEC  dbo.GetLiquidarNominaHijos @IdEncabNuevo,@IdEmpresa,@IdEmpleado,NULL
	
	--Procedimiento actualizar intereses sobre cesantias
	EXEC  dbo.GenerarInteresesCesantias @IdEncabNuevo,@IdEmpleado

		
IF @@error <> 0 GOTO ERR_HANDLER
    
SET @Exito = 1
RETURN
    
ERR_HANDLER:
SET @Exito = 0
	       
END
GO
	/*
	Plantilla de script posterior a la implementación							
	--------------------------------------------------------------------------------------
	 Este archivo contiene instrucciones de SQL que se anexarán al script de compilación.		
	 Use la sintaxis de SQLCMD para incluir un archivo en el script posterior a la implementación.			
	 Ejemplo:      :r .\miArchivo.sql								
	 Use la sintaxis de SQLCMD para hacer referencia a una variable en el script posterior a la implementación.		
	 Ejemplo:      :setvar TableName miTabla							
				   SELECT * FROM [$(TableName)]					
	--------------------------------------------------------------------------------------
	*/

	UPDATE Encabezados_Mov SET FactorImpuesto = 1 WHERE FactorImpuesto=0
GO

GO
PRINT N'Update complete.';


GO

--Actualizar datos de la version
IF NOT EXISTS (SELECT 1 FROM dbo.ZiurVersiones WHERE NumVersion = 940)
BEGIN
INSERT INTO ZiurVersiones (IdVersion, NumVersion, Descripcion)
VALUES (350, 940, 'ERROR CALCULO DE HORAS Y FACTOR IMPUESTO')
END
GO
GO
/* Liberar bloqueo exclusivo por base de datos */
DECLARE @__ZiurDbScriptLockResourceEnd NVARCHAR(200) = N'ZiurSoft:DbScriptLock:' + CAST(DB_ID() AS NVARCHAR(20));
EXEC sp_releaseapplock
    @Resource = @__ZiurDbScriptLockResourceEnd,
    @LockOwner = N'Session';
GO
