USE [YL_MESDB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

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

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询]
    @订单号 int = 0,
    @物料类型 nvarchar(50) = N'',
    @合同号 nvarchar(50) = N'',
    @产品编码 nvarchar(50) = N'',
    @产品名称 nvarchar(50) = N'',
    @工序名称 nvarchar(50) = N'',
    @计划开始 nvarchar(50) = N'',
    @计划完成 nvarchar(50) = N'',
    @排产状态 nvarchar(50) = N'全部',
    @指派对象 nvarchar(50) = N'全部',
    @计划号 nvarchar(50) = N'',
    @发货状态 nvarchar(50) = N'全部',
    @齐套 nvarchar(50) = N'全部',
    @检验状态 nvarchar(50) = N'',
    @发料状态 nvarchar(50) = N'全部',
    @自制件属性 nvarchar(50) = N'全部'
AS
BEGIN
    SET NOCOUNT ON;

    ;WITH SAP缺件源 AS (
        SELECT
            s.DocEntry,
            s.Project COLLATE DATABASE_DEFAULT AS Project,
            s.[行号],
            s.ItemCode COLLATE DATABASE_DEFAULT AS ItemCode,
            s.U_Name COLLATE DATABASE_DEFAULT AS U_Name,
            ISNULL(s.[属性] COLLATE DATABASE_DEFAULT, N'') AS 属性,
            ISNULL(s.[未发货数量], 0) AS 未发货数量,
            ISNULL(s.[库存量], 0) AS 库存数量,
            ISNULL(s.[在制采购], 0) AS 在制采购,
            ISNULL(s.DocNum, 0) AS DocNum,
            s.[采购员] COLLATE DATABASE_DEFAULT AS 采购员,
            s.[采购预计交货日期],
            ISNULL(s.[采购未清数量], 0) AS 采购未清数量,
            ISNULL(s.[到货草稿], 0) AS 到货草稿
        FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc] AS s
        WHERE ISNULL(s.[未发货数量], 0) > 0
    ),
    SAP缺件 AS (
        SELECT TOP (2000)
            src.*
        FROM (
            SELECT
                SAP缺件源.*,
                ROW_NUMBER() OVER (
                    PARTITION BY
                        SAP缺件源.DocEntry,
                        SAP缺件源.Project,
                        SAP缺件源.ItemCode,
                        SAP缺件源.属性
                    ORDER BY
                        SAP缺件源.[未发货数量] DESC,
                        SAP缺件源.[行号]
                ) AS rn
            FROM SAP缺件源
        ) AS src
        WHERE src.rn = 1
    ),
    查询结果 AS (
    SELECT
        ISNULL(v.[计划号], N'') AS [计划号],
        ISNULL(v.[合同号], N'') AS [合同号],
        v.[订单编号] AS [订单号],
        v.[物料编号] AS [产品编码],
        v.[物料描述] AS [产品名称],
        v.[计划数量订单],
        v.[入库数量],
        v.[计划完成] AS [要求完工日期],
        v.[要求发货日期],
        CASE
            WHEN ISNULL(v.[发货状态], 0) = 1 THEN N'已发货'
            ELSE N'未发货'
        END AS [发货状态],
        CASE
            WHEN ISNULL(v.[齐套], 0) = 1 THEN N'是'
            ELSE N'否'
        END AS [齐套],
        CASE
            WHEN ISNULL(v.[拣配状态], 0) = 1 THEN N'已拣配'
            ELSE N'未拣配'
        END AS [拣配状态],
        CASE
            WHEN ISNULL(v.[发料状态], N'') = N'1' THEN N'发料齐套'
            WHEN ISNULL(v.[发料状态], N'') = N'2' THEN N'发料缺件'
            ELSE N'未发料'
        END AS [发料状态],
        CASE
            WHEN ISNULL(v.[任务状态], 0) IN (2, 4) OR v.[开工时间] > '1900-01-01' THEN N'已开工'
            ELSE N'待执行'
        END AS [装配开工],
        v.[完成数量],
        CASE
            WHEN final_check.[计划号] IS NOT NULL THEN N'是'
            ELSE N'否'
        END AS [终检],
        CASE WHEN ISNULL(v.[生产工艺], 0) = 1 THEN N'是' ELSE N'否' END AS [生产工艺],
        CASE WHEN ISNULL(v.[排产状态], 0) = 1 THEN N'已排产' ELSE N'未排产' END AS [排产状态],
        ISNULL(v.[自制件属性], N'') AS [自制件属性],
        v.[计划开始时间] AS [预计齐套时间],
        sap.ItemCode AS [缺件物料编码],
        sap.U_Name AS [缺件物料名称],
        sap.[未发货数量] AS [缺件数量],
        sap.[库存数量] AS [库存数量],
        CASE WHEN sap.[属性] = N'' THEN N'外购' ELSE sap.[属性] END AS [缺件属性],
        CASE
            WHEN sap.[属性] = N'' THEN ISNULL(CONVERT(nvarchar(50), NULLIF(sap.[在制采购], 0)), N'')
            ELSE ISNULL(CONVERT(nvarchar(50), detail_order.[订单编号]), N'')
        END AS [缺件生产订单号],
        CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(current_step.[当前序], N'') END AS [进度],
        CASE
            WHEN sap.[属性] = N'' THEN
                N'采购员:' + ISNULL(NULLIF(sap.[采购员], N''), N'-') +
                N' / 未清数量:' + CONVERT(nvarchar(30), sap.[采购未清数量]) +
                N' / 到货草稿:' + CONVERT(nvarchar(30), sap.[到货草稿]) +
                N' / 质检状态:' + ISNULL(purchase_check.[质检状态], N'未完成')
            ELSE ISNULL(route.[工艺路线], N'')
        END AS [工艺路线],
        CASE
            WHEN sap.[属性] = N'' THEN sap.[采购预计交货日期]
            ELSE route.[预计完成时间]
        END AS [预计完成时间],
        CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(route.[工艺路线明细], N'[]') END AS [工艺路线明细],
        sap.[采购未清数量],
        sap.[到货草稿],
        ISNULL(purchase_check.[质检状态], CASE WHEN sap.[属性] = N'' THEN N'未完成' ELSE N'' END) AS [质检状态],
        sap.DocEntry AS [SAP单据],
        sap.[行号] AS [SAP行号]
    FROM SAP缺件 AS sap
    OUTER APPLY (
        SELECT TOP (1) m.*
        FROM [dbo].[View_生产订单_MES] AS m
        WHERE m.[物料类型] = N'pit_Resource'
          AND ISNULL(m.[排产状态], 0) = 1
          AND m.[订单编号] = sap.DocEntry
        ORDER BY m.[订单行号]
    ) AS v
    OUTER APPLY (
        SELECT m.*
        FROM (
            SELECT
                m.*,
                ROW_NUMBER() OVER (
                    PARTITION BY m.[订单编号]
                    ORDER BY m.[订单行号]
                ) AS rn
            FROM [dbo].[View_生产订单_MES] AS m
            WHERE m.[物料类型] = N'pit_Resource'
              AND ISNULL(m.[排产状态], 0) = 1
              AND m.[订单编号] <> v.[订单编号]
              AND (
                  (sap.[属性] = N'机加件' AND (
                      m.[物料编号] = sap.ItemCode
                      OR (sap.DocNum > 0 AND m.[订单编号] = sap.DocNum)
                  ))
                  OR (sap.[属性] LIKE N'%装配%' AND m.[物料编号] = sap.ItemCode AND ISNULL(m.[合同号], N'') = ISNULL(sap.Project, N''))
              )
        ) AS m
        WHERE m.rn = 1
    ) AS detail_order
    OUTER APPLY (
        SELECT TOP (1) q.[计划号]
        FROM [dbo].[YL_质量检验_质检记录] AS q
        WHERE q.[质检类型] = N'终检'
          AND q.[计划号] = v.[订单编号]
    ) AS final_check
    OUTER APPLY (
        SELECT
            MAX(p.[计划完成时间]) AS [预计完成时间],
            STUFF((
                SELECT N'、' + p2.[工序名称] +
                    CASE WHEN ISNULL(p2.[指派对象], N'') = N'' THEN N'' ELSE N'(' + p2.[指派对象] + N')' END
                FROM [dbo].[View_生产订单_MES] AS p2
                WHERE p2.[订单编号] = detail_order.[订单编号]
                  AND p2.[物料类型] = N'pit_Resource'
                ORDER BY p2.[订单行号]
                FOR XML PATH(N''), TYPE
            ).value(N'.', N'nvarchar(max)'), 1, 1, N'') AS [工艺路线],
            (
                SELECT
                    p2.[订单行号],
                    p2.[工序名称],
                    p2.[指派对象],
                    p2.[计划开始时间],
                    p2.[计划完成时间],
                    ISNULL(p2.[进度], 0) AS [进度],
                    ISNULL(p2.[完成数量], 0) AS [完成数量],
                    ISNULL(p2.[收料数量], 0) AS [收料数量],
                    ISNULL(p2.[加工状态], 0) AS [加工状态],
                    p2.[开工时间],
                    ISNULL(check_qty.[收检合格数], 0) AS [收检合格数],
                    ISNULL(check_qty.[收检不合格数], 0) AS [收检不合格数]
                FROM [dbo].[View_生产订单_MES] AS p2
                OUTER APPLY (
                    SELECT
                        SUM(ISNULL(q.[合格数], 0)) AS [收检合格数],
                        SUM(ISNULL(q.[不合格数], 0)) AS [收检不合格数]
                    FROM [dbo].[YL_质量检验_质检记录] AS q
                    WHERE q.[TaskAID] = p2.[TaskAID]
                      AND q.[质检类型] = N'收检'
                ) AS check_qty
                WHERE p2.[订单编号] = detail_order.[订单编号]
                  AND p2.[物料类型] = N'pit_Resource'
                ORDER BY p2.[订单行号]
                FOR JSON PATH
            ) AS [工艺路线明细]
        FROM [dbo].[View_生产订单_MES] AS p
        WHERE p.[订单编号] = detail_order.[订单编号]
          AND p.[物料类型] = N'pit_Resource'
    ) AS route
    OUTER APPLY (
        SELECT TOP (1)
            pending.[订单行号],
            pending.[工序名称],
            pending.[加工状态],
            pending.[进度],
            pending.[完成数量],
            pending.[计划数量],
            pending.[开工时间]
        FROM [dbo].[View_生产订单_MES] AS pending
        WHERE pending.[订单编号] = detail_order.[订单编号]
          AND pending.[物料类型] = N'pit_Resource'
          AND NOT (
              ISNULL(pending.[进度], 0) >= 100
              OR (ISNULL(pending.[计划数量], 0) > 0 AND ISNULL(pending.[完成数量], 0) >= ISNULL(pending.[计划数量], 0))
          )
        ORDER BY pending.[订单行号]
    ) AS pending
    OUTER APPLY (
        SELECT TOP (1) prev.[工序名称]
        FROM [dbo].[View_生产订单_MES] AS prev
        WHERE prev.[订单编号] = detail_order.[订单编号]
          AND prev.[物料类型] = N'pit_Resource'
          AND prev.[订单行号] < pending.[订单行号]
        ORDER BY prev.[订单行号] DESC
    ) AS prev_step
    OUTER APPLY (
        SELECT TOP (1) last_step.[工序名称]
        FROM [dbo].[View_生产订单_MES] AS last_step
        WHERE last_step.[订单编号] = detail_order.[订单编号]
          AND last_step.[物料类型] = N'pit_Resource'
        ORDER BY last_step.[订单行号] DESC
    ) AS last_step
    OUTER APPLY (
        SELECT
            CASE
                WHEN detail_order.[订单编号] IS NULL THEN N''
                WHEN pending.[订单行号] IS NULL THEN ISNULL(last_step.[工序名称], N'') + N'毕'
                WHEN ISNULL(pending.[进度], 0) > 0
                     OR ISNULL(pending.[完成数量], 0) > 0
                     OR ISNULL(pending.[加工状态], 0) IN (2, 3, 4, 5, 6)
                     OR pending.[开工时间] > '1900-01-01'
                    THEN ISNULL(pending.[工序名称], N'') + N'中'
                WHEN prev_step.[工序名称] IS NULL THEN N''
                ELSE prev_step.[工序名称] + N'毕待' + ISNULL(pending.[工序名称], N'')
            END AS [当前序]
    ) AS current_step
    OUTER APPLY (
        SELECT
            CASE
                WHEN sap.[属性] <> N'' THEN N''
                WHEN EXISTS (
                    SELECT 1
                    FROM [dbo].[质量检验_质检任务_SAP] AS task
                    OUTER APPLY (
                        SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量]
                        FROM [dbo].[YL_质量检验_质检记录] AS q
                        WHERE q.[检测类型编号] = 5
                          AND q.[计划号] = task.[订单编号]
                          AND q.[行号] = task.[行号]
                          AND q.[订单类型] = task.[订单类型]
                    ) AS checked_qty
                    WHERE sap.[到货草稿] > 0
                      AND task.[订单类型] = N'20'
                      AND task.[订单编号] = sap.[到货草稿]
                      AND ISNULL(task.[入库数量], 0) > 0
                )
                AND NOT EXISTS (
                    SELECT 1
                    FROM [dbo].[质量检验_质检任务_SAP] AS task
                    OUTER APPLY (
                        SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量]
                        FROM [dbo].[YL_质量检验_质检记录] AS q
                        WHERE q.[检测类型编号] = 5
                          AND q.[计划号] = task.[订单编号]
                          AND q.[行号] = task.[行号]
                          AND q.[订单类型] = task.[订单类型]
                    ) AS checked_qty
                    WHERE sap.[到货草稿] > 0
                      AND task.[订单类型] = N'20'
                      AND task.[订单编号] = sap.[到货草稿]
                      AND (
                          ISNULL(task.[入库数量], 0) <= 0
                          OR ISNULL(checked_qty.[已检验数量], 0) < ISNULL(task.[入库数量], 0)
                      )
                ) THEN N'已完成'
                ELSE N'未完成'
            END AS [质检状态]
    ) AS purchase_check
    WHERE
        v.[订单编号] IS NOT NULL
        AND (@订单号 <= 0 OR v.[订单编号] = @订单号)
        AND (@计划号 = N'' OR ISNULL(v.[计划号], N'') = @计划号)
        AND (@合同号 = N'' OR ISNULL(v.[合同号], N'') LIKE N'%' + @合同号 + N'%')
        AND (@产品编码 = N'' OR ISNULL(v.[物料编号], N'') LIKE N'%' + @产品编码 + N'%')
        AND (@产品名称 = N'' OR ISNULL(v.[物料描述], N'') LIKE N'%' + @产品名称 + N'%')
        AND (@工序名称 = N'' OR EXISTS (
            SELECT 1
            FROM [dbo].[View_生产订单_MES] AS fp
            WHERE fp.[订单编号] = v.[订单编号]
              AND fp.[工序名称] = @工序名称
        ))
        AND (@计划开始 = N'' OR v.[计划开始时间] >= TRY_CONVERT(datetime, @计划开始))
        AND (@计划完成 = N'' OR v.[计划开始时间] <= TRY_CONVERT(datetime, @计划完成))
        AND (@排产状态 = N'全部' OR @排产状态 = N'' OR
            (@排产状态 = N'已完成' AND ISNULL(v.[排产状态], 0) = 1) OR
            (@排产状态 = N'未完成' AND ISNULL(v.[排产状态], 0) = 0)
        )
        AND (@指派对象 = N'全部' OR @指派对象 = N'' OR EXISTS (
            SELECT 1
            FROM [dbo].[View_生产订单_MES] AS ap
            WHERE ap.[订单编号] = v.[订单编号]
              AND ap.[指派对象] IN (SELECT LTRIM(RTRIM(value)) FROM STRING_SPLIT(@指派对象, N','))
        ))
        AND (@发货状态 = N'全部' OR @发货状态 = N'' OR
            (@发货状态 = N'已发货' AND ISNULL(v.[发货状态], N'0') = N'1') OR
            (@发货状态 = N'未发货' AND ISNULL(v.[发货状态], N'0') <> N'1')
        )
        AND (@齐套 = N'全部' OR @齐套 = N'' OR
            (@齐套 = N'是' AND ISNULL(v.[齐套], 0) = 1) OR
            (@齐套 = N'否' AND ISNULL(v.[齐套], 0) <> 1)
        )
        AND (@发料状态 = N'全部' OR @发料状态 = N'' OR
            (@发料状态 = N'发料齐套' AND ISNULL(v.[发料状态], N'0') = N'1') OR
            (@发料状态 = N'发料缺件' AND ISNULL(v.[发料状态], N'0') = N'2') OR
            (@发料状态 = N'未发料' AND ISNULL(v.[发料状态], N'0') NOT IN (N'1', N'2'))
        )
        AND (@自制件属性 = N'全部' OR @自制件属性 = N'' OR
            (@自制件属性 = N'机加' AND (sap.[属性] = N'机加件' OR v.[自制件属性] = N'机加件')) OR
            (@自制件属性 = N'装配' AND (sap.[属性] LIKE N'%装配%' OR v.[自制件属性] LIKE N'%装配%'))
        )
        AND (@检验状态 = N'' OR (sap.[属性] = N'' AND ISNULL(purchase_check.[质检状态], N'') = @检验状态))
    )
    SELECT TOP (1000)
        [计划号],
        [合同号],
        [订单号],
        [产品编码],
        [产品名称],
        [计划数量订单],
        [入库数量],
        [要求完工日期],
        [要求发货日期],
        [发货状态],
        [齐套],
        [拣配状态],
        [发料状态],
        [装配开工],
        [完成数量],
        [终检],
        [生产工艺],
        [排产状态],
        [自制件属性],
        [预计齐套时间],
        [缺件物料编码],
        [缺件物料名称],
        [缺件数量],
        [库存数量],
        [缺件属性],
        [缺件生产订单号],
        [进度],
        [工艺路线],
        [预计完成时间],
        [工艺路线明细],
        [采购未清数量],
        [到货草稿],
        [质检状态],
        [SAP单据],
        [SAP行号]
    FROM (
        SELECT
            查询结果.*,
            ROW_NUMBER() OVER (
                PARTITION BY
                    [订单号],
                    CASE
                        WHEN ISNULL([缺件生产订单号], N'') <> N'' THEN [缺件生产订单号]
                        ELSE [缺件物料编码] + N':' + CONVERT(nvarchar(30), [SAP行号])
                    END
                ORDER BY [缺件数量] DESC, [SAP单据], [SAP行号]
            ) AS rn
        FROM 查询结果
    ) AS dedup
    WHERE rn = 1
    ORDER BY
        [预计齐套时间],
        [订单号],
        [缺件生产订单号],
        [缺件物料编码];
END
GO
