/*
  设计报工任务模块
  说明：
  1. 新建独立设计报工表和独立存储过程。
  2. 不写入现有生产报工表。
  3. 不上传 SAP。
  4. 不新增菜单权限，不写入菜单表和角色权限表。
*/

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

IF OBJECT_ID(N'[dbo].[MES_设计报工_任务]', N'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[MES_设计报工_任务]
    (
        [DID] int IDENTITY(1,1) NOT NULL PRIMARY KEY,
        [项目号] nvarchar(100) NULL,
        [物料编码] nvarchar(100) NULL,
        [物料名称] nvarchar(200) NULL,
        [图号] nvarchar(100) NULL,
        [任务描述] nvarchar(500) NULL,
        [关联父件物料编码] nvarchar(100) NULL,
        [关联父件物料名称] nvarchar(200) NULL,
        [设计要求] nvarchar(max) NULL,
        [研发立项号] nvarchar(100) NULL,
        [研发目的] nvarchar(500) NULL,
        [指派对象ID] nvarchar(1000) NULL,
        [指派对象] nvarchar(1000) NULL,
        [预计开始时间] datetime NULL,
        [预计结束时间] datetime NULL,
        [单据状态] nvarchar(50) NOT NULL CONSTRAINT [DF_MES_设计报工_任务_单据状态] DEFAULT (N'待开始'),
        [创建日期] datetime NOT NULL CONSTRAINT [DF_MES_设计报工_任务_创建日期] DEFAULT (GETDATE()),
        [创建人] nvarchar(100) NULL,
        [最后编辑人] nvarchar(100) NULL,
        [最后编辑时间] datetime NULL,
        [备注] nvarchar(500) NULL
    );
END
GO

IF OBJECT_ID(N'[dbo].[MES_设计报工_记录]', N'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[MES_设计报工_记录]
    (
        [RID] int IDENTITY(1,1) NOT NULL PRIMARY KEY,
        [DID] int NOT NULL,
        [操作人ID] nvarchar(100) NULL,
        [操作人] nvarchar(100) NULL,
        [开始时间] datetime NULL,
        [结束时间] datetime NULL,
        [工时秒数] int NULL,
        [报工状态] nvarchar(50) NOT NULL CONSTRAINT [DF_MES_设计报工_记录_报工状态] DEFAULT (N'执行中'),
        [已校验] bit NOT NULL CONSTRAINT [DF_MES_设计报工_记录_已校验] DEFAULT (0),
        [校验人ID] nvarchar(100) NULL,
        [校验人] nvarchar(100) NULL,
        [校验时间] datetime NULL,
        [创建时间] datetime NOT NULL CONSTRAINT [DF_MES_设计报工_记录_创建时间] DEFAULT (GETDATE()),
        [备注] nvarchar(500) NULL,
        CONSTRAINT [FK_MES_设计报工_记录_任务] FOREIGN KEY ([DID]) REFERENCES [dbo].[MES_设计报工_任务]([DID])
    );
END
GO

IF OBJECT_ID(N'[dbo].[MES_设计报工_校验记录]', N'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[MES_设计报工_校验记录]
    (
        [VID] int IDENTITY(1,1) NOT NULL PRIMARY KEY,
        [RID] int NOT NULL,
        [DID] int NOT NULL,
        [校验前开始时间] datetime NULL,
        [校验前结束时间] datetime NULL,
        [校验后开始时间] datetime NULL,
        [校验后结束时间] datetime NULL,
        [校验后工时秒数] int NULL,
        [校验人ID] nvarchar(100) NULL,
        [校验人] nvarchar(100) NULL,
        [校验时间] datetime NOT NULL CONSTRAINT [DF_MES_设计报工_校验记录_校验时间] DEFAULT (GETDATE()),
        [校验备注] nvarchar(500) NULL
    );
END
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_MES_设计报工_任务_查询' AND object_id = OBJECT_ID(N'[dbo].[MES_设计报工_任务]'))
    CREATE INDEX [IX_MES_设计报工_任务_查询] ON [dbo].[MES_设计报工_任务]([单据状态], [项目号], [物料编码], [预计开始时间], [预计结束时间]);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_MES_设计报工_记录_DID' AND object_id = OBJECT_ID(N'[dbo].[MES_设计报工_记录]'))
    CREATE INDEX [IX_MES_设计报工_记录_DID] ON [dbo].[MES_设计报工_记录]([DID], [开始时间], [结束时间], [已校验]);
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_物料查询]
    @过滤 nvarchar(200) = N''
AS
BEGIN
    SET NOCOUNT ON;

    SELECT TOP 100
        CAST([物料编码] AS nvarchar(100)) AS [物料编码],
        ISNULL(
            NULLIF(CAST([物料名称] AS nvarchar(200)), N''),
            CAST([物料描述] AS nvarchar(200))
        ) AS [物料名称],
        CAST([物料描述] AS nvarchar(500)) AS [物料描述],
        CAST([规格型号] AS nvarchar(200)) AS [规格型号],
        CAST([自制件属性] AS nvarchar(100)) AS [自制件属性]
    FROM [SAP].[SBO_YL].[dbo].[UBT_OITM]
    WHERE
        ISNULL(@过滤, N'') = N''
        OR CAST([物料编码] AS nvarchar(100)) LIKE N'%' + @过滤 + N'%'
        OR CAST([物料名称] AS nvarchar(200)) LIKE N'%' + @过滤 + N'%'
        OR CAST([物料描述] AS nvarchar(500)) LIKE N'%' + @过滤 + N'%'
    ORDER BY CAST([物料编码] AS nvarchar(100));
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_人员查询]
    @过滤 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @人员 table
    (
        [人员编号] int NULL,
        [人员姓名] nvarchar(100) NULL,
        [账号] nvarchar(100) NULL,
        [角色] nvarchar(100) NULL,
        [部门名称] nvarchar(100) NULL
    );

    INSERT INTO @人员
    EXEC [dbo].[系统管理_人员管理_所有有效人员查询];

    SELECT TOP 200
        CAST([人员编号] AS nvarchar(50)) AS [人员编号],
        [人员姓名],
        [账号],
        [角色],
        [部门名称]
    FROM @人员
    WHERE
        ISNULL(@过滤, N'') = N''
        OR CAST([人员编号] AS nvarchar(50)) LIKE N'%' + @过滤 + N'%'
        OR [人员姓名] LIKE N'%' + @过滤 + N'%'
        OR [账号] LIKE N'%' + @过滤 + N'%'
    ORDER BY [人员姓名];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_项目查询]
    @过滤 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT TOP 100
        [项目号]
    FROM [dbo].[MES_设计报工_任务]
    WHERE
        ISNULL([项目号], N'') <> N''
        AND (ISNULL(@过滤, N'') = N'' OR [项目号] LIKE N'%' + @过滤 + N'%')
    ORDER BY [项目号];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_查询]
    @DID int = NULL,
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @图号 nvarchar(100) = N'',
    @关联父件物料编码 nvarchar(100) = N'',
    @预计开始时间_Start nvarchar(30) = N'',
    @预计开始时间_End nvarchar(30) = N'',
    @预计结束时间_Start nvarchar(30) = N'',
    @预计结束时间_End nvarchar(30) = N'',
    @单据状态 nvarchar(50) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @预计开始日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_Start, N''));
    DECLARE @预计开始日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_End, N''));
    DECLARE @预计结束日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_Start, N''));
    DECLARE @预计结束日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_End, N''));

    SELECT TOP 1000
        t.[DID],
        t.[项目号],
        t.[物料编码],
        t.[物料名称],
        t.[图号],
        t.[任务描述],
        t.[关联父件物料编码],
        t.[关联父件物料名称],
        t.[设计要求],
        t.[研发立项号],
        t.[研发目的],
        t.[指派对象ID],
        t.[指派对象],
        CONVERT(varchar(19), t.[预计开始时间], 120) AS [预计开始时间],
        CONVERT(varchar(19), t.[预计结束时间], 120) AS [预计结束时间],
        t.[单据状态],
        CONVERT(varchar(19), t.[创建日期], 120) AS [创建日期],
        t.[创建人],
        t.[最后编辑人],
        CONVERT(varchar(19), t.[最后编辑时间], 120) AS [最后编辑时间],
        t.[备注],
        ISNULL(r.[报工次数], 0) AS [报工次数],
        ISNULL(r.[未结束报工数], 0) AS [未结束报工数],
        CONVERT(varchar(19), r.[最后开始时间], 120) AS [最后开始时间],
        CONVERT(varchar(19), r.[最后结束时间], 120) AS [最后结束时间]
    FROM [dbo].[MES_设计报工_任务] AS t
    OUTER APPLY
    (
        SELECT
            COUNT(1) AS [报工次数],
            SUM(CASE WHEN rr.[结束时间] IS NULL THEN 1 ELSE 0 END) AS [未结束报工数],
            MAX(rr.[开始时间]) AS [最后开始时间],
            MAX(rr.[结束时间]) AS [最后结束时间]
        FROM [dbo].[MES_设计报工_记录] AS rr
        WHERE rr.[DID] = t.[DID]
    ) AS r
    WHERE
        (@DID IS NULL OR @DID = 0 OR t.[DID] = @DID)
        AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%')
        AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%')
        AND (ISNULL(@图号, N'') = N'' OR t.[图号] LIKE N'%' + @图号 + N'%')
        AND (ISNULL(@关联父件物料编码, N'') = N'' OR t.[关联父件物料编码] LIKE N'%' + @关联父件物料编码 + N'%')
        AND (ISNULL(@单据状态, N'') = N'' OR @单据状态 = N'全部' OR t.[单据状态] = @单据状态)
        AND (@预计开始日期1 IS NULL OR t.[预计开始时间] >= @预计开始日期1)
        AND (@预计开始日期2 IS NULL OR t.[预计开始时间] < DATEADD(day, 1, @预计开始日期2))
        AND (@预计结束日期1 IS NULL OR t.[预计结束时间] >= @预计结束日期1)
        AND (@预计结束日期2 IS NULL OR t.[预计结束时间] < DATEADD(day, 1, @预计结束日期2))
    ORDER BY t.[DID] DESC;
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_新增]
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @物料名称 nvarchar(200) = N'',
    @图号 nvarchar(100) = N'',
    @任务描述 nvarchar(500) = N'',
    @关联父件物料编码 nvarchar(100) = N'',
    @关联父件物料名称 nvarchar(200) = N'',
    @设计要求 nvarchar(max) = N'',
    @研发立项号 nvarchar(100) = N'',
    @研发目的 nvarchar(500) = N'',
    @指派对象ID nvarchar(1000) = N'',
    @指派对象 nvarchar(1000) = N'',
    @预计开始时间 nvarchar(30) = N'',
    @预计结束时间 nvarchar(30) = N'',
    @创建人 nvarchar(100) = N'',
    @备注 nvarchar(500) = N''
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO [dbo].[MES_设计报工_任务]
    (
        [项目号], [物料编码], [物料名称], [图号], [任务描述],
        [关联父件物料编码], [关联父件物料名称], [设计要求],
        [研发立项号], [研发目的], [指派对象ID], [指派对象],
        [预计开始时间], [预计结束时间], [单据状态],
        [创建人], [最后编辑人], [最后编辑时间], [备注]
    )
    VALUES
    (
        NULLIF(@项目号, N''), NULLIF(@物料编码, N''), NULLIF(@物料名称, N''), NULLIF(@图号, N''), NULLIF(@任务描述, N''),
        NULLIF(@关联父件物料编码, N''), NULLIF(@关联父件物料名称, N''), NULLIF(@设计要求, N''),
        NULLIF(@研发立项号, N''), NULLIF(@研发目的, N''), NULLIF(@指派对象ID, N''), NULLIF(@指派对象, N''),
        TRY_CONVERT(datetime, NULLIF(@预计开始时间, N'')), TRY_CONVERT(datetime, NULLIF(@预计结束时间, N'')), N'待开始',
        NULLIF(@创建人, N''), NULLIF(@创建人, N''), GETDATE(), NULLIF(@备注, N'')
    );

    SELECT CAST(1 AS int) AS [result], N'新增成功' AS [message], SCOPE_IDENTITY() AS [DID];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_编辑]
    @DID int,
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @物料名称 nvarchar(200) = N'',
    @图号 nvarchar(100) = N'',
    @任务描述 nvarchar(500) = N'',
    @关联父件物料编码 nvarchar(100) = N'',
    @关联父件物料名称 nvarchar(200) = N'',
    @设计要求 nvarchar(max) = N'',
    @研发立项号 nvarchar(100) = N'',
    @研发目的 nvarchar(500) = N'',
    @指派对象ID nvarchar(1000) = N'',
    @指派对象 nvarchar(1000) = N'',
    @预计开始时间 nvarchar(30) = N'',
    @预计结束时间 nvarchar(30) = N'',
    @最后编辑人 nvarchar(100) = N'',
    @备注 nvarchar(500) = N''
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message];
        RETURN;
    END

    UPDATE [dbo].[MES_设计报工_任务]
    SET
        [项目号] = NULLIF(@项目号, N''),
        [物料编码] = NULLIF(@物料编码, N''),
        [物料名称] = NULLIF(@物料名称, N''),
        [图号] = NULLIF(@图号, N''),
        [任务描述] = NULLIF(@任务描述, N''),
        [关联父件物料编码] = NULLIF(@关联父件物料编码, N''),
        [关联父件物料名称] = NULLIF(@关联父件物料名称, N''),
        [设计要求] = NULLIF(@设计要求, N''),
        [研发立项号] = NULLIF(@研发立项号, N''),
        [研发目的] = NULLIF(@研发目的, N''),
        [指派对象ID] = NULLIF(@指派对象ID, N''),
        [指派对象] = NULLIF(@指派对象, N''),
        [预计开始时间] = TRY_CONVERT(datetime, NULLIF(@预计开始时间, N'')),
        [预计结束时间] = TRY_CONVERT(datetime, NULLIF(@预计结束时间, N'')),
        [最后编辑人] = NULLIF(@最后编辑人, N''),
        [最后编辑时间] = GETDATE(),
        [备注] = NULLIF(@备注, N'')
    WHERE [DID] = @DID;

    SELECT CAST(1 AS int) AS [result], N'编辑成功' AS [message];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_删除]
    @DID int
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'该任务已有设计报工记录，不能删除' AS [message];
        RETURN;
    END

    DELETE FROM [dbo].[MES_设计报工_任务]
    WHERE [DID] = @DID;

    SELECT CAST(1 AS int) AS [result], N'删除成功' AS [message];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_开始]
    @DID int,
    @操作人ID nvarchar(100) = N'',
    @操作人 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message];
        RETURN;
    END

    IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成')
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务已完成，不能开始' AS [message];
        RETURN;
    END

    IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'该任务存在未结束的报工记录' AS [message];
        RETURN;
    END

    INSERT INTO [dbo].[MES_设计报工_记录]([DID], [操作人ID], [操作人], [开始时间], [报工状态])
    VALUES(@DID, NULLIF(@操作人ID, N''), NULLIF(@操作人, N''), GETDATE(), N'执行中');

    UPDATE [dbo].[MES_设计报工_任务]
    SET [单据状态] = N'执行中', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE()
    WHERE [DID] = @DID;

    SELECT CAST(1 AS int) AS [result], N'开始成功' AS [message], SCOPE_IDENTITY() AS [RID];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_结束]
    @DID int,
    @操作人ID nvarchar(100) = N'',
    @操作人 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @RID int;
    SELECT TOP 1 @RID = [RID]
    FROM [dbo].[MES_设计报工_记录]
    WHERE [DID] = @DID AND [结束时间] IS NULL
    ORDER BY [开始时间] DESC, [RID] DESC;

    IF @RID IS NULL
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'没有未结束的报工记录' AS [message];
        RETURN;
    END

    UPDATE [dbo].[MES_设计报工_记录]
    SET
        [结束时间] = GETDATE(),
        [工时秒数] = DATEDIFF(second, [开始时间], GETDATE()),
        [报工状态] = N'已结束'
    WHERE [RID] = @RID;

    UPDATE [dbo].[MES_设计报工_任务]
    SET [单据状态] = N'已结束', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE()
    WHERE [DID] = @DID AND [单据状态] <> N'已完成';

    SELECT CAST(1 AS int) AS [result], N'结束成功' AS [message], @RID AS [RID];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_完成]
    @DID int,
    @操作人 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message];
        RETURN;
    END

    IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务存在未结束报工，不能完成' AS [message];
        RETURN;
    END

    IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NOT NULL)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'任务未产生已结束报工，不能完成' AS [message];
        RETURN;
    END

    UPDATE [dbo].[MES_设计报工_任务]
    SET [单据状态] = N'已完成', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE()
    WHERE [DID] = @DID;

    SELECT CAST(1 AS int) AS [result], N'完成成功' AS [message];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_记录_查询]
    @DID int = NULL,
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @操作人 nvarchar(100) = N'',
    @开始日期 nvarchar(30) = N'',
    @结束日期 nvarchar(30) = N'',
    @校验状态 nvarchar(50) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始日期, N''));
    DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束日期, N''));

    SELECT TOP 1000
        r.[RID],
        r.[DID],
        t.[项目号],
        t.[物料编码],
        t.[物料名称],
        t.[图号],
        t.[任务描述],
        t.[指派对象],
        r.[操作人ID],
        r.[操作人],
        CONVERT(varchar(19), r.[开始时间], 120) AS [开始时间],
        CONVERT(varchar(19), r.[结束时间], 120) AS [结束时间],
        r.[工时秒数],
        CAST(CAST(ISNULL(r.[工时秒数], 0) / 3600.0 AS decimal(18, 2)) AS varchar(30)) AS [工时小时],
        r.[报工状态],
        r.[已校验],
        CASE WHEN r.[已校验] = 1 THEN N'已校验' ELSE N'未校验' END AS [校验状态],
        r.[校验人],
        CONVERT(varchar(19), r.[校验时间], 120) AS [校验时间],
        r.[备注],
        t.[单据状态]
    FROM [dbo].[MES_设计报工_记录] AS r
    INNER JOIN [dbo].[MES_设计报工_任务] AS t ON r.[DID] = t.[DID]
    WHERE
        (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID)
        AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%')
        AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%')
        AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%')
        AND (@开始 IS NULL OR r.[开始时间] >= @开始)
        AND (@结束 IS NULL OR r.[开始时间] < DATEADD(day, 1, @结束))
        AND (
            ISNULL(@校验状态, N'') = N''
            OR @校验状态 = N'全部'
            OR (@校验状态 = N'已校验' AND r.[已校验] = 1)
            OR (@校验状态 = N'未校验' AND r.[已校验] = 0)
        )
    ORDER BY r.[RID] DESC;
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时校验_查询]
    @DID int = NULL,
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @操作人 nvarchar(100) = N'',
    @开始日期 nvarchar(30) = N'',
    @结束日期 nvarchar(30) = N'',
    @校验状态 nvarchar(50) = N'未校验'
AS
BEGIN
    SET NOCOUNT ON;

    EXEC [dbo].[设计报工_记录_查询]
        @DID = @DID,
        @项目号 = @项目号,
        @物料编码 = @物料编码,
        @操作人 = @操作人,
        @开始日期 = @开始日期,
        @结束日期 = @结束日期,
        @校验状态 = @校验状态;
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时校验_保存]
    @RID int,
    @开始时间 nvarchar(30),
    @结束时间 nvarchar(30),
    @校验人ID nvarchar(100) = N'',
    @校验人 nvarchar(100) = N'',
    @校验备注 nvarchar(500) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始时间, N''));
    DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束时间, N''));
    DECLARE @DID int;
    DECLARE @旧开始 datetime;
    DECLARE @旧结束 datetime;

    SELECT @DID = [DID], @旧开始 = [开始时间], @旧结束 = [结束时间]
    FROM [dbo].[MES_设计报工_记录]
    WHERE [RID] = @RID;

    IF @DID IS NULL
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'报工记录不存在' AS [message];
        RETURN;
    END

    IF @开始 IS NULL OR @结束 IS NULL OR @结束 <= @开始
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'开始时间和结束时间不合法' AS [message];
        RETURN;
    END

    INSERT INTO [dbo].[MES_设计报工_校验记录]
    (
        [RID], [DID], [校验前开始时间], [校验前结束时间],
        [校验后开始时间], [校验后结束时间], [校验后工时秒数],
        [校验人ID], [校验人], [校验时间], [校验备注]
    )
    VALUES
    (
        @RID, @DID, @旧开始, @旧结束,
        @开始, @结束, DATEDIFF(second, @开始, @结束),
        NULLIF(@校验人ID, N''), NULLIF(@校验人, N''), GETDATE(), NULLIF(@校验备注, N'')
    );

    UPDATE [dbo].[MES_设计报工_记录]
    SET
        [开始时间] = @开始,
        [结束时间] = @结束,
        [工时秒数] = DATEDIFF(second, @开始, @结束),
        [报工状态] = N'已结束',
        [已校验] = 1,
        [校验人ID] = NULLIF(@校验人ID, N''),
        [校验人] = NULLIF(@校验人, N''),
        [校验时间] = GETDATE(),
        [备注] = NULLIF(@校验备注, N'')
    WHERE [RID] = @RID;

    SELECT CAST(1 AS int) AS [result], N'校验成功' AS [message];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时校验_批量保存]
    @RIDs nvarchar(max),
    @校验人ID nvarchar(100) = N'',
    @校验人 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @RID表 table([RID] int PRIMARY KEY);
    DECLARE @xml xml;

    SET @xml = TRY_CONVERT(xml, N'<r><i>' + REPLACE(ISNULL(@RIDs, N''), N',', N'</i><i>') + N'</i></r>');

    INSERT INTO @RID表([RID])
    SELECT DISTINCT TRY_CONVERT(int, T.c.value(N'.', N'nvarchar(30)'))
    FROM @xml.nodes(N'/r/i') AS T(c)
    WHERE TRY_CONVERT(int, T.c.value(N'.', N'nvarchar(30)')) IS NOT NULL;

    IF NOT EXISTS (SELECT 1 FROM @RID表)
    BEGIN
        SELECT CAST(0 AS int) AS [result], N'没有可校验记录' AS [message];
        RETURN;
    END

    INSERT INTO [dbo].[MES_设计报工_校验记录]
    (
        [RID], [DID], [校验前开始时间], [校验前结束时间],
        [校验后开始时间], [校验后结束时间], [校验后工时秒数],
        [校验人ID], [校验人], [校验时间], [校验备注]
    )
    SELECT
        r.[RID], r.[DID], r.[开始时间], r.[结束时间],
        r.[开始时间], r.[结束时间], r.[工时秒数],
        NULLIF(@校验人ID, N''), NULLIF(@校验人, N''), GETDATE(), N'批量校验'
    FROM [dbo].[MES_设计报工_记录] AS r
    INNER JOIN @RID表 AS ids ON r.[RID] = ids.[RID]
    WHERE r.[开始时间] IS NOT NULL AND r.[结束时间] IS NOT NULL;

    UPDATE r
    SET
        [已校验] = 1,
        [校验人ID] = NULLIF(@校验人ID, N''),
        [校验人] = NULLIF(@校验人, N''),
        [校验时间] = GETDATE()
    FROM [dbo].[MES_设计报工_记录] AS r
    INNER JOIN @RID表 AS ids ON r.[RID] = ids.[RID]
    WHERE r.[开始时间] IS NOT NULL AND r.[结束时间] IS NOT NULL;

    SELECT CAST(1 AS int) AS [result], N'批量校验成功' AS [message], @@ROWCOUNT AS [count];
END
GO

CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时报表_作业者工时_查询]
    @开始日期 nvarchar(30) = N'',
    @结束日期 nvarchar(30) = N'',
    @操作人 nvarchar(100) = N'',
    @项目号 nvarchar(100) = N'',
    @物料编码 nvarchar(100) = N'',
    @DID int = NULL
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始日期, N''));
    DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束日期, N''));

    ;WITH base AS
    (
        SELECT
            r.[RID],
            r.[DID],
            ISNULL(r.[操作人], N'') AS [操作人],
            CONVERT(varchar(10), r.[开始时间], 120) AS [工作日期],
            t.[项目号],
            t.[物料编码],
            t.[物料名称],
            t.[图号],
            t.[任务描述],
            r.[开始时间],
            r.[结束时间],
            ISNULL(r.[工时秒数], 0) AS [工时秒数],
            r.[已校验],
            r.[备注]
        FROM [dbo].[MES_设计报工_记录] AS r
        INNER JOIN [dbo].[MES_设计报工_任务] AS t ON r.[DID] = t.[DID]
        WHERE
            r.[开始时间] IS NOT NULL
            AND r.[结束时间] IS NOT NULL
            AND (@开始 IS NULL OR r.[开始时间] >= @开始)
            AND (@结束 IS NULL OR r.[开始时间] < DATEADD(day, 1, @结束))
            AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%')
            AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%')
            AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%')
            AND (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID)
    ),
    result AS
    (
        SELECT
            1 AS [Level],
            N'p-' + [操作人] AS [id],
            CAST(N'' AS nvarchar(100)) AS [parentId],
            [操作人],
            CAST(N'' AS nvarchar(20)) AS [工作日期],
            CAST(NULL AS int) AS [RID],
            CAST(NULL AS int) AS [DID],
            CAST(N'' AS nvarchar(100)) AS [项目号],
            CAST(N'' AS nvarchar(100)) AS [物料编码],
            CAST(N'' AS nvarchar(200)) AS [物料名称],
            CAST(N'' AS nvarchar(100)) AS [图号],
            CAST(N'' AS nvarchar(500)) AS [任务描述],
            CAST(N'' AS varchar(19)) AS [开始时间],
            CAST(N'' AS varchar(19)) AS [结束时间],
            COUNT(1) AS [报工次数],
            CAST(SUM([工时秒数]) / 3600.0 AS decimal(18, 2)) AS [工时小时],
            CAST(N'' AS nvarchar(20)) AS [校验状态],
            CAST(N'' AS nvarchar(500)) AS [备注]
        FROM base
        GROUP BY [操作人]

        UNION ALL

        SELECT
            2 AS [Level],
            N'd-' + [操作人] + N'-' + [工作日期] AS [id],
            N'p-' + [操作人] AS [parentId],
            [操作人],
            [工作日期],
            CAST(NULL AS int) AS [RID],
            CAST(NULL AS int) AS [DID],
            CAST(N'' AS nvarchar(100)) AS [项目号],
            CAST(N'' AS nvarchar(100)) AS [物料编码],
            CAST(N'' AS nvarchar(200)) AS [物料名称],
            CAST(N'' AS nvarchar(100)) AS [图号],
            CAST(N'' AS nvarchar(500)) AS [任务描述],
            CAST(N'' AS varchar(19)) AS [开始时间],
            CAST(N'' AS varchar(19)) AS [结束时间],
            COUNT(1) AS [报工次数],
            CAST(SUM([工时秒数]) / 3600.0 AS decimal(18, 2)) AS [工时小时],
            CAST(N'' AS nvarchar(20)) AS [校验状态],
            CAST(N'' AS nvarchar(500)) AS [备注]
        FROM base
        GROUP BY [操作人], [工作日期]

        UNION ALL

        SELECT
            3 AS [Level],
            N'r-' + CAST([RID] AS nvarchar(20)) AS [id],
            N'd-' + [操作人] + N'-' + [工作日期] AS [parentId],
            [操作人],
            [工作日期],
            [RID],
            [DID],
            ISNULL([项目号], N'') AS [项目号],
            ISNULL([物料编码], N'') AS [物料编码],
            ISNULL([物料名称], N'') AS [物料名称],
            ISNULL([图号], N'') AS [图号],
            ISNULL([任务描述], N'') AS [任务描述],
            CONVERT(varchar(19), [开始时间], 120) AS [开始时间],
            CONVERT(varchar(19), [结束时间], 120) AS [结束时间],
            1 AS [报工次数],
            CAST([工时秒数] / 3600.0 AS decimal(18, 2)) AS [工时小时],
            CASE WHEN [已校验] = 1 THEN N'已校验' ELSE N'未校验' END AS [校验状态],
            ISNULL([备注], N'') AS [备注]
        FROM base
    )
    SELECT *
    FROM result
    ORDER BY [操作人], [工作日期], [Level], [RID];
END
GO
