Function NDW_Scheduler_Events(CtrlEntId, Event, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from Infineon. Name : NDW_Scheduler_Events Description : This function acts as a commuter module for all events related to this window. Notes : Commuter Modules are automatically called from the Promoted_Events function which is called by the application-specific promoted event handler. This makes it possible to add QuickEvents that need to execute Basic+ logic without having use the Form Designer to make the association, although this is limited to the events which are currently promoted. If the form needs to call the commuter module directly then the QuickEvent parameters should be formatted like this: '@SELF','@EVENT',['@PARAM1','@PARAMx'] Parameters : CtrlEntId [in] -- The fully qualified name of the control calling the promoted event Event [in] -- The event being executed. See the Notes section regarding "PRE" events Param1-15 [in] -- Additional event parameter holders EventFlow [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in EVENT_SETUP insert History : (Date, Initials, Notes) 06/01/17 dmb Created initial commuter module. 04/20/21 djs Updated GetReactorEntities to use PickPlace instead of Dedicated and Non-Dedicated reactor assignments for form color purposes. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #Window NDW_SCHEDULER $insert APP_INSERTS $insert EVENT_SETUP $insert MSG_EQUATES $insert SCHED_DET_EQUATES $insert WO_LOG_EQUATES $insert PRS_LAYER_EQU $insert POPUP_EQUATES $INSERT LOGICAL $insert SECURITY_RIGHTS_EQU $insert REACTOR_EQUATES $insert WO_STEP_EQUATES $insert SCHEDULE_EVENT_SUMMMARY_EQUATES $insert SCHED_DET_NG_EQUATES $insert COMPANY_EQUATES $insert USER_CONFIG_EQUATES $insert RLIST_EQUATES Equ LightGrey$ TO 239 + (239*256) + (239*65536) Equ LTORANGE$ TO 255 + (220*256) + (128*65536) Equ Comma$ to ',' Declare function SRP_Array, Schedule_Services, Epi_Part_Services, MemberOf, Reactor_Services, SRP_JSON Declare function EntId, MemberOf, Repository, Security_Check, Security_Err_Msg, Obj_Prod_Spec, Rds_Supplement_Maint Declare function DateTime, Database_Services, SRP_Get_IdleTime, Environment_Services, Declare function Logging_Services, GetCurrentProcessID Declare subroutine obj_Appwindow, Schedule_Services, Epi_Part_Services, SRP_Stopwatch, SRP_JSON, Database_Services Declare subroutine Security_Err_Msg, Start_Window, Messaging_Services, Work_Order_Services, Sleepery, Logging_Services ProcessID = GetCurrentProcessID() LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\SchedulerPro' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ' : @User4 : ' ' : ProcessID : ' Crash Log.csv' Headers = 'Logging DTM' : @FM : 'LSL User' : @FM : 'Notes' objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, True$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM SubclassInfo = Form_Services('FindSubclassControl') Subclass = SubclassInfo<1> // Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler. If Event EQ 'OLE' then Transfer Event to OIEvent Transfer Param1 to Event Transfer Param2 to Param1 Transfer Param3 to Param2 Transfer Param4 to Param3 Transfer Param5 to Param4 Transfer Param6 to Param5 Transfer Param7 to Param6 Transfer Param8 to Param7 end GoToEvent Event for CtrlEntID Return EventFlow else EVENT_CONTINUE$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Event WINDOW.CREATE(CreateParam) // Update UI based on security membership rights. Begin Case Case MemberOf(@USER4, 'SCHEDULER_ADMIN') // Allowed to access everything. Case MemberOf(@USER4, 'SCHEDULER_MASTER') // Reactor utilization is view only. Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_ASM_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_HTR_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_GAN_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_GAN_UTILIZATION', 'VISIBLE', False$) Case Otherwise$ // Reactor utilization is not visible. Set_Property(@Window : '.OLE_DIV_REACTOR_TYPE_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_GAN_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_GAN_UTILIZATION', 'VISIBLE', False$) Size = Get_Property(@Window : '.OLE_DIV_BOTTOM', 'SIZE') Size<2> = Size<2> - 162 Set_Property(@Window : '.OLE_DIV_BOTTOM', 'SIZE', Size) End Case Set_Property(@Window, 'VISIBLE', 3) GoSub Setup_OLE_Controls ASMUtil = Epi_Part_Services('GetReactorUtilization', 'ASM') ASMPlusUtil = Epi_Part_Services('GetReactorUtilization', 'ASM+') HTRUtil = Epi_Part_Services('GetReactorUtilization', 'HTR') EpiProUtil = Epi_Part_Services('GetReactorUtilization', 'EpiPro') GaNUtil = Epi_Part_Services('GetReactorUtilization', 'GaN') Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'INVALUE', ASMUtil) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'INVALUE', ASMPlusUtil) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'INVALUE', HTRUtil) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'INVALUE', EpiProUtil) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'INVALUE', GaNUtil) end event Event WINDOW.CLOSE(CancelFlag) UserConfigKey = @User4:'*':@Window UserConfigRec = Get_Property(@Window, '@USER_CONFIG_REC') UserConfigProps = UserConfigRec UserConfigVals = UserConfigRec IntervalSize = Get_Property(@Window:'.OLE_SCHEDULE', 'OLE.IntervalSize') Locate 'IntervalSize' in UserConfigProps using @VM setting vPos then UserConfigVals<0, vPos> = IntervalSize end else UserConfigProps<0, -1> = 'IntervalSize' UserConfigVals<0, -1> = IntervalSize UserConfigRec = UserConfigProps end UserConfigRec = UserConfigVals Database_Services('WriteDataRow', 'USER_CONFIG', UserConfigKey, UserConfigRec, True$, False$, True$) end event Event EDL_REACTOR_FILTER.LOSTFOCUS(Flag, FocusID) PrevFilterType = Get_Property(CtrlEntId, '@PREV_FILTER_TYPE') FilterType = Get_Property(CtrlEntId, 'TEXT') If FilterType NE PrevFilterType then Begin Case Case FilterType _EQC 'Reactor Type' FilterOptions = 'ASM' : @FM FilterOptions := 'ASM+' : @FM FilterOptions := 'HTR' : @FM FilterOptions := 'EpiPro' : @FM FilterOptions := 'GaN' Case FilterType _EQC 'Reactor Assignment' FilterOptions = 'Dedicated' : @FM FilterOptions := 'Non-Dedicated' : @FM FilterOptions := 'GaN' : @FM FilterOptions := 'Out of Service' Case FilterType _EQC 'Wafer Size' FilterOptions = '125 mm 5 in' : @FM FilterOptions := '150 mm 6 in' : @FM FilterOptions := '200 mm 8 in' : @FM Case FilterType _EQC 'Cleanroom Area' FilterOptions = 'Front-Evens' : @FM FilterOptions := 'Front-Odds' : @FM FilterOptions := 'Front-Evens-HTR' : @FM FilterOptions := 'Front-Odds-HTR' : @FM FilterOptions := 'Tunnel' : @FM FilterOptions := 'EpiPro Room' : @FM FilterOptions := 'Back-Evens' : @FM FilterOptions := 'Back-Odds' : @FM FilterOptions := 'GaN' End Case Set_Property(CtrlEntId, '@PREV_FILTER_TYPE', FilterType) Ctrl = @Window : '.OLE_TRE_REACTOR_FILTER_OPTIONS' ItemList = '' For Each FilterOption in FilterOptions using @FM ItemList := 1 : @VM : FilterOption : @VM : FilterOption : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : 'Left' : @FM Next FilterOption ItemList[-1, 1] = '' Set_Property(Ctrl, 'OLE.ItemList', ItemList) Set_Property(Ctrl, 'OLE.ItemChecked[All]', True$) Post_Event(Ctrl, 'OLE', 'OnItemCheck') end end event Event EDL_WORK_ORDER_SEARCH.LOSTFOCUS(Flag, FocusID) PrevWorkOrderNo = Get_Property(CtrlEntId, '@PREV_WORK_ORDER_NO') SearchWorkOrderNo = Get_Property(CtrlEntId, 'TEXT') If SearchWorkOrderNo NE PrevWorkOrderNo then // Restore already selected appointments to their normal backcolor. Set_Property(@Window, 'REDRAW', False$) SearchAppointmentKeys = Get_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS') If SearchAppointmentKeys NE '' then For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral' Case Flags<3> BackColor = 'LightGray' Case Otherwise$ BackColor = 'LightSteelBlue' End Case Appt<4> = BackColor Appt<5> = 'Black' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey end SearchAppointmentKeys = '' AppointmentList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.AppointmentList') AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AllAppointmentKeys = AppointmentArray<2> For Each AppointmentKey in AllAppointmentKeys using @VM setting vPos WorkOrderNo = Xlate('SCHED_DET_NG', AppointmentKey, 'WO_NO', 'X') If WorkOrderNo EQ SearchWorkOrderNo then SearchAppointmentKeys := AppointmentKey : @FM end Next AppointmentKey SearchAppointmentKeys[-1, 1] = '' For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral L=40' Case Flags<3> BackColor = 'LightGray L=40' Case Otherwise$ BackColor = 'LightSteelBlue L=40' End Case Appt<4> = BackColor Appt<5> = 'White' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey Set_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS', SearchAppointmentKeys) Send_Message(@Window : '.OLE_SCHEDULE', 'OLE.EnsureVisible', SearchAppointmentKeys<1>) Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.SelAppt[' : SearchAppointmentKeys<1> : ']') Set_Property(CtrlEntId, '@PREV_WORK_ORDER_NO', SearchWorkOrderNo) Set_Property(@Window : '.EDL_EPI_PART_SEARCH', 'TEXT', '') Set_Property(@Window, 'REDRAW', True$) end end event Event EDL_EPI_PART_SEARCH.LOSTFOCUS(Flag, FocusID) PrevEpiPartNo = Get_Property(CtrlEntId, '@PREV_EPI_PART_NO') SearchEpiPartNo = Get_Property(CtrlEntId, 'TEXT') If SearchEpiPartNo NE PrevEpiPartNo then // Restore already selected appointments to their normal backcolor. Set_Property(@Window, 'REDRAW', False$) SearchAppointmentKeys = Get_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS') If SearchAppointmentKeys NE '' then For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral' Case Flags<3> BackColor = 'LightGray' Case Otherwise$ BackColor = 'LightSteelBlue' End Case Appt<4> = BackColor Appt<5> = 'Black' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey end SearchAppointmentKeys = '' AppointmentList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.AppointmentList') AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AllAppointmentKeys = AppointmentArray<2> For Each AppointmentKey in AllAppointmentKeys using @VM setting vPos WorkOrderNo = Xlate('SCHED_DET_NG', AppointmentKey, 'WO_NO', 'X') EpiPartNo = Xlate('WO_LOG', WorkOrderNo, 'EPI_PART_NO', 'X') If EpiPartNo EQ SearchEpiPartNo then SearchAppointmentKeys := AppointmentKey : @FM end Next AppointmentKey SearchAppointmentKeys[-1, 1] = '' For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral L=40' Case Flags<3> BackColor = 'LightGray L=40' Case Otherwise$ BackColor = 'LightSteelBlue L=40' End Case Appt<4> = BackColor Appt<5> = 'White' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey Set_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS', SearchAppointmentKeys) Send_Message(@Window : '.OLE_SCHEDULE', 'OLE.EnsureVisible', SearchAppointmentKeys<1>) Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.SelAppt[' : SearchAppointmentKeys<1> : ']') Set_Property(CtrlEntId, '@PREV_EPI_PART_NO', SearchEpiPartNo) Set_Property(@Window : '.EDL_WORK_ORDER_SEARCH', 'TEXT', '') Set_Property(@Window, 'REDRAW', True$) end end event Event OLE_SCHEDULE.OnApptDblClick(ApptID, Button, Shift, Ctrl) PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup If Button EQ 'Left' then SchedEventRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) WorkOrderNo = SchedEventRec EpiPartNo = Xlate('WO_LOG', WorkOrderNo, 'EPI_PART_NO', 'X') ReactorNo = SchedEventRec StartDate = Field(SchedEventRec, '.', 1) WOStepKey = WorkOrderNo : '*1' ReactType = Xlate('REACTOR', ReactorNo, 'REACT_TYPE', 'X') PopupId = Entid(@AppID<1>, 'POPUP', '', 'DAILY_SCHED_OPTS') OverRide = '' Display = Xlate('SYSREPOSPOPUPS', 'LSL2**DAILY_SCHED_OPTS', PDISPLAY$, 'X') if MemberOf(@USER4, 'ENGINEERING') OR MemberOf(@USER4, 'SUPERVISOR') OR MemberOf(@USER4, 'LEAD') then ;* Added LEAD security group to allow asign supplements -dkk 12/5/14 * ADD OPTION TO ASSIGN SUPPLEMENTS Display := @vm:'Assign Supplements':@tm:'SUPPLEMENTS' end OverRide = Display ChosenOpt = repository( 'EXECUTE', PopupId, @window, OverRide ) RdsKeys = '' BEGIN CASE CASE ChosenOpt = 'QUOTE' IF security_check( 'Quote', Read$ ) THEN WORec = XLATE('WO_LOG',WorkOrderNo,'','X') OrderNo = WORec OrderItemNos = WORec QuoteNo = XLATE('ORDER_DET',OrderNo:'*':OrderItemNos<1,1>,1,'X') Void = start_window( 'QUOTE2', @window, QuoteNo:'*CENTER', '', '' ) END ELSE security_err_msg( 'Quote', Read$ ) END CASE ChosenOpt = 'PSN' IF security_check( 'Prod Spec', Read$ ) THEN PSNId = XLATE('WO_STEP',WOStepKey,WO_STEP_PROD_SPEC_ID$,'X') Void = start_window( 'PROD_SPEC', @window, PSNId:'*CENTER', '', '' ) END ELSE security_err_msg( 'Prod Spec', Read$ ) END CASE ChosenOpt = 'RECIPE' if security_check( 'Recipe', Read$ ) then PSN = XLATE('WO_STEP',WOStepKey,1,'X') LayerSpecs = obj_Prod_Spec('GetLayerProp',PSN:@RM:@RM:1) ;* Returns specs for all layers in internal format LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet RecipeNo = LayerSpec Void = start_window( 'RECIPE', @window, RecipeNo:'*CENTER', '', '' ) end else security_err_msg( 'Recipe', Read$ ) end CASE ChosenOpt = 'RDS' if security_check( 'RDS', Read$ ) then RDSKeys = Schedule_Services('GetEventRDSKeys', ApptID) If RDSKeys NE '' then SelRDSKeys = Dialog_Box('NDW_RDS_QUERY', @Window, RDSKeys) IF SelRDSKeys NE '' THEN Void = Start_Window( 'RDS', @window, SelRDSKeys:'*CENTER', '', '' ) END end else MsgStruct = '' MsgStruct = '*' ; // Information icon Msg(@Window, MsgStruct, 'OK', '', 'Scheduler':@FM:'RDS records for this work order event do not yet exist.') end end else security_err_msg( 'RDS', Read$ ) end CASE ChosenOpt = 'WO' if security_check( 'WO Log', Read$ ) then Start_Window('NDW_WO_LOG', @Window, WorkOrderNo) end else security_err_msg( 'WO Log', Read$ ) end CASE ChosenOpt = 'WO_STAT' PSN = XLATE('WO_STEP',WOStepKey,1,'X') ReactorType = XLATE('PROD_SPEC',PSN,80,'X') BEGIN CASE CASE ReactorType = 'P' Or ReactorType = 'EPP' obj_Appwindow('ViewRelated','WO_PROD_EPI':@RM:WOStepKey) CASE ReactorType = 'GAN' obj_Appwindow('ViewRelated','WO_PROD_GAN':@RM:WOStepKey) CASE 1 obj_Appwindow('ViewRelated','WO_PROD':@RM:WOStepKey) END CASE case ChosenOpt = 'SUPPLEMENTS' Void = rds_supplement_maint( WorkOrderNo ) case 1 Null end case end end event Event OLE_SCHEDULE.OnScheduleClick(EntityId, Button, Location, Point, Shift, Ctrl) ContextMenu = '' If MemberOf(@USER4, 'SCHEDULER_ADMIN') OR MemberOf(@USER4, 'SCHEDULER_MASTER') then If Button EQ 'Right' AND Location EQ 'Entity' then ContextMenu := 'ADD' : @VM : 'Add Work Order Events...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADDBLOCK' : @VM : 'Add Block Out Events...' : @VM : 1 : @FM end end If (@Station[1, 11] _EQC 'MESIRWAP001') OR (@Station[1, 9] _EQC 'MESSA01EC') then If Button EQ 'Right' AND Location EQ 'Entity' then If ContextMenu NE '' then ContextMenu := '' : @FM end ContextMenu := 'ADJUSTREACTOR' : @VM : 'Auto Adjust Reactor ' : EntityId : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADJUSTREACTORLOGONLY' : @VM : 'Auto Adjust Reactor ' : EntityId : ' (Log Only)' : @VM : 1 : @FM ContextMenu := 'ADJUSTALLREACTORSLOGONLY' : @VM : 'Auto Adjust All Reactors (Log Only)' : @VM : 1 : @FM end end If ContextMenu NE '' then ContextMenu[-1, 1] = '' X = Field(Point, ',', 1) StartDTM = Send_Message(CtrlEntId, 'OLE.MapClientToTime', X, 1) Send_Message(CtrlEntId, 'OLE.ShowContextMenu', Point, ContextMenu, EntityID : @VM : StartDTM) end end event Event OLE_SCHEDULE.OnApptHover(ApptID, Point) PopupCtrl = @Window : '.OLE_POPUP' Set_Property(@Window, '@PREV_APPT_ID', ApptID) PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ False$ then GoSub DisplayPopup end event Event OLE_SCHEDULE.OnScheduleMouseMove(EntityId, ApptID, Location, Point, Shift, Ctrl) PrevApptID = Get_Property(@Window, '@PREV_APPT_ID') If ( (ApptID EQ '') or (ApptID NE PrevApptID) ) then GoSub DismissPopup end end event Event OLE_SCHEDULE.OnApptClick(ApptID, Button, Shift, Ctrl, Point) Begin Case Case Button EQ 'Left' Null Case Button EQ 'Right' ScheduleDetail = Schedule_Services('GetScheduleDetail', ApptID) ReactorNo = ScheduleDetail WONo = ScheduleDetail ProcessedCass = ScheduleDetail UnprocessedCass = ScheduleDetail InProgress = (ProcessedCass NE '') EligibleToStop = False$ EpiPro = (Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X') EQ 'EPP') For each CassNo in UnprocessedCass using @VM setting vPos WOMatKey = WONo:'*':CassNo If EpiPro then WMIKey = WONo:'*1*':CassNo RDSNos = Xlate('WM_IN', WMIKey, 'RDS_NO', 'X') RDSNo = RDSNos<0, 25> end else RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X') end DateIn = Xlate('RDS', RDSNo, 'DATE_IN', 'X') If DateIn EQ '' then EligibleToStop = True$ Until EligibleToStop EQ True$ Next CassNo ContextMenu = '' If MemberOf(@USER4, 'SCHEDULER_ADMIN') OR MemberOf(@USER4, 'SCHEDULER_MASTER') then BlockOut = ScheduleDetail If BlockOut then ContextMenu := 'CANCELBLOCK' : @VM : 'Cancel Block Out Event...' : @VM : 1 : @FM end else WorkOrderNo = ScheduleDetail HotFlag = Xlate('WO_LOG', WONo, 'HOT_FLAG', 'X') If HotFlag then ContextMenu := 'REMOVE_HOT_FLAG' : @VM : 'Remove Hot Flag' : @VM : 1 : @FM end else ContextMenu := 'ADD_HOT_FLAG' : @VM : 'Add Hot Flag' : @VM : 1 : @FM end ContextMenu := '' : @FM ContextMenu := 'ADD' : @VM : 'Add Work Order Events...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'MODIFY' : @VM : 'Modify Work Order Event...' : @VM : 1 : @FM ContextMenu := '' : @FM If InProgress EQ True$ then ContextMenu := 'STOP' : @VM : 'Stop Work Order Event...' : @VM : EligibleToStop : @FM end else ContextMenu := 'CANCEL' : @VM : 'Cancel Work Order Event...' : @VM : 1 : @FM end ContextMenu := '' : @FM ContextMenu := 'ADDBLOCK' : @VM : 'Add Block Out Events...' : @VM : 1 : @FM * ContextMenu := '' : @FM * ContextMenu := 'FORCEADJUST' : @VM : 'Force Auto-Adjustment for ' : WorkOrderNo : @VM : 1 : @FM If MemberOf(@USER4, 'SCHEDULER_MASTER') then ContextMenu := '' : @FM ContextMenu := 'REMOVEEVENT' : @VM : 'Remove This Work Order Event' : @VM : 1 : @FM end end end If ContextMenu NE '' then ContextMenu[-1, 1] = '' X = Field(Point, ',', 1) DateTime = Send_Message(CtrlEntId, 'OLE.MapClientToTime', X, 1) StartDate = DateTime[1, '.'] UserData = '' UserData<0, 1> = ReactorNo UserData<0, 2> = DateTime UserData<0, 3> = ApptID Send_Message(CtrlEntId, 'OLE.ShowContextMenu', Point, ContextMenu, UserData) end End Case end event Event OLE_SCHEDULE.OnContextMenuClick(Item, UserData) PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup Convert @VM to @FM in UserData ReactorNo = UserData<1> SchedDTM = UserData<2> ApptID = UserData<3> RefreshWO = Xlate('SCHED_DET_NG', ApptID, 'WO_NO', 'X') RemAppts = Xlate('REACTOR', ReactorNo, 'SCHED_EVENTS', 'X') Swap @VM with @FM in RemAppts Begin Case Case Item EQ 'ADD_HOT_FLAG' Work_Order_Services('SetHotFlag', RefreshWO, True$) If Error_Services('NoError') then ScheduleEventSummary = Schedule_Services('GetScheduleEventSummary', ApptID, False$) Send_Message(CtrlEntID, 'OLE.RemoveAppts', ApptID) ScheduleEvent = ReactorNo : @VM ScheduleEvent := ApptID : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : ' L=' : 80 : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM ScheduleEvent := ScheduleEventSummary : @SVM : ScheduleEventSummary : @SVM : ScheduleEventSummary : @SVM : ScheduleEventSummary Send_Message(CtrlEntID, 'OLE.AddAppts', ScheduleEvent) Send_Event('REACT_STATUS_EVEN', 'TIMER') Send_Event('REACT_STATUS_ODD', 'TIMER') WOLogVis = Get_Property('NDW_WO_LOG', 'VISIBLE') If WOLogVis then FormWONo = Get_Property('NDW_WO_LOG.EDL_WO_NO', 'TEXT') If FormWONo EQ RefreshWO then Set_Property('NDW_WO_LOG.CHB_HOT_FLAG', 'CHECK', True$) end end else Error_Services('DisplayError') end Case Item EQ 'REMOVE_HOT_FLAG' Work_Order_Services('SetHotFlag', RefreshWO, False$) If Error_Services('NoError') then ScheduleEventSummary = Schedule_Services('GetScheduleEventSummary', ApptID, False$) Send_Message(CtrlEntID, 'OLE.RemoveAppts', ApptID) ScheduleEvent = ReactorNo : @VM ScheduleEvent := ApptID : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : ' L=' : 80 : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := ScheduleEventSummary : @VM ScheduleEvent := @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM ScheduleEvent := ScheduleEventSummary : @SVM : ScheduleEventSummary : @SVM : ScheduleEventSummary : @SVM : ScheduleEventSummary Send_Message(CtrlEntID, 'OLE.AddAppts', ScheduleEvent) Send_Event('REACT_STATUS_EVEN', 'TIMER') Send_Event('REACT_STATUS_ODD', 'TIMER') WOLogVis = Get_Property('NDW_WO_LOG', 'VISIBLE') If WOLogVis then FormWONo = Get_Property('NDW_WO_LOG.EDL_WO_NO', 'TEXT') If FormWONo EQ RefreshWO then Set_Property('NDW_WO_LOG.CHB_HOT_FLAG', 'CHECK', False$) end end else Error_Services('DisplayError') end Case Item EQ 'ADD' AddEventDetails = Dialog_Box('NDW_SCHEDULER_ADD_WO', @Window, UserData) If AddEventDetails NE '' then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage ReactorNo = AddEventDetails<1> WorkOrder = AddEventDetails<2> RefreshWO = WorkOrder StartDTM = AddEventDetails<3> StopDTM = AddEventDetails<4> Description = AddEventDetails<5> WaferQty = AddEventDetails<6> NewApptID = Schedule_Services('AddSchedEvent', ReactorNo, WorkOrder, StartDTM, StopDTM, Description, WaferQty) NewAppt = Schedule_Services('GetScheduleEvent', NewApptID) If Error_Services('NoError') then GoSub RefreshReactor If NewApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', NewApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'MODIFY' ModifyEventDetails = Dialog_Box('NDW_SCHEDULER_MODIFY_WO', @Window, UserData) If ModifyEventDetails NE '' then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage OrigRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) ReactorNo = ModifyEventDetails<1> WorkOrder = ModifyEventDetails<2> RefreshWO = WorkOrder StartDTM = ModifyEventDetails<3> StopDTM = ModifyEventDetails<4> Description = ModifyEventDetails<5> WaferQty = ModifyEventDetails<6> Schedule_Services('ModifySchedEvent', ApptID, ReactorNo, WorkOrder, StartDTM, StopDTM, Description, WaferQty) If Error_Services('NoError') then GoSub RefreshReactor If ApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec, OrigRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'STOP' StopEventDetails = Dialog_Box('NDW_SCHEDULER_STOP_WO', @Window, UserData) If StopEventDetails NE '' then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage OrigRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) ReactorNo = StopEventDetails<1> WorkOrder = StopEventDetails<2> RefreshWO = WorkOrder StartDTM = StopEventDetails<3> StopDTM = StopEventDetails<4> Description = StopEventDetails<5> WaferQty = StopEventDetails<6> Schedule_Services('ModifySchedEvent', ApptID, ReactorNo, WorkOrder, StartDTM, StopDTM, Description, WaferQty) If Error_Services('NoError') then GoSub RefreshReactor If ApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec, OrigRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'CANCEL' Response = Dialog_Box('NDW_SCHEDULER_CANCEL_WO', @Window, UserData) If Response EQ 'Proceed' then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage OrigRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('CancelScheduleEvent', ApptID) If Error_Services('NoError') then GoSub RefreshReactor If ApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec, OrigRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'ADDBLOCK' BlockEventDetails = Dialog_Box('NDW_SCHEDULER_ADD_BLOCK', @Window, UserData) If BlockEventDetails NE '' then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage BlockReactorNo = BlockEventDetails<1> BlockStartDTM = BlockEventDetails<2> BlockStopDTM = BlockEventDetails<3> BlockComment = BlockEventDetails<4> BlockType = BlockEventDetails<5> BlockOption = BlockEventDetails<6> BlockId = Schedule_Services('AddBlockOutEvent', BlockReactorNo, BlockStartDTM, BlockStopDTM, BlockType, BlockComment, BlockOption) If Error_Services('NoError') then GoSub RefreshReactor If BlockID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', BlockID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'CANCELBLOCK' Response = Msg(@Window, MsgStruct, 'YESNO', '', 'Cancel Block Out' : @FM : 'Cancel block out event?') If Response EQ True$ then Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage OrigRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) ReactorNo = Xlate('SCHED_DET_NG', ApptID, 'REACT_NO', 'X') UpdatedEvents = Schedule_Services('CancelScheduleEvent', ApptID, True$) If Error_Services('NoError') then GoSub RefreshReactor If ApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec, OrigRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage end Case Item EQ 'REMOVEEVENT' Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage OrigRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('DeleteScheduleDetail', ApptID) Send_Message(CtrlEntId, 'RemoveAppts', ApptID) If Error_Services('NoError') then GoSub RefreshReactor If ApptID NE '' then SchedRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) Schedule_Services('NotifySupervisorsIfSameDayChange', SchedRec, OrigRec) end end else Error_Services('DisplayError') end GoSub HideWaitMessage End Case If ( (RefreshWO NE '') and (Item NE 'ADD_HOT_FLAG') and (Item NE 'REMOVE_HOT_FLAG') ) then Work_Order_Services('UpdateUnscheduledQuantities', RefreshWO) end end event Event OLE_SCHEDULE.OnDateChange(Date) DateList = Get_Property(CtrlEntId, '@DATE_LIST') ReloadStartDate = Date - 60 ReloadEndDate = Date + 60 ReloadWorkOrders = False$ For Date = ReloadStartDate to ReloadEndDate Locate Date in DateList using @FM setting fPos else ReloadWorkOrders = True$ Until ReloadWorkOrders EQ True$ Next Date If ReloadWorkOrders then // The ShowWaitMessage gosub hides the schedule control and displays the picture contorl with the indicated caption. Caption = 'Please wait...updating schedule' GoSub ShowWaitMessage // Update the work orders AppointmentList = Schedule_Services('GetScheduleEvents', ReloadStartDate, ReloadEndDate) Set_Property(@Window, '@APPT_LIST', AppointmentList) Send_Message(CtrlEntId, 'OLE.AddAppts', AppointmentList) // The SetScheduleFlags gosub loops through the AppointmentKeys array and parses the AppointmentFlags // array for the ApptFlags property. AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AppointmentKeys = AppointmentArray<2> Convert @VM to @FM in AppointmentKeys AppointmentFlags = AppointmentArray<19> Convert @VM to @FM in AppointmentFlags GoSub SetScheduleFlags For Date = ReloadStartDate to ReloadEndDate Locate Date in DateList using @FM setting fPos else DateList = Insert(DateList, fPos, 0, 0, Date) end Next Date Set_Property(CtrlEntId, '@DATE_LIST', DateList) GoSub HideWaitMessage end end event Event OLE_DATEPICKER.OnSelChange(FirstDate) SelectedDate = Get_Property(CtrlEntId, 'OLE.Selection') Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Date', SelectedDate) Send_Event(@Window : '.OLE_SCHEDULE', 'OLE', 'OnDateChange', SelectedDate) end event Event OLE_TRE_REACTOR_FILTER_OPTIONS.OnItemCheck(Item, Checked) Set_Property(@Window, 'REDRAW', False$) FilterType = Get_Property(@Window : '.EDL_REACTOR_FILTER', 'TEXT') FilterOptions = Get_Property(CtrlEntId, 'OLE.RootChildren') ItemsChecked = '' For Each FilterOption in FilterOptions using @FM setting fPos If Get_Property(CtrlEntId, 'OLE.ItemChecked[' : FilterOption : ']') then ItemsChecked := FilterOption : @FM end Next FilterOption ItemsChecked[-1, 1] = '' // Make sure all reactors are visible again. EntityList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityList') For Each Entity in EntityList using @FM EntityID = Entity<0, 3> If Not(Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : EntityID : ']')) then Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : EntityID : ']', True$) end Next Entity // Now apply the filter optons and hide those entities which should be hidden. Reactors = Reactor_Services('GetReactors') objReactors = '' If SRP_JSON(objReactors, 'PARSE', Reactors) EQ '' then objReactorArray = SRP_JSON(objReactors, 'GET', 'Reactors') NumObjects = SRP_JSON(objReactorArray, 'GETCOUNT') For ObjectCount = 1 to NumObjects ReactorNo = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].ReactorNumber') Begin Case Case FilterType _EQC 'Reactor Type' Type = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].TypeVerbose') Locate Type in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Reactor Assignment' AssignmentDescription = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].AssignmentDescription') Locate AssignmentDescription in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Cleanroom Area' Location = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].Location') Locate Location in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Wafer Size' WaferSize = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].SusceptorSize') Locate WaferSize in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Cleanroom Area' Null End Case Next ObjectCount SRP_JSON(objReactorArray, 'RELEASE') end SRP_JSON(objReactors, 'RELEASE') Set_Property(@Window, 'REDRAW', True$) end event Event EDL_ASM_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_ASM_PLUS_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_HTR_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_EPIPRO_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_GAN_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event OLE_PUB_UPDATE_ASM_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) ASMUtil = Get_Property(@Window : '.EDL_ASM_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'ASM', ASMUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) ASMPlusUtil = Get_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'ASM+', ASMPlusUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_HTR_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) HTRUtil = Get_Property(@Window : '.EDL_HTR_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'HTR', HTRUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_EPIPRO_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) EpiProUtil = Get_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'EpiPro', EpiProUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_GAN_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) GaNUtil = Get_Property(@Window : '.EDL_GAN_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'GaN', GaNUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_REFRESH_SCHEDULE.OnClick(Point, Button, Shift, Ctrl) GoSub RefreshSchedule end event Event OLE_SUBCLASS.OnOptionClick(CtrlId) Send_Event(CtrlId, 'OPTIONS') end event Event OLE_SUBCLASS.OnComboClick(CtrlId) Send_Event(CtrlId, 'LOSTFOCUS') end event Event OLE_POPUP.OnItemClick(Item) ApptID = Get_Property(CtrlEntId, '@APPTID') SchedDetNGRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) WorkOrderNo = SchedDetNGRec EpiPartNo = Xlate('WO_LOG', WorkOrderNo, 'EPI_PART_NO', 'X') ReactorNo = SchedDetNGRec StartDate = Field(SchedDetNGRec, '.', 1) WOStepKey = WorkOrderNo : '*1' // Item is the index value of the item being clicked on from the ItemList property. PreviousItemArray = Get_Property(CtrlEntId, 'OLE.Item[' : Item - 1 : ']') PreviousCaption = PreviousItemArray<2> CurrentItemArray = Get_Property(CtrlEntId, 'OLE.Item[' : Item : ']') CurrentCaption = CurrentItemArray<2> GoSub DismissPopup Begin Case Case PreviousCaption _EQC 'Work Order:' if security_check( 'WO Log', Read$ ) then Void = start_window( 'NDW_WO_LOG', @window, WorkOrderNo, '', '' ) end else security_err_msg( 'WO Log', Read$ ) end Case PreviousCaption _EQC 'Epi Part:' Void = start_window( 'EPI_PART', @window, EpiPartNo : '*CENTER', '', '' ) Case PreviousCaption _EQC 'PSN:' IF security_check( 'Prod Spec', Read$ ) THEN PSNId = XLATE('WO_STEP',WOStepKey,WO_STEP_PROD_SPEC_ID$,'X') Void = start_window( 'PROD_SPEC', @window, PSNId:'*CENTER', '', '' ) END ELSE security_err_msg( 'Prod Spec', Read$ ) END Case PreviousCaption _EQC 'Recipe:' if security_check( 'Recipe', Read$ ) then PSN = XLATE('WO_STEP',WOStepKey,1,'X') LayerSpecs = obj_Prod_Spec('GetLayerProp',PSN:@RM:@RM:1) ;* Returns specs for all layers in internal format LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet RecipeNo = LayerSpec Void = start_window( 'RECIPE', @window, RecipeNo:'*CENTER', '', '' ) end else security_err_msg( 'Recipe', Read$ ) end Case PreviousCaption _EQC 'SCHED_DET Key:' SchedDetKeyID = CurrentCaption call SRP_Editor_Open('Record', 'SCHED_DET_NG' : @FM : SchedDetKeyID, 1) End Case end event Event OLE_PUB_ZOOM_IN.OnClick(Point, Button, Shift, Ctrl) PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup Ctrl = @Window : '.OLE_SCHEDULE' IntervalSize = Get_Property(Ctrl, 'OLE.IntervalSize') IntervalSize += 2 Set_Property(Ctrl, 'OLE.IntervalSize', IntervalSize) ; // Space (width) for each time increment (in pixels) ZoomPercent = ((IntervalSize + 1) * 10):'%' Set_Property(@Window:'.LBL_ZOOM_PERCENT', 'TEXT', ZoomPercent) GoSub EnableZoomButtons end event Event OLE_PUB_ZOOM_OUT.OnClick(Point, Button, Shift, Ctrl) PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup Ctrl = @Window : '.OLE_SCHEDULE' IntervalSize = Get_Property(Ctrl, 'OLE.IntervalSize') IntervalSize -= 2 Set_Property(Ctrl, 'OLE.IntervalSize', IntervalSize) ; // Space (width) for each time increment (in pixels) ZoomPercent = ((IntervalSize + 1) * 10):'%' Set_Property(@Window:'.LBL_ZOOM_PERCENT', 'TEXT', ZoomPercent) GoSub EnableZoomButtons end event Event WINDOW.OMNIEVENT(Message, Param1, Param2, Param3, Param4) If Message EQ 'RefreshSchedule' then Sender = Param1 If Sender NE @User4 then // Only update the schedule if someone else sent the update message (e.g. the auto-scheduler service). PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup Caption = 'Please wait...refreshing schedule' GoSub ShowWaitMessage GoSub UpdateAppointmentList GoSub HideWaitMessage end end end event Event WINDOW.INACTIVATED() PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Setup_OLE_Controls: Ctrl = @Window : '.OLE_PICTURE' Set_Property(Ctrl, 'OLE.BackgroundColor', 'Vertical(Gradient(LightSteelBlue L=90, LightSteelBlue L=80, 30%), Gradient(LightSteelBlue L=75, LightSteelBlue L=80), Border(LightSteelBlue L=50, LightSteelBlue L=50, LightSteelBlue L=50, LightSteelBlue L=50))') Set_Property(Ctrl, 'OLE.Font', SystemTypeface$ : @SVM : 30 : @SVM : 700) // The ShowWaitMessage gosub hides the schedule control and displays the picture contorl with the indicated caption. Caption = 'Please wait...loading schedule' GoSub ShowWaitMessage Ctrl = @Window : '.OLE_SCHEDULE' // Setup the inital date range during the 'Create' StartDate = Date() - 120 EndDate = Date() + 120 DateList = '' For Date = StartDate to EndDate DateList := Date : @FM Next Date DateList[-1, 1] = '' Set_Property(Ctrl, '@DATE_LIST', DateList) Set_Property(Ctrl, 'OLE.Border', 'XP Flat') Set_Property(Ctrl, 'OLE.View', 'MultiDayHorz') ; // Landscape mode Set_Property(Ctrl, 'OLE.DateHeaderFormat', 'DDDD - mmm DD, YYYY') Set_Property(Ctrl, 'OLE.CurrentTimeColor', 'Blue') Set_Property(Ctrl, 'OLE.ShowCalendar', False$) Set_Property(Ctrl, 'OLE.ShowTree', False$) Set_Property(Ctrl, 'OLE.AllowLeadTime', False$) Set_Property(Ctrl, 'OLE.AllowTrailTime', False$) Set_Property(Ctrl, 'OLE.EnableLeadTrailDisplay', Trail$) Set_Property(Ctrl, 'OLE.AppointmentMetrics', 4 : @FM : 4) Set_Property(Ctrl, 'OLE.Interval', 60) ; // Number of minutes per interval UserConfigKey = @User4:'*':@Window UserConfigRec = Database_Services('ReadDataRow', 'USER_CONFIG', UserConfigKey) If UserConfigRec NE '' then Set_Property(@Window, '@USER_CONFIG_REC', UserConfigRec) UserConfigProps = UserConfigRec UserConfigVals = UserConfigRec Locate 'IntervalSize' in UserConfigProps using @VM setting vPos then IntervalSize = UserConfigVals<0, vPos> ZoomPercent = ((IntervalSize + 1) * 10):'%' Set_Property(@Window:'.LBL_ZOOM_PERCENT', 'TEXT', ZoomPercent) end else IntervalSize = 11 end end else IntervalSize = 11 end Set_Property(Ctrl, 'OLE.IntervalSize', IntervalSize) ; // Space (width) for each time increment (in pixels) Set_Property(Ctrl, 'OLE.TimeRange', 0 :@FM: 24 :@FM: 4) ; // <3> is hour display increment // Setup the initial reactors list. This populates the EntityList variable. GoSub GetReactorEntities Set_Property(Ctrl, 'OLE.EntityList', EntityList) Set_Property(Ctrl, 'OLE.AutoSize', 0) Set_Property(Ctrl, 'OLE.EntitySize[All]', 75) Set_Property(Ctrl, 'OLE.Date', Date()-1) Layout = '' Layout<1, 1> = 'APPTDATA' Layout<1, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<1, 3> = 'NAME' Layout<1, 4> = '' Layout<1, 5> = 'Segoe UI' : @SVM : 9 : @SVM : 700 Layout<1, 6> = 'Center' Layout<1, 7> = 'Center' Layout<1, 8> = 0 Layout<1, 10> = 1 Layout<2, 1> = 'APPTDATA' Layout<2, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<2, 3> = 'DESC' Layout<2, 4> = '' Layout<2, 6> = 'Center' Layout<2, 7> = 'Bottom' Layout<2, 8> = 1 Layout<2, 10> = 0 Layout<3, 1> = 'FLAGS' Layout<3, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<3, 3> = 'bmps\scheduler.png' Layout<3, 4> = 4 : @SVM : @SVM : 0 Layout<3, 6> = 'Right' Layout<3, 7> = '' Layout<3, 8> = '' Layout<3, 10> = 0 Set_Property(Ctrl, 'OLE.Layout', Layout) // The GetScheduleAppointments gosub populates the AppointmentList, AppointmentKeys, and AppointmentFlags variables. GoSub GetScheduleAppointments Set_Property(Ctrl, 'OLE.AppointmentList', AppointmentList) // The SetScheduleFlags gosub loops through the AppointmentKeys array and parses the AppointmentFlags // array for the ApptFlags property. GoSub SetScheduleFlags Qualify = '' Qualify<1> = 1 Qualify<4> = 0 Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptClick', Qualify) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptDblClick', Qualify) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnScheduleClick', Qualify) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualify) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptHover', Qualify) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnScheduleMouseMove', Qualify) Set_Property(Ctrl, "OLE.EnableMouseMoveEvent", True$) Send_Message(@Window:'.OLE_PUB_ZOOM_IN', 'QUALIFY_EVENT', 'OLE.OnClick', Qualify) Send_Message(@Window:'.OLE_PUB_ZOOM_OUT', 'QUALIFY_EVENT', 'OLE.OnClick', Qualify) Fonts = '' Fonts<1> = 'Segoe UI' : @SVM : '10' ; // Column Hours Fonts<2> = 'Segoe UI' : @SVM : '6' ; // Column Minutes Fonts<3> = 'Segoe UI' : @SVM : '12' : @SVM : '700' ; // Reactor No Fonts<4> = 'Segoe UI' : @SVM : '8' ; // Reactor Meta Fonts<5> = 'Segoe UI' : @SVM : '12' : @SVM : '700' ; // Column Date and Day Set_Property(Ctrl, 'OLE.ScheduleFonts', Fonts) Qualify<4> = 1 Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnDateChange', Qualify) Qualify<4> = 0 GoSub HideWaitMessage Ctrl = @Window : '.OLE_DATEPICKER' Set_Property(Ctrl, 'OLE.Border', 'XP Flat') Set_Property(Ctrl, 'OLE.Font', 'Segoe UI' : @SVM : '9') Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnSelChange', 1) Ctrl = @Window : '.OLE_SUBCLASS' EditLine = @Window : '.EDL_REACTOR_FILTER' Set_Property(EditLine, 'TEXT', 'Reactor Type') Post_Event(EditLine, 'LOSTFOCUS') Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_REACTOR_FILTER' FilterTypes = 'Reactor Type' : @STM : 'Reactor Assignment' : @STM : 'Wafer Size' : @STM : 'Cleanroom Area' Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = FilterTypes Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnOptionClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnComboClick', 1) EditLine = @Window : '.EDL_WORK_ORDER_SEARCH' Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_WORK_ORDER_SEARCH' ApptIDs = AppointmentArray<2> WorkOrders = Xlate('SCHED_DET_NG', ApptIDs, 'WO_NO', 'X') Convert @VM to @FM in WorkOrders Convert '*' to @VM in WorkOrders WorkOrders = SRP_Array('Rotate', WorkOrders, @FM, @VM) WorkOrders = WorkOrders<1> Convert @VM to @FM in WorkOrders WorkOrders = SRP_Array('Clean', WorkOrders, 'TrimAndMakeUnique', @FM) WorkOrders = SRP_Array('SortRows', WorkOrders, 'AR1', 'LIST', @FM, @VM) Convert @FM to @STM in WorkOrders Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = WorkOrders Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,10> = 0 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) EditLine = @Window : '.EDL_EPI_PART_SEARCH' Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_EPI_PART_SEARCH' Convert @STM to @VM in WorkOrders EpiParts = Xlate('WO_LOG', WorkOrders, 'EPI_PART_NO', 'X') Convert @VM to @FM in EpiParts Convert '*' to @VM in EpiParts EpiParts = SRP_Array('Rotate', EpiParts, @FM, @VM) Convert @VM to @FM in EpiParts EpiParts = SRP_Array('Clean', EpiParts, 'TrimAndMakeUnique', @FM) OSWrite EpiParts to 'E:\apps\Temp\TEMP\EpiParts.txt' EpiParts = SRP_Array('SortRows', EpiParts, 'AR1', 'LIST', @FM, @VM) Convert @FM to @STM in EpiParts Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = EpiParts Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,10> = 0 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) Ctrl = @Window : '.OLE_TRE_REACTOR_FILTER_OPTIONS' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnItemCheck', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptDblClick', 1) Ctrls = 'OLE_PUB_UPDATE_ASM_UTILIZATION,OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION,OLE_PUB_UPDATE_HTR_UTILIZATION,OLE_PUB_UPDATE_EPIPRO_UTILIZATION,OLE_PUB_UPDATE_GAN_UTILIZATION' For Each ButtonCtrl in Ctrls using ',' Ctrl = @Window : '.' : ButtonCtrl Set_Property(Ctrl, 'OLE.Icon', '.\BMPS\Save.png') Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnClick', 1) Next ButtonCtrl Ctrl = @Window : '.OLE_PUB_REFRESH_SCHEDULE' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnClick', 1) Ctrl = @Window : '.OLE_POPUP' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnItemClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnHide', 1) GoSub EnableZoomButtons return DisplayPopup: Utility('CURSOR', 'H') Set_Property(PopupCtrl, '@APPTID', ApptID) Appt = Get_Property(CtrlEntID, 'OLE.Appt[' : ApptID : ']') HoverData = '' BackColor = 'LightSteelBlue'; //Appt<4> ; // Use the same BackColor of the current appointment as the base. EventRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', ApptID) WorkOrderNo = EventRec; EpiPartNo = Xlate('WO_LOG', WorkOrderNo, 'EPI_PART_NO', 'X') ReactorNo = EventRec Date = EventRec Sequence = '' Summary = Schedule_Services('GetScheduleEventSummary', ApptID, True$) BlockOut = Summary If BlockOut then HoverData := 'Reactor:' : @VM : ReactorNo : @FM HoverData := 'Type:' : @VM : Summary : @FM HoverData := 'Block Type: ' : @VM : Summary :@FM HoverData := 'Start Date:' : @VM : OConv(Summary, 'DT/^3H') : @FM HoverData := 'End Date:' : @VM : OConv(Summary, 'DT/^3H') : @FM HoverData := 'Total Days:' : @VM : Summary end else HoverData := 'Reactor:' : @VM : ReactorNo : @FM HoverData := 'Type:' : @VM : Summary : @FM HoverData := 'Susceptor:' : @VM : Summary : @FM HoverData := 'Work Order:' : @VM : WorkOrderNo : @FM HoverData := 'Customer:' : @VM : Summary : @FM HoverData := 'Epi Part:' : @VM : EpiPartNo : @FM HoverData := 'PSN:' : @VM : Summary : @FM HoverData := 'Recipe:' : @VM : Summary : @FM HoverData := 'Start Date:' : @VM : OConv(Summary, 'DT/^3H') : @FM HoverData := 'End Date:' : @VM : OConv(Summary, 'DT/^3H') : @FM HoverData := 'Total Days:' : @VM : Summary : @FM HoverData := 'Total Wafers:' : @VM : Summary : @FM HoverData := 'Remaining Wafers:' : @VM : Summary : @FM HoverData := 'Complete:' : @VM : Summary end Note = Summary If Note NE '' then HoverData := @FM : 'Note:' : @VM : Summary end If MemberOf(@USER4, 'OI_ADMIN') then HoverData := @FM : 'SCHED_DET Key:' : @VM : ApptID end BackColor := ' L=40' NumLines = DCount(HoverData, @FM) ForeColor = 'White' Linkcolor = 'LightGray' // Calculate the size and position of the popup. By default it will appear to the right of the // appointment (order), but if it will display off the screen then move it to the left. DesktopWidth = Get_Property('SYSTEM', 'SIZE')<1> DesktopHeight = Get_Property('SYSTEM', 'SIZE')<2> WindowOffsetX = Get_Property(@Window, 'SIZE')<1> WindowOffsetY = Get_Property(@Window, 'SIZE')<2> ApptRect = Get_Property(CtrlEntId, 'OLE.ApptRect[' : ApptId : ']') RectLeft = ApptRect<1> RectTop = ApptRect<2> RectRight = ApptRect<3> RectBottom = ApptRect<4> If BlockOut then ItemWidth = 260 end else ItemWidth = 300 end PopupWidth = ItemWidth + 4 + 30 ItemHeight = 20 PopupHeight = NumLines * ItemHeight + 14 MouseX = Field(Point, ',', 1) MouseY = Field(Point, ',', 2) ApptHCenter = RectTop + ((RectBottom - RectTop) / 2) ApptVCenter = RectLeft + ((RectRight - RectLeft) / 2) ItemMargin = 12 YItemMargin = 0 Begin Case Case ( (MouseY + PopupHeight) GT DesktopHeight) // SRP Popup will fit if displayed on the top TailPosition = 'Bottom' PopupHeight = NumLines * ItemHeight + 30 PopupWidth -= 13 PopupX = MouseX - (PopupWidth / 2) PopupY = MouseY - PopupHeight Case ( ( (MouseX + PopupWidth) LE DesktopWidth) and ( (MouseY - PopupHeight) GT 0) ) // SRP Popup will fit if displayed on the right TailPosition = 'Left' ItemMargin = 28 PopupX = MouseX + 10 PopupY = (MouseY - (PopupHeight / '2.1') ) PopupWidth += 18 Case ( (MouseX + PopupWidth) GT DesktopWidth) // SRP Popup will fit if displayed on the left TailPosition = 'Right' PopupWidth += 4 PopupX = MouseX - PopupWidth PopupY = (MouseY - (PopupHeight / '2.1') ) Case Otherwise$ // SRP Popup will fit if displayed on the bottom TailPosition = 'Top' PopupWidth -= 12 PopupHeight = NumLines * ItemHeight + 50 PopupX = MouseX - (PopupWidth / 2) PopupY = MouseY YItemMargin = 20 End Case ItemList = '' If HoverData NE '' then For Each Item in HoverData using @FM setting ItemCnt // Add the label. Label = Item<0, 1> If BlockOut then ItemList := ItemMargin : @SVM : 5 + (ItemCnt - 1) * ItemHeight + YItemMargin : @SVM : ItemWidth * (2/5) : @SVM : ItemHeight : @VM end else ItemList := ItemMargin : @SVM : 5 + (ItemCnt - 1) * ItemHeight + YItemMargin : @SVM : ItemWidth * (9/20) : @SVM : ItemHeight : @VM end ItemList := Label : @VM ItemList := Forecolor : @VM ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' : @VM ItemList := 'Left' : @SVM : 'Center' : @VM ItemList := @FM // Add the value. Value = Item<0, 2> If BlockOut then ItemList := ItemMargin + (ItemWidth * (2/5)) : @SVM : 5 + (ItemCnt - 1) * ItemHeight + YItemMargin : @SVM : ItemWidth * (3/5) : @SVM : ItemHeight : @VM end else ItemList := ItemMargin + (ItemWidth * (9/20)) : @SVM : 5 + (ItemCnt - 1) * ItemHeight + YItemMargin : @SVM : ItemWidth * (11/20) : @SVM : ItemHeight : @VM end ItemList := Value : @VM If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := Linkcolor : @VM end else ItemList := Forecolor : @VM end If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '1' : @VM end else ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' : @VM end ItemList := 'Left' : @SVM : 'Center' : @VM If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := True$ : @VM : False$ : @VM end ItemList := @FM Next Item ItemList[-1, 1] = '' end Set_Property(PopupCtrl, 'OLE.Theme', 'Custom') Set_Property(PopupCtrl, 'OLE.Opacity', 255) Set_Property(PopupCtrl, 'OLE.Animation', 'N') Set_Property(PopupCtrl, 'OLE.Background', 'Vertical(Gradient(' : Backcolor : ', ' : Backcolor : '), Border(' : Backcolor : ' L=20))' : @FM : 'None' : @FM : 'None') Set_Property(PopupCtrl, 'OLE.ItemList', ItemList) Set_Property(PopupCtrl, 'OLE.ShowDelay', 0) Set_Property(PopupCtrl, 'OLE.Size', 0 : @FM : 0 : @FM : PopupWidth : @FM : PopupHeight) // This identifies the position of the tail. Options are: // Left, Top, Right, Bottom Set_Property(PopupCtrl, 'OLE.Pointer', TailPosition) Utility('CURSOR', 'A') // This tells the popup to appear at the designated X and Y coordinates which // have been calculated above based on the relative location of the order. Send_Message(PopupCtrl, 'OLE.ShowAt', PopupX, PopupY) return DismissPopup: PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then Send_Message(PopupCtrl, 'OLE.Close') Set_Property(@Window, '@PREV_APPT_ID', '') end return ShowWaitMessage: Set_Property(@Window : '.OLE_PICTURE', 'OLE.Caption', Caption) Set_Property(@Window : '.OLE_PICTURE', 'VISIBLE', 1) Set_Property(@Window : '.OLE_SCHEDULE', 'VISIBLE', 0) * Set_Property(@Window, 'REDRAW', 0) return HideWaitMessage: Set_Property(@Window : '.OLE_SCHEDULE', 'VISIBLE', 1) Set_Property(@Window : '.OLE_PICTURE', 'OLE.Caption', '') Set_Property(@Window : '.OLE_PICTURE', 'VISIBLE', 0) return GetScheduleAppointments: Ctrl = @Window : '.OLE_SCHEDULE' AppointmentList = '' AppointmentKeys = '' AppointmentFlags = '' StartDate = Date() - 160 EndDate = Date() + 160 AppointmentList = Schedule_Services('GetScheduleEvents', StartDate, EndDate) Set_Property(@Window, '@APPT_LIST', AppointmentList) AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AppointmentKeys = AppointmentArray<2> Convert @VM to @FM in AppointmentKeys AppointmentFlags = AppointmentArray<19> Convert @VM to @FM in AppointmentFlags DateList = Get_Property(@Window, '@DATE_LIST') For Date = StartDate to EndDate Locate Date in DateList using @FM setting fPos else DateList = Insert(DateList, fPos, 0, 0, Date) end Next Date Set_Property(CtrlEntId, '@DATE_LIST', DateList) return SetScheduleFlags: Ctrl = @Window : '.OLE_SCHEDULE' For Each AppointmentKey in AppointmentKeys using @FM setting fPos Flags = AppointmentFlags If Sum(Flags) GT 0 then Convert @SVM to @FM in Flags Set_Property(Ctrl, 'OLE.ApptFlags[' : AppointmentKey : ']', Flags) end Next AppointmentKey return GetReactorEntities: Ctrl = @Window : '.OLE_SCHEDULE' If Memory_Services('IsValueCurrent', Ctrl : '*EntityList', 3600, True$) then EntityList = Memory_Services('GetValue', Ctrl : '*EntityList') end else EntityList = '' Reactors = Reactor_Services('GetReactors') If SRP_JSON(objReactors, 'PARSE', Reactors) EQ '' then objReactorArray = SRP_JSON(objReactors, 'GET', 'Reactors') objReactorList = SRP_JSON(objReactorArray, 'GETELEMENTS') For Each objReactor in objReactorList using @FM ReactorNo = SRP_JSON(objReactor, 'GETVALUE', 'ReactorNumber') Type = SRP_JSON(objReactor, 'GETVALUE', 'TypeVerbose') Size = SRP_JSON(objReactor, 'GETVALUE', 'SusceptorSize') Assignment = SRP_JSON(objReactor, 'GETVALUE', 'AssignmentCode') SecondChamber = SRP_JSON(objReactor, 'GETVALUE', 'SecondChamber') PickPlace = SRP_JSON(objReactor, 'GETVALUE', 'PickPlace') NotRepairable = SRP_JSON(objReactor, 'GETVALUE', 'NotRepairable') EpiPro = (Type EQ 'EpiPro') Begin Case Case Assignment EQ 'G' // GaN Background = 'SkyBlue' Case Assignment EQ 'O' // Out-of-Service Background = 'Silver' Case Not(NotRepairable) Background = 'LightGreen' Case NotRepairable Background = LTORANGE$ Case Otherwise$ Background = 'Silver' End Case If (Type NE 'EpiPro') OR (SecondChamber NE '') then EntityName = ReactorNo If SecondChamber NE '' then EntityName := '/' : SecondChamber EntityList := 'ENT' : @VM : 1 : @VM : ReactorNo : @VM : EntityName : @VM : Type : CRLF$ : Size : @VM : 'Black' : @VM : Background : @FM end SRP_JSON(objReactor, 'RELEASE') Next objReactor EntityList[-1, 1] = '' SRP_JSON(objReactorArray, 'RELEASE') end SRP_JSON(objReactors, 'RELEASE') Memory_Services('SetValue', Ctrl : '*EntityList', EntityList) end return ParseScheduleEvent: If Assigned(objScheduleEvent) else objScheduleEvent = '' If objScheduleEvent EQ '' then SRP_JSON(objScheduleEvent, 'PARSE', ScheduleEvent) end If objScheduleEvent GT 0 then ReactorNo = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.ReactorNumber') ReactorType = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.Type') SusceptorSize = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.SusceptorSize') ScheduleDate = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ScheduleDate') ScheduleDate = Iconv(ScheduleDate, 'D') Sequence = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Sequence') BackColor = SRP_JSON(objScheduleEvent, 'GETVALUE', 'BackColor') ForeColor = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ForeColor') ModifiedDTM = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ModifiedDTM') BlockOut = Iconv(SRP_JSON(objScheduleEvent, 'GETVALUE', 'BlockOut'), 'BYes,No') BlockOutType = SRP_JSON(objScheduleEvent, 'GETVALUE', 'BlockOutType') Description = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Note') objWorkOrder = SRP_JSON(objScheduleEvent, 'GET', 'WorkOrder') WorkOrderNo = SRP_JSON(objWorkOrder, 'GETVALUE', 'WorkOrderNumber') EpiPartNo = SRP_JSON(objWorkOrder, 'GETVALUE', 'EpiPartNumber') PSN = SRP_JSON(objWorkOrder, 'GETVALUE', 'PSN') Recipe = SRP_JSON(objWorkOrder, 'GETVALUE', 'Recipe') HotLot = Iconv(SRP_JSON(objWorkOrder, 'GETVALUE', 'HotLot'), 'BYes,No') Closed = Iconv(SRP_JSON(objWorkOrder, 'GETVALUE', 'Closed'), 'BYes,No') CustNameShort = SRP_JSON(objWorkOrder, 'GETVALUE', 'Company.NameShort') SRP_JSON(objWorkOrder, 'RELEASE') If BackColor EQ '' then Begin Case Case BackColor NE '' // Set in the schedule detail record. Use current color. Case HotLot BackColor = 'LightCoral' Case Closed BackColor = 'LightGray' Case BlockOut BackColor = 'Plum' Case Otherwise$ BackColor = 'LightSteelBlue' End Case end Current = False$ ; // Assume false for now. If (ScheduleDate GE Date()) then If (ModifiedDTM NE '') then CurrentDTM = Iconv(Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTH'), 'DTM') ElapseTime = (CurrentDTM - ModifiedDTM) * 24 IF (ElapseTime LE 12) then CurrentFlag = True$ end end end If ForeColor EQ '' then ForeColor = 'Black' FirstSchedDetKeyID = SRP_JSON(objScheduleEvent, 'GETVALUE', 'FirstSchedDetKeyID') FirstReactorNo = FirstSchedDetKeyID[1, '*'] FirstScheduleDate = Oconv(FirstSchedDetKeyID[Col2() + 1, '*'], 'D4/') LastSchedDetKeyID = SRP_JSON(objScheduleEvent, 'GETVALUE', 'LastSchedDetKeyID') LastReactorNo = LastSchedDetKeyID[1, '*'] LastScheduleDate = Oconv(LastSchedDetKeyID[Col2() + 1, '*'], 'D4/') TotalScheduledDays = SRP_JSON(objScheduleEvent, 'GETVALUE', 'TotalScheduledDays') TotalWafers = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.TotalWafers') WafersRemaining = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.WafersRemaining') PercentComplete = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.PercentComplete') ScheduleEvent = SRP_JSON(objScheduleEvent, 'STRINGIFY', 'FAST') SRP_JSON(objScheduleEvent, 'RELEASE') end return EnableZoomButtons: Ctrl = @Window : '.OLE_SCHEDULE' IntervalSize = Get_Property(Ctrl, 'OLE.IntervalSize') Set_Property(@Window:'.OLE_PUB_ZOOM_OUT', 'ENABLED', (IntervalSize GT 9)) Set_Property(@Window:'.LBL_ZOOM_OUT', 'ENABLED', (IntervalSize GT 9)) Set_Property(@Window:'.OLE_PUB_ZOOM_IN', 'ENABLED', (IntervalSize LT 29)) Set_Property(@Window:'.LBL_ZOOM_IN', 'ENABLED', (IntervalSize LT 29)) return UpdateAppointmentList: Ctrl = @Window : '.OLE_SCHEDULE' CurrApptList = Get_Property(Ctrl, 'OLE.AppointmentList') CurrApptArray = SRP_Array('Rotate', CurrApptList, @FM, @VM) CurrApptKeys = CurrApptArray<2> Convert @VM to @FM in CurrApptKeys // Remove all appointments in the schedule control Send_Message(Ctrl, 'OLE.RemoveAppts', CurrApptKeys) GoSub GetScheduleAppointments // Populate the schedule control with the the new list Send_Message(Ctrl, 'OLE.AddAppts', AppointmentList) GoSub SetScheduleFlags return RefreshReactor: Ctrl = @Window : '.OLE_SCHEDULE' Caption = 'Please wait...updating the schedule' GoSub ShowWaitMessage Set_Property(Ctrl, "OLE.Redraw", False$) If RemAppts NE '' then Send_Message(Ctrl, 'RemoveAppts', RemAppts) Schedule_Services('AdjustScheduleEvents', ReactorNo) ReactEventKeys = Xlate('REACTOR', ReactorNo, 'SCHED_EVENTS', 'X') Swap @VM with @FM in ReactEventKeys AddAppts = '' For each EventKey in ReactEventKeys using @FM setting fPos AddAppts = Schedule_Services('GetScheduleEvent', EventKey) Next EventKey If AddAppts NE '' then Send_Message(Ctrl, 'AddAppts', AddAppts) Set_Property(Ctrl, "OLE.Redraw", True$) GoSub HideWaitMessage return RefreshSchedule: // The ShowWaitMessage gosub hides the schedule control and displays the picture control with the indicated caption. PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup Caption = 'Please wait...refreshing schedule' GoSub ShowWaitMessage GoSub UpdateAppointmentList GoSub HideWaitMessage Return