Compile function PM_Services(@Service, @Params) #pragma precomp SRP_PreCompiler $Insert APP_INSERTS $Insert SERVICE_SETUP $Insert PM_EQUATES $Insert PM_SPEC_EQUATES $Insert TOOL_EQUATES EQU COL$PMSKEY TO 1 EQU COL$STATUS TO 2 EQU COL$NOTIFICAITON TO 3 EQU COL$DUEBY To 4 EQU COL$CURRPMKEY To 5 Declare subroutine Database_Services, Error_Services, Set_Status, obj_PM_Spec, Tool_Services, Btree.Extract Declare subroutine Logging_Services, Pm_Services, RList, Obj_Notes, PM_Spec_Services Declare function Datetime, Database_Services, Error_Services, obj_PM_Spec, obj_Tool, Environment_Services, LCASE Declare function Logging_Services, Pm_Services, NextKey, SRP_Datetime, Lsl_Users_Services, Active_Directory_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Tool' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Tool Log.csv' Headers = 'Logging DTM' : @FM : 'ToolID' : @FM : 'Notes' : @FM : 'Error' objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Scrubbers\PMCompletion' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Tool Log.csv' Headers = 'Logging DTM' : @FM : 'ToolID' : @FM : 'Notes' : @FM : 'Message' objLogScrubbers = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\PM\Notifications' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' PM_Notifications.csv' Headers = 'Logging DTM' : @FM : 'ToolID' : @FM : 'Message' objLogNotifications = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM ChangeModes = Database_Services('ReadDataRow', 'APP_INFO', 'QUAL_CHANGE_MODES') GoToService Return Response or "" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options BOOLEAN = True$, False$ Options PM_CLASSES = 'SCRUBBER', '5S' Options AREAS = 'CLEANROOM', 'SHIPPING/RECEIVING', 'MAINTENANCE' //----------------------------------------------------------------------------- // SERVICES //----------------------------------------------------------------------------- Service StartPM(PMNo, UserID, StartDTM) If PMNo NE '' then If UserID EQ '' then UserID = @User4 If StartDTM EQ '' then StartDTM = Datetime() PMRec = Database_Services('ReadDataRow', 'PM', PMNo) If Error_Services('NoError') then PMSNo = PMRec ToolID = Xlate('PM_SPEC', PMSNo, PM_SPEC_TOOL_ID$, 'X') If ( (PMSNo NE '') and (ToolID NE '') ) then EarlyStartDTM = IConv(Xlate('PM_SPEC', PMSNo, 'EARLY_START', 'X'), 'DT') If StartDTM GE EarlyStartDTM then // Only change the tool mode if the tool is in one of the modes listed in the APP_INFO*QUAL_CHANGE_MODES // record! This is to preserve other tool modes as the current mode such as SCHED_MTC. CurrMode = Xlate('TOOL', ToolID, 'CURR_MODE', 'X')<1,1> Locate CurrMode in ChangeModes using @FM setting fPos then Reason = 'PM No. ':PMNo:' Started' NewMode = 'VER' Tool_Services('ChangeToolMode', ToolID, NewMode, Reason, UserID, True$) end else LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ToolID LogData<3> = 'Unable to locate curr mode in the list of modes to change from.' LogData<4> = '' Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end If Error_Services('NoError') then PMRec = UserID PMRec = StartDTM Database_Services('WriteDataRow', 'PM', PMNo, PMRec, True$, False$, True$) end else Error_Services('Add', 'Error in ':Service:' service. Error calling Tool_Services("ChangeToolMode") Error code: ':Error_Services('GetMessage')) end end else // It is too early to start this PM Error_Services('Add', 'Error in ':Service:' service. Too early to start PMNo ':PMNo:'.') end end else // Null PMSNo or ToolID error Error_Services('Add', 'Error in ':Service:' service. Null PM_SPEC ID or ToolID for PMNo ':PMNo:'.') end end end else // Null PMNo error Error_Services('Add', 'Error in ':Service:' service. Null PMNo passed in.') end End Service Service CompletePM(PMNo, UserID, CompDTM) If PMNo NE '' then PMRec = Database_Services('ReadDataRow', 'PM', PMNo) If Error_Services('NoError') then PMSNo = PMRec ToolID = Xlate('PM_SPEC', PMSNo, PM_SPEC_TOOL_ID$, 'X') If ( (PMSNo NE '') and (ToolID NE '') ) then If UserID EQ '' then UserID = @User4 If CompDTM EQ '' then CompDTM = Datetime() ToolCycleCnt = Xlate('PM_SPEC', PMSNo, 'TOOL_CYCLE_CNT', 'X') If ToolCycleCnt EQ '' then ToolCycleCnt = '0' Overdue = False$ // Scan for other overdue quals. Only place tool into PROD if all quals are complete. Open 'DICT.PM_SPEC' to PMSDict then ToolPMSpecKeys = '' Option = '' Flag = '' // Ignore archived PM_SPEC! Query = 'TOOL_ID':@VM:ToolID:@FM:'ARCHIVED':@VM:'#1':@FM Btree.Extract(Query, 'PM_SPEC', PMSDict, ToolPMSpecKeys, Option, Flag) If Flag EQ 0 then If ToolPMSpecKeys NE '' then Today = Date() CurrDtm = ICONV(OCONV(Date(),'D'):' ':OCONV(Time(),'MT'), 'DT' ) CurrCnt = XLATE('TOOL', ToolID, TOOL_CYCLE_CNT$, 'X') For each PMSpecKey in ToolPMSpecKeys using @VM If PMSpecKey NE PMSNo then // Check for overdue qual PM for this PM_SPEC PMSpecRec = Database_Services('ReadDataRow', 'PM_SPEC', PMSpecKey) ActPMKeys = PMSpecRec Units = PMSpecRec Conv = '' If Units = 'D' then Conv = 'D' If Units = 'T' then Conv = 'DT' If Units = 'Q' then Conv = 'MD0' Now = '' If Units = 'D' then Now = Today If Units = 'T' then Now = CurrDtm If Units = 'Q' then Now = CurrCnt pmCnt = COUNT(ActPMKeys,@VM) + (ActPMKeys NE '') If pmCnt = 0 then pmCnt = 1 SchedStarts = obj_PM_Spec('SchedStart',PMSpecKey:@RM:PMSpecRec) EarlyStarts = obj_PM_Spec('EarlyStart',PMSpecKey:@RM:PMSpecRec) LateStarts = obj_PM_Spec('LateStart', PMSpecKey:@RM:PMSpecRec) For I = 1 to pmCnt SchedStart = SchedStarts<1,I> EarlyStart = EarlyStarts<1,I> LateStart = LateStarts<1,I> If Conv NE '' then SchedStartIn = ICONV(SchedStart,Conv) EarlyStartIn = ICONV(EarlyStart,Conv) LateStartIn = ICONV(LateStart,Conv) end else SchedStartIn = SchedStart EarlyStartIn = EarlyStart LateStartIn = LateStart end If ( ( (LateStartIn = '') AND (Now = SchedStartIn) ) or (Now > LateStartIn) ) then // Tool is overdue for a qual. Overdue = True$ end Until Overdue Next I end Until Overdue Next PMSpecKey end end end If Not(Overdue) then NewMode = 'PROD' Reason = 'PM No. ':PMNo:' completed.' end else NewMode = 'QUAL_OVERDUE' Reason = 'PM No. ':PMNo:' completed, but another qual is overdue.' end // Only change the tool mode if the tool is in one of the modes listed in the APP_INFO*QUAL_CHANGE_MODES // record! This is to preserve other tool modes as the current mode such as SCHED_MTC. CurrMode = Xlate('TOOL', ToolID, 'CURR_MODE', 'X')<1,1> Locate CurrMode in ChangeModes using @FM setting fPos then Tool_Services('ChangeToolMode', ToolID, NewMode, Reason, UserID, True$) end else LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ToolID LogData<3> = 'Unable to locate curr mode in the list of modes to change from.' LogData<4> = '' Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end If Error_Services('NoError') then PMRec = UserID PMRec = CompDTM PMRec = ToolCycleCnt Database_Services('WriteDataRow', 'PM', PMNo, PMRec, True$, False$, True$) If Error_Services('NoError') then // Update Last PM Comp DTM in PM_SPEC record PM_Spec_Services('UpdatePMCompDtm', PMSNo) If Error_Services('NoError') then Set_Status(0) ErrCode = '' obj_PM_Spec('SchedNewPM',PMSNo:@RM:OCONV(Date(),'D4'):@RM:OCONV(Time(),'MTS'):@RM:ToolCycleCnt:@RM:PMNo) If Get_Status(ErrCode) then ErrorMsg = 'Error in ':Service:' service. Error calling obj_PM_Spec("SchedNewPM") for ' ErrorMsg := 'PM_SPEC ':PMSNo:' and PM ':PMNo:'. Error code: ':ErrCode Error_Services('Add', ErrorMsg) end end end end else ErrorMsg = 'Error in ':Service:' service. Error calling Tool_Services("ChangeToolMode") ' ErrorMsg := 'PM ':PMNo:' for PM_SPEC ':PMSNo:' not completed! Error code: ':Error_Services('GetMessage') Error_Services('Add', ErrorMsg) end end else Error_Services('Add', 'Error in ':Service:' service. Null PM_SPEC ID or ToolID for PMNo ':PMNo:'.') end end end else Error_Services('Add', 'Error in ':Service:' service. Null PMNo passed in.') end end service Service CompleteNonToolPM(PMNo, UserID, CurrDTM) If PMNo NE '' then If UserID EQ '' then UserID = @User4 If CurrDTM EQ '' then StartDTM = Datetime() PMRec = Database_Services('ReadDataRow', 'PM', PMNo) PMSNo = PMRec If Error_Services('NoError') then EarlyStartDTM = IConv(Xlate('PM_SPEC', PMSNo, 'EARLY_START', 'X'), 'DT') If CurrDTM GE EarlyStartDTM then PMRec = UserID PMRec = CurrDTM PMRec = UserID PMRec = CurrDTM PMRec = 0 Database_Services('WriteDataRow', 'PM', PMNo, PMRec, True$, False$, True$) If Error_Services('NoError') then // Update Last PM Comp DTM in PM_SPEC record PM_Spec_Services('UpdatePMCompDtm', PMSNo) If Error_Services('NoError') then Set_Status(0) ErrCode = '' obj_PM_Spec('SchedNewPM',PMSNo:@RM:OCONV(Date(),'D4'):@RM:OCONV(Time(),'MTS'):@RM:0:@RM:PMNo) //Pm_Services('ScheduleNextPM', PMSNo, PMNo) If Error_Services('HasError') then ErrorMsg = 'Error in ':Service:' service. Error calling obj_PM_Spec("SchedNewPM") for ' ErrorMsg := 'PM_SPEC ':PMSNo:' and PM ':PMNo:'. Error code: ':ErrCode Error_Services('Add', ErrorMsg) end end end end else Error_Services('Add', 'Error in ':Service:' service. Too early to start PMNo ':PMNo:'.') end end end end service Service MonitorQuals() hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then Open 'TOOL' to hTool then ToolIDs = obj_Tool('KeysByType') For each ToolID in ToolIDs using @VM NotDue = True$ DueSoon = False$ CurrentlyDue = False$ Overdue = False$ NotScheduled = False$ ReadV OrigPMStatus from hTool, ToolID, TOOL_PM_STATUS$ then Open 'DICT.PM_SPEC' to PMSDict then ToolPMSpecKeys = '' Option = '' Flag = '' Query = 'TOOL_ID':@VM:ToolID:@FM:'ARCHIVED':@VM:'#1':@FM Btree.Extract(Query, 'PM_SPEC', PMSDict, ToolPMSpecKeys, Option, Flag) If Flag EQ 0 then If ToolPMSpecKeys NE '' then Today = Date() CurrDtm = ICONV(OCONV(Date(),'D'):' ':OCONV(Time(),'MT'), 'DT' ) CurrCnt = XLATE('TOOL', ToolID, TOOL_CYCLE_CNT$, 'X') For each PMSpecKey in ToolPMSpecKeys using @VM PMSpecRec = Database_Services('ReadDataRow', 'PM_SPEC', PMSpecKey) ActPMKeys = PMSpecRec Units = PMSpecRec Conv = '' If Units = 'D' then Conv = 'D' If Units = 'T' then Conv = 'DT' If Units = 'Q' then Conv = 'MD0' Now = '' If Units = 'D' then Now = Today If Units = 'T' then Now = CurrDtm If Units = 'Q' then Now = CurrCnt pmCnt = COUNT(ActPMKeys,@VM) + (ActPMKeys NE '') If pmCnt = 0 then pmCnt = 1 SchedStarts = obj_PM_Spec('SchedStart',PMSpecKey:@RM:PMSpecRec) EarlyStarts = obj_PM_Spec('EarlyStart',PMSpecKey:@RM:PMSpecRec) LateStarts = obj_PM_Spec('LateStart', PMSpecKey:@RM:PMSpecRec) For I = 1 to pmCnt SchedStart = SchedStarts<1,I> EarlyStart = EarlyStarts<1,I> LateStart = LateStarts<1,I> If Conv NE '' then SchedStartIn = ICONV(SchedStart,Conv) EarlyStartIn = ICONV(EarlyStart,Conv) LateStartIn = ICONV(LateStart,Conv) end else SchedStartIn = SchedStart EarlyStartIn = EarlyStart LateStartIn = LateStart end BEGIN CASE CASE SchedStartIn = '' ; NotScheduled = True$ CASE EarlyStartIn = '' AND Now LE SchedStartIn ; NotDue = True$ CASE Now < EarlyStartIn ; NotDue = True$ CASE Now < SchedStartIn ; DueSoon = True$ CASE LateStartIn = '' AND Now = SchedStartIn ; CurrentlyDue = True$ CASE LateStartIn = '' AND Now > SchedStartIn ; Overdue = True$ CASE Now > LateStartIn ; Overdue = True$ CASE Now GE SchedStartIn ; CurrentlyDue = True$ ; END CASE Next I Next PMSpecKey PMStatus = '' Begin Case Case Overdue PMStatus = 'OVERDUE' ToolClass = Xlate('TOOL', ToolID, 'CLASS', 'X') MonitoredToolTypes = 'FTIR,4PP,HGCV' Locate ToolClass in MonitoredToolTypes using ',' setting Dummy then // Only change the tool mode if the tool is in one of the modes listed below. // record! This is to preserve other tool modes as the current mode such as SCHED_MTC. CurrMode = Xlate('TOOL', ToolID, 'CURR_MODE', 'X')<1,1> ServiceModes = 'PROD':@FM:'LIM':@FM:'VER' Locate CurrMode in ServiceModes using @FM setting fPos then PMDesc = PMSpecRec Reason = 'Verification not performed.' Tool_Services('ChangeToolMode', ToolID, 'QUAL_OVERDUE', Reason, 'OI_ADMIN', True$) end end Case CurrentlyDue PMStatus = 'CURRENTLY_DUE' Case DueSoon PMStatus = 'DUE_SOON' Case NotScheduled PMStatus = 'NOT_SCHEDULED' Case NotDue PMStatus = 'NOT_DUE' Case Otherwise$ PMStatus = 'ERROR' End Case If OrigPMStatus _NEC PMStatus then // Only write the column if the PM status has changed. WriteV PMStatus on hTool, ToolID, TOOL_PM_STATUS$ else null end end else // No PM_SPEC records defined for this tool If OrigPMStatus _NEC 'NOT_SCHEDULED' then // Only write the column if the PM status has changed. WriteV 'NOT_SCHEDULED' on hTool, ToolID, TOOL_PM_STATUS$ else null end end end end end Next ToolID end Unlock hSysLists, ServiceKeyID else Null end end service Service FailedPM(PMNo, UserID, StartDTM) If UserID EQ '' then UserID = @User4 If StartDTM EQ '' then StartDTM = Datetime() PMRec = Database_Services('ReadDataRow', 'PM', PMNo) If Error_Services('NoError') then PMSNo = PMRec ToolID = Xlate('PM_SPEC', PMSNo, PM_SPEC_TOOL_ID$, 'X') If ( (PMSNo NE '') and (ToolID NE '') ) then EarlyStartDTM = IConv(Xlate('PM_SPEC', PMSNo, 'EARLY_START', 'X'), 'DT') If StartDTM GE EarlyStartDTM then // Only change the tool mode if the tool is in one of the modes listed in the APP_INFO*QUAL_CHANGE_MODES // record! This is to preserve other tool modes as the current mode such as SCHED_MTC. CurrMode = Xlate('TOOL', ToolID, 'CURR_MODE', 'X')<1,1> Locate CurrMode in ChangeModes using @FM setting fPos then Reason = 'PM No. ':PMNo:' Failed' NewMode = 'VER_FAILED' Tool_Services('ChangeToolMode', ToolID, NewMode, Reason, UserID, True$) end else LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ToolID LogData<3> = 'Unable to locate curr mode in the list of modes to change from.' LogData<4> = '' Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end end else // It is too early to start this PM Error_Services('Add', 'Error in ':Service:' service. Too early to start PMNo ':PMNo:'.') end end end end service Service ProcessQual(PSN, ToolID, CompDtm, Pass) StatusCode = 'UID001' Message = '' If ( (PSN NE '') and (ToolID NE '') and (CompDtm NE '') and (Pass NE '') ) then // Find scheduled PM for this qual check. // There should only be one PM_SPEC defined for this qual check at this time. Option = '' Flag = '' PMSpecKeyID = '' Open 'DICT.PM_SPEC' to PmsDict then Query = 'TOOL_ID':@VM:ToolID:@FM:'DESC':@VM:'[':PSN:']':@FM:'ARCHIVED':@VM:'#1':@FM Btree.Extract(Query, 'PM_SPEC', PmsDict, PMSpecKeyID, '', Flag) CurrPMKey = '' If Flag EQ 0 then If PMSpecKeyID NE '' then CurrPMKey = Xlate('PM_SPEC', PMSpecKeyID, 'PM_KEYS', 'X') If CurrPMKey NE '' then CompDtm[-3, 1] = '' PMDtm = IConv(CompDtm, 'DT') If CompDtm EQ '' then PMDtm = Datetime() end If Pass then // The qual files do not contain which user performed the qual check, so just use OI_ADMIN for now. // The qual files only contain the complete datetime. Use it for both the start and complete datetime. PM_Services('StartPM', CurrPMKey, 'OI_ADMIN', PMDtm) If Error_Services('NoError') then PM_Services('CompletePM', CurrPMKey, 'OI_ADMIN', PMDtm) If Error_Services('NoError') then StatusCode = 'UID000' Message = Service : ' : PM ':CurrPMKey:' for PM_SPEC ':PMSpecKeyID:' completed successfully.' end else StatusCode = 'UID002' Message = Service : ' : ' : Error_Services('GetMessage') end end else StatusCode = 'UID001' Message = Service : ' : ' : Error_Services('GetMessage') end end else // Failing Qual PM_Services('FailedPM', CurrPMKey, 'OI_ADMIN', PMDtm) If Error_Services('NoError') then StatusCode = 'UID001' Message = 'Qual fail for ':ToolID:' ':PSN:'. Qual NOT marked complete.' end else StatusCode = 'UID001' Message = Error_Services('GetMessage') end end end else StatusCode = 'UID001' Message = 'No scheduled PM found for ':ToolID:' ':PSN:'.' end end else StatusCode = 'UID001' Message = 'No PM_SPEC record found for ':ToolID:' ':PSN:'.' end end else StatusCode = 'UID002' Message = 'Error calling Btree.Extract. Btree flag: ':Flag end end else StatusCode = 'UID002' Message = 'Error opening DICT.PM_SPEC.' end end else end Response = StatusCode:@FM:Message end service Service Get5SPMs(ShowArchived=BOOLEAN, Area=AREAS) Option = '' Flag = '' keylist = '' Query = '' Open 'DICT.PM_SPEC' to PmsDict then if Not(ShowArchived) then Query := 'ARCHIVED':@VM:'#1':@FM end If Area NE '' then Query := 'AREA':@VM:Area:@FM end Query := 'FIVE_S_FLAG':@VM:True$:@FM Btree.Extract(Query, 'PM_SPEC', PmsDict, keylist, '', Flag) end Response = keylist end service Service GetScrubberPMs(ShowArchived=BOOLEAN) Option = '' Flag = '' keylist = '' Query = '' Open 'DICT.PM_SPEC' to PmsDict then if NOT(ShowArchived) then Query := 'PM_CLASS':@VM:'SCRUBBER':@FM Query := 'ARCHIVED':@VM:'#1':@FM end else Query := 'PM_CLASS':@VM:'SCRUBBER':@FM end Btree.Extract(Query, 'PM_SPEC', PmsDict, keylist, '', Flag) end Response = keylist end service Service ScheduleNextPM(PMSID, PMNo, StartQty) //This service is designed to schedule the next PM based on the completion time of the last completion. //Rather than scheduling the next PM based on a set schedule. CurrDTM = Datetime() CurrDt = Date() PMSpecRec = Database_Services('ReadDataRow', 'PM_SPEC', PMSID) Interval = PMSpecRec Units = PMSpecRec thisStartQty = ICONV(StartQty,'MD0') SchedDt = '' SchedTm = '' SchedQty = '' BEGIN CASE CASE Units = 'D' //SchedDt = CurrDTM + PMSpecRec ;* Interval is in days SchedDt = SRP_Datetime('AddDays', CurrDt, Interval) CASE Units = 'T' Interval = PMSpecRec ;* Interval is in hours Interval = ( Interval/24 ) ;* Convert hours to decimal part of day EarlyStartDelta = PMSpecRec SchedDTM = CurrDTM + Interval SchedDTM = OCONV(SchedDTM, 'DT/^S') SchedDt = SchedDTM[1,' '] SchedTm = SchedDTM[COL2()+1,' '] SchedDt = ICONV(SchedDt,'D') SchedTm = ICONV(SchedTm,'MT') CASE Units = 'Q' // Run-based PM if thisStartQty NE '' then SchedQty = Interval + thisStartQty end else Error_Services('Add', 'Start Qty not supplied to PM_Services -> ScheduleNextPM') end Case Units = 'M' //Month based PM SchedDt = SRP_Datetime('AddMonths', CurrDt, Interval) CASE 1 * Missing Units RETURN END CASE if Error_Services('NoError') then PMNo = NextKey('PM') ;* Next PMKey PMRec = '' PMRec = PMSId ;* New PMRec PMrec = 'AUTO' ;* Automated process user PMRec = CurrDTM PMRec = SchedDt PMRec = SchedTm PMRec = OCONV(SchedQty,'MD0') Database_Services('WriteDataRow', 'PM', PMNo, PMRec) end end service Service GetPMNotificationRecipients(PMSID) Recipients = '' If PMSID NE '' then If RowExists('PM_SPEC', PMSID) then Recipients := Lsl_Users_Services('GetOnShiftUsersByClass', 'Si Shift Supervisors', 0) Recipients := @VM : Lsl_Users_Services('GetOnShiftUsersByClass', 'Lead Operator', 0) ADNotificationGroups = XLATE('PM_SPEC', PMSID, PM_SPEC_AD_NOTIFICATION_GROUPS$, 'X') IF ADNotificationGroups NE '' then for each ADGroup in ADNotificationGroups using @VM GroupMemberList = Active_Directory_Services('GetADGroupMembersByGroupName', ADGroup, 'INFINEON') for each GroupMember in GroupMemberList using @FM ADUsername = LCASE(GroupMember<1,1>) ADToLSLUserMap = Database_Services('ReadDataRow', 'APP_INFO', 'AD_TO_LSL_USER_MAP') ADToLSLUserMap<1> = LCASE(ADToLSLUserMap<1>) Locate ADUsername in ADToLSLUserMap<1> using @VM setting userPos then LSLUserID = ADToLSLUserMap<2, userPos> Recipients<1, -1> = LSLUserID end Next GroupMember Next ADGroup end end else Error_Services('Add', 'Error in GetPMNotificationRecipients: PM Spec record with key id ' : PMSID : 'does not exist.') end end else Error_Services('Add', 'Error in GetPMNotificationRecipients: PMSID was null') end Response = Recipients end service Service SendPMNotifications() hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then errMessage = '' PMStatuses = Pm_Services('GetPMStatuses') SentFrom = 'OI_ADMIN' AttachWindow = '' AttachKey = '' SendToGroup = '' for each PMStatusLine in PMStatuses using @FM Status = PMStatusLine<1,COL$STATUS> LastNotification = PMStatusLine<1,COL$NOTIFICAITON> PMDesc = XLATE('PM_SPEC', PMStatusLine<1,COL$PMSKEY>, PM_SPEC_DESC$, 'X') PMKey = PMStatusLine<1,COL$CURRPMKEY> PMRec = Database_Services('ReadDataRow', 'PM', PMKey) PMSpecKey = PMStatusLine<1, COL$PMSKEY> PMSRec = Database_Services('ReadDataRow', 'PM_SPEC', PMSpecKey) Tool = PMSRec SendEarlyNotification = PMSRec SendDueNotification = PMSRec SendLateNotification = PMSRec If LastNotification EQ '' then Begin Case Case Status EQ 'EARLY' IF SendEarlyNotification then If PMRec EQ '' then PMRec = Datetime() Database_Services('WriteDataRow', 'PM', PMKey, PMRec, 1, 0, 1) if Error_Services('NoError') then UpdatedPMRec = Database_Services('ReadDataRow', 'PM', PMKey, True$, 0, False$) If UpdatedPMRec NE '' then Recipients = PM_Services('GetPMNotificationRecipients', PMSpecKey) if Error_Services('NoError') then LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY NOTIFICATIONS Prechecks passed, message okay to send.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) Subject = 'PM Task Coming Due' Message = 'Tool: ': Tool : ' - ' :PMDesc:" is coming due. Scheduled due by " : OCONV(PMStatusLine<1,COL$DUEBY>, 'DT') Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY NOTIFICATIONS OBJ_Notes has been called by this point, message should have been sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = 'EARLY Notifcation wasn not marked as completed when it should have been.' LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'EARLY notification did not send because it has been marked as being already sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end Case Status EQ 'DUE' If SendDueNotification then If PMRec EQ '' then PMRec = Datetime() Database_Services('WriteDataRow', 'PM', PMKey, PMRec, 1, 0, 1) if Error_Services('NoError') then UpdatedPMRec = Database_Services('ReadDataRow', 'PM', PMKey, True$, 0, False$) If UpdatedPMRec NE '' then Recipients = PM_Services('GetPMNotificationRecipients', PMSpecKey) if Error_Services('NoError') then LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE NOTIFICATIONS Prechecks passed, message okay to send.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) Subject = 'PM Task Due' Message = 'Tool: ': Tool : ' - ' :PMDesc:" is due. Scheduled due by " : OCONV(PMStatusLine<1,COL$DUEBY>, 'DT') Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE NOTIFICATIONS OBJ_Notes has been called by this point, message should have been sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = 'DUE Notifcation was not marked as completed when it should have been.' LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'DUE notification did not send because it has been marked as being already sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end Case Status EQ 'LATE' if SendLateNotification then If PMRec EQ '' then PMRec = Datetime() Database_Services('WriteDataRow', 'PM', PMKey, PMRec, 1, 0, 1) if Error_Services('NoError') then //Check to make sure this change is commited by rereading in the record UpdatedPMRec = Database_Services('ReadDataRow', 'PM', PMKey, True$, 0, False$) If UpdatedPMRec NE '' then Recipients = PM_Services('GetPMNotificationRecipients', PMSpecKey) if Error_Services('NoError') then LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE NOTIFICATIONS Prechecks passed, message okay to send.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) Subject = 'PM overdue' Message = 'Tool: ': Tool : ' - ' :PMDesc:" is overdue. Scheduled due by " : OCONV(PMStatusLine<1,COL$DUEBY>, 'DT') Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE NOTIFICATIONS OBJ_Notes has been called by this point, message should have been sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = 'LATE Notifcation was not marked as completed when it should have been.' LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else errMessage = Error_Services('GetMessage') LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE notification failed - ' : errMessage Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end else LogData = '' LogData<1> = LoggingDTM;//Defined at entry of subroutine LogData<2> = Tool LogData<3> = PMDesc LogData<4> = 'LATE notification did not send because it has been marked as being already sent.' Logging_Services('AppendLog', objLogNotifications, LogData, @RM, @FM, False$) end end End Case end Next PMStatus Unlock hSysLists, ServiceKeyID else Null end end service Service GetPMStatuses() SendEarlyCnt = 0 SendDueCnt = 0 SendLateCnt = 0 DuePMs = '' //Step 1: Get all PM's that are not complete equ TARGET_ACTIVELIST$ to 5 Statement = "SELECT PM_SPEC WITH ARCHIVED NE 1" rlist( Statement, target_activelist$, '', '', '' ) PMSpecList = '' IF @RecCount then EoF = 0 NumKeys = @RecCount Cnt = 0 Loop ReadNext PmsId Else EoF = 1 until EoF PMSpecList<-1> = PmsId Repeat end for each PmsKey in PMSpecList using @FM CurrDt = Date() CurrDtm = Datetime() PmsRec = Database_Services('ReadDataRow', 'PM_SPEC', PmsKey) Is5S = PmsRec Units = PmsRec CurrPMId = PmsRec CurrPmRec = Database_Services('ReadDataRow', 'PM', CurrPMId) Begin Case Case Units EQ 'T' EarlyStart = ICONV(obj_PM_Spec('EarlyStart',PmsKey:@RM:PmsRec), 'DT') DueStart = ICONV(obj_PM_Spec('SchedStart',PmsKey:@RM:PmsRec), 'DT') LateStart = ICONV(obj_PM_Spec('LateStart',PmsKey:@RM:PmsRec), 'DT') Case Units EQ 'D' EarlyStart = ICONV(obj_PM_Spec('EarlyStart',PmsKey:@RM:PmsRec), 'D') DueStart = ICONV(obj_PM_Spec('SchedStart',PmsKey:@RM:PmsRec), 'D') LateStart = ICONV(obj_PM_Spec('LateStart',PmsKey:@RM:PmsRec), 'D') Case 0 EarlyStart = obj_PM_Spec('EarlyStart',PmsKey:@RM:PmsRec) DueStart = obj_PM_Spec('SchedStart',PmsKey:@RM:PmsRec) LateStart = obj_PM_Spec('LateStart',PmsKey:@RM:PmsRec) End Case SendEarly = false$ SendDue = false$ SendLate = false$ NotDue = false$ Begin Case Case Units EQ 'D' Begin Case Case CurrDt GE EarlyStart AND CurrDt LT DueStart //Send Early Start SendEarly = True$ Case CurrDt GE DueStart AND CurrDt LT LateStart //Send Due Start SendDue = True$ Case CurrDt GE LateStart //Send Late Start SendLate = True$ Case OTHERWISE$ NotDue = True$ End Case Case Units EQ 'T' Begin Case Case CurrDtm GE EarlyStart AND CurrDtm LT DueStart //Send Early Start SendEarly = True$ Case CurrDtm GE DueStart AND CurrDtm LT LateStart //Send Due Start SendDue = True$ Case CurrDtm GE LateStart //Send Late Start SendLate = True$ Case OTHERWISE$ NotDue = True$ End Case Case Units EQ 'Q' End Case If SendEarly then SendEarlyCnt += 1 NotificationSent = CurrPMRec DuePMs<-1> = PmsKey : @VM : 'EARLY' : @VM : NotificationSent : @VM : LateStart : @VM : CurrPMId end If SendDue then SendDueCnt += 1 NotificationSent = CurrPMRec DuePMs<-1> = PmsKey : @VM : 'DUE' : @VM: NotificationSent : @VM : LateStart : @VM : CurrPMId end If SendLate then SendLateCnt += 1 NotificationSent = CurrPMRec DuePMs<-1> = PmsKey : @VM : 'LATE' : @VM : NotificationSent : @VM : LateStart : @VM : CurrPMId end If NotDue then DuePMs<-1> = PmsKey : @VM : 'Not Due' end Next PmsKey Response = DuePMs end service Service CompleteScrubberPM(ScrubberID) Option = '' Flag = '' keylist = '' Query = '' Open 'DICT.PM_SPEC' to PmsDict then Query := 'TOOL_ID':@VM:ScrubberID:@FM Btree.Extract(Query, 'PM_SPEC', PmsDict, keylist, '', Flag) end ScrubberPMSpecKeys = keylist If DCOUNT(ScrubberPMSpecKeys, @VM) GT 0 then for each PMSKey in keylist using @VM PMKeys = XLATE('PM_SPEC', PMSKey, 'PM_KEYS', 'X') If DCount(PMKeys, @VM GT 0) then for each PMKey in PMKeys using @VM Pm_Services('CompleteNonToolPM', PMKey, 'SYSTEM', DateTime()) If Error_Services('HasError') then ErrMsg = Error_Services('GetMessage') Error_Services('Add', 'Error trying to complete Scrubber PM:' : ErrMsg) LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ScrubberID LogData<3> = 'Error' LogData<4> = 'PM ' : PMKey : '. ' : ErrMsg Logging_Services('AppendLog', objLogScrubbers, LogData, @RM, @FM) end else LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ScrubberID LogData<3> = 'Success' LogData<4> = 'PM ' : PMKey : ' Completed successfully' Logging_Services('AppendLog', objLogScrubbers, LogData, @RM, @FM) end Next PMKey end else ErrMsg = 'There were no scheduled PMs for ' : ScrubberID Error_Services('Add', ErrMsg) LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ScrubberID LogData<3> = 'Error' LogData<4> = ErrMsg Logging_Services('AppendLog', objLogScrubbers, LogData, @RM, @FM) end Next PMSKey end else ErrMsg = 'There were no defined PMs for ' : ScrubberID Error_Services('Add', ErrMsg) Error_Services('Add', ErrMsg) LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = ScrubberID LogData<3> = 'Error' LogData<4> = ErrMsg Logging_Services('AppendLog', objLogScrubbers, LogData, @RM, @FM) end end service Service GetActivePMsByToolId(ToolId) ErrorMessage = '' ActivePMIdList = '' If ToolId NE '' then Open 'DICT.PM_SPEC' to @DICT then Option = '' Flag = '' PMSpecList = '' SearchStr = 'TOOL_ID':@VM:ToolId:@FM SearchStr := 'ARCHIVED':@VM:'#1':@FM Btree.Extract(SearchStr, 'PM_SPEC', @DICT, PMSpecList, '', Flag) If Flag EQ 0 AND PMSpecList NE '' then for each PMSpecId in PMSpecList using @VM ActivePMKeys = Database_Services('ReadDataColumn', 'PM_SPEC', PMSpecId, PM_SPEC_PM_KEYS$, True$, 0, False$) If ActivePMKeys NE '' then ActivePMIdList<1,-1> = ActivePMKeys end Next PMSpecId end else ErrorMessage = 'Error in PM_Services -> GetActivePMsByToolIdAndType, unable to find active PM Specs for this tool id' end end else ErrorMessage = 'Error in PM_Services -> GetActivePMsByToolIdAndType, error opening PM_SPEC dictionary' end end else ErrorMessage = 'Error in PM_Services -> GetActivePMsByToolIdAndType, null tool id passed to routine' end Response = ActivePMIdList end service Processing: ctr += 1 return