65 lines
2.2 KiB
Transact-SQL
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
|