750 lines
20 KiB
SQL
750 lines
20 KiB
SQL
SET PATH *LIBL ;
|
|
|
|
CREATE OR REPLACE FUNCTION RESTAPI.SFP_GET_HOURLY_OEE_LIVE (
|
|
IN_PARM CLOB(2147483647) )
|
|
RETURNS CLOB(2147483647)
|
|
LANGUAGE SQL
|
|
SPECIFIC RESTAPI.SFP_GET_HOURLY_OEE_LIVE
|
|
NOT DETERMINISTIC
|
|
MODIFIES SQL DATA
|
|
CALLED ON NULL INPUT
|
|
SET OPTION ALWBLK = *ALLREAD ,
|
|
ALWCPYDTA = *OPTIMIZE ,
|
|
COMMIT = *NONE ,
|
|
DECRESULT = (31, 31, 00) ,
|
|
DYNDFTCOL = *NO ,
|
|
DYNUSRPRF = *USER ,
|
|
SRTSEQ = *HEX
|
|
BEGIN
|
|
DECLARE ENV VARCHAR ( 20 ) DEFAULT '' ;
|
|
DECLARE V_DATE DATE ;
|
|
DECLARE V_DATE_STR VARCHAR ( 10 ) DEFAULT '' ;
|
|
DECLARE V_WC VARCHAR ( 5 ) DEFAULT '' ;
|
|
DECLARE V_SITE VARCHAR ( 3 ) DEFAULT '' ;
|
|
DECLARE V_DATE_CY DECIMAL ( 7 , 0 ) DEFAULT 0 ;
|
|
DECLARE V_DATE_PRIOR_CY DECIMAL ( 7 , 0 ) DEFAULT 0 ;
|
|
DECLARE LL VARCHAR ( 1024 ) DEFAULT '' ;
|
|
DECLARE V_IN_PARM CLOB ( 2 G ) DEFAULT '' ;
|
|
-- Parse input parameters first (before env extraction modifies In_Parm)
|
|
SET V_DATE_STR = COALESCE ( JSON_VALUE ( IN_PARM , '$.date' ) , '' ) ;
|
|
SET V_WC = COALESCE ( JSON_VALUE ( IN_PARM , '$.workcenter' ) , '' ) ;
|
|
SET V_SITE = COALESCE ( JSON_VALUE ( IN_PARM , '$.site' ) , '' ) ;
|
|
-- Parse date - set to Current_Date if not provided
|
|
IF V_DATE_STR <> '' THEN
|
|
SET V_DATE = DATE ( V_DATE_STR ) ;
|
|
ELSE
|
|
SET V_DATE = CURRENT_DATE ;
|
|
END IF ;
|
|
-- Extract env handling all input formats (object, array, string)
|
|
SET V_IN_PARM = IN_PARM ;
|
|
WHILE CISTOOLS . JSON_TYPE ( V_IN_PARM ) IN ( 'object' , 'array' , 'string' )
|
|
DO
|
|
SET V_IN_PARM =
|
|
CASE CISTOOLS . JSON_TYPE ( V_IN_PARM )
|
|
WHEN 'object' THEN JSON_VALUE ( V_IN_PARM , '$.env' )
|
|
WHEN 'array' THEN JSON_VALUE ( V_IN_PARM , '$[0]' )
|
|
WHEN 'string' THEN REPLACE ( V_IN_PARM , '"' , '' )
|
|
ELSE TRIM ( V_IN_PARM )
|
|
END ;
|
|
END WHILE ;
|
|
SET ENV = V_IN_PARM ;
|
|
SET LL = CISTOOLS . SET_LIBRARY_LIST ( ENV ) ;
|
|
-- Calculate CYYMMDD dates
|
|
SET V_DATE_CY = ZONED ( V_DATE ) - 19000000 ;
|
|
SET V_DATE_PRIOR_CY = ZONED ( V_DATE - 1 DAY ) - 19000000 ;
|
|
RETURN
|
|
WITH
|
|
-- ========== RUN TRANSACTIONS (ON/OF) ==========
|
|
RUN_ON AS (
|
|
SELECT T . ORDNO , T . OPSEQ , T . ITNBR , T . WKCTR ,
|
|
COALESCE ( T . EMPNO , T . BADGE ) AS EMP_KEY ,
|
|
T . TDATE AS ON_DATE , T . TTIME AS ON_TIME , T . RUNCD ,
|
|
M . STID ,
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( T . TDATE ) ) ||
|
|
LPAD ( T . TTIME , 6 , '0' ) , 'YYYYMMDDHH24MISS' )
|
|
AS ON_TS ,
|
|
ROW_NUMBER ( ) OVER (
|
|
PARTITION BY T . ORDNO , T . OPSEQ , COALESCE (
|
|
T . EMPNO , T . BADGE ) , T . RUNCD , T . WKCTR
|
|
ORDER BY T . TDATE , T . TTIME
|
|
) AS SEQ
|
|
FROM MOTRAN T
|
|
JOIN MOMAST M
|
|
ON T . ORDNO = M . ORDNO
|
|
WHERE T . TCODE = 'ON'
|
|
AND T . RUNCD = 'R'
|
|
AND T . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , T . WKCTR )
|
|
AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID )
|
|
AND T . ACREC = 'A'
|
|
AND T . TDATE BETWEEN V_DATE_PRIOR_CY AND V_DATE_CY
|
|
) ,
|
|
RUN_OFF AS (
|
|
SELECT T . ORDNO , T . OPSEQ , T . WKCTR ,
|
|
COALESCE ( T . EMPNO , T . BADGE ) AS EMP_KEY ,
|
|
T . TDATE AS OFF_DATE , T . TTIME AS OFF_TIME , T . QTCOM ,
|
|
T . QTSCP , T . RUNCD , M . STID ,
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( T . TDATE ) ) ||
|
|
LPAD ( T . TTIME , 6 , '0' ) , 'YYYYMMDDHH24MISS' )
|
|
AS OFF_TS ,
|
|
ROW_NUMBER ( ) OVER (
|
|
PARTITION BY T . ORDNO , T . OPSEQ , COALESCE (
|
|
T . EMPNO , T . BADGE ) , T . RUNCD , T . WKCTR
|
|
ORDER BY T . TDATE , T . TTIME
|
|
) AS SEQ
|
|
FROM MOTRAN T
|
|
JOIN MOMAST M
|
|
ON T . ORDNO = M . ORDNO
|
|
WHERE T . TCODE = 'OF'
|
|
AND T . RUNCD = 'R'
|
|
AND T . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , T . WKCTR )
|
|
AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID )
|
|
AND T . ACREC = 'A'
|
|
AND T . TDATE = V_DATE_CY
|
|
) ,
|
|
CURRENT_END AS (
|
|
SELECT
|
|
CASE
|
|
WHEN V_DATE = CURRENT_DATE THEN CURRENT_TIMESTAMP
|
|
ELSE
|
|
TO_DATE (
|
|
ZONED ( V_DATE ) || '235959' , 'YYYYMMDDHH24MISS' )
|
|
END AS DEFAULT_END_TS
|
|
FROM SYSIBM . SYSDUMMY1
|
|
) ,
|
|
RUN_MATCHED AS (
|
|
SELECT ON_T . ORDNO , ON_T . ITNBR , ON_T . WKCTR , ON_T . STID ,
|
|
ON_T . ON_TS AS START_TS ,
|
|
COALESCE ( OFF_T . OFF_TS , CE . DEFAULT_END_TS ) AS END_TS ,
|
|
COALESCE ( OFF_T . OFF_DATE , V_DATE_CY ) AS OFF_DATE ,
|
|
COALESCE (
|
|
OFF_T . OFF_TIME ,
|
|
CASE
|
|
WHEN
|
|
V_DATE = CURRENT_DATE
|
|
THEN ZONED ( CURRENT_TIME )
|
|
ELSE 235959
|
|
END ) AS OFF_TIME ,
|
|
COALESCE ( OFF_T . QTCOM , 0 ) AS QTY_COMPLETE ,
|
|
COALESCE ( OFF_T . QTSCP , 0 ) AS QTY_SCRAP ,
|
|
CASE
|
|
COALESCE ( R . TBCDE , ' ' )
|
|
WHEN
|
|
' '
|
|
THEN
|
|
CASE
|
|
WHEN
|
|
COALESCE ( R . SRLHU , 0 ) > 0
|
|
THEN 1.0 / R . SRLHU / 60
|
|
ELSE 0
|
|
END
|
|
WHEN 'P' THEN COALESCE ( R . SRLHU , 0 ) / 60
|
|
WHEN
|
|
'M'
|
|
THEN
|
|
CASE
|
|
WHEN
|
|
COALESCE ( R . SRLHU , 0 ) > 0
|
|
THEN 1.0 / R . SRLHU
|
|
ELSE 0
|
|
END
|
|
WHEN
|
|
'1'
|
|
THEN
|
|
CASE
|
|
WHEN
|
|
COALESCE ( R . SRLHU , 0 ) > 0
|
|
THEN 10.0 / R . SRLHU / 60
|
|
ELSE 0
|
|
END
|
|
WHEN
|
|
'2'
|
|
THEN
|
|
CASE
|
|
WHEN
|
|
COALESCE ( R . SRLHU , 0 ) > 0
|
|
THEN 100.0 / R . SRLHU / 60
|
|
ELSE 0
|
|
END
|
|
WHEN
|
|
'3'
|
|
THEN
|
|
CASE
|
|
WHEN
|
|
COALESCE ( R . SRLHU , 0 ) > 0
|
|
THEN 1000.0 / R . SRLHU / 60
|
|
ELSE 0
|
|
END
|
|
ELSE 0
|
|
END AS PCS_PER_MIN
|
|
FROM RUN_ON ON_T
|
|
CROSS JOIN CURRENT_END CE
|
|
LEFT JOIN RUN_OFF OFF_T
|
|
ON ON_T . ORDNO = OFF_T . ORDNO
|
|
AND ON_T . OPSEQ = OFF_T . OPSEQ
|
|
AND ON_T . EMP_KEY = OFF_T . EMP_KEY
|
|
AND ON_T . RUNCD = OFF_T . RUNCD
|
|
AND ON_T . SEQ = OFF_T . SEQ
|
|
AND ON_T . WKCTR = OFF_T . WKCTR
|
|
AND ON_T . STID = OFF_T . STID
|
|
LEFT JOIN MOROUT R
|
|
ON ON_T . ORDNO = R . ORDNO
|
|
AND ON_T . OPSEQ = R . OPSEQ
|
|
) ,
|
|
-- ========== DOWNTIME TRANSACTIONS (DB/DE) ==========
|
|
DOWN_BEGIN AS (
|
|
SELECT T . ORDNO , T . OPSEQ ,
|
|
CAST (
|
|
CAST ( T . RECD AS VARCHAR ( 6 ) CCSID 37 ) AS VARCHAR ( 6 )
|
|
CCSID 1208 ) AS REASON_CODE , T . WKCTR ,
|
|
COALESCE ( T . EMPNO , T . BADGE ) AS EMP_KEY ,
|
|
T . TDATE AS DB_DATE , T . TTIME AS DB_TIME , M . STID ,
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( T . TDATE ) ) ||
|
|
LPAD ( T . TTIME , 6 , '0' ) , 'YYYYMMDDHH24MISS' )
|
|
AS DB_TS ,
|
|
ROW_NUMBER ( ) OVER (
|
|
PARTITION BY T . ORDNO , T . OPSEQ , COALESCE (
|
|
T . EMPNO , T . BADGE ) , T . WKCTR
|
|
ORDER BY T . TDATE , T . TTIME
|
|
) AS SEQ
|
|
FROM MOTRAN T
|
|
JOIN MOMAST M
|
|
ON T . ORDNO = M . ORDNO
|
|
WHERE T . TCODE = 'DB'
|
|
AND T . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , T . WKCTR )
|
|
AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID )
|
|
AND T . ACREC = 'A'
|
|
AND T . TDATE BETWEEN V_DATE_PRIOR_CY AND V_DATE_CY
|
|
) ,
|
|
DOWN_END AS (
|
|
SELECT T . ORDNO , T . OPSEQ , T . WKCTR ,
|
|
COALESCE ( T . EMPNO , T . BADGE ) AS EMP_KEY ,
|
|
T . TDATE AS DE_DATE , T . TTIME AS DE_TIME , M . STID ,
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( T . TDATE ) ) ||
|
|
LPAD ( T . TTIME , 6 , '0' ) , 'YYYYMMDDHH24MISS' )
|
|
AS DE_TS ,
|
|
ROW_NUMBER ( ) OVER (
|
|
PARTITION BY T . ORDNO , T . OPSEQ , COALESCE (
|
|
T . EMPNO , T . BADGE ) , T . WKCTR
|
|
ORDER BY T . TDATE , T . TTIME
|
|
) AS SEQ
|
|
FROM MOTRAN T
|
|
JOIN MOMAST M
|
|
ON T . ORDNO = M . ORDNO
|
|
WHERE T . TCODE = 'DE'
|
|
AND T . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , T . WKCTR )
|
|
AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID )
|
|
AND T . ACREC = 'A'
|
|
AND T . TDATE = V_DATE_CY
|
|
) ,
|
|
DOWN_MATCHED AS (
|
|
SELECT DB . ORDNO , DB . REASON_CODE , DB . WKCTR , DB . STID ,
|
|
COALESCE ( R . KDSCHED , 'N' ) AS IS_SCHEDULED ,
|
|
DB . DB_TS AS START_TS ,
|
|
COALESCE ( DE . DE_TS , CE . DEFAULT_END_TS ) AS END_TS
|
|
FROM DOWN_BEGIN DB
|
|
CROSS JOIN CURRENT_END CE
|
|
LEFT JOIN DOWN_END DE
|
|
ON DB . ORDNO = DE . ORDNO
|
|
AND DB . OPSEQ = DE . OPSEQ
|
|
AND DB . EMP_KEY = DE . EMP_KEY
|
|
AND DB . SEQ = DE . SEQ
|
|
AND DB . WKCTR = DE . WKCTR
|
|
AND DB . STID = DE . STID
|
|
LEFT JOIN SFCDWR R
|
|
ON DB . REASON_CODE = R . KDREASN
|
|
) ,
|
|
-- ========== WORKCENTER/SITE LIST ==========
|
|
WC_SITE_LIST AS (
|
|
SELECT DISTINCT WKCTR , STID
|
|
FROM RUN_MATCHED
|
|
UNION
|
|
SELECT DISTINCT WKCTR , STID
|
|
FROM DOWN_MATCHED
|
|
) ,
|
|
-- ========== HOURLY BREAKDOWN ==========
|
|
ALL_HOURS AS (
|
|
SELECT HR AS HOUR_NUM ,
|
|
TO_DATE (
|
|
ZONED ( V_DATE ) || LPAD ( HR * 10000 , 6 , '0' ) ,
|
|
'YYYYMMDDHH24MISS' ) AS HR_START_TS ,
|
|
CASE
|
|
WHEN
|
|
HR = 23
|
|
THEN
|
|
TO_DATE (
|
|
ZONED ( V_DATE + 1 DAY ) || '000000' ,
|
|
'YYYYMMDDHH24MISS' )
|
|
ELSE
|
|
TO_DATE (
|
|
ZONED ( V_DATE ) ||
|
|
LPAD ( ( HR + 1 ) * 10000 , 6 , '0' ) ,
|
|
'YYYYMMDDHH24MISS' )
|
|
END AS HR_END_TS
|
|
FROM (
|
|
VALUES ( 0 ) , ( 1 ) , ( 2 ) , ( 3 ) , ( 4 ) , ( 5 ) , ( 6 ) , ( 7 ) , ( 8 ) ,( 9 ) , ( 10 ) , ( 11 ) , ( 12 ) , ( 13 ) , ( 14 ) , ( 15 ) ,
|
|
( 16 ) , ( 17 ) , ( 18 ) , ( 19 ) , ( 20 ) , ( 21 ) , ( 22 ) ,
|
|
( 23 )
|
|
) T ( HR )
|
|
) ,
|
|
-- Run time by hour per workcenter/site
|
|
RUN_HOURLY AS (
|
|
SELECT H . HOUR_NUM , R . WKCTR , R . STID ,
|
|
GREATEST (
|
|
0 , TIMESTAMPDIFF (
|
|
2 , CHAR (
|
|
LEAST ( R . END_TS , H . HR_END_TS ) -
|
|
GREATEST ( R . START_TS , H . HR_START_TS ) ) ) )
|
|
AS RUN_SECONDS , R . PCS_PER_MIN , R . QTY_COMPLETE ,
|
|
R . QTY_SCRAP , R . OFF_DATE , R . OFF_TIME , R . ITNBR , R . ORDNO
|
|
FROM RUN_MATCHED R , ALL_HOURS H
|
|
WHERE R . START_TS < H . HR_END_TS
|
|
AND R . END_TS > H . HR_START_TS
|
|
) ,
|
|
RUN_BY_HOUR AS (
|
|
SELECT HOUR_NUM , WKCTR , STID , SUM ( RUN_SECONDS ) AS RUN_SEC ,
|
|
DEC (
|
|
SUM (
|
|
DEC ( RUN_SECONDS , 15 , 4 ) *
|
|
DEC ( PCS_PER_MIN , 15 , 8 ) / 60 ) , 15 , 4 )
|
|
AS EXPECTED_QTY ,
|
|
SUM (
|
|
CASE
|
|
WHEN
|
|
HOUR (
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( OFF_DATE ) ) ||
|
|
LPAD ( OFF_TIME , 6 , '0' ) ,
|
|
'YYYYMMDDHH24MISS' ) ) = HOUR_NUM
|
|
AND CISTOOLS . CYMD2DATE ( OFF_DATE ) = V_DATE
|
|
THEN QTY_COMPLETE
|
|
ELSE 0
|
|
END ) AS ACTUAL_QTY ,
|
|
SUM (
|
|
CASE
|
|
WHEN
|
|
HOUR (
|
|
TO_DATE (
|
|
ZONED ( CISTOOLS . CYMD2DATE ( OFF_DATE ) ) ||
|
|
LPAD ( OFF_TIME , 6 , '0' ) ,
|
|
'YYYYMMDDHH24MISS' ) ) = HOUR_NUM
|
|
AND CISTOOLS . CYMD2DATE ( OFF_DATE ) = V_DATE
|
|
THEN QTY_SCRAP
|
|
ELSE 0
|
|
END ) AS SCRAP_QTY
|
|
FROM RUN_HOURLY
|
|
WHERE RUN_SECONDS > 0
|
|
GROUP BY HOUR_NUM , WKCTR , STID
|
|
) ,
|
|
-- Items per hour/wkctr/stid
|
|
HOURLY_ITEMS AS (
|
|
SELECT DISTINCT HOUR_NUM , WKCTR , STID , ORDNO , ITNBR
|
|
FROM RUN_HOURLY
|
|
WHERE RUN_SECONDS > 0
|
|
) ,
|
|
HOURLY_ITEMS_AGG AS (
|
|
SELECT HOUR_NUM , WKCTR , STID ,
|
|
JSON_ARRAYAGG (
|
|
JSON_OBJECT (
|
|
'orderNumber' : CAST (
|
|
CAST ( TRIM ( ORDNO ) AS VARCHAR ( 15 ) CCSID 37 ) AS
|
|
VARCHAR ( 15 ) CCSID 1208 ) , 'itemNumber' : CAST (
|
|
CAST ( TRIM ( ITNBR ) AS VARCHAR ( 15 ) CCSID 37 ) AS
|
|
VARCHAR ( 15 ) CCSID 1208 )
|
|
) FORMAT JSON
|
|
) AS ITEMS
|
|
FROM HOURLY_ITEMS
|
|
GROUP BY HOUR_NUM , WKCTR , STID
|
|
) ,
|
|
-- Downtime by hour per workcenter/site
|
|
DOWN_HOURLY AS (
|
|
SELECT H . HOUR_NUM , D . WKCTR , D . STID , D . IS_SCHEDULED ,
|
|
GREATEST (
|
|
0 , TIMESTAMPDIFF (
|
|
2 , CHAR (
|
|
LEAST ( D . END_TS , H . HR_END_TS ) -
|
|
GREATEST ( D . START_TS , H . HR_START_TS ) ) ) )
|
|
AS DOWN_SECONDS
|
|
FROM DOWN_MATCHED D , ALL_HOURS H
|
|
WHERE D . START_TS < H . HR_END_TS
|
|
AND D . END_TS > H . HR_START_TS
|
|
) ,
|
|
DOWN_BY_HOUR AS (
|
|
SELECT HOUR_NUM , WKCTR , STID , SUM (
|
|
CASE
|
|
WHEN IS_SCHEDULED = 'Y' THEN DOWN_SECONDS
|
|
ELSE 0
|
|
END ) AS SCHED_DOWN_SEC , SUM (
|
|
CASE
|
|
WHEN IS_SCHEDULED <> 'Y' THEN DOWN_SECONDS
|
|
ELSE 0
|
|
END ) AS UNSCHED_DOWN_SEC
|
|
FROM DOWN_HOURLY
|
|
WHERE DOWN_SECONDS > 0
|
|
GROUP BY HOUR_NUM , WKCTR , STID
|
|
) ,
|
|
-- ========== COMBINE AND CALCULATE OEE ==========
|
|
HOURLY_COMBINED AS (
|
|
SELECT A . HOUR_NUM , W . WKCTR , W . STID ,
|
|
COALESCE ( R . RUN_SEC , 0 ) AS RUN_SEC ,
|
|
COALESCE ( R . EXPECTED_QTY , DEC ( 0 , 15 , 4 ) )
|
|
AS EXPECTED_QTY ,
|
|
COALESCE ( R . ACTUAL_QTY , DEC ( 0 , 15 , 4 ) ) AS ACTUAL_QTY ,
|
|
COALESCE ( R . SCRAP_QTY , DEC ( 0 , 15 , 4 ) ) AS SCRAP_QTY ,
|
|
COALESCE ( D . SCHED_DOWN_SEC , 0 ) AS SCHED_DOWN_SEC ,
|
|
COALESCE ( D . UNSCHED_DOWN_SEC , 0 ) AS UNSCHED_DOWN_SEC ,
|
|
I . ITEMS ,
|
|
LEAST (
|
|
COALESCE ( R . RUN_SEC , 0 ) +
|
|
COALESCE ( D . SCHED_DOWN_SEC , 0 ) +
|
|
COALESCE ( D . UNSCHED_DOWN_SEC , 0 ) , 3600 )
|
|
AS TOTAL_ACTIVE_SEC
|
|
FROM ALL_HOURS A
|
|
CROSS JOIN WC_SITE_LIST W
|
|
LEFT JOIN RUN_BY_HOUR R
|
|
ON A . HOUR_NUM = R . HOUR_NUM
|
|
AND W . WKCTR = R . WKCTR
|
|
AND W . STID = R . STID
|
|
LEFT JOIN DOWN_BY_HOUR D
|
|
ON A . HOUR_NUM = D . HOUR_NUM
|
|
AND W . WKCTR = D . WKCTR
|
|
AND W . STID = D . STID
|
|
LEFT JOIN HOURLY_ITEMS_AGG I
|
|
ON A . HOUR_NUM = I . HOUR_NUM
|
|
AND W . WKCTR = I . WKCTR
|
|
AND W . STID = I . STID
|
|
) ,
|
|
HOURLY_WITH_CUM AS (
|
|
SELECT H . * , SUM ( RUN_SEC ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_RUN , SUM ( EXPECTED_QTY ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_EXPECTED , SUM ( ACTUAL_QTY ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_ACTUAL , SUM ( SCRAP_QTY ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_SCRAP , SUM ( SCHED_DOWN_SEC ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_SCHED_DOWN , SUM ( UNSCHED_DOWN_SEC ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_UNSCHED_DOWN , SUM ( TOTAL_ACTIVE_SEC ) OVER (
|
|
PARTITION BY WKCTR , STID
|
|
ORDER BY HOUR_NUM ROWS UNBOUNDED PRECEDING
|
|
) AS CUM_ACTIVE
|
|
FROM HOURLY_COMBINED H
|
|
) ,
|
|
HOURLY_OEE AS (
|
|
SELECT H . * ,
|
|
CASE
|
|
WHEN
|
|
TOTAL_ACTIVE_SEC > 0
|
|
THEN
|
|
INT (
|
|
( CAST ( RUN_SEC AS DOUBLE ) /
|
|
CAST ( TOTAL_ACTIVE_SEC AS DOUBLE ) ) * 100
|
|
+ 0.5 )
|
|
ELSE 0
|
|
END AS HRLY_AVAIL ,
|
|
CASE
|
|
WHEN
|
|
EXPECTED_QTY > 0
|
|
THEN
|
|
LEAST (
|
|
INT (
|
|
( ACTUAL_QTY / EXPECTED_QTY ) * 100 +
|
|
0.5 ) , 999 )
|
|
ELSE 0
|
|
END AS HRLY_PERF ,
|
|
CASE
|
|
WHEN
|
|
( ACTUAL_QTY + SCRAP_QTY ) > 0
|
|
THEN
|
|
INT (
|
|
( ACTUAL_QTY / ( ACTUAL_QTY + SCRAP_QTY ) ) *
|
|
100 + 0.5 )
|
|
ELSE 100
|
|
END AS HRLY_QUAL ,
|
|
CASE
|
|
WHEN
|
|
CUM_ACTIVE > 0
|
|
THEN
|
|
INT (
|
|
( CAST ( CUM_RUN AS DOUBLE ) /
|
|
CAST ( CUM_ACTIVE AS DOUBLE ) ) * 100 +
|
|
0.5 )
|
|
ELSE 0
|
|
END AS CUM_AVAIL ,
|
|
CASE
|
|
WHEN
|
|
CUM_EXPECTED > 0
|
|
THEN
|
|
LEAST (
|
|
INT (
|
|
( CUM_ACTUAL / CUM_EXPECTED ) * 100 +
|
|
0.5 ) , 999 )
|
|
ELSE 0
|
|
END AS CUM_PERF ,
|
|
CASE
|
|
WHEN
|
|
( CUM_ACTUAL + CUM_SCRAP ) > 0
|
|
THEN
|
|
INT (
|
|
( CUM_ACTUAL / ( CUM_ACTUAL + CUM_SCRAP ) ) *
|
|
100 + 0.5 )
|
|
ELSE 100
|
|
END AS CUM_QUAL
|
|
FROM HOURLY_WITH_CUM H
|
|
) ,
|
|
HOURLY_FINAL AS (
|
|
SELECT H . * ,
|
|
CASE
|
|
WHEN
|
|
HRLY_AVAIL > 0
|
|
AND HRLY_PERF > 0
|
|
AND HRLY_QUAL > 0
|
|
THEN
|
|
INT (
|
|
( CAST ( HRLY_AVAIL AS DOUBLE ) *
|
|
CAST ( HRLY_PERF AS DOUBLE ) *
|
|
CAST ( HRLY_QUAL AS DOUBLE ) / 10000 ) +
|
|
0.5 )
|
|
ELSE 0
|
|
END AS HRLY_OEE ,
|
|
CASE
|
|
WHEN
|
|
CUM_AVAIL > 0
|
|
AND CUM_PERF > 0
|
|
AND CUM_QUAL > 0
|
|
THEN
|
|
INT (
|
|
( CAST ( CUM_AVAIL AS DOUBLE ) *
|
|
CAST ( CUM_PERF AS DOUBLE ) *
|
|
CAST ( CUM_QUAL AS DOUBLE ) / 10000 ) +
|
|
0.5 )
|
|
ELSE 0
|
|
END AS CUM_OEE
|
|
FROM HOURLY_OEE H
|
|
) ,
|
|
-- ========== SHIFT TIMES PER WORKCENTER ==========
|
|
SHIFT_TIMES AS (
|
|
SELECT W . WSWKCT AS WKCTR , W . WSSTID AS STID ,
|
|
W . WSSF1B AS SHIFT1_BEGIN , W . WSSF1E AS SHIFT1_END ,
|
|
W . WSSF2B AS SHIFT2_BEGIN , W . WSSF2E AS SHIFT2_END ,
|
|
W . WSSF3B AS SHIFT3_BEGIN , W . WSSF3E AS SHIFT3_END ,
|
|
W . WSDEND AS DAY_END
|
|
FROM SFCCWKS W
|
|
) ,
|
|
-- ========== BUILD JSON ==========
|
|
JSON_HOURS AS (
|
|
SELECT WKCTR , STID , HOUR_NUM ,
|
|
JSON_OBJECT (
|
|
'hour' : HOUR_NUM , 'hourLabel' :
|
|
CASE
|
|
WHEN HOUR_NUM = 0 THEN '12AM'
|
|
WHEN
|
|
HOUR_NUM < 12
|
|
THEN TRIM ( CHAR ( HOUR_NUM ) ) || 'AM'
|
|
WHEN HOUR_NUM = 12 THEN '12PM'
|
|
ELSE TRIM ( CHAR ( HOUR_NUM - 12 ) ) || 'PM'
|
|
END ,
|
|
'items' : COALESCE ( ITEMS , JSON_ARRAY ( ) ) FORMAT JSON ,
|
|
'runMinutes' : INT ( RUN_SEC / 60 ) ,
|
|
'scheduledDownMinutes' : INT ( SCHED_DOWN_SEC / 60 ) ,
|
|
'unscheduledDownMinutes' : INT (
|
|
UNSCHED_DOWN_SEC / 60 ) , 'expectedQty' : DEC (
|
|
EXPECTED_QTY , 10 , 2 ) , 'actualQty' : DEC (
|
|
ACTUAL_QTY , 10 , 2 ) , 'scrapQty' : DEC (
|
|
SCRAP_QTY , 10 , 2 ) , 'cumulativeExpected' : DEC (
|
|
CUM_EXPECTED , 10 , 2 ) , 'cumulativeActual' : DEC (
|
|
CUM_ACTUAL , 10 , 2 ) , 'cumulativeScrap' : DEC (
|
|
CUM_SCRAP , 10 , 2 ) , 'variance' : DEC (
|
|
CUM_ACTUAL - CUM_EXPECTED , 10 , 2 ) ,
|
|
'hourlyAvailability' : HRLY_AVAIL ,
|
|
'hourlyPerformance' : HRLY_PERF ,
|
|
'hourlyQuality' : HRLY_QUAL , 'hourlyOee' : HRLY_OEE ,
|
|
'cumulativeAvailability' : CUM_AVAIL ,
|
|
'cumulativePerformance' : CUM_PERF ,
|
|
'cumulativeQuality' : CUM_QUAL ,
|
|
'cumulativeOee' : CUM_OEE
|
|
) AS HOUR_OBJ
|
|
FROM HOURLY_FINAL
|
|
) ,
|
|
WC_TOTALS AS (
|
|
SELECT WKCTR , STID , MAX ( CUM_ACTUAL ) AS TOTAL_ACTUAL ,
|
|
MAX ( CUM_EXPECTED ) AS TOTAL_EXPECTED ,
|
|
MAX ( CUM_SCRAP ) AS TOTAL_SCRAP ,
|
|
MAX ( CUM_RUN ) AS TOTAL_RUN_SEC ,
|
|
MAX ( CUM_SCHED_DOWN ) AS TOTAL_SCHED_DOWN ,
|
|
MAX ( CUM_UNSCHED_DOWN ) AS TOTAL_UNSCHED_DOWN ,
|
|
MAX ( CUM_OEE ) AS FINAL_OEE ,
|
|
MAX ( CUM_AVAIL ) AS FINAL_AVAIL ,
|
|
MAX ( CUM_PERF ) AS FINAL_PERF ,
|
|
MAX ( CUM_QUAL ) AS FINAL_QUAL
|
|
FROM HOURLY_FINAL
|
|
GROUP BY WKCTR , STID
|
|
) ,
|
|
JSON_WORKCENTERS AS (
|
|
SELECT
|
|
JSON_OBJECT (
|
|
'workcenter' : CAST (
|
|
CAST ( T . WKCTR AS VARCHAR ( 5 ) CCSID 37 ) AS VARCHAR (
|
|
5 ) CCSID 1208 ) , 'site' : CAST (
|
|
CAST ( T . STID AS VARCHAR ( 3 ) CCSID 37 ) AS VARCHAR ( 3 )
|
|
CCSID 1208 ) , 'hours' : ( SELECT JSON_ARRAYAGG (
|
|
H . HOUR_OBJ FORMAT JSON
|
|
ORDER BY H . HOUR_NUM
|
|
)
|
|
FROM JSON_HOURS H
|
|
WHERE H . WKCTR = T . WKCTR
|
|
AND H . STID = T . STID ) FORMAT JSON ,
|
|
'totals' : JSON_OBJECT (
|
|
'actualQty' : DEC (
|
|
COALESCE ( T . TOTAL_ACTUAL , DEC ( 0 , 15 , 4 ) ) , 10 ,
|
|
2 ) , 'expectedQty' : DEC (
|
|
COALESCE ( T . TOTAL_EXPECTED , DEC ( 0 , 15 , 4 ) ) , 10 ,
|
|
2 ) ,
|
|
'scrapQty' : DEC (
|
|
COALESCE ( T . TOTAL_SCRAP , DEC ( 0 , 15 , 4 ) ) , 10 , 2
|
|
) , 'variance' : DEC (
|
|
COALESCE (
|
|
T . TOTAL_ACTUAL - T . TOTAL_EXPECTED , DEC (
|
|
0 , 15 , 4 ) ) , 10 , 2 ) , 'runMinutes' : INT (
|
|
COALESCE ( T . TOTAL_RUN_SEC , 0 ) / 60 ) ,
|
|
'scheduledDownMinutes' : INT (
|
|
COALESCE ( T . TOTAL_SCHED_DOWN , 0 ) / 60 ) ,
|
|
'unscheduledDownMinutes' : INT (
|
|
COALESCE ( T . TOTAL_UNSCHED_DOWN , 0 ) / 60 ) ,
|
|
'oeePercentage' : COALESCE ( T . FINAL_OEE , 0 ) ,
|
|
'availabilityPercentage' : COALESCE (
|
|
T . FINAL_AVAIL , 0 ) ,
|
|
'performancePercentage' : COALESCE (
|
|
T . FINAL_PERF , 0 ) ,
|
|
'qualityPercentage' : COALESCE ( T . FINAL_QUAL , 0 )
|
|
) , 'shiftTimes' : (
|
|
SELECT JSON_OBJECT (
|
|
'shift1Begin' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT1_BEGIN > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT1_BEGIN , 6 , '0' ) ,
|
|
1 , 2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD (
|
|
S . SHIFT1_BEGIN , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'shift1End' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT1_END > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT1_END , 6 , '0' ) , 1 ,
|
|
2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT1_END , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'shift2Begin' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT2_BEGIN > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT2_BEGIN , 6 , '0' ) ,
|
|
1 , 2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD (
|
|
S . SHIFT2_BEGIN , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'shift2End' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT2_END > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT2_END , 6 , '0' ) , 1 ,
|
|
2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT2_END , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'shift3Begin' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT3_BEGIN > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT3_BEGIN , 6 , '0' ) ,
|
|
1 , 2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD (
|
|
S . SHIFT3_BEGIN , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'shift3End' :
|
|
CASE
|
|
WHEN
|
|
S . SHIFT3_END > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT3_END , 6 , '0' ) , 1 ,
|
|
2 ) || ':' ||
|
|
SUBSTRING (
|
|
LPAD ( S . SHIFT3_END , 6 , '0' ) ,
|
|
3 , 2 )
|
|
ELSE NULL
|
|
END , 'dayEnd' :
|
|
CASE
|
|
WHEN
|
|
S . DAY_END > 0
|
|
THEN
|
|
SUBSTRING (
|
|
LPAD ( S . DAY_END , 6 , '0' ) , 1 , 2 )
|
|
|| ':' ||
|
|
SUBSTRING (
|
|
LPAD ( S . DAY_END , 6 , '0' ) , 3 ,
|
|
2 )
|
|
ELSE NULL
|
|
END
|
|
)
|
|
FROM SHIFT_TIMES S
|
|
WHERE S . WKCTR = T . WKCTR
|
|
AND S . STID = T . STID
|
|
FETCH FIRST 1 ROW ONLY ) FORMAT JSON
|
|
) AS WC_OBJ
|
|
FROM WC_TOTALS T
|
|
ORDER BY T . WKCTR , T . STID ) SELECT JSON_ARRAY (
|
|
JSON_OBJECT (
|
|
'date' : TO_CHAR ( V_DATE , 'YYYY-MM-DD' ) , 'workcenters' : (
|
|
SELECT JSON_ARRAYAGG (
|
|
WC_OBJ FORMAT JSON
|
|
)
|
|
FROM JSON_WORKCENTERS ) FORMAT JSON ,
|
|
'dataSource' : 'MOTRAN (Live)' , 'generatedAt' : TO_CHAR (
|
|
CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' )
|
|
) )
|
|
FROM SYSIBM . SYSDUMMY1 ;
|
|
END ;
|
|
|
|
GRANT ALTER , EXECUTE
|
|
ON SPECIFIC FUNCTION RESTAPI.SFP_GET_HOURLY_OEE_LIVE
|
|
TO AMAPICS WITH GRANT OPTION ;
|
|
|
|
GRANT EXECUTE
|
|
ON SPECIFIC FUNCTION RESTAPI.SFP_GET_HOURLY_OEE_LIVE
|
|
TO PUBLIC ;
|
|
|