open-insight/LSL2/STPROC/PM_SERVICES.txt
Infineon\Ouellette 7a389414c5 Added in a check to logging a PM failure to
prevent early failure logging. Similar to how
logging successes function.
2025-02-24 12:47:15 -07:00

1097 lines
58 KiB
Plaintext

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<PM_PMS_ID$>
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<PM_START_BY$> = UserID
PMRec<PM_START_DTM$> = 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<PM_PMS_ID$>
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<PM_SPEC_PM_KEYS$>
Units = PMSpecRec<PM_SPEC_UNITS$>
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<PM_COMP_BY$> = UserID
PMRec<PM_COMP_DTM$> = CompDTM
PMRec<PM_COMP_QTY$> = 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<PM_PMS_ID$>
If Error_Services('NoError') then
EarlyStartDTM = IConv(Xlate('PM_SPEC', PMSNo, 'EARLY_START', 'X'), 'DT')
If CurrDTM GE EarlyStartDTM then
PMRec<PM_START_BY$> = UserID
PMRec<PM_START_DTM$> = CurrDTM
PMRec<PM_COMP_BY$> = UserID
PMRec<PM_COMP_DTM$> = CurrDTM
PMRec<PM_COMP_QTY$> = 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<PM_SPEC_PM_KEYS$>
Units = PMSpecRec<PM_SPEC_UNITS$>
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<PM_SPEC_DESC$>
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<PM_PMS_ID$>
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<PM_SPEC_INTERVAL$>
Units = PMSpecRec<PM_SPEC_UNITS$>
thisStartQty = ICONV(StartQty,'MD0')
SchedDt = ''
SchedTm = ''
SchedQty = ''
BEGIN CASE
CASE Units = 'D'
//SchedDt = CurrDTM + PMSpecRec<PM_SPEC_INTERVAL$> ;* Interval is in days
SchedDt = SRP_Datetime('AddDays', CurrDt, Interval)
CASE Units = 'T'
Interval = PMSpecRec<PM_SPEC_INTERVAL$> ;* Interval is in hours
Interval = ( Interval/24 ) ;* Convert hours to decimal part of day
EarlyStartDelta = PMSpecRec<PM_SPEC_EARLY_START_DELTA$>
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<PM_PMS_ID$> = PMSId ;* New PMRec
PMrec<PM_ENTER_BY$> = 'AUTO' ;* Automated process user
PMRec<PM_ENTER_DTM$> = CurrDTM
PMRec<PM_SCHED_DT$> = SchedDt
PMRec<PM_SCHED_TM$> = SchedTm
PMRec<PM_SCHED_QTY$> = 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<PM_SPEC_TOOL_ID$>
SendEarlyNotification = PMSRec<PM_SPEC_SEND_EARLY_NOTIFICATION$>
SendDueNotification = PMSRec<PM_SPEC_SEND_DUE_NOTIFICATION$>
SendLateNotification = PMSRec<PM_SPEC_SEND_LATE_NOTIFICATION$>
If LastNotification EQ '' then
Begin Case
Case Status EQ 'EARLY'
IF SendEarlyNotification then
If PMRec<PM_EARLY_NOTIF_SENT$> EQ '' then
PMRec<PM_EARLY_NOTIF_SENT$> = 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<PM_EARLY_NOTIF_SENT$> 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<PM_DUE_NOTIF_SENT$> EQ '' then
PMRec<PM_DUE_NOTIF_SENT$> = 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<PM_DUE_NOTIF_SENT$> 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<PM_LATE_NOTIF_SENT$> EQ '' then
PMRec<PM_LATE_NOTIF_SENT$> = 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<PM_LATE_NOTIF_SENT$> 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<PM_SPEC_FIVE_S_FLAG$>
Units = PmsRec<PM_SPEC_UNITS$>
CurrPMId = PmsRec<PM_SPEC_PM_KEYS$, 1>
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<PM_EARLY_NOTIF_SENT$>
DuePMs<-1> = PmsKey : @VM : 'EARLY' : @VM : NotificationSent : @VM : LateStart : @VM : CurrPMId
end
If SendDue then
SendDueCnt += 1
NotificationSent = CurrPMRec<PM_DUE_NOTIF_SENT$>
DuePMs<-1> = PmsKey : @VM : 'DUE' : @VM: NotificationSent : @VM : LateStart : @VM : CurrPMId
end
If SendLate then
SendLateCnt += 1
NotificationSent = CurrPMRec<PM_LATE_NOTIF_SENT$>
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