USE [YL_MESDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

IF OBJECT_ID(N'[dbo].[生产管理_结算工时_查询]', N'P') IS NULL
    EXEC(N'CREATE PROCEDURE [dbo].[生产管理_结算工时_查询] AS BEGIN SET NOCOUNT ON; END')
GO

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

    ;WITH 结算任务 AS (
        SELECT
            AID,
            订单编号,
            物料编号,
            物料描述
        FROM [dbo].[MES_接口_生产计划]
        WHERE 单据状态 IS NULL
    ),
    基础数据 AS (
        SELECT TOP (CASE WHEN ISNULL(@数据条数, 0) <= 0 THEN 100 ELSE @数据条数 END)
            v.TaskAID,
            v.开始时间,
            v.操作内容,
            v.操作类别,
            v.操作人,
            v.加工工时,
            v.操作数值,
            v.订单合同号,
            v.订单号,
            v.订单行号,
            v.产品编码,
            v.产品名称,
            v.工序名称,
            v.工位名称,
            p.物料编号,
            p.物料描述
        FROM [dbo].[View_生产工时视图] v
        INNER JOIN 结算任务 p ON p.AID = v.TaskAID
        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 (@工位 IS NULL OR @工位 = '' OR v.工位名称 LIKE '%' + @工位 + '%')
          AND ISNULL(v.加工工时, 0) > 0
          AND (ISNULL(v.操作内容, '') IN ('报工', '辅助结束') OR ISNULL(v.操作类别, '') IN ('报工', '辅助结束'))
        ORDER BY v.开始时间 DESC
    ),
    明细键 AS (
        SELECT DISTINCT
            TaskAID,
            CONVERT(VARCHAR(19), 开始时间, 120) AS 开始时间
        FROM 基础数据
    ),
    操作人明细 AS (
        SELECT
            k.TaskAID,
            k.开始时间,
            LTRIM(RTRIM(s.value)) AS 操作人
        FROM 明细键 k
        INNER JOIN [dbo].[View_生产工时视图全部] v2
          ON v2.TaskAID = k.TaskAID
         AND v2.开始时间 >= CONVERT(DATETIME, k.开始时间, 120)
         AND v2.开始时间 < DATEADD(SECOND, 1, CONVERT(DATETIME, k.开始时间, 120))
        CROSS APPLY STRING_SPLIT(REPLACE(REPLACE(ISNULL(v2.操作人, ''), N'，', ','), N'、', ','), ',') s
        WHERE ISNULL(v2.加工工时, 0) <= 0
          AND NULLIF(LTRIM(RTRIM(s.value)), '') IS NOT NULL
    ),
    操作人拼接 AS (
        SELECT
            TaskAID,
            开始时间,
            STRING_AGG(操作人, ',') AS 操作人
        FROM (
            SELECT DISTINCT TaskAID, 开始时间, 操作人
            FROM 操作人明细
        ) x
        GROUP BY TaskAID, 开始时间
    ),
    结算明细 AS (
        SELECT
            ISNULL(b.物料编号, b.产品编码) AS 物料编号,
            ISNULL(b.物料描述, b.产品名称) AS 物料描述,
            b.订单号,
            b.工位名称,
            b.TaskAID,
            b.工序名称,
            b.订单行号,
            ISNULL(o.操作人, '') AS 操作人,
            CASE
                WHEN ISNULL(b.操作内容, '') LIKE '%辅助%' OR ISNULL(b.操作类别, '') LIKE '%辅助%' THEN '辅助结束'
                ELSE '报工'
            END AS 操作类型,
            CAST(ISNULL(b.加工工时, 0) / 60.0 / 60.0 AS DECIMAL(18, 4)) AS 工时小时,
            ISNULL(b.操作数值, 0) AS 完成数
        FROM 基础数据 b
        LEFT JOIN 操作人拼接 o
          ON o.TaskAID = b.TaskAID
         AND o.开始时间 = CONVERT(VARCHAR(19), b.开始时间, 120)
    ),
    订单工位汇总基础 AS (
        SELECT
            物料编号,
            物料描述,
            订单号,
            工位名称,
            MAX(工序名称) AS 工序名称,
            MAX(订单行号) AS 工序顺序,
            COUNT(*) AS 记录数,
            SUM(CASE WHEN 操作类型 = '报工' THEN 工时小时 ELSE 0 END) AS 报工工时,
            SUM(CASE WHEN 操作类型 = '辅助结束' THEN 工时小时 ELSE 0 END) AS 主辅工时,
            SUM(CASE WHEN 操作类型 = '报工' THEN 完成数 ELSE 0 END) AS 报工完成数,
            SUM(CASE WHEN 操作类型 = '辅助结束' THEN 完成数 ELSE 0 END) AS 辅助完成数,
            SUM(工时小时) AS 合计工时
        FROM 结算明细 j
        GROUP BY 物料编号, 物料描述, 订单号, 工位名称
    ),
    订单工位操作人 AS (
        SELECT
            物料编号,
            订单号,
            ISNULL(工位名称, '') AS 工位名称,
            STRING_AGG(操作人, ',') AS 操作人
        FROM (
            SELECT DISTINCT
                j.物料编号,
                j.订单号,
                ISNULL(j.工位名称, '') AS 工位名称,
                LTRIM(RTRIM(s.value)) AS 操作人
            FROM 结算明细 j
            CROSS APPLY STRING_SPLIT(REPLACE(REPLACE(ISNULL(j.操作人, ''), N'，', ','), N'、', ','), ',') s
            WHERE NULLIF(LTRIM(RTRIM(s.value)), '') IS NOT NULL
        ) x
        GROUP BY 物料编号, 订单号, ISNULL(工位名称, '')
    ),
    订单工位汇总 AS (
        SELECT
            b.物料编号,
            b.物料描述,
            b.订单号,
            b.工位名称,
            b.工序名称,
            b.工序顺序,
            b.记录数,
            b.报工工时,
            b.主辅工时,
            b.报工完成数,
            b.辅助完成数,
            b.合计工时,
            ISNULL(o.操作人, '') AS 操作人
        FROM 订单工位汇总基础 b
        LEFT JOIN 订单工位操作人 o
          ON o.物料编号 = b.物料编号
         AND o.订单号 = b.订单号
         AND o.工位名称 = ISNULL(b.工位名称, '')
    ),
    物料汇总 AS (
        SELECT
            物料编号,
            物料描述,
            SUM(记录数) AS 记录数,
            SUM(报工工时) AS 报工工时,
            SUM(主辅工时) AS 主辅工时,
            SUM(报工完成数) AS 报工完成数,
            SUM(辅助完成数) AS 辅助完成数,
            SUM(合计工时) AS 合计工时
        FROM 订单工位汇总
        GROUP BY 物料编号, 物料描述
    )
    SELECT
        1 AS [Level],
        物料编号 AS materialCode,
        物料描述 AS materialDesc,
        ISNULL(物料描述, '') + ' ' + ISNULL(物料编号, '') AS taskDescription,
        '' AS productionOrderNo,
        '' AS station,
        CAST(报工工时 AS VARCHAR(20)) AS reportWorkHours,
        CAST(主辅工时 AS VARCHAR(20)) AS auxiliaryWorkHours,
        CAST(报工完成数 AS VARCHAR(20)) AS reportFinishQty,
        CAST(辅助完成数 AS VARCHAR(20)) AS auxiliaryFinishQty,
        CAST(合计工时 AS VARCHAR(20)) AS totalWorkHours,
        CAST(CASE WHEN 报工完成数 > 0 THEN (报工工时 - 0 * 报工完成数) / 报工完成数 ELSE 0 END AS VARCHAR(20)) AS clampingTime,
        CAST(0 AS VARCHAR(20)) AS programTime,
        CAST(CASE WHEN 报工完成数 > 0 THEN 报工工时 / 报工完成数 ELSE 0 END AS VARCHAR(20)) AS settlementReportPieceHours,
        CAST(CASE WHEN 辅助完成数 > 0 THEN 主辅工时 / 辅助完成数 ELSE 0 END AS VARCHAR(20)) AS settlementAuxiliaryPieceHours,
        '' AS operatorNames,
        CAST(记录数 AS VARCHAR(20)) AS recordCount
    FROM 物料汇总

    UNION ALL

    SELECT
        2 AS [Level],
        物料编号 AS materialCode,
        物料描述 AS materialDesc,
        ISNULL(物料描述, '') + ' ' + ISNULL(物料编号, '')
            + CASE WHEN NULLIF(ISNULL(工序名称, ''), '') IS NULL THEN '' ELSE ' ' + 工序名称 END
            + CASE WHEN 工序顺序 IS NULL THEN '' ELSE ' 序' + CAST(工序顺序 AS VARCHAR(20)) END AS taskDescription,
        ISNULL(订单号, '') AS productionOrderNo,
        ISNULL(工位名称, '') AS station,
        CAST(报工工时 AS VARCHAR(20)) AS reportWorkHours,
        CAST(主辅工时 AS VARCHAR(20)) AS auxiliaryWorkHours,
        CAST(报工完成数 AS VARCHAR(20)) AS reportFinishQty,
        CAST(辅助完成数 AS VARCHAR(20)) AS auxiliaryFinishQty,
        CAST(合计工时 AS VARCHAR(20)) AS totalWorkHours,
        CAST(CASE WHEN 报工完成数 > 0 THEN (报工工时 - 0 * 报工完成数) / 报工完成数 ELSE 0 END AS VARCHAR(20)) AS clampingTime,
        CAST(0 AS VARCHAR(20)) AS programTime,
        CAST(CASE WHEN 报工完成数 > 0 THEN 报工工时 / 报工完成数 ELSE 0 END AS VARCHAR(20)) AS settlementReportPieceHours,
        CAST(CASE WHEN 辅助完成数 > 0 THEN 主辅工时 / 辅助完成数 ELSE 0 END AS VARCHAR(20)) AS settlementAuxiliaryPieceHours,
        ISNULL(操作人, '') AS operatorNames,
        CAST(记录数 AS VARCHAR(20)) AS recordCount
    FROM 订单工位汇总

    ORDER BY materialCode, [Level], productionOrderNo, station
END
GO
