/*
Reject 歷史績效表建置腳本
目的:
  - 以 DW_MES_LOTREJECTHISTORY 為主，建立可直接報表化的日彙總績效表
  - 補齊產品/工站維度，並區分扣帳報廢與不扣帳報廢
*/

/* ============================================================
   1) 建表 (執行一次)
   ============================================================ */

CREATE TABLE DWH.DW_PJ_REJECT_HISTORY_PERF_D (
    TXN_DAY                   DATE            NOT NULL,
    TXN_MONTH                 VARCHAR2(7)     NOT NULL,
    WORKCENTER_GROUP          VARCHAR2(40)    NOT NULL,
    WORKCENTERSEQUENCE_GROUP  NUMBER(10)      NOT NULL,
    WORKCENTERNAME            VARCHAR2(40)    NOT NULL,
    SPECNAME                  VARCHAR2(40)    NOT NULL,
    EQUIPMENTNAME             VARCHAR2(255)   NOT NULL,
    PRIMARY_EQUIPMENTNAME     VARCHAR2(40)    NOT NULL,
    PRODUCTLINENAME           VARCHAR2(40)    NOT NULL,
    PJ_TYPE                   VARCHAR2(40)    NOT NULL,
    LOSSREASONNAME            VARCHAR2(40)    NOT NULL,
    REJECTCATEGORYNAME        VARCHAR2(40)    NOT NULL,
    REJECT_EVENT_ROWS         NUMBER          NOT NULL,
    AFFECTED_LOT_COUNT        NUMBER          NOT NULL,
    AFFECTED_WORKORDER_COUNT  NUMBER          NOT NULL,
    MOVEIN_QTY                NUMBER          NOT NULL,
    REJECT_QTY                NUMBER          NOT NULL,
    REJECT_TOTAL_QTY          NUMBER          NOT NULL,
    DEFECT_QTY                NUMBER          NOT NULL,
    STANDBY_QTY               NUMBER          NOT NULL,
    QTYTOPROCESS_QTY          NUMBER          NOT NULL,
    INPROCESS_QTY             NUMBER          NOT NULL,
    PROCESSED_QTY             NUMBER          NOT NULL,
    REJECT_RATE_PCT           NUMBER(18, 4)   NOT NULL,
    DEFECT_RATE_PCT           NUMBER(18, 4)   NOT NULL,
    REJECT_SHARE_PCT          NUMBER(18, 4)   NOT NULL,
    LAST_REFRESH_TS           DATE            NOT NULL
);

CREATE INDEX DWH.IDX_RJH_PERF_D_01 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (TXN_DAY);
CREATE INDEX DWH.IDX_RJH_PERF_D_02 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (WORKCENTER_GROUP, TXN_DAY);
CREATE INDEX DWH.IDX_RJH_PERF_D_03 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (PRIMARY_EQUIPMENTNAME, TXN_DAY);
CREATE INDEX DWH.IDX_RJH_PERF_D_04 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (LOSSREASONNAME, TXN_DAY);


/* ============================================================
   2) 區間刷新 (可每日排程)
   綁定參數:
     :start_date (YYYY-MM-DD)
     :end_date   (YYYY-MM-DD)
   ============================================================ */

DELETE FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D
WHERE TXN_DAY >= TO_DATE(:start_date, 'YYYY-MM-DD')
  AND TXN_DAY < TO_DATE(:end_date, 'YYYY-MM-DD') + 1;

INSERT /*+ APPEND */ INTO DWH.DW_PJ_REJECT_HISTORY_PERF_D (
    TXN_DAY,
    TXN_MONTH,
    WORKCENTER_GROUP,
    WORKCENTERSEQUENCE_GROUP,
    WORKCENTERNAME,
    SPECNAME,
    EQUIPMENTNAME,
    PRIMARY_EQUIPMENTNAME,
    PRODUCTLINENAME,
    PJ_TYPE,
    LOSSREASONNAME,
    REJECTCATEGORYNAME,
    REJECT_EVENT_ROWS,
    AFFECTED_LOT_COUNT,
    AFFECTED_WORKORDER_COUNT,
    MOVEIN_QTY,
    REJECT_QTY,
    REJECT_TOTAL_QTY,
    DEFECT_QTY,
    STANDBY_QTY,
    QTYTOPROCESS_QTY,
    INPROCESS_QTY,
    PROCESSED_QTY,
    REJECT_RATE_PCT,
    DEFECT_RATE_PCT,
    REJECT_SHARE_PCT,
    LAST_REFRESH_TS
)
WITH workcenter_map AS (
    SELECT
        WORK_CENTER,
        MIN(WORK_CENTER_GROUP) KEEP (
            DENSE_RANK FIRST ORDER BY WORKCENTERSEQUENCE_GROUP
        ) AS WORKCENTER_GROUP,
        MIN(WORKCENTERSEQUENCE_GROUP) AS WORKCENTERSEQUENCE_GROUP
    FROM DWH.DW_MES_SPEC_WORKCENTER_V
    WHERE WORK_CENTER IS NOT NULL
    GROUP BY WORK_CENTER
),
reject_raw AS (
    SELECT
        TRUNC(r.TXNDATE) AS TXN_DAY,
        TO_CHAR(TRUNC(r.TXNDATE), 'YYYY-MM') AS TXN_MONTH,
        r.CONTAINERID,
        NVL(TRIM(r.PJ_WORKORDER), TRIM(c.MFGORDERNAME)) AS PJ_WORKORDER,
        NVL(TRIM(c.PJ_TYPE), '(NA)') AS PJ_TYPE,
        NVL(TRIM(c.PRODUCTLINENAME), '(NA)') AS PRODUCTLINENAME,
        NVL(TRIM(r.WORKCENTERNAME), '(NA)') AS WORKCENTERNAME,
        NVL(TRIM(wm.WORKCENTER_GROUP), NVL(TRIM(r.WORKCENTERNAME), '(NA)')) AS WORKCENTER_GROUP,
        NVL(wm.WORKCENTERSEQUENCE_GROUP, 999) AS WORKCENTERSEQUENCE_GROUP,
        NVL(TRIM(r.SPECNAME), '(NA)') AS SPECNAME,
        NVL(TRIM(r.EQUIPMENTNAME), '(NA)') AS EQUIPMENTNAME,
        NVL(
            TRIM(REGEXP_SUBSTR(r.EQUIPMENTNAME, '[^,]+', 1, 1)),
            NVL(TRIM(r.EQUIPMENTNAME), '(NA)')
        ) AS PRIMARY_EQUIPMENTNAME,
        NVL(TRIM(r.LOSSREASONNAME), '(未填寫)') AS LOSSREASONNAME,
        NVL(TRIM(r.REJECTCATEGORYNAME), '(未填寫)') AS REJECTCATEGORYNAME,
        NVL(r.MOVEINQTY, 0) AS MOVEINQTY,
        NVL(r.REJECTQTY, 0) AS REJECT_QTY,
        NVL(r.STANDBYQTY, 0) AS STANDBY_QTY,
        NVL(r.QTYTOPROCESS, 0) AS QTYTOPROCESS_QTY,
        NVL(r.INPROCESSQTY, 0) AS INPROCESS_QTY,
        NVL(r.PROCESSEDQTY, 0) AS PROCESSED_QTY,
        NVL(r.REJECTQTY, 0)
          + NVL(r.STANDBYQTY, 0)
          + NVL(r.QTYTOPROCESS, 0)
          + NVL(r.INPROCESSQTY, 0)
          + NVL(r.PROCESSEDQTY, 0) AS REJECT_TOTAL_QTY,
        NVL(r.DEFECTQTY, 0) AS DEFECT_QTY,
        ROW_NUMBER() OVER (
            PARTITION BY NVL(
                TRIM(r.HISTORYMAINLINEID),
                TRIM(r.CONTAINERID) || ':' || TO_CHAR(r.TXNDATE, 'YYYYMMDDHH24MISS') || ':' || NVL(TRIM(r.SPECID), '-')
            )
            ORDER BY NVL(TRIM(r.LOSSREASONNAME), ' ')
        ) AS EVENT_RN
    FROM DWH.DW_MES_LOTREJECTHISTORY r
    LEFT JOIN DWH.DW_MES_CONTAINER c
      ON c.CONTAINERID = r.CONTAINERID
    LEFT JOIN workcenter_map wm
      ON wm.WORK_CENTER = r.WORKCENTERNAME
    WHERE r.TXNDATE >= TO_DATE(:start_date, 'YYYY-MM-DD')
      AND r.TXNDATE < TO_DATE(:end_date, 'YYYY-MM-DD') + 1
),
daily_agg AS (
    SELECT
        TXN_DAY,
        TXN_MONTH,
        WORKCENTER_GROUP,
        WORKCENTERSEQUENCE_GROUP,
        WORKCENTERNAME,
        SPECNAME,
        EQUIPMENTNAME,
        PRIMARY_EQUIPMENTNAME,
        PRODUCTLINENAME,
        PJ_TYPE,
        LOSSREASONNAME,
        REJECTCATEGORYNAME,
        COUNT(*) AS REJECT_EVENT_ROWS,
        COUNT(DISTINCT CONTAINERID) AS AFFECTED_LOT_COUNT,
        COUNT(DISTINCT PJ_WORKORDER) AS AFFECTED_WORKORDER_COUNT,
        SUM(CASE WHEN EVENT_RN = 1 THEN MOVEINQTY ELSE 0 END) AS MOVEIN_QTY,
        SUM(REJECT_QTY) AS REJECT_QTY,
        SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY,
        SUM(DEFECT_QTY) AS DEFECT_QTY,
        SUM(STANDBY_QTY) AS STANDBY_QTY,
        SUM(QTYTOPROCESS_QTY) AS QTYTOPROCESS_QTY,
        SUM(INPROCESS_QTY) AS INPROCESS_QTY,
        SUM(PROCESSED_QTY) AS PROCESSED_QTY
    FROM reject_raw
    GROUP BY
        TXN_DAY,
        TXN_MONTH,
        WORKCENTER_GROUP,
        WORKCENTERSEQUENCE_GROUP,
        WORKCENTERNAME,
        SPECNAME,
        EQUIPMENTNAME,
        PRIMARY_EQUIPMENTNAME,
        PRODUCTLINENAME,
        PJ_TYPE,
        LOSSREASONNAME,
        REJECTCATEGORYNAME
)
SELECT
    TXN_DAY,
    TXN_MONTH,
    WORKCENTER_GROUP,
    WORKCENTERSEQUENCE_GROUP,
    WORKCENTERNAME,
    SPECNAME,
    EQUIPMENTNAME,
    PRIMARY_EQUIPMENTNAME,
    PRODUCTLINENAME,
    PJ_TYPE,
    LOSSREASONNAME,
    REJECTCATEGORYNAME,
    REJECT_EVENT_ROWS,
    AFFECTED_LOT_COUNT,
    AFFECTED_WORKORDER_COUNT,
    MOVEIN_QTY,
    REJECT_QTY,
    REJECT_TOTAL_QTY,
    DEFECT_QTY,
    STANDBY_QTY,
    QTYTOPROCESS_QTY,
    INPROCESS_QTY,
    PROCESSED_QTY,
    CASE
        WHEN MOVEIN_QTY = 0 THEN 0
        ELSE ROUND(REJECT_TOTAL_QTY * 100 / MOVEIN_QTY, 4)
    END AS REJECT_RATE_PCT,
    CASE
        WHEN MOVEIN_QTY = 0 THEN 0
        ELSE ROUND(DEFECT_QTY * 100 / MOVEIN_QTY, 4)
    END AS DEFECT_RATE_PCT,
    CASE
        WHEN (REJECT_TOTAL_QTY + DEFECT_QTY) = 0 THEN 0
        ELSE ROUND(REJECT_TOTAL_QTY * 100 / (REJECT_TOTAL_QTY + DEFECT_QTY), 4)
    END AS REJECT_SHARE_PCT,
    SYSDATE AS LAST_REFRESH_TS
FROM daily_agg;

COMMIT;


/* ============================================================
   3) 快速驗證查詢
   ============================================================ */

SELECT
    TXN_DAY,
    WORKCENTER_GROUP,
    SUM(MOVEIN_QTY) AS MOVEIN_QTY,
    SUM(REJECT_QTY) AS REJECT_QTY,
    SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY,
    SUM(DEFECT_QTY) AS DEFECT_QTY,
    ROUND(SUM(REJECT_TOTAL_QTY) * 100 / NULLIF(SUM(MOVEIN_QTY), 0), 4) AS REJECT_RATE_PCT
FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D
WHERE TXN_DAY BETWEEN TO_DATE(:start_date, 'YYYY-MM-DD') AND TO_DATE(:end_date, 'YYYY-MM-DD')
GROUP BY TXN_DAY, WORKCENTER_GROUP
ORDER BY TXN_DAY DESC, WORKCENTER_GROUP;
