USE [YL_MESDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*
    2026-06-30
    生产订单关闭查询：可关闭订单补充“无工时但满足其他可关闭条件”的特殊情况。

    规则：
    1. 有工时订单：继续要求 View_生产工时视图 中所有工时记录已校验。
    2. 无工时订单：必须在 MES_接口_生产计划 中存在，且 View_生产工时视图 中没有任何工时记录。
    3. 无工时订单不做工时全部校验，但仍必须满足原有可关闭条件：
       - 单据状态为空；
       - 终检/收检/计划数量/入库数量满足原过程 HAVING 条件；
       - 入库数量等于终检合格数。
*/
ALTER PROCEDURE [dbo].[计划排产_生产订单关闭_查询全部订单]
    @订单号 nvarchar(100) = N'',
    @单据状态 nvarchar(100) = N'',  -- 可选值：'已关闭'、'未关闭'、'可关闭'
    @属性 nvarchar(100) = N''
AS
BEGIN
    SET NOCOUNT ON;

    IF (@单据状态 = N'可关闭')
    BEGIN
        CREATE TABLE #工时订单
        (
            订单号 nvarchar(100) NOT NULL PRIMARY KEY
        );

        INSERT INTO #工时订单 (订单号)
        SELECT DISTINCT CONVERT(nvarchar(100), 订单号)
        FROM dbo.View_生产工时视图
        WHERE 订单号 IS NOT NULL;

        ;WITH 收检数量 AS
        (
            SELECT
                计划号,
                SUM(ISNULL(合格数, 0)) AS 合格数合计,
                SUM(ISNULL(不合格数, 0)) AS 不合格数合计
            FROM dbo.YL_质量检验_质检记录
            WHERE 质检类型 = N'收检'
            GROUP BY 计划号
        ),
        终检数量 AS
        (
            SELECT
                计划号,
                SUM(ISNULL(合格数, 0)) AS 终检合格数合计,
                SUM(ISNULL(不合格数, 0)) AS 终检不合格数合计
            FROM dbo.YL_质量检验_质检记录
            WHERE 质检类型 = N'终检'
            GROUP BY 计划号
        ),
        可关闭订单 AS
        (
            SELECT
                v.订单号 AS 订单编号,
                MAX(v.产品名称) AS 产品名称,
                MAX(v.产品编码) AS 产品编码,
                MAX(v.入库数量) AS 入库数量,
                MAX(v.订单合同号) AS 合同号,
                MAX(终检数量.终检不合格数合计) AS 终检不合格数合计,
                MAX(终检数量.终检合格数合计) AS 终检合格数合计,
                MAX(v.计划数量) AS 计划数量,
                MAX(v.确认状态) AS 确认状态,
                MAX(v.单据状态) AS 单据状态,
                MAX(收检数量.不合格数合计) AS 不合格数合计,
                MIN(CASE WHEN v.Expr1 IS NULL THEN 0 ELSE 1 END) AS 是否全部校验
            FROM dbo.View_生产工时视图 AS v
            LEFT JOIN 收检数量 ON v.订单号 = 收检数量.计划号
            LEFT JOIN 终检数量 ON v.订单号 = 终检数量.计划号
            WHERE v.单据状态 IS NULL
              AND (@订单号 = N'' OR v.订单号 = @订单号)
              AND (
                    @属性 NOT IN (N'机加', N'装配')
                    OR (@属性 = N'机加' AND v.自制件属性 = N'机加件')
                    OR (@属性 = N'装配' AND v.自制件属性 LIKE N'%装配%')
                  )
            GROUP BY v.订单号
            HAVING
                MIN(CASE WHEN v.Expr1 IS NULL THEN 0 ELSE 1 END) = 1
                AND (
                    MAX(终检数量.终检合格数合计) + MAX(收检数量.不合格数合计) = MAX(v.计划数量)
                    OR MAX(v.计划数量) = MAX(v.入库数量)
                    OR MAX(收检数量.不合格数合计) = MAX(v.计划数量)
                )
                AND MAX(ISNULL(v.入库数量, 0)) = MAX(ISNULL(终检数量.终检合格数合计, 0))

            UNION ALL

            SELECT
                CONVERT(nvarchar(100), p.订单编号) AS 订单编号,
                MAX(p.物料描述) AS 产品名称,
                MAX(p.物料编号) AS 产品编码,
                MAX(p.入库数量) AS 入库数量,
                MAX(p.合同号) AS 合同号,
                MAX(终检数量.终检不合格数合计) AS 终检不合格数合计,
                MAX(终检数量.终检合格数合计) AS 终检合格数合计,
                MAX(p.计划数量) AS 计划数量,
                MAX(p.确认状态) AS 确认状态,
                MAX(p.单据状态) AS 单据状态,
                MAX(收检数量.不合格数合计) AS 不合格数合计,
                1 AS 是否全部校验
            FROM dbo.MES_接口_生产计划 AS p
            LEFT JOIN 收检数量 ON CONVERT(nvarchar(100), p.订单编号) = CONVERT(nvarchar(100), 收检数量.计划号)
            LEFT JOIN 终检数量 ON CONVERT(nvarchar(100), p.订单编号) = CONVERT(nvarchar(100), 终检数量.计划号)
            LEFT JOIN #工时订单 AS wh ON wh.订单号 = CONVERT(nvarchar(100), p.订单编号)
            WHERE p.单据状态 IS NULL
              AND wh.订单号 IS NULL
              AND (@订单号 = N'' OR CONVERT(nvarchar(100), p.订单编号) = @订单号)
              AND (
                    @属性 NOT IN (N'机加', N'装配')
                    OR (@属性 = N'机加' AND p.自制件属性 = N'机加件')
                    OR (@属性 = N'装配' AND p.自制件属性 LIKE N'%装配%')
                  )
            GROUP BY p.订单编号
            HAVING
                (
                    MAX(终检数量.终检合格数合计) + MAX(收检数量.不合格数合计) = MAX(p.计划数量)
                    OR MAX(p.计划数量) = MAX(p.入库数量)
                    OR MAX(收检数量.不合格数合计) = MAX(p.计划数量)
                )
                AND MAX(ISNULL(p.入库数量, 0)) = MAX(ISNULL(终检数量.终检合格数合计, 0))
        )
        SELECT
            订单编号,
            产品名称,
            产品编码,
            入库数量,
            合同号,
            终检不合格数合计,
            终检合格数合计,
            计划数量,
            确认状态,
            单据状态,
            不合格数合计,
            是否全部校验
        FROM 可关闭订单
        ORDER BY 订单编号;

        RETURN;
    END

    SELECT TOP 100
        v.订单编号,
        MAX(v.物料描述) AS 产品名称,
        MAX(v.物料编号) AS 产品编码,
        MAX(v.入库数量) AS 入库数量,
        MAX(v.合同号) AS 合同号,
        MAX(zj_终检数量.终检不合格数合计) AS 终检不合格数合计,
        MAX(zj_终检数量.终检合格数合计) AS 终检合格数合计,
        MAX(v.计划数量) AS 计划数量,
        MAX(v.确认状态) AS 确认状态,
        MAX(v.单据状态) AS 单据状态
    FROM dbo.MES_接口_生产计划 AS v
    LEFT JOIN
    (
        SELECT
            计划号,
            SUM(ISNULL(合格数, 0)) AS 终检合格数合计,
            SUM(ISNULL(不合格数, 0)) AS 终检不合格数合计
        FROM dbo.YL_质量检验_质检记录
        WHERE 质检类型 = N'终检'
        GROUP BY 计划号
    ) AS zj_终检数量 ON v.订单编号 = zj_终检数量.计划号
    WHERE 1 = 1
      AND (@订单号 = N'' OR CONVERT(nvarchar(100), v.订单编号) = @订单号)
      AND (
            @单据状态 NOT IN (N'SAP未关闭', N'已关闭', N'未关闭')
            OR (@单据状态 = N'SAP未关闭' AND v.单据状态 = N'已关闭')
            OR (@单据状态 = N'已关闭' AND (v.单据状态 = N'已关闭' OR v.单据状态 = N'已取消'))
            OR (@单据状态 = N'未关闭' AND v.单据状态 IS NULL)
          )
      AND (
            @属性 NOT IN (N'机加', N'装配')
            OR (@属性 = N'机加' AND v.自制件属性 = N'机加件')
            OR (@属性 = N'装配' AND v.自制件属性 LIKE N'%装配%')
          )
    GROUP BY v.订单编号;
END
GO
