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

    -- 获取班次信息
    DECLARE @白班开始时间 TIME = '07:45:00'
    DECLARE @白班结束时间 TIME = '16:30:00'
    DECLARE @夜班开始时间 TIME = '16:30:00'
    DECLARE @夜班结束时间 TIME = '00:40:00'
    
    ;WITH 基础数据 AS (
        SELECT top (@数据条数)
            v.开始时间,
            v.结束时间,
            v.操作内容,
            v.加工工时,
            v.操作数值,
            v.订单号,
            v.订单行号,
            v.订单合同号,
            v.产品编码,
            v.产品名称,
            v.工序名称,
            v.TaskAID,
            v.工位名称,
            -- 根据时间判断班次
            CASE 
                WHEN CAST(v.开始时间 AS TIME) >= @白班开始时间 
                     AND CAST(v.开始时间 AS TIME) < @白班结束时间 THEN '白班'
                WHEN CAST(v.开始时间 AS TIME) >= @夜班开始时间 
                     OR CAST(v.开始时间 AS TIME) < @夜班结束时间 THEN '夜班'
                ELSE '其他'
            END AS 计算班次,
            -- 标记实际工时和辅助工时
            CASE WHEN v.操作内容 = '报工' THEN v.加工工时 ELSE 0 END AS 实际加工工时,
            CASE WHEN v.操作内容 = '辅助结束' THEN v.加工工时 ELSE 0 END AS 辅助加工工时,
            -- 标记报工数量和辅助数量
            CASE WHEN v.操作内容 = '报工' THEN v.操作数值 ELSE 0 END AS 实际报工数量,
            CASE WHEN v.操作内容 = '辅助结束' THEN v.操作数值 ELSE 0 END AS 辅助报工数量,
            -- 关联工艺库获取标准工时（工艺工时）
            p.标准工时 AS 工艺工时
        FROM View_生产工时视图 v
        LEFT JOIN 车间生产管理工艺_零件生产工艺_工艺库 p 
            ON v.订单号 = p.订单编号 
            AND v.订单行号 = p.工艺顺序
        WHERE (@开始日期 IS NULL OR @开始日期 = '' OR v.开始时间 >= @开始日期)
		  AND (@结束日期 IS NULL OR @结束日期 = '' OR v.结束时间 >= @结束日期)
          AND (@合同号 IS NULL OR @合同号 = '' OR v.订单合同号 LIKE '%' + @合同号 + '%')
          AND (@产品编码 IS NULL OR @产品编码 = '' OR v.产品编码 LIKE '%' + @产品编码 + '%')
          AND (@订单号 IS NULL OR @订单号 = '' OR v.订单号 = @订单号)
          -- 去掉报工时间为0的数据（实际加工工时或辅助加工工时不为0）
          AND (CASE WHEN v.操作内容 = '报工' THEN v.加工工时 ELSE 0 END > 0 
               OR CASE WHEN v.操作内容 = '辅助结束' THEN v.加工工时 ELSE 0 END > 0)
    ),
    -- 获取每个TaskAID对应的任务描述（取第一条记录）
    Task描述 AS (
        SELECT DISTINCT
            TaskAID,
            -- 任务描述：产品名称 + 产品编码 + 工序名称
            ISNULL(产品名称, '') + ' ' + ISNULL(产品编码, '') + ' ' + ISNULL(工序名称, '') + '  序'+ CAST(订单行号 AS VARCHAR(50)) AS 任务描述
        FROM 基础数据
    ),
    -- 第一层：按TaskAID汇总
    TaskAID汇总 AS (
        SELECT 
            b.TaskAID,
            t.任务描述,
            '' AS 工作日期,
            '' AS 班次,
            COUNT(*) AS 报工次数,
            SUM(实际报工数量) AS 实际报工数量,
            SUM(辅助报工数量) AS 辅助报工数量,
            CAST(SUM(实际加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 实际工时小时,
            CAST(SUM(辅助加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 辅助工时小时,
            -- 计算平均实际工时（实际加工工时/实际报工数量）
            CASE 
                WHEN SUM(实际报工数量) > 0 
                THEN CAST((SUM(实际加工工时) / 60.0 / 60.0) / SUM(实际报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均实际工时,
            -- 计算平均辅助工时（辅助加工工时/辅助报工数量）
            CASE 
                WHEN SUM(辅助报工数量) > 0 
                THEN CAST((SUM(辅助加工工时) / 60.0 / 60.0) / SUM(辅助报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均辅助工时,
            -- 工艺工时（取第一条记录的工艺工时）
            MAX(b.工艺工时) AS 工艺工时
        FROM 基础数据 b
        LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
        GROUP BY b.TaskAID, t.任务描述
    ),
    -- 第二层：按TaskAID和日期汇总
    日期汇总 AS (
        SELECT 
            b.TaskAID,
            t.任务描述,
            CONVERT(VARCHAR(10), b.开始时间, 120) AS 工作日期,
            '' AS 班次,
            COUNT(*) AS 报工次数,
            SUM(实际报工数量) AS 实际报工数量,
            SUM(辅助报工数量) AS 辅助报工数量,
            CAST(SUM(实际加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 实际工时小时,
            CAST(SUM(辅助加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 辅助工时小时,
            -- 计算平均实际工时（实际加工工时/实际报工数量）
            CASE 
                WHEN SUM(实际报工数量) > 0 
                THEN CAST((SUM(实际加工工时) / 60.0 / 60.0) / SUM(实际报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均实际工时,
            -- 计算平均辅助工时（辅助加工工时/辅助报工数量）
            CASE 
                WHEN SUM(辅助报工数量) > 0 
                THEN CAST((SUM(辅助加工工时) / 60.0 / 60.0) / SUM(辅助报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均辅助工时,
            -- 工艺工时（取该日期第一条记录的工艺工时）
            MAX(b.工艺工时) AS 工艺工时
        FROM 基础数据 b
        LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
        GROUP BY b.TaskAID, t.任务描述, CONVERT(VARCHAR(10), b.开始时间, 120)
    ),
    -- 第三层：按TaskAID、日期和班次汇总
    班次汇总 AS (
        SELECT 
            b.TaskAID,
            t.任务描述,
            CONVERT(VARCHAR(10), b.开始时间, 120) AS 工作日期,
            b.计算班次,
            b.工位名称,
            COUNT(*) AS 报工次数,
            SUM(实际报工数量) AS 实际报工数量,
            SUM(辅助报工数量) AS 辅助报工数量,
            CAST(SUM(实际加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 实际工时小时,
            CAST(SUM(辅助加工工时) / 60.0 / 60.0 AS DECIMAL(10,1)) AS 辅助工时小时,
            -- 计算平均实际工时（实际加工工时/实际报工数量）
            CASE 
                WHEN SUM(实际报工数量) > 0 
                THEN CAST((SUM(实际加工工时) / 60.0 / 60.0) / SUM(实际报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均实际工时,
            -- 计算平均辅助工时（辅助加工工时/辅助报工数量）
            CASE 
                WHEN SUM(辅助报工数量) > 0 
                THEN CAST((SUM(辅助加工工时) / 60.0 / 60.0) / SUM(辅助报工数量) AS DECIMAL(10,2))
                ELSE 0 
            END AS 平均辅助工时,
            -- 工艺工时（取该班次第一条记录的工艺工时）
            MAX(b.工艺工时) AS 工艺工时
        FROM 基础数据 b
        LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
        GROUP BY b.TaskAID, t.任务描述, CONVERT(VARCHAR(10), b.开始时间, 120), b.计算班次, b.工位名称
    )
    
    -- 第一层：TaskAID汇总
    SELECT 
        1 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        '' AS dateLabel,
        '' AS shift,
		'' AS 工位名称,
        CAST(实际报工数量 AS VARCHAR(20)) AS reportQty,
        CAST(实际工时小时 AS VARCHAR(20)) AS actualWorkHours,
        CAST(辅助工时小时 AS VARCHAR(20)) AS auxiliaryWorkHours,
        CAST(平均实际工时 AS VARCHAR(20)) AS avgActualWorkHours,
        CAST(平均辅助工时 AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,  -- 工艺工时
        '' AS contractNo,
        '' AS orderNo,
        '' AS productCode,
        '' AS productName,
        '' AS processName,
        CAST(报工次数 AS VARCHAR(20)) AS reportCount
    FROM TaskAID汇总
    WHERE 实际工时小时 > 0 OR 辅助工时小时 > 0

    UNION ALL

    -- 第二层：日期汇总
    SELECT 
        2 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        工作日期 AS dateLabel,
        '' AS shift,
		'' AS 工位名称,
        CAST(实际报工数量 AS VARCHAR(20)) AS reportQty,
        CAST(实际工时小时 AS VARCHAR(20)) AS actualWorkHours,
        CAST(辅助工时小时 AS VARCHAR(20)) AS auxiliaryWorkHours,
        CAST(平均实际工时 AS VARCHAR(20)) AS avgActualWorkHours,
        CAST(平均辅助工时 AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,  -- 工艺工时
        '' AS contractNo,
        '' AS orderNo,
        '' AS productCode,
        '' AS productName,
        '' AS processName,
        CAST(报工次数 AS VARCHAR(20)) AS reportCount
    FROM 日期汇总
    WHERE 实际工时小时 > 0 OR 辅助工时小时 > 0

    UNION ALL

    -- 第三层：班次汇总
    SELECT 
        3 AS [Level],
        TaskAID,
        任务描述 AS taskDescription,
        工作日期 AS dateLabel,
        计算班次 AS shift,
		工位名称 AS 工位名称,
        CAST(实际报工数量 AS VARCHAR(20)) AS reportQty,
        CAST(实际工时小时 AS VARCHAR(20)) AS actualWorkHours,
        CAST(辅助工时小时 AS VARCHAR(20)) AS auxiliaryWorkHours,
        CAST(平均实际工时 AS VARCHAR(20)) AS avgActualWorkHours,
        CAST(平均辅助工时 AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
        CAST(ISNULL(工艺工时, 0) AS VARCHAR(20)) AS processWorkHours,  -- 工艺工时
        '' AS contractNo,
        '' AS orderNo,
        '' AS productCode,
        '' AS productName,
        '' AS processName,
        CAST(报工次数 AS VARCHAR(20)) AS reportCount
    FROM 班次汇总
    WHERE 实际工时小时 > 0 OR 辅助工时小时 > 0

    ORDER BY TaskAID, dateLabel, shift, [Level]
END

