Files
MoonPro.net/SQL Utils/V5.1/MoonPro_1805.739.sql
T
Samuele E. Locatelli 2b1479f315 spostamento update SQL
2018-05-03 15:06:47 +02:00

667 lines
70 KiB
PL/PgSQL

/****** Object: StoredProcedure [dbo].[stp_StatoProd_getByMacchina] Script Date: 02/05/2018 21:15:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*************************************
* STORED PROCEDURE stp_StatoProd_getByMacchina
* recupera per la macchina indicata lo stato di produzione (pz Buoni / Scarto confermati e tot pezzi prod ad una specifica DataOra)
*
* modif.: S.E.L.
* il: 2018.05.02
**************************************/
ALTER PROCEDURE [dbo].[stp_StatoProd_getByMacchina]
(
@idxMacchina NVARCHAR(50)
,@DataOra DATETIME = NULL
)
AS
SET XACT_ABORT ON;
BEGIN TRAN
-- recupero ODL corrente...
IF @DataOra IS NULL SET @DataOra = GETDATE()
-- imposto valori accessori
DECLARE @IdxODL INT = 0
DECLARE @DataInizioOdl DATETIME
DECLARE @CodArticolo NVARCHAR(50) = 'ND'
DECLARE @PzConfBuoni INT = 0 -- TOT Buoni GIA' confermati
DECLARE @PzConfScarto INT = 0 -- TOT Scarti GIA' confermati
DECLARE @PzRichODL INT = 0 -- Pezzi Richiesti x ODL
DECLARE @PzTotODL INT = 0 -- Pezzi Prodotti x ODL fino a DataOra
DECLARE @Pz2RecTot INT = 0 -- Pezzi Prodotti da confermare (TOT = BUONI + SCARTO)
DECLARE @Pz2RecScarto INT = 0 -- Pezzi scarto registrati da confermare con produzione
-- recupero da tab ODL il codice odl stesso e l'articolo data macchina e data/ora...
SELECT @IdxODL = ISNULL(IdxODL,0), @CodArticolo = ISNULL(CodArticolo,'-'), @PzRichODL = NumPezzi, @DataInizioOdl = DataInizio
FROM ODL
WHERE IdxMacchina = @IdxMacchina
AND DataInizio <= @DataOra
AND ISNULL(DataFine, GETDATE()) >= @DataOra
-- calcolo data ora ultima conferma
DECLARE @lastConf AS DATETIME
DECLARE @startProd AS DATETIME
DECLARE @endProd AS DATETIME
-- prendo le date di produzione...
SET @startProd = (SELECT TOP 1 DataOraRif FROM dbo.TempiCicloRilevati WHERE IdxMacchina = @idxMacchina ORDER BY DataOraRif ASC)
--SET @endProd = (SELECT TOP 1 DataOraRif FROM TempiCicloRilevati WHERE IdxMacchina = @idxMacchina ORDER BY DataOraRif DESC)
SET @endProd = @DataOra --GETDATE()
-- calcolo data!
SET @lastConf = ISNULL((SELECT TOP 1 ISNULL(DataRif, @startProd) FROM dbo.DatiConfermati WHERE IdxMacchina = @idxMacchina ORDER BY DataRif DESC), @startProd)
-- Per ogni ODL della macchina nel periodo controllo e aggiorno il CodArticolo
-- x tutti i tempiciclo sottostanti
;WITH cteOdl AS -- ODL Macchina nel periodo
(
SELECT IdxODL, CodArticolo, IdxMacchina, DataInizio, ISNULL(DataFine, @EndProd) AS DataFine, PzPallet
FROM dbo.ODL
WHERE IdxMacchina = @idxMacchina
AND ( ( DataInizio <= @lastConf AND DataFine > @lastConf )
OR ( DataInizio <= @lastConf AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
)
UPDATE dbo.TempiCicloRilevati
SET CodArticolo = cteOdl.CodArticolo,
PzProd = cteOdl.PzPallet,
TCMedio = TCMedio * PzProd / cteOdl.PzPallet -- sistemo anche il tempo ciclo in base ai PzPallet
FROM cteOdl
INNER JOIN dbo.TempiCicloRilevati AS tc
ON cteOdl.IdxMacchina = tc.IdxMacchina
AND tc.DataOraRif >= cteOdl.DataInizio AND tc.DataOraRif <= cteOdl.DataFine
WHERE cteOdl.CodArticolo <> tc.CodArticolo -- UPD solo se CodArticolo non corretto
OR cteOdl.PzPallet <> tc.PzProd -- o PzProd
-- recupero i dati GLOBALI confermati
SELECT @PzConfBuoni = ISNULL(SUM(pezziConf),0), @PzConfScarto= ISNULL(SUM(pezziScar),0)
FROM ElencoConfermeProd
WHERE idxMacchina = @idxMacchina
AND dataFrom >= @DataInizioOdl
-- recupero i dati dei pezzi prodotti alla data richiesta
SELECT @PzTotODL = ISNULL(SUM(PzProd),0)
FROM dbo.TempiCicloRilevati
WHERE IdxMacchina = @idxMacchina
AND DataOraRif BETWEEN @DataInizioOdl AND @DataOra
-- ora recupero gli scarti registrati ma NON confermati con produzione
SELECT @Pz2RecScarto = ISNULL(SUM(Qta),0)
FROM RegistroScarti
WHERE IdxMacchina = @idxMacchina
AND DataOra BETWEEN @lastConf AND @DataOra -- potrei mettere dalla data ora inizio ODL: @DataInizioOdl
AND DataOraProdRec IS NULL
-- calcolo NUOVI pezzi da confermare....
SELECT @Pz2RecTot = @PzTotODL - (@PzConfBuoni + @PzConfScarto)
-- ora ritorno TUTTI i dati...
SELECT @idxMacchina as idxMacchina
,ISNULL(@PzTotODL,0) AS PzTotODL
,ISNULL(@PzConfScarto,0) AS PzConfScarto
,ISNULL(@PzConfBuoni,0) AS PzConfBuoni
,ISNULL(@PzRichODL,0) AS PzRichODL
,ISNULL(@Pz2RecTot,0) AS Pz2RecTot
,ISNULL(@Pz2RecScarto,0) AS Pz2RecScarto
,@lastConf AS DataFrom
,@endProd AS DataTo
COMMIT TRAN
RETURN
/****** Object: StoredProcedure [dbo].[stp_ConfermaProduzCompleta] Script Date: 02/05/2018 21:10:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*************************************
* STORED PROCEDURE stp_ConfermaProduzCompleta
*
* conferma la produzione per la macchina indicata salvando le informazioni nelle tabelle DatiProduzione e DatiConfermati
*
*
* a) creo i periodi corretti con ODL
* b) ciclo nei periodi x caricare dati confermati x periodo
* c) Inserisco periodi che non sono coperti da ODL come 'T_OFF'
* d) Confermo differenze
*
*
* modif.: Steamware
* modif: 2015.05.12
* modif: 2018.01.22 gestione Commessa Esterna e PezziDaRilav
**************************************/
ALTER PROCEDURE [dbo].[stp_ConfermaProduzCompleta]
(
@idxMacchina NVARCHAR(50),
@MatrApp INT,
@dataFrom DATETIME,
@dataTo DATETIME,
@pezziConf INT,
@pezziScar INT = 0, -- pezzi scartati (registrati da 2016.11.20) DA INDICARE COME VALORE > 0!!! sennò faccio ABS...
@TipoConf INT = 0, -- Tipo intervallo conferma: 0 = periodo intero, 1 = per giorni, 2 = per turni
@DataOraApp DATETIME = NULL, -- di norma GETDATE() nel programma - serve per ricalcolo
@TestConferma BIT = 1 -- TestConferma : 1 = verifica conf. duplicata e inserisci in ElencoConfermeProd, 0 = nessuna verifica e inserimento ( per ricalcolo )
)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @CommessaEsterna AS NVARCHAR(50) = ''
DECLARE @pezziDaRilav AS INT = 0; -- declare pz da rilav. da mettere poi nei parametri
-- 2016.11.17 gestione SCARTI
-- fix scarti: DA INDICARE COME VALORE > 0!!! sennò faccio ABS...
SELECT @pezziScar = ABS(@pezziScar)
-- DECLARE @DataOraApp AS DATETIME;
IF @DataOraApp IS NULL
SET @DataOraApp = GETDATE() -- salvo data elaborazione x tutte le sotto procedure
-- IN PRIMIS CONTROLLO CHE NON CI SIA GIA' ALTRA CONFERMA x quella macchina entro ultimi 2 minuti (non permesso...)
-- non faccio ISOLATION perchè solo un approvatore ( da Samuele )
IF NOT EXISTS ( -- se non trovata una conferma entro 2 minuti elaboro conferma
SELECT DataOraConf
FROM dbo.ElencoConfermeProd
WHERE IdxMacchina = @idxMacchina
AND DataOraConf >= DATEADD(mi,-2,GETDATE() )
) OR @TestConferma = 0
BEGIN
-- leggo dati ODL x Cod. Ordine esterno
SELECT @CommessaEsterna=CommessaAs400 FROM dbo.ODL
WHERE IdxMacchina=@IdxMacchina AND @DataTo BETWEEN DataInizio AND ISNULL(DataFine,'21990101')
-- INSERISCO record della conferma se @TestConferma = 1
IF @TestConferma = 1
INSERT INTO dbo.ElencoConfermeProd ( DataOraConf, idxMacchina, MatrApp, dataFrom, dataTo, pezziConf, pezziScar, pezziDaRilav, CommessaEsterna, TipoConf )
SELECT @DataOraApp, @idxMacchina, @MatrApp, @dataFrom, @dataTo, @pezziConf, @pezziScar, @pezziDaRilav, @CommessaEsterna , @TipoConf
DECLARE @NumPzConteggiati INT = 0 -- num pezzi che risultano dal conteggio automatico
, @Periodi INT = 1 -- numero di periodi da confermare (1 solo, giornate, turni...)
, @ShiftTurno INT = 6 -- shift turno (dalle 6.00)
, @DurataTurno INT = 8 -- durata turno
CREATE TABLE #Periodi (
RowNum INT NULL
, IdxMacchina NVARCHAR(50) NULL
, IdxODL INT NULL
, DataFrom DATETIME NULL
, DataTo DATETIME NULL
, Turno INT NULL
, PzProdNC INT NULL
)
-- a) Creo la tabella dei periodi dove devo calcolare i tempi di produzione in base al tipo conferma ( giornata, turni )
-- Crea periodi solo dove è presente ODL
-- ==============================
-- conferma per PERIODO INTERO
-- ==============================
IF @TipoConf = 0
BEGIN
SELECT @Periodi = 1
;WITH cteODL AS -- prendo tutte ODL nel periodo
(
SELECT IdxODL, CodArticolo, IdxMacchina, DataInizio, ISNULL(DataFine, DATEADD(dd,1,@dataTo)) AS DataFine
FROM ODL
WHERE IdxMacchina = @idxMacchina
AND
( ( DataInizio < @dataTo AND DataFine > @dataFrom )
OR ( DataInizio < @dataTo AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
)
-- inserisco 1 unica riga (periodo) per ogni ODL
INSERT INTO #Periodi
SELECT tbl.*, ISNULL(SUM(tcr.PzProd),0) as PzProdNC
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY cteODL.DataInizio ASC) AS Row
, @idxMacchina as IdxMacchina
, IdxOdl
, CASE WHEN DataInizio < @dataFrom THEN @dataFrom ELSE DataInizio END as startDate
, CASE WHEN @dataTo < DataFine THEN @dataTo ELSE DataFine END as endDate
, 0 as Turno
FROM cteODL
WHERE IdxMacchina = @idxMacchina
AND ((DataInizio BETWEEN @dataFrom AND @dataTo)
OR (DataFine BETWEEN @dataFrom AND @dataTo))
) as tbl LEFT OUTER JOIN TempiCicloRilevati tcr ON tbl.idxMacchina = tcr.idxMacchina and tcr.DataOraRif BETWEEN tbl.startDate and tbl.endDate
GROUP BY tbl.Row, tbl.IdxMacchina, tbl.IdxODL, tbl.startDate, tbl.endDate, tbl.Turno
ORDER BY tbl.startDate
END
-- ==============================
-- conferma per GIORNATE comprese nell'intervallo del periodo (quindi parziale la prima e l'ultima se conferma NON effettuata alle 00.00)
-- ==============================
ELSE IF @TipoConf = 1
BEGIN
SELECT @Periodi = DATEDIFF(DD, @dataFrom, @dataTo) --+ 1 -- aggiungo 1 perché conteggia le DATE PIENE e voglio avere sia primo che ultimo gg...
;WITH ctePrd AS
(
SELECT CASE WHEN @dataFrom > DATEADD(DD,n,dbo.f_dateOnly(@dataFrom)) THEN @dataFrom ELSE DATEADD(DD,n,dbo.f_dateOnly(@dataFrom)) END as DtFrom
,CASE WHEN @dataTo < DATEADD(DD,n+1,dbo.f_dateOnly(@dataFrom)) THEN @dataTo ELSE DATEADD(DD,n+1,dbo.f_dateOnly(@dataFrom)) END as DtTo
FROM TallyTable
WHERE n <= @Periodi
),
cteODL AS
(
SELECT IdxODL, CodArticolo, IdxMacchina, DataInizio, ISNULL(DataFine, DATEADD(dd,1,@dataTo)) as DataFine
FROM ODL
WHERE IdxMacchina = @idxMacchina
AND
( ( DataInizio < @dataTo AND DataFine > @dataFrom )
OR ( DataInizio < @dataTo AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
)
-- ciclo nei periodi (GIORNI) ed inserisco @Periodi righe di periodo...
INSERT INTO #Periodi
SELECT tbl.*, ISNULL(SUM(tcr.PzProd),0) as PzProdNC
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY cteODL.DataInizio ASC) AS Row
, @idxMacchina as idxMacchina
, IdxOdl
, CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END as startDate
, CASE WHEN DtTo < DataFine THEN DtTo ELSE DataFine END as endDate
, 0 as Turno
FROM ctePrd CROSS JOIN cteODL -- CROSS JOIN della produttoria tra ODL del giorno e giorni disponibili
WHERE IdxMacchina = @idxMacchina
AND ( (DataInizio BETWEEN DtFrom AND DtTo)
OR (DataFine BETWEEN DtFrom AND DtTo)
OR (DataInizio <= DtFrom AND DataFine >= DtTo)
)
) as tbl LEFT OUTER JOIN TempiCicloRilevati tcr ON tbl.idxMacchina = tcr.idxMacchina and tcr.DataOraRif BETWEEN tbl.startDate and tbl.endDate
GROUP BY tbl.Row, tbl.IdxMacchina, tbl.IdxODL, tbl.startDate, tbl.endDate, tbl.Turno
ORDER BY tbl.startDate
END
-- ==============================
-- conferma per TURNI INTERI compresi nell'intervallo del periodo
-- ==============================
ELSE IF @TipoConf = 2
BEGIN
SELECT @Periodi = CEILING(CAST(DATEDIFF(HH, @dataFrom, @dataTo) AS FLOAT) / @DurataTurno) + 1
;WITH ctePrd AS
(
SELECT CASE WHEN @dataFrom > DATEADD(HH,@DurataTurno*n+@ShiftTurno,dbo.f_dateOnly(@dataFrom))
THEN @dataFrom
ELSE DATEADD(HH,@DurataTurno*n+@ShiftTurno,dbo.f_dateOnly(@dataFrom)) END as DtFrom
,CASE WHEN @dataTo < DATEADD(HH,@DurataTurno*(n+1)+@ShiftTurno,dbo.f_dateOnly(@dataFrom))
THEN @dataTo
ELSE DATEADD(HH,@DurataTurno*(n+1)+@ShiftTurno,dbo.f_dateOnly(@dataFrom)) END as DtTo
FROM TallyTable
WHERE n <= @Periodi
),
cteODL AS
(
SELECT IdxODL, CodArticolo, IdxMacchina, DataInizio, ISNULL(DataFine, DATEADD(dd,1,@dataTo)) as DataFine
FROM ODL
WHERE IdxMacchina = @idxMacchina
AND
( ( DataInizio < @dataTo AND DataFine > @dataFrom )
OR ( DataInizio < @dataTo AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
)
-- ciclo nei periodi (TURNI) ed inserisco @Periodi righe di periodo...
INSERT INTO #Periodi
SELECT tbl.*, ISNULL(SUM(tcr.PzProd),0) as PzProdNC
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY cteODL.DataInizio ASC) AS Row
, @idxMacchina AS idxMacchina
, IdxOdl
, CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END as startDate
, CASE WHEN DtTo < DataFine THEN DtTo ELSE DataFine END as endDate
, CEILING((DATEPART(HH,CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END)-@ShiftTurno)/@DurataTurno) + 1 as turno
FROM ctePrd CROSS JOIN cteODL -- CROSS JOIN della produttoria tra ODL del turno e turni disponibili
WHERE IdxMacchina = @idxMacchina
AND ( (DataInizio BETWEEN DtFrom AND DtTo)
OR (DataFine BETWEEN DtFrom AND DtTo)
OR (DataInizio <= DtFrom AND DataFine >= DtTo)
)
) as tbl
LEFT OUTER JOIN TempiCicloRilevati tcr ON tbl.idxMacchina = tcr.idxMacchina and tcr.DataOraRif BETWEEN tbl.startDate and tbl.endDate
GROUP BY tbl.Row, tbl.IdxMacchina, tbl.IdxODL, tbl.startDate, tbl.endDate, tbl.Turno
ORDER BY tbl.startDate
END
SELECT * FROM #Periodi
-- ================================================================
--#region b)
-- per ogni PERIODO ho TUTTI gli ODL intersecati: faccio ciclo!!!!
-- ================================================================
DECLARE @idxOdl INT
,@Inizio DATETIME
,@Fine DATETIME
,@DataRif DATETIME
,@Turno INT
,@PzProd INT
,@PzProdTot INT
,@IdxStatoP INT = 13 -- HARD CODED!!!!
,@deltaPz INT = 0
-- inizializzo
DECLARE @imax INT,
@i INT
SELECT @imax = COUNT(*) FROM #Periodi
SET @i = 1
WHILE (@i <= @imax)
BEGIN
SELECT @idxOdl = IdxODL
, @Inizio = DataFrom
, @Fine = DataTo
, @DataRif = dbo.f_dateOnly(DataFrom)
, @Turno = Turno
, @PzProd = PzProdNC
FROM #Periodi
WHERE RowNum = @i
-- SELECT * FROM #Periodi WHERE RowNum = @i
IF @Inizio < @Fine -- se Iniz <> Fine e il periodo è coerente
BEGIN
-- approvo num pz non confermati x gli ODL:
EXEC dbo.stp_DatiConf_conferma @idxOdl, @idxMacchina, @MatrApp, @Inizio, @Fine, @Turno, @IdxStatoP, @PzProd, 0, @DataOraApp
--select 'stp_DatiConf_conferma' as stp, @idxOdl, @idxMacchina, @MatrApp, @Inizio, @Fine, @Turno, @IdxStatoP, @PzProd
-- confermo i tempi splittati: stp_DatiProd_insAllPeriodo
EXEC dbo.stp_DatiProd_insAllPeriodo @idxMacchina, @Inizio, @Fine, @DataRif, @Turno, @MatrApp, @DataOraApp
--select 'stp_DatiProd_insAllPeriodo' as stp, @idxMacchina, @Inizio, @Fine, @DataRif, @Turno, @MatrApp
END
SET @i = @i + 1
END -- WHILE
--#endregion
-- ==============================
-- c) CARICO PERIODI SENZA ODL in in DatiProduzione come 'T_OFF'
-- ==============================
DECLARE @ClasseTempo NVARCHAR(50);
DECLARE @DataFirstODL AS DATETIME = '21000101'
SET @ClasseTempo = 'T_OFF';
SELECT @DataFirstODL = MIN(DataInizio) FROM dbo.ODL WHERE IdxMacchina = @IdxMacchina
IF @TipoConf = 0
BEGIN
-- *** DA COMPLETARE
SET @ClasseTempo = @ClasseTempo;
END
-- ==============================
-- periodi senza ODL per GIORNATA INTERA
-- ==============================
ELSE IF @TipoConf = 1
BEGIN
;WITH ctePrd AS -- elenco periodi
(
SELECT CASE WHEN @dataFrom > DATEADD(DD,n,dbo.f_dateOnly(@dataFrom)) THEN @dataFrom ELSE DATEADD(DD,n,dbo.f_dateOnly(@dataFrom)) END as DtFrom
,CASE WHEN @dataTo < DATEADD(DD,n+1,dbo.f_dateOnly(@dataFrom)) THEN @dataTo ELSE DATEADD(DD,n+1,dbo.f_dateOnly(@dataFrom)) END as DtTo
FROM TallyTable
WHERE n <= @Periodi
),cteODLAll AS -- creo periodi ODL + ODL fittizio inizio nel caso non trovi ODL nel periodo
(
SELECT 0 AS IdxODL, @IdxMacchina AS IdxMacchina, @dataFrom-1000 AS DataInizio, @dataFrom AS DataFine
WHERE @DataFirstODL < @dataFrom -- se il periodo è precedente alla prima ODL non lo considero
UNION
SELECT IdxODL, IdxMacchina, DataInizio, ISNULL( DataFine, DATEADD(dd,1,@dataTo) ) as DataFine
FROM dbo.ODL
WHERE IdxMacchina = @idxMacchina
AND ( ( DataInizio < @dataTo AND DataFine > @dataFrom )
OR ( DataInizio < @dataTo AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
),cteODL AS
(
SELECT ROW_NUMBER() OVER( ORDER BY DataInizio ASC) AS RowNum, IdxODL, IdxMacchina, DataInizio, DataFine
FROM cteODLAll
)
,cteNoODL AS -- periodi macchina senza ODL
(
SELECT DISTINCT P1.IdxMacchina, P1.DataFine AS DataInizio, ISNULL(P2.DataInizio, @DataTo ) AS DataFine -- , p2.DataInizio as dt2,p2.DataFine as dt3
FROM cteODL AS P1
LEFT JOIN cteODL AS P2 ON P1.RowNum + 1 = P2.RowNum -- aggancio a riga successiva
WHERE DATEDIFF( MINUTE, P1.DataFine, ISNULL( P2.DataInizio , @DataTo ) ) > 5 -- solo se diff è positiva e > 5 minuti
)
INSERT INTO dbo.DatiProduzione( IdxODL, DataOraApp, DataRif, TurnoRif, CodArticolo, IdxMacchina, TCAssegnato, MatrOpr, MatrApp,
DataOraFrom, DataOraTo, TotPzProd, Tempo, ClasseTempo, Causale)
SELECT 0 AS idxODL, @DataOraApp, dbo.f_dateOnly(tbl.startDate) AS DataRif, turno, '' AS CodArticolo, idxMacchina, 0 AS TC, @MatrApp, @MatrApp
,startDate, endDate, 0 AS pz, CAST(ISNULL(DATEDIFF(n, startDate, endDate) ,0) AS DECIMAL(18,8)) / 60 AS Tempo , @ClasseTempo, @ClasseTempo
FROM (
SELECT DISTINCT
idxMacchina
, CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END AS startDate
, CASE WHEN DtTo < DataFine THEN DtTo ELSE DataFine END AS endDate
, 0 AS Turno
FROM ctePrd
CROSS JOIN cteNoODL -- CROSS JOIN della produttoria tra NoODL del giorno e giorni disponibili
WHERE ( ( DataInizio BETWEEN DtFrom AND DtTo )
OR ( DataFine BETWEEN DtFrom AND DtTo )
OR ( DataInizio <= DtFrom AND DataFine >= DtTo ) )
) AS tbl
WHERE startDate < endDate
END
-- ==============================
-- periodi senza ODL per TURNI nell'intervallo del periodo
-- ==============================
ELSE IF @TipoConf = 2
BEGIN
;WITH ctePrd AS
(
SELECT CASE WHEN @dataFrom > DATEADD(HH,@DurataTurno*n+@ShiftTurno,dbo.f_dateOnly(@dataFrom))
THEN @dataFrom
ELSE DATEADD(HH,@DurataTurno*n+@ShiftTurno,dbo.f_dateOnly(@dataFrom)) END as DtFrom
,CASE WHEN @dataTo < DATEADD(HH,@DurataTurno*(n+1)+@ShiftTurno,dbo.f_dateOnly(@dataFrom))
THEN @dataTo
ELSE DATEADD(HH,@DurataTurno*(n+1)+@ShiftTurno,dbo.f_dateOnly(@dataFrom)) END as DtTo
FROM TallyTable
WHERE n <= @Periodi
),cteODLAll AS -- creo periodi ODL + ODL fittizio inizio nel caso non trovi ODL nel periodo
(
SELECT 0 AS IdxODL, @IdxMacchina AS IdxMacchina, @dataFrom-1000 AS DataInizio, @dataFrom AS DataFine
WHERE @DataFirstODL < @dataFrom -- se il periodo è precedente alla prima ODL non lo considero
UNION
SELECT IdxODL, IdxMacchina, DataInizio, ISNULL( DataFine, DATEADD(dd,1,@dataTo) ) as DataFine
FROM dbo.ODL
WHERE IdxMacchina = @idxMacchina
AND ( ( DataInizio < @dataTo AND DataFine > @dataFrom )
OR ( DataInizio < @dataTo AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
),cteODL AS
(
SELECT ROW_NUMBER() OVER( ORDER BY DataInizio ASC) AS RowNum, IdxODL, IdxMacchina, DataInizio, DataFine
FROM cteODLAll
)
,cteNoODL AS -- periodi macchina senza ODL
(
SELECT DISTINCT P1.IdxMacchina, P1.DataFine AS DataInizio, ISNULL(P2.DataInizio, @DataTo ) AS DataFine -- , p2.DataInizio as dt2,p2.DataFine as dt3
FROM cteODL AS P1
LEFT JOIN cteODL AS P2 ON P1.RowNum + 1 = P2.RowNum -- aggancio a riga successiva
WHERE DATEDIFF( MINUTE, P1.DataFine, ISNULL( P2.DataInizio , @DataTo ) ) > 5 -- solo se diff è positiva e > 5 minuti
)
INSERT INTO dbo.DatiProduzione( IdxODL, DataOraApp, DataRif, TurnoRif, CodArticolo, IdxMacchina, TCAssegnato, MatrOpr, MatrApp,
DataOraFrom, DataOraTo, TotPzProd, Tempo, ClasseTempo, Causale)
SELECT 0 AS idxODL, @DataOraApp, dbo.f_dateOnly(tbl.startDate) AS DataRif, turno, '' AS CodArticolo, idxMacchina, 0 AS TC, @MatrApp, @MatrApp
,startDate, endDate, 0 AS pz, CAST(ISNULL(DATEDIFF(n, startDate, endDate) ,0) AS DECIMAL(18,8)) / 60 AS Tempo , @ClasseTempo, @ClasseTempo
FROM (
SELECT DISTINCT -- ROW_NUMBER() OVER( ORDER BY cteNoODL.DataInizio ASC) AS RowNum,
idxMacchina
, CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END as startDate
, CASE WHEN DtTo < DataFine THEN DtTo ELSE DataFine END as endDate
, CEILING((DATEPART(HH,CASE WHEN DataInizio < DtFrom THEN DtFrom ELSE DataInizio END)-@ShiftTurno)/@DurataTurno) + 1 as turno
FROM ctePrd
CROSS JOIN cteNoODL -- CROSS JOIN della produttoria tra NoODL del giorno e giorni disponibili
WHERE ( ( DataInizio BETWEEN DtFrom AND DtTo )
OR ( DataFine BETWEEN DtFrom AND DtTo )
OR ( DataInizio <= DtFrom AND DataFine >= DtTo ) )
) AS tbl
WHERE startDate < endDate
END
-- ===============================
-- d) INFINE CONFERMO DIFFERENZE
-- ===============================
-- infine confermo differenze:
SELECT @PzProdTot = ISNULL(SUM(TotPzProd),0)
FROM dbo.DatiProduzione
WHERE IdxMacchina = @idxMacchina
AND DataOraFrom >= @dataFrom AND DataOraTo <= @dataTo
AND Causale <> 'T_CorrProd' -- escludo cmq le correzioni di produzione
---- Fino al 2015-05-08
--SELECT @PzProdTot = ISNULL(SUM(tcr.PzProd),0)
--FROM dbo.TempiCicloRilevati tcr
--WHERE tcr.DataOraRif BETWEEN @dataFrom AND @dataTo
-- AND IdxMacchina = @idxMacchina
-- 2016.11.17 gestione SCARTI
-- update x DatiConf: (TUTTO SU ULTIMO ODL... e su adesso) AL NETTO DEGLI SCARTI
SELECT @DataRif = @dataTo
SELECT @deltaPz = @pezziConf - (@PzProdTot - @pezziScar)
IF @idxOdl IS NOT NULL
BEGIN
-- inverto valore scarti (come negativo)
SELECT @pezziScar = - ABS(@pezziScar)
EXEC dbo.stp_DatiConf_conferma @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @IdxStatoP, @deltaPz, @pezziScar, @DataOraApp
--select 'stp_DatiConf_conferma' as stp, @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @IdxStatoP, @deltaPz, @pezziScar, @DataOraApp
---- inserisco scartid: (TUTTO SU ULTIMO ODL... e su adesso)
EXEC dbo.stp_DatiProd_insert @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @pezziScar, 0, 'T_Scarto', @DataOraApp
--select 'stp_DatiProd_insert' as stp, @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @pezziScar, 0, 'T_Scarto', @DataOraApp
---- update per DatiProd: (TUTTO SU ULTIMO ODL... e su adesso)
EXEC dbo.stp_DatiProd_insert @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @deltaPz, 0, 'T_CorrProd', @DataOraApp
--select 'stp_DatiProd_insert' as stp, @idxOdl, @idxMacchina, @MatrApp, @DataRif, @DataRif, 1, @deltaPz, 0, 'T_CorrProd', @DataOraApp
END
-- 2018.05.02: ora registro gli scarti come acquisiti...
EXEC dbo.stp_RS_recProd @idxMacchina, @dataTo
END
END
/****** Object: StoredProcedure [dbo].[stp_StatoProd_getByMacchina] Script Date: 02/05/2018 22:40:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*************************************
* STORED PROCEDURE stp_StatoProd_getByMacchina
* recupera per la macchina indicata lo stato di produzione (pz Buoni / Scarto confermati e tot pezzi prod ad una specifica DataOra)
*
* modif.: S.E.L.
* il: 2018.05.02
**************************************/
ALTER PROCEDURE [dbo].[stp_StatoProd_getByMacchina]
(
@idxMacchina NVARCHAR(50)
,@DataOra DATETIME = NULL
)
AS
SET XACT_ABORT ON;
BEGIN TRAN
-- in primis: se dataora > adesso rimetto adesso
SET @DataOra = CASE WHEN ISNULL(@DataOra,GETDATE()) >= GETDATE() THEN GETDATE() ELSE @DataOra END
-- imposto valori accessori
DECLARE @IdxODL INT = 0
DECLARE @DataInizioOdl DATETIME
DECLARE @CodArticolo NVARCHAR(50) = 'ND'
DECLARE @PzConfBuoni INT = 0 -- TOT Buoni GIA' confermati
DECLARE @PzConfScarto INT = 0 -- TOT Scarti GIA' confermati
DECLARE @PzRichODL INT = 0 -- Pezzi Richiesti x ODL
DECLARE @PzTotODL INT = 0 -- Pezzi Prodotti x ODL fino a DataOra
DECLARE @Pz2RecTot INT = 0 -- Pezzi Prodotti da confermare (TOT = BUONI + SCARTO)
DECLARE @Pz2RecScarto INT = 0 -- Pezzi scarto registrati da confermare con produzione
-- recupero da tab ODL il codice odl stesso e l'articolo data macchina e data/ora...
SELECT @IdxODL = ISNULL(IdxODL,0), @CodArticolo = ISNULL(CodArticolo,'-'), @PzRichODL = NumPezzi, @DataInizioOdl = DataInizio
FROM ODL
WHERE IdxMacchina = @IdxMacchina
AND DataInizio <= @DataOra
AND ISNULL(DataFine, GETDATE()) >= @DataOra
-- calcolo data ora ultima conferma
DECLARE @lastConf AS DATETIME
DECLARE @startProd AS DATETIME
DECLARE @endProd AS DATETIME
-- prendo le date di produzione...
SET @startProd = (SELECT TOP 1 DataOraRif FROM dbo.TempiCicloRilevati WHERE IdxMacchina = @idxMacchina ORDER BY DataOraRif ASC)
--SET @endProd = (SELECT TOP 1 DataOraRif FROM TempiCicloRilevati WHERE IdxMacchina = @idxMacchina ORDER BY DataOraRif DESC)
SET @endProd = @DataOra --GETDATE()
-- calcolo data!
SET @lastConf = ISNULL((SELECT TOP 1 ISNULL(DataRif, @startProd) FROM dbo.DatiConfermati WHERE IdxMacchina = @idxMacchina ORDER BY DataRif DESC), @startProd)
-- Per ogni ODL della macchina nel periodo controllo e aggiorno il CodArticolo
-- x tutti i tempiciclo sottostanti
;WITH cteOdl AS -- ODL Macchina nel periodo
(
SELECT IdxODL, CodArticolo, IdxMacchina, DataInizio, ISNULL(DataFine, @EndProd) AS DataFine, PzPallet
FROM dbo.ODL
WHERE IdxMacchina = @idxMacchina
AND ( ( DataInizio <= @lastConf AND DataFine > @lastConf )
OR ( DataInizio <= @lastConf AND DataFine IS NULL ) ) -- includo Odl non chiuse solo se nel periodo richiesto
)
UPDATE dbo.TempiCicloRilevati
SET CodArticolo = cteOdl.CodArticolo,
PzProd = cteOdl.PzPallet,
TCMedio = TCMedio * PzProd / cteOdl.PzPallet -- sistemo anche il tempo ciclo in base ai PzPallet
FROM cteOdl
INNER JOIN dbo.TempiCicloRilevati AS tc
ON cteOdl.IdxMacchina = tc.IdxMacchina
AND tc.DataOraRif >= cteOdl.DataInizio AND tc.DataOraRif <= cteOdl.DataFine
WHERE cteOdl.CodArticolo <> tc.CodArticolo -- UPD solo se CodArticolo non corretto
OR cteOdl.PzPallet <> tc.PzProd -- o PzProd
-- recupero i dati GLOBALI confermati
SELECT @PzConfBuoni = ISNULL(SUM(pezziConf),0), @PzConfScarto= ISNULL(SUM(pezziScar),0)
FROM ElencoConfermeProd
WHERE idxMacchina = @idxMacchina
AND dataFrom >= @DataInizioOdl
-- recupero i dati dei pezzi prodotti alla data richiesta
SELECT @PzTotODL = ISNULL(SUM(PzProd),0)
FROM dbo.TempiCicloRilevati
WHERE IdxMacchina = @idxMacchina
AND DataOraRif BETWEEN @DataInizioOdl AND @DataOra
-- ora recupero gli scarti registrati ma NON confermati con produzione
SELECT @Pz2RecScarto = ISNULL(SUM(Qta),0)
FROM RegistroScarti
WHERE IdxMacchina = @idxMacchina
AND DataOra BETWEEN @lastConf AND @DataOra -- potrei mettere dalla data ora inizio ODL: @DataInizioOdl
AND DataOraProdRec IS NULL
-- calcolo NUOVI pezzi da confermare....
SELECT @Pz2RecTot = @PzTotODL - (@PzConfBuoni + @PzConfScarto)
-- ora ritorno TUTTI i dati...
SELECT @idxMacchina as idxMacchina
,ISNULL(@PzTotODL,0) AS PzTotODL
,ISNULL(@PzConfScarto,0) AS PzConfScarto
,ISNULL(@PzConfBuoni,0) AS PzConfBuoni
,ISNULL(@PzRichODL,0) AS PzRichODL
,ISNULL(@Pz2RecTot,0) AS Pz2RecTot
,ISNULL(@Pz2RecScarto,0) AS Pz2RecScarto
,@lastConf AS DataFrom
,@endProd AS DataTo
COMMIT TRAN
RETURN