SET PATH *LIBL ; CREATE OR REPLACE FUNCTION RESTAPI.SFP_GET_WORK_ORDERS ( IN_PARM CLOB(2147483647) ) RETURNS CLOB(2147483647) LANGUAGE SQL SPECIFIC RESTAPI.SFP_GET_WORK_ORDERS 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 V_CUTOFF DECIMAL ( 7 , 0 ) DEFAULT 9999999 ; DECLARE V_SORT CHAR ( 1 ) DEFAULT 'D' ; DECLARE V_TODAY DECIMAL ( 7 , 0 ) ; 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' ) , '' ) ; SET V_SORT = COALESCE ( UPPER ( JSON_VALUE ( IN_PARM , '$.sort' ) ) , 'D' ) ; SET V_CUTOFF = COALESCE ( DECIMAL ( JSON_VALUE ( IN_PARM , '$.cutoffDate' ) , 7 , 0 ) , 9999999 ) ; -- 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 -- Get all orders with routing operations at this workcenter BASE_ORDERS AS ( SELECT R . ORDNO , R . OPSEQ , R . AWRKC AS WKCTR , R . OPSTC , R . SSTDT , R . SCODT , R . TQCTD , R . SCRAP , R . OPDSC , M . FITEM , M . FDESC , M . OSTAT , M . ORQTY , M . QTDEV , M . QTYRC , M . QTSCP , M . QTSPL , M . ODUDT , M . SSTDT AS MO_SSTDT , M . STID , M . UU40MY , -- Calculate open at operation M . ORQTY + M . QTDEV - COALESCE ( M . QTSPL , 0 ) AS ADJ_QTY FROM MOROUT R JOIN MOMAST M ON R . ORDNO = M . ORDNO WHERE R . AWRKC = COALESCE ( NULLIF ( V_WC , '' ) , R . AWRKC ) AND R . OPSTC BETWEEN '10' AND '30' AND M . OSTAT BETWEEN '10' AND '40' AND M . ORLCD = 5 AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID ) AND ( V_CUTOFF = 9999999 OR M . ODUDT <= V_CUTOFF ) ) , -- Get active ON transactions (employees currently on jobs) ACTIVE_TRANS AS ( SELECT T . ORDNO , T . OPSEQ , T . BADGE , T . SUBTP , T . TRFMT , T . TDATE ,T . TTIME , ROW_NUMBER ( ) OVER ( PARTITION BY T . ORDNO , T . OPSEQ , T . BADGE ORDER BY T . TDATE DESC , T . TTIME DESC ) AS RN FROM TRDATA T JOIN MOMAST M ON T . ORDNO = M . ORDNO WHERE T . TRFMT IN ( 'ON' , 'OF' ) AND T . WKCTR = COALESCE ( NULLIF ( V_WC , '' ) , T . WKCTR ) AND M . STID = COALESCE ( NULLIF ( V_SITE , '' ) , M . STID ) AND T . ACREC = 'Y' AND T . TSTAT < 5 ) , -- Filter to only currently ON (latest trans is ON) CURRENTLY_ON AS ( SELECT ORDNO , OPSEQ , BADGE , SUBTP FROM ACTIVE_TRANS WHERE RN = 1 AND TRFMT = 'ON' ) , -- Aggregate active employees per order/operation ACTIVE_EMPS AS ( SELECT ORDNO , OPSEQ , COUNT ( DISTINCT BADGE ) AS ACTIVE_COUNT , MAX ( CASE WHEN SUBTP = 'R' THEN 1 ELSE 0 END ) AS HAS_RUN , MAX ( CASE WHEN SUBTP = 'S' THEN 1 ELSE 0 END ) AS HAS_SETUP , MAX ( CASE WHEN SUBTP = 'I' THEN 1 ELSE 0 END ) AS HAS_INDIRECT , LISTAGG ( DISTINCT CAST ( BADGE AS VARCHAR ( 10 ) ) , ',' ) WITHIN GROUP ( ORDER BY BADGE ) AS EMP_LIST FROM CURRENTLY_ON GROUP BY ORDNO , OPSEQ ) , -- Get management priorities PRIORITIES AS ( SELECT SMORDR AS ORDNO , SMOPSQ AS OPSEQ , SMPRI AS PRIORITY FROM SFMPRI WHERE SMPRI <> '' ) , -- Get prior operation quantities for open at operation calc PRIOR_OPS AS ( SELECT R . ORDNO , R . OPSEQ , COALESCE ( SUM ( CASE WHEN PR . OPSEQ < R . OPSEQ THEN PR . TQCTD ELSE 0 END ) , 0 ) AS PRIOR_COMPLETE FROM MOROUT R LEFT JOIN MOROUT PR ON R . ORDNO = PR . ORDNO AND PR . OPSEQ < R . OPSEQ GROUP BY R . ORDNO , R . OPSEQ ) , -- Combine all data COMBINED AS ( SELECT B . * , COALESCE ( A . ACTIVE_COUNT , 0 ) AS ACTIVE_EMP_COUNT , COALESCE ( A . HAS_RUN , 0 ) AS HAS_RUN , COALESCE ( A . HAS_SETUP , 0 ) AS HAS_SETUP , COALESCE ( A . HAS_INDIRECT , 0 ) AS HAS_INDIRECT , A . EMP_LIST , P . PRIORITY AS MGMT_PRIORITY , -- Calculate open at operation B . ADJ_QTY - COALESCE ( PO . PRIOR_COMPLETE , 0 ) AS OPEN_AT_OP , -- Determine status/sort priority CASE WHEN A . ACTIVE_COUNT > 0 THEN 'A' -- Active WHEN P . PRIORITY IS NOT NULL THEN 'B' -- Priority ELSE 'C' -- Normal END AS SORT_PRIORITY , -- Determine active type CASE WHEN A . HAS_RUN = 1 THEN 'R' WHEN A . HAS_SETUP = 1 THEN 'S' WHEN A . HAS_INDIRECT = 1 THEN 'I' ELSE '' END AS ACTIVE_TYPE FROM BASE_ORDERS B LEFT JOIN ACTIVE_EMPS A ON B . ORDNO = A . ORDNO AND B . OPSEQ = A . OPSEQ LEFT JOIN PRIORITIES P ON B . ORDNO = P . ORDNO AND ( P . OPSEQ = COALESCE ( NULLIF ( B . OPSEQ , '' ) , P . OPSEQ ) ) LEFT JOIN PRIOR_OPS PO ON B . ORDNO = PO . ORDNO AND B . OPSEQ = PO . OPSEQ ) , -- Build JSON for each order JSON_ORDERS AS ( SELECT JSON_OBJECT ( 'orderNumber' : CAST ( TRIM ( ORDNO ) AS VARCHAR ( 7 ) CCSID 37 ) , 'operationSequence' : CAST ( TRIM ( OPSEQ ) AS VARCHAR ( 4 ) CCSID 37 ) , 'workcenter' : CAST ( TRIM ( WKCTR ) AS VARCHAR ( 5 ) CCSID 37 ) , 'site' : CAST ( TRIM ( STID ) AS VARCHAR ( 3 ) CCSID 37 ) , 'itemNumber' : CAST ( TRIM ( FITEM ) AS VARCHAR ( 15 ) CCSID 37 ) , 'itemDescription' : CAST ( TRIM ( FDESC ) AS VARCHAR ( 40 ) CCSID 37 ) , 'operationDescription' : CAST ( TRIM ( OPDSC ) AS VARCHAR ( 40 ) CCSID 37 ) , 'orderStatus' : CAST ( TRIM ( OSTAT ) AS VARCHAR ( 2 ) CCSID 37 ) , 'operationStatus' : CAST ( TRIM ( OPSTC ) AS VARCHAR ( 2 ) CCSID 37 ) , 'orderQuantity' : DEC ( ORQTY , 11 , 3 ) , 'quantityComplete' : DEC ( QTYRC , 11 , 3 ) , 'quantityScrap' : DEC ( QTSCP , 11 , 3 ) , 'openAtOperation' : DEC ( COALESCE ( OPEN_AT_OP , ADJ_QTY ) , 11 , 3 ) , 'operationScrap' : DEC ( SCRAP , 11 , 3 ) , 'orderDueDate' : CASE WHEN ODUDT > 0 THEN TO_CHAR ( DATE ( TIMESTAMP_FORMAT ( CHAR ( ODUDT + 19000000 ) , 'YYYYMMDD' ) ) , 'YYYY-MM-DD' ) ELSE NULL END , 'operationStartDate' : CASE WHEN SSTDT > 0 THEN TO_CHAR ( DATE ( TIMESTAMP_FORMAT ( CHAR ( SSTDT + 19000000 ) , 'YYYYMMDD' ) ) , 'YYYY-MM-DD' ) ELSE NULL END , 'operationDueDate' : CASE WHEN SCODT > 0 THEN TO_CHAR ( DATE ( TIMESTAMP_FORMAT ( CHAR ( SCODT + 19000000 ) , 'YYYYMMDD' ) ) , 'YYYY-MM-DD' ) ELSE NULL END , 'managementPriority' : CAST ( TRIM ( COALESCE ( MGMT_PRIORITY , '' ) ) AS VARCHAR ( 4 ) CCSID 37 ) , 'sortPriority' : SORT_PRIORITY , 'isActive' : CASE WHEN ACTIVE_EMP_COUNT > 0 THEN 'true' ELSE 'false' END FORMAT JSON , 'activeType' : CAST ( ACTIVE_TYPE AS VARCHAR ( 1 ) CCSID 37 ) , 'activeTypeLabel' : CASE ACTIVE_TYPE WHEN 'R' THEN 'Run' WHEN 'S' THEN 'Setup' WHEN 'I' THEN 'Indirect' ELSE '' END , 'activeEmployeeCount' : ACTIVE_EMP_COUNT , 'activeEmployees' : CAST ( COALESCE ( EMP_LIST , '' ) AS VARCHAR ( 100 ) CCSID 37 ) ) AS ORDER_OBJ , SORT_PRIORITY , CASE V_SORT WHEN 'D' THEN CHAR ( ODUDT ) WHEN 'S' THEN CHAR ( SSTDT ) WHEN 'M' THEN ORDNO WHEN 'I' THEN FITEM WHEN 'E' THEN FDESC ELSE CHAR ( ODUDT ) END AS SORT_FIELD FROM COMBINED ) , -- Count totals TOTALS AS ( SELECT MAX ( WKCTR ) AS WKCTR , MAX ( STID ) AS STID , COUNT ( * ) AS TOTAL_ORDERS , SUM ( CASE WHEN ACTIVE_EMP_COUNT > 0 THEN 1 ELSE 0 END ) AS ACTIVE_ORDERS , SUM ( CASE WHEN MGMT_PRIORITY IS NOT NULL THEN 1 ELSE 0 END ) AS PRIORITY_ORDERS , SUM ( ACTIVE_EMP_COUNT ) AS TOTAL_ACTIVE_EMPS FROM COMBINED ) SELECT JSON_OBJECT ( 'workcenter' : CAST ( WKCTR AS VARCHAR ( 5 ) CCSID 37 ) , 'site' : CAST ( STID AS VARCHAR ( 3 ) CCSID 37 ) , 'orders' : ( SELECT JSON_ARRAYAGG ( ORDER_OBJ FORMAT JSON ORDER BY SORT_PRIORITY , SORT_FIELD ) FROM JSON_ORDERS ) FORMAT JSON , 'summary' : ( SELECT JSON_OBJECT ( 'totalOrders' : TOTAL_ORDERS , 'activeOrders' : ACTIVE_ORDERS , 'priorityOrders' : PRIORITY_ORDERS , 'totalActiveEmployees' : TOTAL_ACTIVE_EMPS ) FROM TOTALS ) FORMAT JSON , 'sortBy' : V_SORT , 'sortLabel' : CASE V_SORT WHEN 'D' THEN 'Due Date' WHEN 'S' THEN 'Start Date' WHEN 'M' THEN 'Order Number' WHEN 'I' THEN 'Item Number' WHEN 'E' THEN 'Description' ELSE 'Due Date' END , 'generatedAt' : TO_CHAR ( CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' ) ) FROM TOTALS ; END ; GRANT ALTER , EXECUTE ON SPECIFIC FUNCTION RESTAPI.SFP_GET_WORK_ORDERS TO AMAPICS WITH GRANT OPTION ; GRANT EXECUTE ON SPECIFIC FUNCTION RESTAPI.SFP_GET_WORK_ORDERS TO PUBLIC ;