SET PATH *LIBL ; 

CREATE OR REPLACE FUNCTION RESTAPI.SFP_GET_SHIFT_INFO ( 
	IN_PARM CLOB(2147483647) ) 
	RETURNS CLOB(2147483647)   
	LANGUAGE SQL 
	SPECIFIC RESTAPI.SFP_GET_SHIFT_INFO 
	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_WC VARCHAR ( 5 ) DEFAULT '' ; 
DECLARE V_SITE VARCHAR ( 3 ) DEFAULT '' ; 
DECLARE LL VARCHAR ( 1024 ) DEFAULT '' ; 
DECLARE V_IN_PARM CLOB ( 2 G ) DEFAULT '' ; 
-- Error handling variables 
DECLARE V_SQLSTATE CHAR ( 5 ) DEFAULT '00000' ; 
DECLARE V_SQLCODE INTEGER DEFAULT 0 ; 
DECLARE V_ERRMSG VARCHAR ( 500 ) DEFAULT '' ; 
DECLARE V_HTTP_STATUS INTEGER DEFAULT 200 ; 
DECLARE V_HAS_ERROR INTEGER DEFAULT 0 ; 
-- Continue handlers for error capture 
DECLARE CONTINUE HANDLER FOR SQLSTATE '22007'  -- Invalid datetime 
BEGIN 
SET V_SQLSTATE = '22007' ; 
GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; 
SET V_HTTP_STATUS = 400 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
DECLARE CONTINUE HANDLER FOR SQLSTATE '22003'  -- Numeric out of range 
BEGIN 
SET V_SQLSTATE = '22003' ; 
GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; 
SET V_HTTP_STATUS = 400 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'  -- No data found 
BEGIN 
SET V_SQLSTATE = '02000' ; 
SET V_ERRMSG = 'No data found for the specified criteria' ; 
SET V_HTTP_STATUS = 404 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
DECLARE CONTINUE HANDLER FOR SQLSTATE '42501'  -- Not authorized 
BEGIN 
SET V_SQLSTATE = '42501' ; 
GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; 
SET V_HTTP_STATUS = 403 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
DECLARE CONTINUE HANDLER FOR SQLSTATE '42704'  -- Object not found 
BEGIN 
SET V_SQLSTATE = '42704' ; 
GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; 
SET V_HTTP_STATUS = 404 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
BEGIN 
GET DIAGNOSTICS CONDITION 1 
V_SQLSTATE = RETURNED_SQLSTATE , 
V_SQLCODE = DB2_RETURNED_SQLCODE , V_ERRMSG = MESSAGE_TEXT ; 
SET V_HTTP_STATUS = 500 ; 
SET V_HAS_ERROR = 1 ; 
END ; 
-- Parse input parameters 
SET V_WC = COALESCE ( JSON_VALUE ( IN_PARM , '$.workcenter' ) , '' ) ; 
SET V_SITE = COALESCE ( JSON_VALUE ( IN_PARM , '$.site' ) , '' ) ; 
-- 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 ) ; 
-- Validate environment was set 
IF ENV = '' 
OR ENV IS NULL THEN 
RETURN 
JSON_OBJECT ( 
'error' : JSON_OBJECT ( 
'http_status' : 400 , 'sqlstate' : '22001' , 
'message' : 'Environment parameter is required' 
) 
) ; 
END IF ; 
-- Check for errors from library list setup 
IF V_HAS_ERROR = 1 THEN 
RETURN 
JSON_OBJECT ( 
'error' : JSON_OBJECT ( 
'http_status' : V_HTTP_STATUS , 'sqlstate' : V_SQLSTATE , 
'message' : V_ERRMSG 
) 
) ; 
END IF ; 
RETURN 
WITH SHIFT_CALC AS ( 
SELECT WSWKCT AS WORKCENTER , WSSTID AS SITE , 
TRIM ( WSGRP1 ) AS PLANT , TRIM ( WSGRP2 ) AS DEPT , 
WSCCRW AS CURRENT_CREW , TRIM ( WSDWNR ) AS DOWN_REASON , 
KDRDESC AS DOWN_DESCRIPTION , 
KDSCHED AS SCHEDULED_DOWN , 
CURRENT_TIMESTAMP AS CURRENT_TS , 
-- Shift 1 boundaries 
TO_DATE ( 
ZONED ( CURRENT_DATE ) || LPAD ( WSSF1B , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT1_START , 
TO_DATE ( 
ZONED ( 
CASE 
WHEN WSSF1E >= WSSF1B THEN CURRENT_DATE 
ELSE CURRENT_DATE + 1 DAY 
END ) || LPAD ( WSSF1E , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT1_END , 
-- Shift 2 boundaries 
TO_DATE ( 
ZONED ( CURRENT_DATE ) || LPAD ( WSSF2B , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT2_START , 
TO_DATE ( 
ZONED ( 
CASE 
WHEN WSSF2E >= WSSF2B THEN CURRENT_DATE 
ELSE CURRENT_DATE + 1 DAY 
END ) || LPAD ( WSSF2E , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT2_END , 
-- Shift 3 boundaries 
TO_DATE ( 
ZONED ( CURRENT_DATE ) || LPAD ( WSSF3B , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT3_START , 
TO_DATE ( 
ZONED ( 
CASE 
WHEN WSSF3E >= WSSF3B THEN CURRENT_DATE 
ELSE CURRENT_DATE + 1 DAY 
END ) || LPAD ( WSSF3E , 6 , '0' ) , 
'YYYYMMDDHH24MISS' ) AS SHIFT3_END , 
WSSF1B AS SF1_BEGIN , WSSF1E AS SF1_END , 
WSSF2B AS SF2_BEGIN , WSSF2E AS SF2_END , 
WSSF3B AS SF3_BEGIN , WSSF3E AS SF3_END , 
WSDEND AS DAY_END 
FROM SFCCWKS 
LEFT JOIN SFCDWR 
ON TRIM ( WSDWNR ) = COALESCE ( 
TRIM ( KDREASN ) , LEFT ( 
KDRDESC , LENGTH ( TRIM ( WSDWNR ) ) ) ) 
WHERE WSWKCT = COALESCE ( NULLIF ( V_WC , '' ) , WSWKCT ) 
AND WSSTID = COALESCE ( NULLIF ( V_SITE , '' ) , WSSTID ) 
) , 
SHIFT_INFO AS ( 
SELECT WORKCENTER , SITE , PLANT , DEPT , CURRENT_CREW , 
DOWN_REASON , CURRENT_TS , SHIFT1_START , SHIFT1_END , 
SHIFT2_START , SHIFT2_END , SHIFT3_START , SHIFT3_END , 
SF1_BEGIN , SF1_END , SF2_BEGIN , SF2_END , SF3_BEGIN , 
SF3_END , DAY_END , DOWN_DESCRIPTION , SCHEDULED_DOWN , 
CASE 
WHEN 
CURRENT_TS BETWEEN SHIFT1_START AND SHIFT1_END 
THEN 1 
WHEN 
CURRENT_TS BETWEEN SHIFT2_START AND SHIFT2_END 
THEN 2 
WHEN 
CURRENT_TS BETWEEN SHIFT3_START AND SHIFT3_END 
THEN 3 
ELSE 0 
END AS SHIFT_NUM , 
CASE 
WHEN 
CURRENT_TS BETWEEN SHIFT1_START AND SHIFT1_END 
THEN SHIFT1_START 
WHEN 
CURRENT_TS BETWEEN SHIFT2_START AND SHIFT2_END 
THEN SHIFT2_START 
WHEN 
CURRENT_TS BETWEEN SHIFT3_START AND SHIFT3_END 
THEN SHIFT3_START 
ELSE NULL 
END AS CURRENT_SHIFT_START , 
CASE 
WHEN 
CURRENT_TS BETWEEN SHIFT1_START AND SHIFT1_END 
THEN SHIFT1_END 
WHEN 
CURRENT_TS BETWEEN SHIFT2_START AND SHIFT2_END 
THEN SHIFT2_END 
WHEN 
CURRENT_TS BETWEEN SHIFT3_START AND SHIFT3_END 
THEN SHIFT3_END 
ELSE NULL 
END AS CURRENT_SHIFT_END 
FROM SHIFT_CALC 
) , 
JSON_ROWS AS ( 
SELECT 
JSON_OBJECT ( 
'workcenterId' : WORKCENTER , 'site' : SITE , 
'plant' : PLANT , 'department' : DEPT , 
'currentCrew' : CURRENT_CREW , 'downReason' : 
CASE 
WHEN DOWN_REASON = '' THEN NULL 
ELSE 
JSON_OBJECT ( 
'reasonCode' VALUE TRIM ( DOWN_REASON ) , 
'descriptiveReason' VALUE TRIM ( 
DOWN_DESCRIPTION ) , 'secheduled' VALUE 
CASE SCHEDULED_DOWN 
WHEN 'Y' THEN 'true' 
ELSE 'false' 
END FORMAT JSON 
) 
END FORMAT JSON , 'isDown' : 
CASE 
WHEN DOWN_REASON <> '' THEN 'true' 
ELSE 'false' 
END FORMAT JSON , 'currentShiftNumber' : SHIFT_NUM , 
'currentShiftStart' : 
CASE 
WHEN 
CURRENT_SHIFT_START IS NOT NULL 
THEN 
TO_CHAR ( 
CURRENT_SHIFT_START , 
'YYYY-MM-DD HH24:MI:SS' ) 
ELSE NULL 
END , 'currentShiftEnd' : 
CASE 
WHEN 
CURRENT_SHIFT_END IS NOT NULL 
THEN 
TO_CHAR ( 
CURRENT_SHIFT_END , 
'YYYY-MM-DD HH24:MI:SS' ) 
ELSE NULL 
END , 'shift1Begin' : SUBSTRING ( 
LPAD ( SF1_BEGIN , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF1_BEGIN , 6 , '0' ) , 3 , 2 ) , 
'shift1End' : SUBSTRING ( 
LPAD ( SF1_END , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF1_END , 6 , '0' ) , 3 , 2 ) , 
'shift2Begin' : SUBSTRING ( 
LPAD ( SF2_BEGIN , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF2_BEGIN , 6 , '0' ) , 3 , 2 ) , 
'shift2End' : SUBSTRING ( 
LPAD ( SF2_END , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF2_END , 6 , '0' ) , 3 , 2 ) , 
'shift3Begin' : SUBSTRING ( 
LPAD ( SF3_BEGIN , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF3_BEGIN , 6 , '0' ) , 3 , 2 ) , 
'shift3End' : SUBSTRING ( 
LPAD ( SF3_END , 6 , '0' ) , 1 , 2 ) || ':' || 
SUBSTRING ( LPAD ( SF3_END , 6 , '0' ) , 3 , 2 ) , 
'dayEnd' : SUBSTRING ( LPAD ( DAY_END , 6 , '0' ) , 1 , 2 ) 
|| ':' || 
SUBSTRING ( LPAD ( DAY_END , 6 , '0' ) , 3 , 2 ) 
) AS WC_OBJ 
FROM SHIFT_INFO 
ORDER BY WORKCENTER , SITE ) SELECT JSON_OBJECT ( 
'workcenters' : JSON_ARRAYAGG ( 
WC_OBJ FORMAT JSON 
) , 'currentTimestamp' : TO_CHAR ( 
CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' ) , 
'generatedAt' : TO_CHAR ( 
CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' ) 
) 
FROM JSON_ROWS ; 
END  ; 

GRANT ALTER , EXECUTE   
ON SPECIFIC FUNCTION RESTAPI.SFP_GET_SHIFT_INFO 
TO AMAPICS WITH GRANT OPTION ; 

GRANT EXECUTE   
ON SPECIFIC FUNCTION RESTAPI.SFP_GET_SHIFT_INFO 
TO PUBLIC ; 

