IF OBJECT_ID(N'dbo.库存盘点_调拨记录', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.库存盘点_调拨记录
    (
        库存调拨流水号 INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
        类型 NVARCHAR(50) NULL,
        物料流水号 INT NULL,
        原物料与货位流水号 INT NULL,
        原货位流水号 INT NULL,
        目标物料与货位流水号 INT NULL,
        目标货位流水号 INT NULL,
        调拨数量 FLOAT NULL,
        调拨前原库存 FLOAT NULL,
        调拨后原库存 FLOAT NULL,
        调拨前目标库存 FLOAT NULL,
        调拨后目标库存 FLOAT NULL,
        调拨备注 NVARCHAR(200) NULL,
        操作人 INT NULL,
        操作时间 DATETIME NULL
    )
END
GO

IF OBJECT_ID(N'dbo.仓储管理_库存盘点_库存调拨', N'P') IS NOT NULL
    DROP PROCEDURE dbo.仓储管理_库存盘点_库存调拨
GO

CREATE PROCEDURE dbo.仓储管理_库存盘点_库存调拨
    @物料与货位流水号 INT = NULL,
    @物料流水号 INT = NULL,
    @原货位流水号 INT = NULL,
    @目标货位流水号 INT = NULL,
    @调拨数量 FLOAT = NULL,
    @原库存数 FLOAT = NULL,
    @调拨备注 NVARCHAR(200) = NULL,
    @操作者 INT = NULL,
    @类型 NVARCHAR(50) = NULL
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    DECLARE @当前库存 FLOAT;
    DECLARE @目标库存 FLOAT;
    DECLARE @调拨前原库存 FLOAT;
    DECLARE @调拨后原库存 FLOAT;
    DECLARE @调拨前目标库存 FLOAT;
    DECLARE @调拨后目标库存 FLOAT;
    DECLARE @目标物料与货位流水号 INT;
    DECLARE @批次编号 NVARCHAR(50);
    DECLARE @总库存 FLOAT;
    DECLARE @错误 NVARCHAR(200);

    IF ISNULL(@物料与货位流水号, 0) = 0
    BEGIN
        SELECT '0' AS result, N'原库存记录不能为空' AS msg;
        RETURN;
    END;

    IF ISNULL(@目标货位流水号, 0) = 0
    BEGIN
        SELECT '0' AS result, N'目标库位不能为空' AS msg;
        RETURN;
    END;

    IF ISNULL(@调拨数量, 0) <= 0
    BEGIN
        SELECT '0' AS result, N'调拨数量必须大于0' AS msg;
        RETURN;
    END;

    IF ISNULL(@原货位流水号, 0) = ISNULL(@目标货位流水号, 0)
    BEGIN
        SELECT '0' AS result, N'目标库位不能与原库位相同' AS msg;
        RETURN;
    END;

    BEGIN TRY
        BEGIN TRANSACTION;

        IF ISNULL(@类型, N'') = N'通用件'
        BEGIN
            SELECT
                @当前库存 = ISNULL(货位存量, 0),
                @物料流水号 = 产品流水号,
                @原货位流水号 = 货位流水号
            FROM dbo.库存管理_半成品与货位对照表 WITH (UPDLOCK, ROWLOCK)
            WHERE 物料与货位流水号 = @物料与货位流水号;

            IF @物料流水号 IS NULL
            BEGIN
                RAISERROR(N'原库存记录不存在', 16, 1);
            END;

            IF @当前库存 < @调拨数量
            BEGIN
                RAISERROR(N'原库位库存不足', 16, 1);
            END;

            SET @调拨前原库存 = @当前库存;
            SET @调拨后原库存 = @当前库存 - @调拨数量;

            UPDATE dbo.库存管理_半成品与货位对照表
            SET
                货位存量 = @调拨后原库存,
                盘点人编号 = @操作者,
                盘点时间 = GETDATE()
            WHERE 物料与货位流水号 = @物料与货位流水号;

            SELECT
                @目标物料与货位流水号 = 物料与货位流水号,
                @目标库存 = ISNULL(货位存量, 0)
            FROM dbo.库存管理_半成品与货位对照表 WITH (UPDLOCK, ROWLOCK)
            WHERE 产品流水号 = @物料流水号
              AND 货位流水号 = @目标货位流水号;

            SET @调拨前目标库存 = ISNULL(@目标库存, 0);
            SET @调拨后目标库存 = @调拨前目标库存 + @调拨数量;

            IF @目标物料与货位流水号 IS NULL
            BEGIN
                INSERT INTO dbo.库存管理_半成品与货位对照表
                    (产品流水号, 货位流水号, 货位存量, 盘点人编号, 盘点时间)
                VALUES
                    (@物料流水号, @目标货位流水号, @调拨数量, @操作者, GETDATE());

                SET @目标物料与货位流水号 = SCOPE_IDENTITY();
            END
            ELSE
            BEGIN
                UPDATE dbo.库存管理_半成品与货位对照表
                SET
                    货位存量 = @调拨后目标库存,
                    盘点人编号 = @操作者,
                    盘点时间 = GETDATE()
                WHERE 物料与货位流水号 = @目标物料与货位流水号;
            END;

            SELECT @总库存 = SUM(ISNULL(货位存量, 0))
            FROM dbo.库存管理_半成品与货位对照表
            WHERE 产品流水号 = @物料流水号;

            UPDATE dbo.库存管理_半成品累计库存
            SET 累计库存 = @总库存
            WHERE 产品流水号 = @物料流水号;

            INSERT INTO dbo.库存盘点_修改记录
                (物料与货位流水号, 产品流水号, 原数量, 更改后数量, 修改人)
            VALUES
                (@物料与货位流水号, @物料流水号, @调拨前原库存, @调拨后原库存, @操作者);

            INSERT INTO dbo.库存盘点_调拨记录
                (类型, 物料流水号, 原物料与货位流水号, 原货位流水号, 目标物料与货位流水号, 目标货位流水号, 调拨数量, 调拨前原库存, 调拨后原库存, 调拨前目标库存, 调拨后目标库存, 调拨备注, 操作人, 操作时间)
            VALUES
                (@类型, @物料流水号, @物料与货位流水号, @原货位流水号, @目标物料与货位流水号, @目标货位流水号, @调拨数量, @调拨前原库存, @调拨后原库存, @调拨前目标库存, @调拨后目标库存, @调拨备注, @操作者, GETDATE());
        END
        ELSE
        BEGIN
            SELECT
                @当前库存 = ISNULL(货位存量, 0),
                @物料流水号 = 物料流水号,
                @原货位流水号 = 货位流水号,
                @批次编号 = 批次号
            FROM dbo.库存管理_物料与货位对照表 WITH (UPDLOCK, ROWLOCK)
            WHERE 物料与货位流水号 = @物料与货位流水号;

            IF @物料流水号 IS NULL
            BEGIN
                RAISERROR(N'原库存记录不存在', 16, 1);
            END;

            IF @当前库存 < @调拨数量
            BEGIN
                RAISERROR(N'原库位库存不足', 16, 1);
            END;

            IF ISNULL(@批次编号, N'') = N''
            BEGIN
                SET @批次编号 = CONVERT(VARCHAR(10), GETDATE(), 23) + N'-PD' + CONVERT(NVARCHAR(50), @物料与货位流水号);

                UPDATE dbo.库存管理_物料与货位对照表
                SET 批次号 = @批次编号
                WHERE 物料与货位流水号 = @物料与货位流水号;
            END;

            SET @调拨前原库存 = @当前库存;
            SET @调拨后原库存 = @当前库存 - @调拨数量;

            UPDATE dbo.库存管理_物料与货位对照表
            SET
                货位存量 = @调拨后原库存,
                盘点人编号 = @操作者,
                盘点时间 = GETDATE()
            WHERE 物料与货位流水号 = @物料与货位流水号;

            SELECT
                @目标物料与货位流水号 = 物料与货位流水号,
                @目标库存 = ISNULL(货位存量, 0)
            FROM dbo.库存管理_物料与货位对照表 WITH (UPDLOCK, ROWLOCK)
            WHERE 物料流水号 = @物料流水号
              AND 货位流水号 = @目标货位流水号
              AND ISNULL(采购合同明细流水号, 0) = 0
              AND ISNULL(工艺计划流水号, 0) = 0;

            SET @调拨前目标库存 = ISNULL(@目标库存, 0);
            SET @调拨后目标库存 = @调拨前目标库存 + @调拨数量;

            IF @目标物料与货位流水号 IS NULL
            BEGIN
                INSERT INTO dbo.库存管理_物料与货位对照表
                    (物料流水号, 货位流水号, 货位存量, 盘点人编号, 盘点时间, 批次号)
                VALUES
                    (@物料流水号, @目标货位流水号, @调拨数量, @操作者, GETDATE(), @批次编号);

                SET @目标物料与货位流水号 = SCOPE_IDENTITY();
            END
            ELSE
            BEGIN
                UPDATE dbo.库存管理_物料与货位对照表
                SET
                    货位存量 = @调拨后目标库存,
                    盘点人编号 = @操作者,
                    盘点时间 = GETDATE()
                WHERE 物料与货位流水号 = @目标物料与货位流水号;
            END;

            SELECT @总库存 = SUM(ISNULL(货位存量, 0))
            FROM dbo.库存管理_物料与货位对照表
            WHERE 物料流水号 = @物料流水号;

            IF NOT EXISTS (
                SELECT 1
                FROM dbo.库存管理_外购件累计库存
                WHERE 物料流水号 = @物料流水号
            )
            BEGIN
                INSERT INTO dbo.库存管理_外购件累计库存
                    (物料流水号, 累计库存)
                VALUES
                    (@物料流水号, @总库存);
            END
            ELSE
            BEGIN
                UPDATE dbo.库存管理_外购件累计库存
                SET 累计库存 = @总库存
                WHERE 物料流水号 = @物料流水号;
            END;

            INSERT INTO dbo.库存盘点_修改记录
                (物料与货位流水号, 物料流水号, 原数量, 更改后数量, 修改人)
            VALUES
                (@物料与货位流水号, @物料流水号, @调拨前原库存, @调拨后原库存, @操作者);

            INSERT INTO dbo.库存盘点_调拨记录
                (类型, 物料流水号, 原物料与货位流水号, 原货位流水号, 目标物料与货位流水号, 目标货位流水号, 调拨数量, 调拨前原库存, 调拨后原库存, 调拨前目标库存, 调拨后目标库存, 调拨备注, 操作人, 操作时间)
            VALUES
                (@类型, @物料流水号, @物料与货位流水号, @原货位流水号, @目标物料与货位流水号, @目标货位流水号, @调拨数量, @调拨前原库存, @调拨后原库存, @调拨前目标库存, @调拨后目标库存, @调拨备注, @操作者, GETDATE());
        END;

        COMMIT TRANSACTION;

        SELECT
            '1' AS result,
            N'调拨成功' AS msg,
            @物料与货位流水号 AS 原物料与货位流水号,
            @目标物料与货位流水号 AS 目标物料与货位流水号,
            @调拨前原库存 AS 调拨前原库存,
            @调拨后原库存 AS 调拨后原库存,
            @调拨前目标库存 AS 调拨前目标库存,
            @调拨后目标库存 AS 调拨后目标库存;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;

        SET @错误 = ERROR_MESSAGE();

        SELECT
            '0' AS result,
            @错误 AS msg;
    END CATCH;
END
GO
