









/*****************************************
* STORED stp_processaGiornaleMagazzino
*
* processa il giornale del magazzino, in modo da controlalre tutte le righe non processate (o eventualmente solo quelle nuove)
* e spostare nella coda di trasferimento con AS400 SOLO i movimenti che soddisfano i criteri specificati nella tabella
* "TabSyncMovMag" 
*
* Steamware, S.E.L.
* mod: 2012.05.25
*
****************************************/
CREATE PROCEDURE [BatchQueue].[stp_processaGiornaleMagazzino]
(
	@CodCS NCHAR(2),
	@lastInsDate DATETIME = NULL -- data-ora da cui cercare i record, se non viene passata è l'ultimo movimento registrato
)
AS

SET XACT_ABORT ON;

BEGIN TRAN

	/**********************************************************************************
	*
	* PROCEDURA in 4 step:
	* - STEP 1: registro rettifiche QUANTITA' in FROM
	* - STEP 2: registro prelievi da mag ext "from" (cambio mag)
	* - STEP 3: registro depositi a mag ext "to" (cambio mag)
	* - STEP 4: registro compensazioni: se from e to corrispondono e mag comp è NON NULLO metto in comp!
	* - STEP 5: verifico e creo movimenti di scarico grezzi tramite distinta
	**********************************************************************************/

	-- in primis: se è nulla la data calcolo l'ultim data di processing...
	IF ( @lastInsDate IS NULL )
	BEGIN
		SET	@lastInsDate = ( SELECT ISNULL(MAX(DataOra), '19000101') FROM GiornaleMagazzino WHERE NOT (DataOraProc IS NULL) )
	END
	
	-- ATTENZIONE!!! DEVE ESSERCI UN PARTICOLARE NON NULLO e != "n.d."
	
	-- ora prendo tutte le righe che mi interessano e cerco match sulla tab TabSyncMovMag e le inserisco in batch...
		
    -- =====================================================================================
	-- STEP 1: rettifico quantità!
    -- =====================================================================================
	INSERT INTO	AS400_BatchMovimenti(DataIns, numOp, CodEvento, Particolare, UDC, CodMagAS, Quantita)
	SELECT	DataOra, numOp, 'UDC_MOD', gm.Particolare, gm.UDC, tsmm.codMagExtFrom , gm.QtaTo - gm.QtaFrom
	FROM	GiornaleMagazzino gm 
	INNER JOIN TabSyncMovMag tsmm ON 
			tsmm.CodCS = @CodCS AND
			gm.CodStatoFrom		= tsmm.CodStatoFrom AND
			gm.CodStatoTo		= tsmm.CodStatoTo AND
			gm.IdxPosizioneFrom	= tsmm.IdxPosizioneFrom AND
			gm.IdxPosizioneTo	= tsmm.IdxPosizioneTo
	WHERE	(gm.DataOra		>= @lastInsDate)	
	AND		(gm.DataOraProc	IS NULL)
	AND		(tsmm.toExt		= 1)                            -- Se devo fare movimento su Sistema EXT
	AND		gm.Particolare <> ''					        -- particolare deve essere disponibile!!!!
    AND		(tsmm.codMagExtTo IS NOT NULL AND tsmm.codMagExtFrom IS NOT NULL )  -- le righe con magazzini ext NULLI non sono permessi
	AND		(tsmm.codMagExtFrom = tsmm.codMagExtTo)         -- Solo se NON VARIA MAG ESTERNO...
    AND		(tsmm.codMagExtTo > 0 AND codMagExtFrom > 0 ) -- e magazzini non 0 ( usato quando non esiste Mag )

	
    -- =====================================================================================	
	-- STEP 2: genero ora casi con 2 mag ext che cambiano: tolgo da FROM
    -- =====================================================================================
	INSERT INTO	AS400_BatchMovimenti(DataIns, numOp, CodEvento, Particolare, UDC, CodMagAS, Quantita)
	SELECT	DataOra, numOp, 'UDC_MOV', gm.Particolare, gm.UDC, tsmm.codMagExtFrom , - gm.QtaFrom
	FROM	GiornaleMagazzino gm 
	INNER JOIN TabSyncMovMag tsmm ON 
			tsmm.CodCS = @CodCS AND
			gm.CodStatoFrom		= tsmm.CodStatoFrom AND
			gm.CodStatoTo		= tsmm.CodStatoTo AND
			gm.IdxPosizioneFrom	= tsmm.IdxPosizioneFrom AND
			gm.IdxPosizioneTo	= tsmm.IdxPosizioneTo
	WHERE	(gm.DataOra		>= @lastInsDate)	
	AND		(gm.DataOraProc	IS NULL)
	AND		(tsmm.toExt		= 1)
	AND		gm.Particolare <> '' -- particolare deve essere disponibile!!!!
    AND		(tsmm.codMagExtTo IS NOT NULL AND tsmm.codMagExtFrom IS NOT NULL )  -- le righe con magazzini ext NULLI non sono permessi
	AND		(tsmm.codMagExtFrom <> tsmm.codMagExtTo) -- se VARIA MAG ESTERNO...
	AND		(tsmm.codMagExtFrom > 0);                -- e mag. partenza non 0 ( usato se non esiste Mag di partenza es. NEW UDC ) 
                                                     -- e non Negativo ( consumo ) non carica nessun magazzino
    -- =====================================================================================
	-- STEP 3: genero ora casi con 2 mag ext che cambiano: metto in TO
    -- =====================================================================================
	INSERT INTO	AS400_BatchMovimenti(DataIns, numOp, CodEvento, Particolare, UDC, CodMagAS, Quantita)
	SELECT	DataOra, numOp, 'UDC_MOV',  gm.Particolare, gm.UDC, tsmm.codMagExtTo  , gm.QtaTo
	FROM	GiornaleMagazzino gm INNER JOIN TabSyncMovMag tsmm ON 
			tsmm.CodCS = @CodCS AND
			gm.CodStatoFrom		= tsmm.CodStatoFrom AND
			gm.CodStatoTo		= tsmm.CodStatoTo AND
			gm.IdxPosizioneFrom	= tsmm.IdxPosizioneFrom AND
			gm.IdxPosizioneTo	= tsmm.IdxPosizioneTo
	WHERE	(gm.DataOra		>= @lastInsDate)	
	AND		(gm.DataOraProc	IS NULL)
	AND		(tsmm.toExt		= 1)
    AND		(tsmm.codMagExtTo IS NOT NULL AND tsmm.codMagExtFrom IS NOT NULL )  -- le righe con magazzini ext NULLI non sono permessi
	AND		gm.Particolare <> ''                     -- particolare deve essere disponibile!!!!
	AND		(tsmm.codMagExtFrom <> tsmm.codMagExtTo) -- se VARIA MAG ESTERNO...
	AND		(tsmm.codMagExtTo > 0);                  -- e mag. destinazione non 0 ( usato se non esiste Mag di arrivo es. DEL UDC )
                                                     -- e non Negativo ( consumo ) non carica nessun magazzino

    -- =====================================================================================
	-- STEP 4: cerco prima casi con magazzini ext origine = destinazione e compensazioni
    -- =====================================================================================
	INSERT INTO	AS400_BatchMovimenti(DataIns, numOp, CodEvento, Particolare, UDC, CodMagAS, Quantita)
	SELECT	DataOra, numOp, 'UDC_COMP',  gm.Particolare, gm.UDC, tsmm.codMagExtComp, gm.QtaFrom - gm.QtaTo 
	FROM	GiornaleMagazzino gm 
	INNER JOIN TabSyncMovMag tsmm ON 
			tsmm.CodCS = @CodCS AND
			gm.CodStatoFrom		= tsmm.CodStatoFrom AND
			gm.CodStatoTo		= tsmm.CodStatoTo AND
			gm.IdxPosizioneFrom	= tsmm.IdxPosizioneFrom AND
			gm.IdxPosizioneTo	= tsmm.IdxPosizioneTo
	WHERE	(gm.DataOra		>= @lastInsDate)	
	AND		(gm.DataOraProc	IS NULL)
	AND		(tsmm.toExt		= 1)
	AND		gm.Particolare <> '' -- particolare deve essere disponibile!!!!
    AND		(tsmm.codMagExtTo IS NOT NULL AND tsmm.codMagExtFrom IS NOT NULL )  -- le righe con magazzini ext NULLI non sono permessi
    AND		(tsmm.codMagExtTo > 0 AND codMagExtFrom > 0 )                       -- e magazzini > 0 ( usato quando non esiste Mag )
	AND		(tsmm.codMagExtComp IS NOT NULL AND tsmm.codMagExtComp <> 0 )       -- HO compensazioni!!!
	AND		(tsmm.codMagExtFrom = tsmm.codMagExtTo);                            -- E NON VARIA MAG ESTERNO...


    -- =====================================================================================
	-- STEP 5: verifico e creo movimenti di scarico grezzi tramite distinta
    -- =====================================================================================
    -- estraggo i mov. già creati che in base alla TabSyncMovMag devono fare mov. di scarico grezzi
    -- tramite distinta base e particolare leggo i relativi grezzi e qta da scaricare
    -- oppure, se il particolare è già un grezzo scarico se stesso
    WITH ctePartMov AS    -- movimenti creati che hanno un ulteriore carico-scarico tramite distinta
    (
        SELECT mov.DataIns , mov.numOp, mov.CodEvento, mov.Particolare, mov.UDC, mov.CodMagAS, mov.Quantita
               ,tsmm.codMagExtDist AS CodMagAS_Update
        --,* 
        FROM dbo.AS400_BatchMovimenti    AS mov
        INNER JOIN dbo.GiornaleMagazzino AS gm 
            ON mov.numOp = gm.numOp
        INNER JOIN dbo.TabSyncMovMag     AS tsmm
            ON	tsmm.CodCS = @CodCS AND
		        gm.CodStatoFrom		= tsmm.CodStatoFrom AND
		        gm.CodStatoTo		= tsmm.CodStatoTo AND
		        gm.IdxPosizioneFrom	= tsmm.IdxPosizioneFrom AND
		        gm.IdxPosizioneTo	= tsmm.IdxPosizioneTo
        WHERE gm.DataOraProc IS NULL 
        AND tsmm.toDistinta = 1         -- movimenti elaborati con compensazione distinta grezzo richiesta toDistinta = 1
        AND codMagExtDist > 0           -- e magazzino di compensazione grezzo impostato
    ),
    -- Cte ricorsiva che a fronte dei particolari passati mi ritorna tutto l'albero della distinta
    -- per tutti i figli del particolare con il relativo calcolo delle quantità
    DistintaCTE ( Particolare , Padre, Figlio, Coeff, QtaDaScar ,Level ) AS 
    (
        SELECT p.Particolare, d.Padre, d.Figlio, d.Coeff , CONVERT( numeric(20,4), d.Coeff ) AS QtaDaScar, 0 AS Level 
        FROM RilPro.DistintaAS400 AS d
        INNER JOIN ctePartMov AS p ON p.Particolare = d.Padre  -- prendo i particolari e leggo l'albero partendo da questi
            UNION ALL
        SELECT Particolare, p.Padre, p.Figlio, p.Coeff,    -- select ricorsiva
               CONVERT( numeric(20,4),( p.Coeff * QtaDaScar ) ) AS QtaDaScar,
               Level + 1
        FROM RilPro.DistintaAS400 AS p
        INNER JOIN DistintaCTE AS f ON p.Padre = f.Figlio
    )
    -- estraggo solo le righe distinta con grezzi come figli
    ,CteGrezzi AS
    (
     SELECT Particolare, Padre, Figlio, Coeff, QtaDaScar, Level
     FROM DistintaCTE
     WHERE SUBSTRING( Figlio, 2,3) = 'GRZ'                         -- solo le righe di scarico grezzi
    )
    INSERT INTO dbo.AS400_BatchMovimenti(DataIns, numOp, CodEvento, Particolare, UDC, CodMagAS, Quantita)
    SELECT    DataIns
            , numOp
            , 'UDC_GRZ' AS CodEvento
            , g.Figlio AS PartGrezzo
            , UDC
            , CodMagAS_Update
            , -( ISNULL( g.QtaDaScar, 1) * p.Quantita ) AS QtaGrezzo   -- quantità grezzi da scaricare secondo la dist. base
    FROM ctePartMov     AS p
    INNER JOIN CteGrezzi AS g ON p.Particolare = g.Particolare
        UNION 
    -- i movimenti di scarico dei grezzi stessi li inserisco direttamente con qta 1=1
    SELECT DataIns, numOp, 'UDC_GRZ' AS CodEvento, Particolare AS PartGrezzo, UDC, CodMagAS_Update, -(Quantita) AS QtaGrezzo
    FROM ctePartMov
    WHERE SUBSTRING( Particolare, 2,3) = 'GRZ' 
    OPTION (MAXRECURSION 50);  -- max n. sottolivelli


    -- =====================================================================================
	-- ora aggiorno le stesse righe di giornale riportate indicando la data ora di processing...
    -- =====================================================================================
	UPDATE	gm
	SET		DataOraProc = GETDATE()
	FROM	GiornaleMagazzino gm 
	INNER JOIN AS400_BatchMovimenti abm 
		ON	gm.numOp = abm.numOp
	WHERE	(gm.DataOra	>= @lastInsDate)	
	AND		(gm.DataOraProc	IS NULL)
	
COMMIT TRAN

RETURN









