diff --git a/RESTAPI/Functions/SFP_GET_WORKCENTERS_DETAILS.sql b/RESTAPI/Functions/SFP_GET_WORKCENTERS_DETAILS.sql
index 411a8d5..a756787 100644
--- a/RESTAPI/Functions/SFP_GET_WORKCENTERS_DETAILS.sql
+++ b/RESTAPI/Functions/SFP_GET_WORKCENTERS_DETAILS.sql
@@ -1 +1,438 @@
-âÅã@×ÁãÈ@\ÓÉÂÓ@^@
%
%ÃÙÅÁãÅ@ÖÙ@ÙÅ×ÓÁÃÅ@ÆäÕÃãÉÖÕ@ÙÅâãÁ×ÉKâÆ×mÇÅãmæÖÙÒÃÅÕãÅÙâmÄÅãÁÉÓâ@M@
%ÉÕm×ÁÙÔ@ÃÓÖÂMòñô÷ôøóöô÷]@]@
%ÙÅãäÙÕâ@ÃÓÖÂMòñô÷ôøóöô÷]@@@
%ÓÁÕÇäÁÇÅ@âØÓ@
%â×ÅÃÉÆÉÃ@ÙÅâãÁ×ÉKâÆ×mÇÅãmæÖÙÒÃÅÕãÅÙâmÄÅãÁÉÓâ@
%ÕÖã@ÄÅãÅÙÔÉÕÉâãÉÃ@
%ÔÖÄÉÆÉÅâ@âØÓ@ÄÁãÁ@
%ÃÁÓÓÅÄ@ÖÕ@ÕäÓÓ@ÉÕ×äã@
%âÅã@Ö×ãÉÖÕ@@ÁÓæÂÓÒ@~@\ÁÓÓÙÅÁÄ@k@
%ÁÓæÃ×èÄãÁ@~@\Ö×ãÉÔÉéÅ@k@
%ÃÖÔÔÉã@~@\ÕÖÕÅ@k@
%ÄÅÃÙÅâäÓã@~@Móñk@óñk@ðð]@k@
%ÄèÕÄÆãÃÖÓ@~@\ÕÖ@k@
%ÄèÕäâÙ×ÙÆ@~@\äâÅÙ@k@
%âÙãâÅØ@~@\ÈÅç@@@
%ÂÅÇÉÕ@
%ÄÅÃÓÁÙÅ@ÅÕå@åÁÙÃÈÁÙ@M@òð@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmâÉãÅ@åÁÙÃÈÁÙ@M@ó@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmæÃ@åÁÙÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmÄÅ×ã@åÁÙÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åm×ÖâÉãÉÖÕ@åÁÙÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmâÈÖæmÁÓÓ@åÁÙÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}†�“¢…}@^@
%ÄÅÃÓÁÙÅ@åmÉÕÄÉÙÅÃã@åÁÙÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}†�“¢…}@^@
%ÄÅÃÓÁÙÅ@ÓÓ@åÁÙÃÈÁÙ@M@ñðòô@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmÉÕm×ÁÙÔ@ÃÓÖÂ@M@ò@Ç@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmãÖÄÁè@ÄÅÃÉÔÁÓ@M@÷@k@ð@]@ÄÅÆÁäÓã@ð@^@
%ÄÅÃÓÁÙÅ@åmÃäãÖÆÆ@ÄÅÃÉÔÁÓ@M@÷@k@ð@]@ÄÅÆÁäÓã@ùùùùùùù@^@
%``@Å™™–™@ˆ�•„“‰•‡@¥�™‰�‚“…¢@
%ÄÅÃÓÁÙÅ@åmâØÓâãÁãÅ@ÃÈÁÙ@M@õ@]@ÄÅÆÁäÓã@}ððððð}@^@
%ÄÅÃÓÁÙÅ@åmâØÓÃÖÄÅ@ÉÕãÅÇÅÙ@ÄÅÆÁäÓã@ð@^@
%ÄÅÃÓÁÙÅ@åmÅÙÙÔâÇ@åÁÙÃÈÁÙ@M@õðð@]@ÄÅÆÁäÓã@}}@^@
%ÄÅÃÓÁÙÅ@åmÈãã×mâãÁãäâ@ÉÕãÅÇÅÙ@ÄÅÆÁäÓã@òðð@^@
%ÄÅÃÓÁÙÅ@åmÈÁâmÅÙÙÖÙ@ÉÕãÅÇÅÙ@ÄÅÆÁäÓã@ð@^@
%``@Ã–•£‰•¤…@ˆ�•„“…™¢@†–™@…™™–™@ƒ�—£¤™…@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓâãÁãÅ@}òòðð÷}@@``@É•¥�“‰„@„�£…£‰”…@
%ÂÅÇÉÕ@
%âÅã@åmâØÓâãÁãÅ@~@}òòðð÷}@^@
%ÇÅã@ÄÉÁÇÕÖâãÉÃâ@ÃÖÕÄÉãÉÖÕ@ñ@åmÅÙÙÔâÇ@~@ÔÅââÁÇÅmãÅçã@^@
%âÅã@åmÈãã×mâãÁãäâ@~@ôðð@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓâãÁãÅ@}òòððó}@@``@Õ¤”…™‰ƒ@–¤£@–†@™�•‡…@
%ÂÅÇÉÕ@
%âÅã@åmâØÓâãÁãÅ@~@}òòððó}@^@
%ÇÅã@ÄÉÁÇÕÖâãÉÃâ@ÃÖÕÄÉãÉÖÕ@ñ@åmÅÙÙÔâÇ@~@ÔÅââÁÇÅmãÅçã@^@
%âÅã@åmÈãã×mâãÁãäâ@~@ôðð@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓâãÁãÅ@}ðòððð}@@``@Õ–@„�£�@†–¤•„@
%ÂÅÇÉÕ@
%âÅã@åmâØÓâãÁãÅ@~@}ðòððð}@^@
%âÅã@åmÅÙÙÔâÇ@~@}Õ–@„�£�@†–¤•„@†–™@£ˆ…@¢—…ƒ‰†‰…„@ƒ™‰£…™‰�}@^@
%âÅã@åmÈãã×mâãÁãäâ@~@ôðô@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓâãÁãÅ@}ôòõðñ}@@``@Õ–£@�¤£ˆ–™‰©…„@
%ÂÅÇÉÕ@
%âÅã@åmâØÓâãÁãÅ@~@}ôòõðñ}@^@
%ÇÅã@ÄÉÁÇÕÖâãÉÃâ@ÃÖÕÄÉãÉÖÕ@ñ@åmÅÙÙÔâÇ@~@ÔÅââÁÇÅmãÅçã@^@
%âÅã@åmÈãã×mâãÁãäâ@~@ôðó@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓâãÁãÅ@}ôò÷ðô}@@``@Ö‚‘…ƒ£@•–£@†–¤•„@
%ÂÅÇÉÕ@
%âÅã@åmâØÓâãÁãÅ@~@}ôò÷ðô}@^@
%ÇÅã@ÄÉÁÇÕÖâãÉÃâ@ÃÖÕÄÉãÉÖÕ@ñ@åmÅÙÙÔâÇ@~@ÔÅââÁÇÅmãÅçã@^@
%âÅã@åmÈãã×mâãÁãäâ@~@ôðô@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%ÄÅÃÓÁÙÅ@ÃÖÕãÉÕäÅ@ÈÁÕÄÓÅÙ@ÆÖÙ@âØÓÅçÃÅ×ãÉÖÕ@
%ÂÅÇÉÕ@
%ÇÅã@ÄÉÁÇÕÖâãÉÃâ@ÃÖÕÄÉãÉÖÕ@ñ@
%åmâØÓâãÁãÅ@~@ÙÅãäÙÕÅÄmâØÓâãÁãÅ@k@
%åmâØÓÃÖÄÅ@~@ÄÂòmÙÅãäÙÕÅÄmâØÓÃÖÄÅ@k@åmÅÙÙÔâÇ@~@ÔÅââÁÇÅmãÅçã@^@
%âÅã@åmÈãã×mâãÁãäâ@~@õðð@^@
%âÅã@åmÈÁâmÅÙÙÖÙ@~@ñ@^@
%ÅÕÄ@^@
%``@×�™¢…@‰•—¤£@—�™�”…£…™¢@
%âÅã@åmâÉãÅ@~@ÃÖÁÓÅâÃÅ@M@ÑâÖÕmåÁÓäÅ@M@ÉÕm×ÁÙÔ@k@}[K¢‰£…}@]@k@}}@]@^@
%âÅã
\ No newline at end of file
+SET PATH *LIBL ; 
+
+CREATE OR REPLACE FUNCTION RESTAPI.SFP_GET_WORKCENTERS_DETAILS ( 
+	IN_PARM CLOB(2147483647) ) 
+	RETURNS CLOB(2147483647)   
+	LANGUAGE SQL 
+	SPECIFIC RESTAPI.SFP_GET_WORKCENTERS_DETAILS 
+	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_SITE VARCHAR ( 3 ) DEFAULT '' ; 
+DECLARE V_WC VARCHAR ( 5 ) DEFAULT '' ; 
+DECLARE V_DEPT VARCHAR ( 5 ) DEFAULT '' ; 
+DECLARE V_POSITION VARCHAR ( 5 ) DEFAULT '' ; 
+DECLARE V_SHOW_ALL VARCHAR ( 5 ) DEFAULT 'false' ; 
+DECLARE V_INDIRECT VARCHAR ( 5 ) DEFAULT 'false' ; 
+DECLARE LL VARCHAR ( 1024 ) DEFAULT '' ; 
+DECLARE V_IN_PARM CLOB ( 2 G ) DEFAULT '' ; 
+DECLARE V_TODAY DECIMAL ( 7 , 0 ) DEFAULT 0 ; 
+DECLARE V_CUTOFF DECIMAL ( 7 , 0 ) DEFAULT 9999999 ; 
+-- 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_SITE = COALESCE ( JSON_VALUE ( IN_PARM , '$.site' ) , '' ) ; 
+SET V_WC = COALESCE ( JSON_VALUE ( IN_PARM , '$.workcenter' ) , '' ) ; 
+SET V_DEPT = COALESCE ( JSON_VALUE ( IN_PARM , '$.department' ) , '' ) ; 
+SET V_POSITION = COALESCE ( JSON_VALUE ( IN_PARM , '$.positionTo' ) , '' ) ; 
+SET V_SHOW_ALL = COALESCE ( JSON_VALUE ( IN_PARM , '$.showAll' ) , 'false' ) ;SET V_INDIRECT = COALESCE ( 
+JSON_VALUE ( IN_PARM , '$.indirectOnly' ) , 'false' ) ; 
+-- 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 ; 
+-- Calculate today's date in CYYMMDD 
+SET V_TODAY = ZONED ( CURRENT_DATE ) - 19000000 ; 
+RETURN 
+WITH 
+-- Base workcenter list from FACMST (EPDM) joined with SITMST 
+-- Excludes simulation sites (sims = '0') 
+WC_BASE AS ( 
+SELECT F . WKCTR , F . WCDSC , F . FRMAN , F . DPTNO , F . STID , 
+TRIM ( F . WKGRP ) AS WKGRP , F . WLNCD 
+FROM FACMST F 
+JOIN SITMST S 
+ON F . STID = S . STID 
+WHERE S . SIMS = '0' 
+AND F . STID = COALESCE ( NULLIF ( V_SITE , '' ) , F . STID ) 
+AND F . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , F . WKCTR ) 
+AND F . DPTNO = COALESCE ( NULLIF ( V_DEPT , '' ) , F . DPTNO ) 
+AND F . WKCTR >= COALESCE ( 
+NULLIF ( V_POSITION , '' ) , F . WKCTR ) 
+AND ( V_INDIRECT <> 'true' 
+OR F . WKGRP = 'IND' ) 
+AND ( V_INDIRECT = 'true' 
+OR F . WKGRP <> 'IND' 
+OR V_SHOW_ALL = 'true' ) 
+) , 
+-- Down status from SFCCWKS joined with SFCDWR for reason description 
+DOWN_STATUS AS ( 
+SELECT W . WSWKCT AS WKCTR , W . WSSTID AS STID , 
+TRIM ( W . WSDWNR ) AS DOWN_REASON , 
+TRIM ( D . KDRDESC ) AS DOWN_DESCRIPTION , 
+D . KDSCHED AS SCHEDULED_DOWN , W . WSSF1B , W . WSSF1E , 
+W . WSSF2B , W . WSSF2E , W . WSSF3B , W . WSSF3E , W . WSDEND , 
+W . WSCCRW AS CURRENT_CREW 
+FROM SFCCWKS W 
+LEFT JOIN SFCDWR D 
+ON TRIM ( W . WSDWNR ) = TRIM ( D . KDREASN ) 
+) , 
+-- Latest transaction per badge/ordno/opseq to determine ON status 
+-- Mimics SFP002R get_oncnt logic 
+LATEST_TRANS AS ( 
+SELECT T . BADGE , T . ORDNO , T . OPSEQ , T . TRFMT , 
+ROW_NUMBER ( ) OVER ( 
+PARTITION BY T . BADGE , T . ORDNO , T . OPSEQ 
+ORDER BY T . TDATE DESC , T . TTIME DESC 
+) AS RN 
+FROM TRDATA T 
+WHERE T . TRFMT IN ( 'ON' , 'OF' ) 
+AND T . TSTAT < 5 
+AND T . ACREC = 'Y' 
+) , 
+-- Active employees per workcenter/site 
+ACTIVE_EMPS AS ( 
+SELECT R . AWRKC AS WKCTR , M . STID , COUNT ( * ) AS ACTIVE_OPS , 
+COUNT ( DISTINCT L . BADGE ) AS UNIQUE_EMPS 
+FROM LATEST_TRANS L 
+JOIN MOMAST M 
+ON L . ORDNO = M . ORDNO 
+JOIN MOROUT R 
+ON L . ORDNO = R . ORDNO 
+AND L . OPSEQ = R . OPSEQ 
+WHERE L . RN = 1 
+AND L . TRFMT = 'ON' 
+GROUP BY R . AWRKC , M . STID 
+) , 
+-- Open order count per workcenter/site 
+-- Orders with opstc > '00' and < '40', ostat > '00' and < '45' 
+OPEN_ORDERS AS ( 
+SELECT R . AWRKC AS WKCTR , M . STID , 
+COUNT ( DISTINCT R . ORDNO ) AS OPEN_COUNT 
+FROM MOROUT R 
+JOIN MOMAST M 
+ON R . ORDNO = M . ORDNO 
+WHERE R . OPSTC > '00' 
+AND R . OPSTC < '40' 
+AND M . OSTAT > '00' 
+AND M . OSTAT < '45' 
+AND M . ODUDT <= V_CUTOFF 
+GROUP BY R . AWRKC , M . STID 
+) , 
+-- Planned order count per workcenter/site (from LRP) 
+PLANNED_ORDERS AS ( 
+SELECT W . RPWKCT AS WKCTR , W . RPSTID AS STID , 
+COUNT ( DISTINCT W . RPORTK ) AS PLANNED_COUNT 
+FROM LRPWKCT W 
+JOIN ORDREV O 
+ON W . RPORTK = O . TKEN 
+WHERE W . RPODUD <= V_CUTOFF 
+AND W . RPORTK <> ' ' 
+AND O . NNUMB = ' ' 
+GROUP BY W . RPWKCT , W . RPSTID 
+) , 
+-- Combine all data 
+WC_COMBINED AS ( 
+SELECT B . WKCTR , B . WCDSC , B . FRMAN , B . DPTNO , B . STID , B . WKGRP , 
+B . WLNCD , COALESCE ( D . DOWN_REASON , '' ) AS DOWN_REASON , 
+COALESCE ( D . DOWN_DESCRIPTION , '' ) AS DOWN_DESCRIPTION , 
+COALESCE ( D . SCHEDULED_DOWN , '' ) AS SCHEDULED_DOWN , 
+COALESCE ( D . CURRENT_CREW , '' ) AS CURRENT_CREW , 
+COALESCE ( D . WSSF1B , 0 ) AS SF1_BEGIN , 
+COALESCE ( D . WSSF1E , 0 ) AS SF1_END , 
+COALESCE ( D . WSSF2B , 0 ) AS SF2_BEGIN , 
+COALESCE ( D . WSSF2E , 0 ) AS SF2_END , 
+COALESCE ( D . WSSF3B , 0 ) AS SF3_BEGIN , 
+COALESCE ( D . WSSF3E , 0 ) AS SF3_END , 
+COALESCE ( D . WSDEND , 0 ) AS DAY_END , 
+COALESCE ( A . ACTIVE_OPS , 0 ) AS ACTIVE_OPS , 
+COALESCE ( A . UNIQUE_EMPS , 0 ) AS UNIQUE_EMPS , 
+COALESCE ( O . OPEN_COUNT , 0 ) AS OPEN_ORDERS , 
+COALESCE ( P . PLANNED_COUNT , 0 ) AS PLANNED_ORDERS 
+FROM WC_BASE B 
+LEFT JOIN DOWN_STATUS D 
+ON B . WKCTR = D . WKCTR 
+AND B . STID = D . STID 
+LEFT JOIN ACTIVE_EMPS A 
+ON B . WKCTR = A . WKCTR 
+AND B . STID = A . STID 
+LEFT JOIN OPEN_ORDERS O 
+ON B . WKCTR = O . WKCTR 
+AND B . STID = O . STID 
+LEFT JOIN PLANNED_ORDERS P 
+ON B . WKCTR = P . WKCTR 
+AND B . STID = P . STID 
+) , 
+-- Build JSON for each workcenter 
+JSON_ROWS AS ( 
+SELECT 
+JSON_OBJECT ( 
+'workcenterId' : TRIM ( 
+CAST ( WKCTR AS VARCHAR ( 5 ) CCSID 37 ) ) , 
+'workcenterDescription' : TRIM ( 
+CAST ( WCDSC AS VARCHAR ( 50 ) CCSID 37 ) ) , 
+'site' : TRIM ( CAST ( STID AS VARCHAR ( 5 ) CCSID 37 ) ) , 
+'department' : TRIM ( 
+CAST ( DPTNO AS VARCHAR ( 5 ) CCSID 37 ) ) , 
+'foreman' : TRIM ( 
+CAST ( FRMAN AS VARCHAR ( 5 ) CCSID 37 ) ) , 
+'workGroup' : 
+CASE 
+WHEN WKGRP = '' THEN NULL 
+ELSE CAST ( WKGRP AS VARCHAR ( 50 ) CCSID 37 ) 
+END , 'isProductionLine' : 
+CASE 
+WHEN WLNCD = '1' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON , 'isIndirect' : 
+CASE 
+WHEN WKGRP = 'IND' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON , 'isDown' : 
+CASE 
+WHEN DOWN_REASON <> '' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON , 'downReason' : 
+CASE 
+WHEN DOWN_REASON = '' THEN NULL 
+ELSE 
+JSON_OBJECT ( 
+'reasonCode' : DOWN_REASON , 
+'description' : DOWN_DESCRIPTION , 
+'scheduled' : 
+CASE 
+WHEN 
+SCHEDULED_DOWN = 'Y' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON 
+) 
+END FORMAT JSON , 'currentCrew' : 
+CASE 
+WHEN CURRENT_CREW = '' THEN NULL 
+ELSE CURRENT_CREW 
+END , 'activeOperations' : ACTIVE_OPS , 
+'uniqueEmployees' : UNIQUE_EMPS , 
+'employeeDisplay' : 
+CASE 
+WHEN 
+ACTIVE_OPS > 0 
+THEN 
+TRIM ( CHAR ( UNIQUE_EMPS ) ) || ' / ' || 
+TRIM ( CHAR ( ACTIVE_OPS ) ) 
+ELSE NULL 
+END , 'openOrders' : OPEN_ORDERS , 
+'plannedOrders' : PLANNED_ORDERS , 
+'shiftTimes' : JSON_OBJECT ( 
+'shift1Begin' : 
+CASE 
+WHEN 
+SF1_BEGIN > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF1_BEGIN , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF1_BEGIN , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'shift1End' : 
+CASE 
+WHEN 
+SF1_END > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF1_END , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF1_END , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'shift2Begin' : 
+CASE 
+WHEN 
+SF2_BEGIN > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF2_BEGIN , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF2_BEGIN , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'shift2End' : 
+CASE 
+WHEN 
+SF2_END > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF2_END , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF2_END , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'shift3Begin' : 
+CASE 
+WHEN 
+SF3_BEGIN > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF3_BEGIN , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF3_BEGIN , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'shift3End' : 
+CASE 
+WHEN 
+SF3_END > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( SF3_END , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( SF3_END , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END , 'dayEnd' : 
+CASE 
+WHEN 
+DAY_END > 0 
+THEN 
+SUBSTRING ( 
+LPAD ( DAY_END , 6 , '0' ) , 1 , 2 ) || 
+':' || 
+SUBSTRING ( 
+LPAD ( DAY_END , 6 , '0' ) , 3 , 2 ) 
+ELSE NULL 
+END 
+) 
+) AS WC_OBJ , ACTIVE_OPS , UNIQUE_EMPS 
+FROM WC_COMBINED 
+ORDER BY WKCTR ) , 
+-- Calculate totals 
+TOTALS AS ( 
+SELECT SUM ( ACTIVE_OPS ) AS TOTAL_ACTIVE_OPS , 
+SUM ( UNIQUE_EMPS ) AS TOTAL_UNIQUE_EMPS , 
+COUNT ( * ) AS WORKCENTER_COUNT 
+FROM WC_COMBINED 
+) SELECT JSON_OBJECT ( 
+'workcenters' : ( SELECT JSON_ARRAYAGG ( 
+WC_OBJ FORMAT JSON 
+) 
+FROM JSON_ROWS ) FORMAT JSON , 'totals' : JSON_OBJECT ( 
+'workcenterCount' : T . WORKCENTER_COUNT , 
+'totalActiveOperations' : COALESCE ( T . TOTAL_ACTIVE_OPS , 0 ) , 
+'totalUniqueEmployees' : COALESCE ( T . TOTAL_UNIQUE_EMPS , 0 ) , 
+'employeeDisplay' : TRIM ( 
+CHAR ( COALESCE ( T . TOTAL_UNIQUE_EMPS , 0 ) ) ) || ' / ' || 
+TRIM ( CHAR ( COALESCE ( T . TOTAL_ACTIVE_OPS , 0 ) ) ) 
+) , 'filters' : JSON_OBJECT ( 
+'site' : 
+CASE 
+WHEN V_SITE = '' THEN NULL 
+ELSE V_SITE 
+END , 'workcenter' : 
+CASE 
+WHEN V_WC = '' THEN NULL 
+ELSE V_WC 
+END , 'department' : 
+CASE 
+WHEN V_DEPT = '' THEN NULL 
+ELSE V_DEPT 
+END , 'showAll' : 
+CASE 
+WHEN V_SHOW_ALL = 'true' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON , 'indirectOnly' : 
+CASE 
+WHEN V_INDIRECT = 'true' THEN 'true' 
+ELSE 'false' 
+END FORMAT JSON 
+) , 'generatedAt' : TO_CHAR ( 
+CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' ) 
+) 
+FROM TOTALS T ; 
+END  ; 
+
+GRANT ALTER , EXECUTE   
+ON SPECIFIC FUNCTION RESTAPI.SFP_GET_WORKCENTERS_DETAILS 
+TO AMAPICS WITH GRANT OPTION ; 
+
+GRANT EXECUTE   
+ON SPECIFIC FUNCTION RESTAPI.SFP_GET_WORKCENTERS_DETAILS 
+TO PUBLIC ; 
+
