﻿
/***********************************************************************************
* FUNCTION f_diffOreLavorative
*
* calcola le effettive ore lavorative sottraendo chiusure x festività o aperture programmate
*
***********************************************************************************/
create FUNCTION f_diffOreLavorative
(
	@dataFrom		DATETIME,
	@dataTo			DATETIME,
	@idxMacchina	INT -- per ora non lo considero poiché non ci sono calendari diversi x macchina...
)
RETURNS FLOAT
AS
	BEGIN
	
		-- dichiarazioni variabili
		DECLARE @oreTot		AS FLOAT
		DECLARE @oreOff		AS FLOAT
		DECLARE @tmp_dates TABLE (DateValue DATETIME, h INT)
		SET		@oreTot = 0
		
		-- controllo date coerenti
		IF(@dataTo > @dataFrom)
			BEGIN
				-- calcolo totale "raw" delle ore
				SET		@oreTot		= CAST(ISNULL(DATEDIFF(minute, @dataFrom, @dataTo), 0) AS float) / 60;
				-- definisco tabella cte ricorsiva
				WITH mycte AS
				(
					SELECT CAST(dbo.f_dateOnly(DATEADD(dd,1,@dataFROM)) AS DATETIME) DateValue
					UNION ALL
					SELECT	DateValue + 1
					FROM    mycte   
					WHERE   DateValue + 1 < dbo.f_dateOnly(@dataTo)
				)
				-- carico nella tab temporanea i sabati e le domeniche...
				INSERT into @tmp_dates(DateValue, h)
				SELECT *, CASE ((DATEPART(dw, DateValue) + @@DATEFIRST) % 7) WHEN 0 THEN 16 ELSE 24 END AS h
				FROM    mycte
				WHERE ((DATEPART(dw, DateValue) + @@DATEFIRST) % 7) IN (0,1)
				OPTION (MAXRECURSION 0)	
				-- carico le festività per le date NON ancora presenti
				insert into @tmp_dates(DateValue, h)
				select data as DateValue, 24 as h--, descrizione
				from CalendFesteFerie
				where data between @dataFrom and @dataTo and data not in (select distinct DateValue from @tmp_dates)
				-- aggiorno sabati/domenica che fossero festivi (ipotesi che hfest > h sab/dom...
				UPDATE @tmp_dates
				SET h=24
				WHERE DateValue in (SELECT data FROM CalendFesteFerie WHERE data between @dataFrom and @dataTo)
				
				-- calcolo INFINE le ore off!
				SET @oreOff = (SELECT ISNULL(SUM(h),0) FROM @tmp_dates)
			END
		-- setto le nuove ore totali... se ho un numero di ore > delle fermate le sottraggo per evitare ore engative...
		IF(@oreTot > @oreOff)
			BEGIN
				SET @oreTot = @oreTot - @oreOff
			END
			
		RETURN @oreTot
	END
