From fe317c7a073de662e1a58802da0f17bc87644363 Mon Sep 17 00:00:00 2001 From: Alex Zaw Date: Wed, 25 Feb 2026 23:06:15 +0000 Subject: [PATCH] Update Function SFP_GET_WORKCENTERS_DETAILS --- .../Functions/SFP_GET_WORKCENTERS_DETAILS.sql | 439 +++++++++++++++++- 1 file changed, 438 insertions(+), 1 deletion(-) 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 @@ -@@\@^@ % %@@@@Kmmm@M@ %m@M]@]@ %@M]@@@ %@@ %@Kmmm@ %@@ %@@@ %@@@@ %@@@@~@\@k@ %@~@\@k@ %@~@\@k@ %@~@Mk@k@]@k@ %@~@\@k@ %@~@\@k@ %@~@\@@@ %@ %@@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@mm@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@@@M@@]@@}}@^@ %@mm@@M@@@]@@}}@^@ %@m@@M@@k@@]@@@^@ %@m@@M@@k@@]@@@^@ %``@ř@@@ %@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@}}@]@^@ % \ 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 ; +