USE [YL_MESDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[生产管理_工时查询_工序工时_查询]
    @合同号 NVARCHAR(50) = NULL,
    @产品编码 NVARCHAR(100) = NULL,
    @订单号 NVARCHAR(50) = NULL,
    @开始日期 DATE = NULL,
    @结束日期 DATE = NULL,
    @数据条数 INT = 100
AS
BEGIN
    SET NOCOUNT ON;

    ;WITH 基础数据 AS (
        SELECT TOP (CASE WHEN ISNULL(@数据条数, 0) <= 0 THEN 100 ELSE @数据条数 END)
            v.开始时间,
            v.结束时间,
            v.操作内容,
            v.操作类别,
            v.操作描述,
            v.加工工时,
            v.操作数值,
            v.订单号,
            v.订单行号,
            v.订单合同号,
            v.产品编码,
            v.产品名称,
            v.工序名称,
            v.TaskAID,
            v.工位名称,
            CASE
                WHEN ISNULL(v.操作内容, '') LIKE '%辅助%' OR ISNULL(v.操作类别, '') LIKE '%辅助%' THEN '调机'
                WHEN ISNULL(v.操作内容, '') LIKE '%报工%' OR ISNULL(v.操作类别, '') LIKE '%报工%' THEN '正常'
                ELSE ISNULL(NULLIF(v.操作内容, ''), v.操作类别)
            END AS 报工类型,
            p.标准工时 AS 工艺工时
        FROM [dbo].[View_生产工时视图] v
        LEFT JOIN [dbo].[车间生产管理工艺_零件生产工艺_工艺库] p
            ON v.订单号 = p.订单编号
           AND v.订单行号 = p.工艺顺序
        WHERE (@开始日期 IS NULL OR @开始日期 = '' OR v.开始时间 >= @开始日期)
          AND (@结束日期 IS NULL OR @结束日期 = '' OR v.开始时间 < DATEADD(DAY, 1, @结束日期))
          AND (@合同号 IS NULL OR @合同号 = '' OR v.订单合同号 LIKE '%' + @合同号 + '%')
          AND (@产品编码 IS NULL OR @产品编码 = '' OR v.产品编码 LIKE '%' + @产品编码 + '%')
          AND (@订单号 IS NULL OR @订单号 = '' OR v.订单号 = @订单号)
          AND (ISNULL(v.操作内容, '') IN ('报工', '辅助结束') OR ISNULL(v.操作类别, '') IN ('报工', '辅助结束'))
          AND ISNULL(v.加工工时, 0) > 0
        ORDER BY v.开始时间 DESC
    ),
    明细键 AS (
        SELECT DISTINCT
            TaskAID,
            CONVERT(VARCHAR(19), 开始时间, 120) AS 开始时间
        FROM 基础数据
    ),
    TaskStart报工数量 AS (
        SELECT
            TaskAID,
            CONVERT(VARCHAR(19), 开始时间, 120) AS 开始时间,
            MAX(CASE
                WHEN 操作类别 = '异常' THEN -ISNULL(操作数值, 0)
                ELSE ISNULL(操作数值, 0)
            END) AS 报工数量
        FROM [dbo].[View_生产工时视图全部]
        GROUP BY TaskAID, CONVERT(VARCHAR(19), 开始时间, 120)
    ),
    TaskStart扩展 AS (
        SELECT
            k.TaskAID,
            k.开始时间,
            CASE
                WHEN EXISTS (
                    SELECT 1
                    FROM [dbo].[View_生产工时视图全部] v
                    WHERE v.TaskAID = k.TaskAID
                      AND CONVERT(VARCHAR(19), v.开始时间, 120) = k.开始时间
                      AND ISNULL(v.操作描述, '') LIKE '%白班%'
                ) THEN '白班'
                WHEN EXISTS (
                    SELECT 1
                    FROM [dbo].[View_生产工时视图全部] v
                    WHERE v.TaskAID = k.TaskAID
                      AND CONVERT(VARCHAR(19), v.开始时间, 120) = k.开始时间
                      AND ISNULL(v.操作描述, '') LIKE '%夜班%'
                ) THEN '夜班'
                ELSE ''
            END AS 班次,
            (
                SELECT STRING_AGG(x.操作人, ',')
                FROM (
                    SELECT DISTINCT LTRIM(RTRIM(v2.操作人)) AS 操作人
                    FROM [dbo].[View_生产工时视图全部] v2
                    WHERE v2.TaskAID = k.TaskAID
                      AND CONVERT(VARCHAR(19), v2.开始时间, 120) = k.开始时间
                      AND ISNULL(v2.加工工时, 0) <= 0
                      AND NULLIF(LTRIM(RTRIM(ISNULL(v2.操作人, ''))), '') IS NOT NULL
                ) x
            ) AS 操作人
        FROM 明细键 k
    ),
    明细数据 AS (
        SELECT
            b.TaskAID,
            ISNULL(b.产品名称, '') + ' ' + ISNULL(b.产品编码, '') + ' ' + ISNULL(b.工序名称, '') + '  序' + CAST(ISNULL(b.订单行号, 0) AS VARCHAR(50)) AS 任务描述,
            CONVERT(VARCHAR(10), b.开始时间, 120) AS 工作日期,
            e.班次,
            e.操作人,
            b.订单号 AS 生产订单号,
            b.报工类型,
            qv.报工数量,
            b.工位名称 AS 工位名称,
            CAST(ISNULL(b.加工工时, 0) / 60.0 / 60.0 AS DECIMAL(10, 2)) AS 工时小时,
            CAST(ISNULL(b.加工工时, 0) / 60.0 AS DECIMAL(10, 2)) AS 工时分钟,
            '' AS 程序时间,
            CASE
                WHEN qv.报工数量 > 0 THEN CAST((ISNULL(b.加工工时, 0) / 60.0) / qv.报工数量 AS DECIMAL(10, 2))
                ELSE CAST(ISNULL(b.工艺工时, 0) AS DECIMAL(10, 2))
            END AS 单件工时,
            b.工艺工时,
            CONVERT(VARCHAR(19), b.开始时间, 120) AS 开始时间
        FROM 基础数据 b
        LEFT JOIN TaskStart报工数量 q
          ON q.TaskAID = b.TaskAID
         AND q.开始时间 = CONVERT(VARCHAR(19), b.开始时间, 120)
        LEFT JOIN TaskStart扩展 e
          ON e.TaskAID = b.TaskAID
         AND e.开始时间 = CONVERT(VARCHAR(19), b.开始时间, 120)
        CROSS APPLY (
            SELECT CASE
                WHEN ISNULL(b.工位名称, '') LIKE '%装配%' THEN 0
                ELSE ISNULL(q.报工数量, ISNULL(b.操作数值, 0))
            END AS 报工数量
        ) qv
    ),
    去重数量 AS (
        SELECT
            TaskAID,
            工作日期,
            开始时间,
            MAX(报工数量) AS 报工数量
        FROM 明细数据
        GROUP BY TaskAID, 工作日期, 开始时间
    ),
    Task数量汇总 AS (
        SELECT TaskAID, SUM(报工数量) AS 报工数量
        FROM 去重数量
        GROUP BY TaskAID
    ),
    日期数量汇总 AS (
        SELECT TaskAID, 工作日期, SUM(报工数量) AS 报工数量
        FROM 去重数量
        GROUP BY TaskAID, 工作日期
    ),
    Task汇总 AS (
        SELECT
            m.TaskAID,
            MAX(m.任务描述) AS 任务描述,
            COUNT(*) AS 报工次数,
            ISNULL(q.报工数量, 0) AS 报工数量,
            SUM(m.工时小时) AS 工时小时,
            SUM(m.工时分钟) AS 工时分钟,
            MAX(m.工艺工时) AS 工艺工时
        FROM 明细数据 m
        LEFT JOIN Task数量汇总 q ON q.TaskAID = m.TaskAID
        GROUP BY m.TaskAID, q.报工数量
    ),
    日期汇总 AS (
        SELECT
            m.TaskAID,
            MAX(m.任务描述) AS 任务描述,
            m.工作日期,
            COUNT(*) AS 报工次数,
            ISNULL(q.报工数量, 0) AS 报工数量,
            SUM(m.工时小时) AS 工时小时,
            SUM(m.工时分钟) AS 工时分钟,
            MAX(m.工艺工时) AS 工艺工时
        FROM 明细数据 m
        LEFT JOIN 日期数量汇总 q ON q.TaskAID = m.TaskAID AND q.工作日期 = m.工作日期
        GROUP BY m.TaskAID, m.工作日期, q.报工数量
    )
    SELECT
        1 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        '' AS dateLabel,
        '' AS shift,
        '' AS operatorNames,
        '' AS productionOrderNo,
        '' AS reportType,
        CAST(报工数量 AS VARCHAR(20)) AS reportQty,
        '' AS station,
        CAST(工时小时 AS VARCHAR(20)) AS workHours,
        CAST(工时小时 AS VARCHAR(20)) AS actualWorkHours,
        '' AS programTime,
        CAST(CASE WHEN 报工数量 > 0 THEN 工时分钟 / 报工数量 ELSE ISNULL(工艺工时, 0) END AS VARCHAR(20)) AS pieceWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,
        '' AS startTime,
        CAST(报工次数 AS VARCHAR(20)) AS reportCount
    FROM Task汇总

    UNION ALL

    SELECT
        2 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        工作日期 AS dateLabel,
        '' AS shift,
        '' AS operatorNames,
        '' AS productionOrderNo,
        '' AS reportType,
        CAST(报工数量 AS VARCHAR(20)) AS reportQty,
        '' AS station,
        CAST(工时小时 AS VARCHAR(20)) AS workHours,
        CAST(工时小时 AS VARCHAR(20)) AS actualWorkHours,
        '' AS programTime,
        CAST(CASE WHEN 报工数量 > 0 THEN 工时分钟 / 报工数量 ELSE ISNULL(工艺工时, 0) END AS VARCHAR(20)) AS pieceWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,
        '' AS startTime,
        CAST(报工次数 AS VARCHAR(20)) AS reportCount
    FROM 日期汇总

    UNION ALL

    SELECT
        3 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        工作日期 AS dateLabel,
        班次 AS shift,
        ISNULL(操作人, '') AS operatorNames,
        ISNULL(生产订单号, '') AS productionOrderNo,
        ISNULL(报工类型, '') AS reportType,
        CAST(报工数量 AS VARCHAR(20)) AS reportQty,
        ISNULL(工位名称, '') AS station,
        CAST(工时小时 AS VARCHAR(20)) AS workHours,
        CAST(工时小时 AS VARCHAR(20)) AS actualWorkHours,
        程序时间 AS programTime,
        CAST(单件工时 AS VARCHAR(20)) AS pieceWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,
        开始时间 AS startTime,
        '' AS reportCount
    FROM 明细数据

    ORDER BY TaskAID, dateLabel, [Level], startTime
END
GO
