Files
WebGIM/GimDB/dbo/Functions/f_diffOreLavorative.sql
2017-01-27 22:26:50 +01:00

65 lines
2.2 KiB
Transact-SQL

/***********************************************************************************
* 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