From a96083fbb9319fd48d593ef07f7e9d7396930830 Mon Sep 17 00:00:00 2001 From: Alex Zaw Date: Wed, 25 Feb 2026 23:06:13 +0000 Subject: [PATCH] Update Function SFP_GET_WORK_ORDERS --- RESTAPI/Functions/SFP_GET_WORK_ORDERS.sql | 380 +++++++++++++++++++++- 1 file changed, 379 insertions(+), 1 deletion(-) diff --git a/RESTAPI/Functions/SFP_GET_WORK_ORDERS.sql b/RESTAPI/Functions/SFP_GET_WORK_ORDERS.sql index 352e996..5938a76 100644 --- a/RESTAPI/Functions/SFP_GET_WORK_ORDERS.sql +++ b/RESTAPI/Functions/SFP_GET_WORK_ORDERS.sql @@ -1 +1,379 @@ -@@\@^@ % %@@@@Kmmm@M@ %m@M]@]@ %@M]@@@ %@@ %@Kmmm@ %@@ %@@@ %@@@@ %@@@@~@\@k@ %@~@\@k@ %@~@\@k@ %@~@Mk@k@]@k@ %@~@\@k@ %@~@\@k@ %@~@\@@@ %@ %@@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@k@@]@@@^@ %@m@@M@@]@@}}@^@ %@m@@M@@k@@]@^@ %@@@M@@]@@}}@^@ %@mm@@M@@@]@@}}@^@ %``@ř@@@ %@m@@M@@]@@}}@^@ %@m@@@@^@ %@m@@M@@]@@}}@^@ %@mm@@@@^@ %@mm@@@@^@ %``@Ö@@@@@ %@@@@@}}@@``@ɕ@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@դ@@@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@Ֆ@@@ %@ %@m@~@}}@^@ %@m@~@}Ֆ@@@@@@}@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@Ֆ@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@ւ@@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@ %@ %@@@@ %m@~@m@k@ %m@~@mm@k@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %``@ׁ@@@ %@m@~@@M@m@M@m@k@}[K}@]@k@}}@]@^@ %@m@~@@M@m@M@m@k@}[K}@]@k@}}@]@^@ %@m@~@@M@@M@m@M@m@k@}[K}@]@]@k@}}@]@^@ %@m@~@@M@ % \ No newline at end of file +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 ; +