-- ============================================================
-- 修复: [dbo].[生产管理_外协报表_查询]
-- 问题1: 供应商过滤在 HAVING 中，SELECT 用 MAX(供应商名称)
--         → 搜索"大连金景义"可能显示"芯泰智能"
-- 问题2: GROUP BY 加了供应商名称后，STUFF 子查询未限定供应商
--         → 两个供应商行拿到完全相同的工序列表，看似重复
-- 修复: 
--   ① 供应商过滤移到 WHERE（分组前过滤）
--   ② GROUP BY 加入 供应商名称（每个供应商独立一行）
--   ③ STUFF 子查询加 d2.供应商名称 = d.供应商名称（各行只取自己的工序）
--   ④ ROW_NUMBER 加上 供应商名称（排序确定化）
-- 日期: 2026-05-21
-- ============================================================

USE [YL_MESDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[生产管理_外协报表_查询]
    @订单号 int = 0,
    @合同号 nvarchar(50) = '',
    @产品编码 nvarchar(50) = '',
    @产品名称 nvarchar(50) = '',
    @计划号 nvarchar(50) = '',
    @供应商 nvarchar(100) = '',
    @状态过滤 int = 0,
    @PageCurrent int = 1,
    @PageSize int = 20,
    @PageCount int OUTPUT,
    @ItemCount int OUTPUT
AS
BEGIN
    SET NOCOUNT ON
    
    IF OBJECT_ID('tempdb..#MergedResult') IS NOT NULL DROP TABLE #MergedResult
    
    ;WITH 工单汇总 AS (
        SELECT 
            订单号,
            拆分内码,
            供应商名称,
            MAX(计划号) AS 计划号,
            MAX(合同号) AS 合同号,
            MAX(产品编码) AS 产品编码,
            MAX(产品名称) AS 产品名称,
            MAX(指派数量) AS 指派数量,
            MAX(含税单价) AS 含税单价,
            MAX(含税行总计) AS 含税行总计,
            MAX(开始时间) AS 开始时间,
            MIN(计划开始时间) AS 计划开始时间,
            MIN(计划完成时间) AS 计划完成时间,
            MAX(采购预计到货日期) AS 采购预计到货日期,
            MAX(外协结束时间) AS 外协结束时间,
            MAX(收料数量) AS 收料数量,
            MAX(收检合格数) AS 收检合格数,
            MAX(收检不合格数) AS 收检不合格数,
            MAX(CASE WHEN ISNULL(开票数量, 0) > 0 THEN 1 ELSE 0 END) AS 开票数量,
            MAX(发料数量合计) AS 发料数量合计,
            MAX(收料数量_报工) AS 收料数量_报工,
            MAX(CAST(材质 AS NVARCHAR(MAX))) AS 材质,
            MAX(要求完工日期) AS 要求完工日期,
            MAX(工序计划数量) AS 工序计划数量,
            MAX(完成数量) AS 完成数量,
            MAX(收检合格数) AS 上序合格数,
            MAX(CASE WHEN 订单行号 = 1 OR ISNULL(收检合格数, 0) > 0 THEN 1 ELSE 0 END) AS 执行状态,
            -- ============ 修复点③ ============
            -- STUFF 子查询加上 供应商名称 关联：每个供应商行只聚合自己的工序
            STUFF((
                SELECT ',' + d2.工序名称
                FROM View_外协报表视图 d2
                WHERE d2.订单号 = d.订单号 
                  AND d2.拆分内码 = d.拆分内码
                  AND ISNULL(d2.供应商名称, '') = ISNULL(d.供应商名称, '')
                ORDER BY d2.订单行号
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS 工序名称列表,
            STUFF((
                SELECT ',' + CAST(d2.TaskAID AS VARCHAR(10))
                FROM View_外协报表视图 d2
                WHERE d2.订单号 = d.订单号 
                  AND d2.拆分内码 = d.拆分内码
                  AND ISNULL(d2.供应商名称, '') = ISNULL(d.供应商名称, '')
                ORDER BY d2.订单行号
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS TaskAID列表,
            -- ============ 修复点④ ============
            -- ROW_NUMBER 排序加上 供应商名称，确保分页结果稳定
            ROW_NUMBER() OVER (ORDER BY 订单号, 供应商名称) AS RowNum
        FROM View_外协报表视图 d
        WHERE 1=1
          -- 排除供应商为空的"脏数据"（无SAP采购单关联的行）
          AND ISNULL(d.供应商名称, '') <> ''
          -- ============ 修复点① ============
          -- 供应商过滤放在 WHERE（分组前），不会出现"搜A显示B"
          AND (@供应商 = '' OR d.供应商名称 LIKE '%' + @供应商 + '%')
          -- ====================================
          AND (@订单号 = 0 OR d.订单号 = @订单号)
          AND (@计划号 = '' OR d.计划号 = @计划号)
          AND (@合同号 = '' OR d.合同号 LIKE '%' + @合同号 + '%')
          AND (@产品编码 = '' OR d.产品编码 LIKE '%' + @产品编码 + '%')
          AND (@产品名称 = '' OR d.产品名称 LIKE '%' + @产品名称 + '%')
        -- ============ 修复点② ============
        -- 按 订单号 + 拆分内码 + 供应商名称 分组，每个供应商独立一行
        GROUP BY 订单号, 拆分内码, 供应商名称
        -- ====================================
        HAVING 
            -- 状态过滤依赖聚合值，保留在 HAVING
            (@状态过滤 = 0 OR MAX(CASE WHEN ISNULL(收料数量_报工, 0) < ISNULL(发料数量合计, 0) THEN 1 ELSE 0 END) = 1)
    )
    SELECT 
        计划号,
        合同号,
        订单号,
        产品编码,
        产品名称,
        工序名称列表 AS 工序名称,
        供应商名称,
        指派数量,
        含税单价,
        含税行总计,
        开始时间,
        计划开始时间,
        计划完成时间,
        采购预计到货日期,
        外协结束时间,
        收料数量,
        收检合格数,
        收检不合格数,
        开票数量,
        发料数量合计,
        收料数量_报工,
        材质,
        要求完工日期,
        工序计划数量,
        TaskAID列表 AS TaskAID,
        拆分内码,
        执行状态,
        CASE WHEN 执行状态 = 1 THEN '可执行' ELSE '不可执行' END AS 执行状态文本,
        完成数量,
        上序合格数,
        RowNum
    INTO #MergedResult
    FROM 工单汇总
    
    SELECT @ItemCount = COUNT(*) FROM #MergedResult
    
    IF @ItemCount = 0
        SET @PageCount = 0
    ELSE
        SET @PageCount = CEILING(CAST(@ItemCount AS FLOAT) / @PageSize)
    
    SELECT 
        计划号,
        合同号,
        订单号,
        产品编码,
        产品名称,
        工序名称,
        供应商名称,
        指派数量,
        含税单价,
        含税行总计,
        开始时间,
        计划开始时间,
        计划完成时间,
        采购预计到货日期,
        外协结束时间,
        收料数量,
        收检合格数,
        收检不合格数,
        开票数量,
        发料数量合计,
        收料数量_报工,
        材质,
        要求完工日期,
        工序计划数量,
        TaskAID,
        拆分内码,
        执行状态,
        执行状态文本,
        完成数量,
        上序合格数
    FROM #MergedResult
    WHERE RowNum BETWEEN (@PageCurrent - 1) * @PageSize + 1 AND @PageCurrent * @PageSize
    ORDER BY 订单号, 供应商名称
    
    DROP TABLE #MergedResult
END
GO
