SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/* ============================================================
   Patch prenotazione Picking List a livello documento

   Obiettivo:
   - rendere esclusiva la prenotazione di una sola picking list
   - mantenere la stored con lo stesso nome:
       dbo.sp_xExePackingListPallet
   - introdurre una sorgente di verità per documento prenotato:
       dbo.PickingListReservation
   - far leggere XMag_ViewPackingList.IDStato da tale stato
     e non più soltanto da Celle.IDStato
   ============================================================ */

IF OBJECT_ID(N'dbo.PickingListReservation', N'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[PickingListReservation](
        [ID] [tinyint] NOT NULL,
        [Documento] [varchar](8) NULL,
        [IDOperatore] [int] NULL,
        [ModUtente] [varchar](50) NULL,
        [ModDataOra] [datetime] NULL,
        CONSTRAINT [PK_PickingListReservation] PRIMARY KEY CLUSTERED ([ID] ASC),
        CONSTRAINT [CK_PickingListReservation_Singleton] CHECK ([ID] = 1)
    ) ON [PRIMARY];
END
GO

IF NOT EXISTS (SELECT 1 FROM dbo.PickingListReservation WHERE ID = 1)
BEGIN
    INSERT INTO dbo.PickingListReservation (ID, Documento, IDOperatore, ModUtente, ModDataOra)
    VALUES (1, NULL, NULL, NULL, GETDATE());
END
GO

CREATE OR ALTER PROCEDURE [dbo].[sp_xExePackingListPallet]
    @IDOperatore int,
    @Documento varchar(8),
    @Azione char(1) = 'P',   -- 'P' = Prenota, 'S' = S-prenota
    @RC int OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SET @RC = 0;

    DECLARE @Nominativo varchar(50) = '';
    DECLARE @DocumentoAttivo varchar(8) = NULL;
    DECLARE @Description varchar(255) = '';
    DECLARE @Message varchar(255) = '';
    DECLARE @IDResult int = 0;
    DECLARE @ID int = 0;

    SELECT @Nominativo = [Login]
    FROM dbo.Operatori
    WHERE ID = @IDOperatore;

    IF @Nominativo IS NULL
        SET @Nominativo = 'SYSTEM';

    IF @Azione NOT IN ('P', 'S')
    BEGIN
        SET @RC = -10;
        RETURN;
    END;

    IF NOT EXISTS (
        SELECT 1
        FROM dbo.XMag_ViewPackingList
        WHERE CAST(Documento AS varchar(8)) = @Documento
    )
    BEGIN
        SET @RC = -20;
        RETURN;
    END;

    IF NOT EXISTS (SELECT 1 FROM dbo.PickingListReservation WHERE ID = 1)
    BEGIN
        INSERT INTO dbo.PickingListReservation (ID, Documento, IDOperatore, ModUtente, ModDataOra)
        VALUES (1, NULL, NULL, NULL, GETDATE());
    END;

    SELECT @DocumentoAttivo = NULLIF(LTRIM(RTRIM(Documento)), '')
    FROM dbo.PickingListReservation
    WHERE ID = 1;

    DECLARE @TargetCelle TABLE (
        IDCella int PRIMARY KEY
    );

    INSERT INTO @TargetCelle (IDCella)
    SELECT DISTINCT Cella
    FROM dbo.XMag_ViewPackingList
    WHERE CAST(Documento AS varchar(8)) = @Documento
      AND Cella IS NOT NULL;

    IF @Azione = 'P'
    BEGIN
        IF @DocumentoAttivo = @Documento
            RETURN;

        UPDATE c
        SET c.IDStato = 0,
            c.ModUtente = @Nominativo,
            c.ModDataOra = GETDATE()
        FROM dbo.Celle c
        WHERE ISNULL(c.IDStato, 0) <> 0;

        UPDATE c
        SET c.IDStato = 1,
            c.ModUtente = @Nominativo,
            c.ModDataOra = GETDATE()
        FROM dbo.Celle c
        INNER JOIN @TargetCelle t ON t.IDCella = c.ID;

        UPDATE dbo.PickingListReservation
        SET Documento = @Documento,
            IDOperatore = @IDOperatore,
            ModUtente = @Nominativo,
            ModDataOra = GETDATE()
        WHERE ID = 1;

        SELECT TOP 1 @Description = NAZIONE
        FROM dbo.XMag_ViewPackingList
        WHERE CAST(Documento AS varchar(8)) = @Documento;

        EXEC dbo.sp_LogPackingList
             @ID = @ID,
             @Code = @Documento,
             @Description = @Description,
             @Message = @Message OUTPUT,
             @IDResult = @IDResult OUTPUT;

        RETURN;
    END;

    IF @Azione = 'S'
    BEGIN
        IF ISNULL(@DocumentoAttivo, '') <> @Documento
            RETURN;

        UPDATE c
        SET c.IDStato = 0,
            c.ModUtente = @Nominativo,
            c.ModDataOra = GETDATE()
        FROM dbo.Celle c
        INNER JOIN @TargetCelle t ON t.IDCella = c.ID;

        UPDATE dbo.PickingListReservation
        SET Documento = NULL,
            IDOperatore = @IDOperatore,
            ModUtente = @Nominativo,
            ModDataOra = GETDATE()
        WHERE ID = 1;

        RETURN;
    END;
END;
GO

CREATE OR ALTER VIEW [dbo].[XMag_ViewPackingList]
AS
WITH Base AS (
    SELECT
        dbo.vPreparaPackingList.UDC AS Pallet,
        dbo.vPreparaPackingList.NUMLOT AS Lotto,
        dbo.vPreparaPackingList.CODICE AS Articolo,
        dbo.vPreparaPackingList.DESCR AS Descrizione,
        dbo.vPreparaPackingList.Qta,
        dbo.vPreparaPackingList.NUMDOC AS Documento,
        dbo.vPreparaPackingList.Expr1 AS CodNazione,
        dbo.vPreparaPackingList.NAZIONE,
        CASE
            WHEN Expr1 = 'DE' THEN 10
            WHEN Expr1 = 'TH' THEN CASE WHEN SUBSTRING(dbo.vPreparaPackingList.DESCRDEST, 1, 2) = 'NA' THEN 11 ELSE 13 END
            WHEN Expr1 = 'MEX' THEN 12
            ELSE 4
        END AS Stato,
        ISNULL(dbo.XMag_GiacenzaPallet.NumeroPallet, 0) AS PalletCella,
        ISNULL(dbo.XMag_GiacenzaPallet.IDMagazzino, 1) AS Magazzino,
        ISNULL(dbo.XMag_GiacenzaPallet.IDArea, 5) AS Area,
        ISNULL(dbo.XMag_GiacenzaPallet.IDCella, 1000) AS Cella,
        ISNULL(dbo.Celle.Ordinamento, 99999) AS Ordinamento,
        ISNULL(dbo.Celle.Corsia + ' - ' + dbo.Celle.Colonna + ' - ' + dbo.Celle.Fila, 'Non scaff.') AS Ubicazione,
        SUBSTRING(dbo.vPreparaPackingList.DESCRDEST, 1, 2) AS DEST
    FROM dbo.Celle
    INNER JOIN dbo.XMag_GiacenzaPallet
        ON dbo.Celle.ID = dbo.XMag_GiacenzaPallet.IDCella
    RIGHT OUTER JOIN dbo.vPreparaPackingList
        ON dbo.XMag_GiacenzaPallet.BarcodePallet COLLATE SQL_Latin1_General_CP1_CI_AS = dbo.vPreparaPackingList.UDC
    GROUP BY
        dbo.vPreparaPackingList.Expr1,
        dbo.vPreparaPackingList.NAZIONE,
        dbo.vPreparaPackingList.UDC,
        dbo.vPreparaPackingList.NUMDOC,
        dbo.vPreparaPackingList.NUMLOT,
        dbo.vPreparaPackingList.CODICE,
        dbo.vPreparaPackingList.DESCR,
        dbo.vPreparaPackingList.Qta,
        dbo.XMag_GiacenzaPallet.NumeroPallet,
        dbo.XMag_GiacenzaPallet.IDMagazzino,
        dbo.XMag_GiacenzaPallet.IDArea,
        dbo.XMag_GiacenzaPallet.IDCella,
        dbo.Celle.Ordinamento,
        dbo.Celle.Corsia,
        dbo.Celle.Colonna,
        dbo.Celle.Fila,
        dbo.vPreparaPackingList.DESCRDEST
)
SELECT TOP 10000
    Base.Pallet,
    Base.Lotto,
    Base.Articolo,
    Base.Descrizione,
    Base.Qta,
    Base.Documento,
    Base.CodNazione,
    Base.NAZIONE,
    Base.Stato,
    Base.PalletCella,
    Base.Magazzino,
    Base.Area,
    Base.Cella,
    Base.Ordinamento,
    Base.Ubicazione,
    Base.DEST,
    CASE
        WHEN pr.Documento IS NOT NULL
         AND pr.Documento = CAST(Base.Documento AS varchar(8))
        THEN 1
        ELSE 0
    END AS IDStato
FROM Base
LEFT JOIN dbo.PickingListReservation pr
    ON pr.ID = 1
   AND NULLIF(LTRIM(RTRIM(pr.Documento)), '') IS NOT NULL
ORDER BY
    CASE
        WHEN pr.Documento IS NOT NULL
         AND pr.Documento = CAST(Base.Documento AS varchar(8))
        THEN 1
        ELSE 0
    END DESC,
    Base.Documento,
    Base.Ordinamento;
GO

CREATE OR ALTER PROCEDURE [dbo].[sp_xExePackingListPalletPrenota]
    @IDOperatore int,
    @Documento varchar(8),
    @RC int OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SET @RC = 0;

    DECLARE @Nominativo varchar(50) = '';

    SELECT @Nominativo = LOGIN
    FROM dbo.Operatori
    WHERE ID = @IDOperatore;

    IF @Nominativo IS NULL
        SET @Nominativo = 'SYSTEM';

    UPDATE c
    SET c.IDStato = 1,
        c.ModUtente = @Nominativo,
        c.ModDataOra = GETDATE()
    FROM dbo.Celle c
    WHERE c.ID IN (
        SELECT DISTINCT Cella
        FROM dbo.ViewPackingListRestante
        WHERE CAST(Documento AS varchar(8)) = @Documento
          AND Cella IS NOT NULL
    );
END;
GO

CREATE OR ALTER PROCEDURE [dbo].[sp_ControllaPrenotazionePackingListPalletNew]
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Documento varchar(8) = NULL;
    DECLARE @IDOperatore int = 0;
    DECLARE @Nominativo varchar(50) = 'SYSTEM';
    DECLARE @RC int = 0;

    SELECT
        @Documento = NULLIF(LTRIM(RTRIM(Documento)), ''),
        @IDOperatore = ISNULL(IDOperatore, 0),
        @Nominativo = ISNULL(NULLIF(LTRIM(RTRIM(ModUtente)), ''), 'SYSTEM')
    FROM dbo.PickingListReservation
    WHERE ID = 1;

    IF ISNULL(@Documento, '') = ''
        RETURN;

    IF NOT EXISTS (
        SELECT 1
        FROM dbo.ViewPackingListRestante
        WHERE CAST(Documento AS varchar(8)) = @Documento
    )
    BEGIN
        UPDATE dbo.Celle
        SET IDStato = 0,
            ModUtente = @Nominativo,
            ModDataOra = GETDATE()
        WHERE ISNULL(IDStato, 0) <> 0;

        UPDATE dbo.PickingListReservation
        SET Documento = NULL,
            IDOperatore = @IDOperatore,
            ModUtente = @Nominativo,
            ModDataOra = GETDATE()
        WHERE ID = 1;

        RETURN;
    END;

    UPDATE dbo.Celle
    SET IDStato = 0,
        ModUtente = @Nominativo,
        ModDataOra = GETDATE()
    WHERE ISNULL(IDStato, 0) <> 0;

    IF @IDOperatore <= 0
    BEGIN
        SELECT TOP 1 @IDOperatore = ID
        FROM dbo.Operatori
        WHERE LOGIN = @Nominativo;
    END;

    EXEC dbo.sp_xExePackingListPalletPrenota
         @IDOperatore = @IDOperatore,
         @Documento = @Documento,
         @RC = @RC OUTPUT;
END;
GO
