open-insight/LSL2/STPROC/NDW_SCHEDULER_ADD_WO_EVENTS.txt
Infineon\StieberD 7762b129af pre cutover push
2024-09-04 20:33:41 -07:00

629 lines
24 KiB
Plaintext

Function NDW_Scheduler_Add_WO_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_Add_WO_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/12/17 dmb Created initial commuter module.
01/08/21 djs Began work on version 2.0.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#Window NDW_SCHEDULER_ADD_WO
$insert APP_INSERTS
$insert EVENT_SETUP
$insert MSG_EQUATES
$insert SCHED_DET_NG_EQUATES
$insert WO_LOG_EQUATES
$insert WO_SCHEDULE_NG_EQUATES
$insert REACTOR_EQUATES
Equ OI_DISABLED_GREY$ TO 239 + (239*256) + (239*65536)
Declare function SRP_Array, Schedule_Services, Database_Services, Work_Order_Services, SRP_Math
Declare function Epi_Part_Services, Datetime
Declare subroutine obj_Appwindow, Center_Window, Schedule_Services, Form_Services, SRP_Show_Window
Declare subroutine Form_Services, ErrMsg
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
Type = Get_Property(CtrlEntId, 'TYPE')
If Type EQ 'RADIOBUTTON' then
Convert ' ' to '_' in CtrlEntID
end
GoToEvent Event for CtrlEntID
Return EventFlow else EVENT_CONTINUE$
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Event WINDOW.CREATE(CreateParam)
ReactorNo = CreateParam<1>
SchedStartDTM = CreateParam<2>
Set_Property(@Window, '@SCHED_START_DTM', SchedStartDTM)
NextStartDTM = ''
ReactSchedEvents = Xlate('REACTOR', ReactorNo, 'SCHED_EVENTS', 'X')
If ReactSchedEvents NE '' then
LastEventKey = ReactSchedEvents[-1, 'B':@VM]
LastSchedDetRec = Database_Services('ReadDataRow', 'SCHED_DET_NG', LastEventKey)
If LastSchedDetRec<SCHED_DET_NG.STOP_DTM$> GT SchedStartDTM then
// The datetime passed in by the user (via where they right-clicked on the schedule)
// is before the next available time slot.
NextStartDTM = LastSchedDetRec<SCHED_DET_NG.STOP_DTM$>
end
end
If NextStartDTM NE '' then
StartDTM = NextStartDTM
end else
StartDTM = SchedStartDTM
end
Set_Property(@Window, '@NEXT_START_DTM', StartDTM)
Set_Property(@Window : '.REACTOR_NO', 'TEXT', ReactorNo)
Set_Property(@Window : '.SCHEDULE_START_DTM', 'INVALUE', StartDTM)
GoSub Setup_OLE_Controls
GoSub PopulateControls
Set_Property(@Window : '.CLOSE_BUTTON', 'NEXT', @Window : '.REACTOR_NO')
SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$)
end event
Event WINDOW.CLOSE(CancelFlag)
end event
Event SCHEDULE_OPTIONS_DATETIME.NEXT_AVAILABLE.CLICK()
StartDTM = Get_Property(@Window, '@NEXT_START_DTM')
Set_Property(@Window:'.SCHEDULE_START_DTM', 'INVALUE', StartDTM)
Set_Property(@Window:'.SCHEDULE_START_DTM', 'ENABLED', False$)
Set_Property(@Window:'.SCHEDULE_START_DTM', 'BACKCOLOR', OI_DISABLED_GREY$)
GoSub UpdateWorkOrderDetails
end event
Event SCHEDULE_OPTIONS_DATETIME.SPECIFIC_DATE_AND_TIME.CLICK()
StartDTM = Get_Property(@Window, '@SCHED_START_DTM')
Set_Property(@Window:'.SCHEDULE_START_DTM', 'INVALUE', StartDTM)
Set_Property(@Window:'.SCHEDULE_START_DTM', 'ENABLED', True$)
Set_Property(@Window:'.SCHEDULE_START_DTM', 'BACKCOLOR', WHITE$)
GoSub UpdateWorkOrderDetails
end event
Event SCHEDULE_END_DTM.LOSTFOCUS(Flag, FocusID)
StartDTM = Get_Property(@Window : '.SCHEDULE_START_DTM', 'INVALUE')
EndDTM = Get_Property(CtrlEntId, 'INVALUE')
If StartDTM NE '' AND EndDTM NE '' then
Days = EndDTM - StartDTM + 1
Set_Property(@Window : '.DAYS', 'DEFPROP', Days)
end
end event
Event SCHEDULE_START_DTM.LOSTFOCUS(Flag, FocusID)
WorkOrder = Get_Property(@Window : '.WO_NO', 'TEXT')
If WorkOrder NE '' then
GoSub UpdateWorkOrderDetails
end else
Set_Property(@Window : '.SCHEDULE_END_DTM', 'INVALUE', '')
end
end event
Event WO_NO.LOSTFOCUS(Flag, FocusID)
WONo = Get_Property(CtrlEntID, 'TEXT')
OrigWONo = Get_Property(@Window, '@WO_NO')
If WONo NE OrigWONo then
Set_Property(@Window, '@WO_NO', WONo)
// User changed the value in this control. Update related controls.
GoSub UpdateCustomerName
GoSub InitializeProperties
GoSub UpdateWorkOrderDetails
end
end event
Event SAVE_BUTTON.CLICK()
ResponseData = ''
ReactorNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
WorkOrder = Get_Property(@Window : '.WO_NO', 'TEXT')
StartDTM = Get_Property(@Window : '.SCHEDULE_START_DTM', 'INVALUE')
EndDTM = Get_Property(@Window : '.SCHEDULE_END_DTM', 'INVALUE')
Description = Get_Property(@Window : '.DESCRIPTION', 'INVALUE')
EventQty = Get_Property(@Window : '.SCHEDULE_WAFERS', 'TEXT')
ResponseData = ReactorNo : @FM : WorkOrder : @FM : StartDTM : @FM : EndDTM : @FM : Description : @FM : EventQty
End_Dialog(@Window, ResponseData)
end event
Event CLOSE_BUTTON.CLICK()
Post_Event(@Window, 'CLOSE')
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 SCHEDULE_WAFERS.CHANGED(NewData)
SchedQty = NewData
AvailQty = Get_Property(@Window : '.AVAILABLE_QTY', 'TEXT')
If SchedQty NE '' then
If (SchedQty GT AvailQty) then
Set_Property(CtrlEntID, 'FOCUS', True$)
Set_Property(CtrlEntID, 'SELECTION', 1 : @FM : 999)
Message = 'Schedule quantity must be less than or equal to the available quantity.'
Form_Services('DisplayControlMessage', Message, 'Invalid Quantity', CtrlEntID, 'VALIDATION', 'RGB(229,20,0)')
end else
GoSub UpdateWorkOrderDetails
end
end
GoSub EnableSaveButton
end event
Event SCHEDULE_WAFERS.CHAR(VirtCode, ScanCode, CtrlKey, ShiftKey, AltKey)
Form_Services('CloseControlMessage', CtrlEntId)
end event
Event SCHEDULE_WAFERS.LOSTFOCUS(Flag, FocusID)
SchedQty = Get_Property(CtrlEntID, 'TEXT')
AvailQty = Get_Property(@Window : '.AVAILABLE_QTY', 'TEXT')
If SchedQty GT AvailQty then
Set_Property(CtrlEntID, 'FOCUS', True$)
Set_Property(CtrlEntID, 'SELECTION', 1 : @FM : 999)
Message = 'Schedule quantity must be less than or equal to the available quantity.'
Form_Services('DisplayControlMessage', Message, 'Invalid Quantity', CtrlEntID, 'VALIDATION', 'RGB(229,20,0)')
end else
GoSub UpdateWorkOrderDetails
end
GoSub EnableSaveButton
end event
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Setup_OLE_Controls:
Ctrl = @Window : '.OLE_SUBCLASS'
// Get the current reactor type and size so the GetReactor and GetUnscheduledWorkOrders service results can be filtered
// down to only those items that match the same type and size.
ReactorNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
ReactorRec = Database_Services('ReadDataRow', 'REACTOR', ReactorNo)
ReactorType = ReactorRec<REACTOR_REACT_TYPE$>
SusceptorSize = ReactorRec<REACTOR_SUSC_POCKET_SIZE$>
EditLine = @Window : '.WO_NO'
Handle = Get_Property(EditLine, 'HANDLE')
Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine)
Combo = ''
Combo<1> = 1
Combo<2, 1> = 'Work Order' : @TM : 'Epi Part' : @TM : 'Customer' : @TM : 'Reactor Type' : @TM : 'PSN Block'
Combo<2, 2> = 'L' : @STM : 'DYN' : @TM : 'L' : @STM : 'DYN' : @TM : 'L' : @STM : 'DYN' : @TM : 'L' : @STM : 'DYN' : @TM : 'C' : @STM : 'DYN'
Combo<2, 3> = ''
Combo<2, 4> = 1
Combo<2, 5> = 1
Combo<2, 6> = 0
Combo<2, 7> = 40
Combo<2, 9> = 1
Combo<2,10> = 0
Combo<2,11> = 0
Combo<2,12> = 1
Combo<2,24> = 0
EditLine = @Window : ';WO_NO'
Set_Property(@Window : '.OLE_SUBCLASS', 'OLE.Combo[' : EditLine : ']', Combo)
Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnOptionClick', 1)
Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnComboClick', 1)
return
SelectAll:
Set_Property(CtrlEntId, 'SELECTION', 1 : @FM : 999)
return
UpdateScheduleDetails:
ScheduleDetail = Schedule_Services('GetScheduleDetail', ScheduleKeyID)
Set_Property(@Window, '@ORIG_SCHEDULEDETAIL', ScheduleDetail)
WorkOrder = Get_Property(@Window : '.WO_NO', 'TEXT')
If WorkOrder NE '' then
Set_Property(@Window : '.DESCRIPTION', 'TEXT', ScheduleDetail<SCHED_DET_NG.DESC$>)
end else
Set_Property(@Window : '.DESCRIPTION', 'TEXT', '')
end
return
UpdateCustomerName:
WoNo = Get_Property(@Window : '.WO_NO', 'TEXT')
If WoNo NE '' then
WorkOrderDetail = Work_Order_Services('GetWorkOrderLogDetail', WONo)
CustNo = WorkOrderDetail<WO_LOG_CUST_NO$>
CompanyRow = Database_Services('ReadDataRow', 'COMPANY', CustNo)
CustName = CompanyRow<42>
end else
CustName = ''
end
Set_Property(@Window : '.CUSTOMER_NAME', 'TEXT', CustName)
return
UpdateReactorDetails:
ReactorNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
If Index(ReactorNo, '/', 1) then
// EpiPro reactors formatted as such, "40/42". We must truncate the reactor number to the first reactor.
ReactorNo = Field(ReactorNo, '/', 1, 1)
Set_Property(@Window : '.REACTOR_NO', 'TEXT', ReactorNo)
end
ReactorDetails = Schedule_Services('GetReactorDetails', ReactorNo)
ReactorType = ReactorDetails<REACTOR_REACT_TYPE$>
Begin Case
Case ReactorType _EQC 'EPP' ; ReactorType = 'EpiPro'
Case ReactorType _EQC 'GAN' ; ReactorType = 'GaN'
End Case
Set_Property(@Window : '.REACTOR_TYPE', 'TEXT', ReactorType)
Set_Property(@Window : '.REACTOR_SIZE', 'TEXT', ReactorDetails<REACTOR_SUSC_POCKET_SIZE$>)
FutureEvents = Schedule_Services('GetScheduleEvents', Date() + 1, '', ReactorNo, '', False$)
Set_Property(@Window, '@FUTURE_EVENTS', FutureEvents)
return
InitializeProperties:
WorkOrder = Get_Property(@Window : '.WO_NO', 'TEXT')
ReactNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
ReactorType = Get_Property(@Window : '.REACTOR_TYPE', 'TEXT')
WorkOrderDetail = Work_Order_Services('GetWorkOrderLogDetail', WorkOrder)
RemainingToProcess = Work_Order_Services('GetRemainingWafers', WorkOrder)
RemainingToSchedule = Schedule_Services('GetUnscheduledWfrQty', WorkOrder)
EpiPart = WorkOrderDetail<WO_LOG_EPI_PART_NO$>
MinutesPerWaferAdjusted = Epi_Part_Services('GetAdjustedWafersPerDayScheduler', EpiPart, ReactorType)
ScheduledWfrQty = Schedule_Services('GetScheduledWfrQty', WorkOrder)
WOSchedCass = Schedule_Services('GetScheduledCassettes', WorkOrder)
Set_Property(@Window, '@WORK_ORDER_DETAIL', WorkOrderDetail)
Set_Property(@Window, '@REMAINING_TO_PROCESS', RemainingToProcess)
Set_Property(@Window, '@REMAINING_TO_SCHEDULE', RemainingToSchedule)
Set_Property(@Window, '@MINUTES_PER_WAFER_ADJUSTED', MinutesPerWaferAdjusted)
Set_Property(@Window, '@SCHEDULED_WFR_QTY', ScheduledWfrQty)
Set_Property(@Window, '@WO_SCHED_CASS', WOSchedCass)
return
UpdateWorkOrderDetails:
MinutesPerWaferAdjusted = ''
WorkOrder = Get_Property(@Window : '.WO_NO', 'TEXT')
ReactNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
CurrDTM = Datetime()
If WorkOrder NE '' then
PSNBlocked = False$
WorkOrdersArray = Get_Property(@Window, '@UNSCHEDULED_WORK_ORDERS')
Convert @TM to @FM in WorkOrdersArray
Convert @STM to @VM in WorkOrdersArray
WorkOrderList = WorkOrdersArray<1>
PSNBlockedList = WorkOrdersArray<5>
Locate WorkOrder in WorkOrderList using @VM setting vPos then PSNBlocked = PSNBlockedList<0, vPos>
If PSNBlocked EQ '' then
Set_Property(@Window:'.LBL_PSN_BLOCK', 'VISIBLE', False$)
WorkOrderDetail = Get_Property(@Window, '@WORK_ORDER_DETAIL')
EpiPart = WorkOrderDetail<WO_LOG_EPI_PART_NO$>
TotalWafers = WorkOrderDetail<WO_LOG_WO_QTY$>
RemainingToProcess = Get_Property(@Window, '@REMAINING_TO_PROCESS')
RemainingToSchedule = Get_Property(@Window, '@REMAINING_TO_SCHEDULE')
If TotalWafers GT 0 then
Complete = ( (TotalWafers - RemainingToProcess) / TotalWafers) * 100
end else
Complete = 0
end
ReactorType = Get_Property(@Window : '.REACTOR_TYPE', 'TEXT')
MinutesPerWaferAdjusted = Get_Property(@Window, '@MINUTES_PER_WAFER_ADJUSTED')
ScheduledWfrQty = Get_Property(@Window, '@SCHEDULED_WFR_QTY')
AvailableWfrQty = RemainingToSchedule
EventWafers = Get_Property(@Window:'.SCHEDULE_WAFERS', 'TEXT')
If ( (EventWafers EQ '') and (MinutesPerWaferAdjusted NE '') ) then
EventWafers = AvailableWfrQty
Set_Property(@Window : '.SCHEDULE_WAFERS', 'TEXT', AvailableWfrQty)
end
UnprocessedCassettes = ''
ProcessedCassettes = ''
// Look at the next slot to be scheduled!
// Get the number of wafers scheduled up to this event.
// This should give us the correct starting wafer slot.
StartCassNo = SRP_Math('CEILING', ( (ScheduledWfrQty + 1) / 25))
If StartCassNo EQ 0 then StartCassNo = 1
EventNumCass = SRP_Math('CEILING', (EventWafers / 25))
FirstRDS = ''
EventEngaged = False$
If ReactorType _EQC 'EpiPro' then
// Example: Event starts on WM_IN cassette 6 (i.e. 172125*1*6), slot 13.
StartSlotNo = Mod(ScheduledWfrQty, 25) + 1
StopCassNo = StartCassNo + EventNumCass - 1
StopSlotNo = Mod((ScheduledWfrQty + EventWafers), 25)
If StopSlotNo EQ 0 then StopSlotNo = 25
For CassIndex = 1 to EventNumCass
CassNo = (StartCassNo + CassIndex - 1)
WMIKey = WorkOrder:'*1*':CassNo
WMIRdsKeys = Xlate('WM_IN', WMIKey, 'RDS_NO', 'X')
EventCassRDSKeys = ''
Begin Case
Case CassNo EQ StartCassNo
StartIndex = StartSlotNo
StopIndex = 25
Case CassNo EQ StopCassNo
StartIndex = 1
StopIndex = StopSlotNo
Case ( (CassNo EQ StartCassNo) and (CassNo EQ StopCassNo) )
StartIndex = StartSlotNo
StopIndex = StopSlotNo
Case Otherwise$
StartIndex = 1
StopIndex = 25
End Case
For SlotIndex = StartIndex to StopIndex
If FirstRDS EQ '' then
FirstRDS = WMIRdsKeys<0, SlotIndex>
FirstLoad = Xlate('RDS', FirstRDS, 'DATE_IN', 'X')
EventEngaged = (FirstLoad NE '')
end
EventCassRDSKeys<0, -1> = WMIRdsKeys<0, SlotIndex>
Next SlotIndex
EventCassRDSKeys = SRP_Array('Clean', EventCassRDSKeys, 'TrimAndMakeUnique', @VM)
// Now we have a list of RDS keys that only pertain to this event.
If EventCassRDSKeys NE '' then
// Are all of the RDS runs unloaded?
NumUnloadedRDS = 0
UnloadDtms = Xlate('RDS', EventCassRDSKeys, 'DATETIME_OUT', 'X')
If UnloadDtms NE '' then
For each UnloadDtm in UnloadDtms using @VM
If UnloadDtm NE '' then NumUnloadedRds += 1
Next UnloadDtm
end
NumRDS = DCount(EventCassRDSKeys, @VM)
CassProcessed = (NumRds EQ NumUnloadedRds)
end else
CassProcessed = False$
end
If CassProcessed then
ProcessedCassettes<0, -1> = CassNo
end else
UnprocessedCassettes<0, -1> = CassNo
end
Next CassIndex
ProcessedCassettes = SRP_Array('Join', ProcessedCassettes, UnprocessedCassettes, 'NOT', @VM)
// Estimate event unprocessed wafer quantity for duration estimate
NumUnprocCass = DCount(UnprocessedCassettes, @VM)
UnprocessedWfrQty = ( (NumUnprocCass - 1) * 25 ) + StopSlotNo
end else
// Example: Event starts on WO_MAT cassette 7. We don't need to schedule down to the
// wafer levels with non-epipro work order events.
For CassIndex = 1 to EventNumCass
CassNo = (StartCassNo + CassIndex)
WOMatKey = WorkOrder:'*':CassNo
RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
If FirstRDS EQ '' then
FirstRDS = RDSNo
FirstLoad = Xlate('RDS', FirstRDS, 'DATE_IN', 'X')
EventEngaged = (FirstLoad NE '')
end
UnloadDtm = Xlate('RDS', RDSNo, 'DATETIME_OUT', 'X')
CassProcessed = (UnloadDtm NE '')
If CassProcessed then
ProcessedCassettes<0, -1> = CassNo
end else
UnprocessedCassettes<0, -1> = CassNo
end
Next CassIndex
NumUnprocCass = DCount(UnprocessedCassettes, @VM)
UnprocessedWfrQty = NumUnprocCass * 25
end
// Need to check if user is scheduling part of the work order on another reactor.
PrevSchedEvents = Schedule_Services('GetScheduledEvents', WorkOrder)
If EventEngaged and (PrevSchedEvents EQ '') then
// Event already engaged
// Set start DTM to first load dtm unless the work order is switching reactors or split
Set_Property(@Window:'.OPTIONS_GRP_START_DTM', 'ENABLED', False$)
StartDtm = Xlate('RDS', FirstRDS, 'DATETIME_IN', 'X')
If StartDtm EQ '' then StartDtm = Get_Property(@Window, '@NEXT_START_DTM')
DurationEstimate = Schedule_Services('GetEventDuration', WorkOrder, UnprocessedWfrQty)
EndDTM = StartDtm + DurationEstimate
end else
// Event not engaged yet. Use previous event's end DTM unless it is in the past.
// In that event use the current DTM.
Set_Property(@Window:'.OPTIONS_GRP_START_DTM', 'ENABLED', True$)
NextStartDTM = Get_Property(@Window, '@NEXT_START_DTM')
CurrDTM = Datetime()
If NextStartDTM GT CurrDTM then
StartDTM = NextStartDTM
end else
StartDTM = CurrDTM
end
// Calculate End DTM based on the start DTM in the form and duration estimate
DurationEstimate = Schedule_Services('GetEventDuration', WorkOrder, EventWafers)
Set_Property(@Window:'.SCHEDULE_START_DTM', 'INVALUE', StartDTM)
EndDTM = StartDTM + DurationEstimate
end
If MinutesPerWaferAdjusted EQ '' then
Msg(@Window, 'Warning: ' : EpiPart : ' appears to be missing minutes per wafer values for ' : ReactorType)
Set_Property(@Window:'.CLOSE_BUTTON', 'FOCUS', True$)
end
end else
// PSN Blocked
Set_Property(@Window:'.LBL_PSN_BLOCK', 'VISIBLE', True$)
end
end
If ( (WorkOrder NE '') and (MinutesPerWaferAdjusted NE '') ) then
Set_Property(@Window : '.EPI_PART', 'TEXT', EpiPart)
Set_Property(@Window : '.TOTAL_WAFERS', 'TEXT', TotalWafers)
Set_Property(@Window : '.TOTAL_REMAINING', 'TEXT', RemainingToProcess)
Set_Property(@Window : '.PERCENT_COMPLETE', 'TEXT', Oconv(Complete, 'MD0[ %]S'))
Set_Property(@Window : '.SCHEDULE_START_DTM', 'INVALUE', StartDTM)
Set_Property(@Window : '.SCHEDULE_END_DTM', 'INVALUE', EndDTM)
DurationDaysRounded = SRP_Math('ROUND', DurationEstimate, 1)
Set_Property(@Window : '.DAYS', 'DEFPROP', DurationDaysRounded)
Set_Property(@Window : '.AVAILABLE_QTY', 'TEXT', AvailableWfrQty)
end else
Error_Services('DisplayError')
Set_Property(@Window : '.EPI_PART', 'TEXT', '')
Set_Property(@Window : '.TOTAL_WAFERS', 'TEXT', '')
Set_Property(@Window : '.TOTAL_REMAINING', 'TEXT', '')
Set_Property(@Window : '.SCHEDULE_WAFERS', 'TEXT', '')
Set_Property(@Window : '.PERCENT_COMPLETE', 'TEXT', '')
Set_Property(@Window : '.SCHEDULE_END_DTM', 'INVALUE', '')
Set_Property(@Window : '.DAYS', 'DEFPROP', '')
end
GoSub EnableSaveButton
return
UpdateWorkOrderList:
WorkOrders = ''
// Adding work order.
WorkOrders = Get_Property(@Window, '@UNSCHEDULED_WORK_ORDERS')
If WorkOrders EQ '' then
// Get the current reactor type and size so the GetReactor and GetUnscheduledWorkOrders service results
// can be filtered down to only those items that match the same type and size.
ReactorNo = Get_Property(@Window : '.REACTOR_NO', 'TEXT')
ReactorRec = Database_Services('ReadDataRow', 'REACTOR', ReactorNo)
ReactorType = ReactorRec<REACTOR_REACT_TYPE$>
SusceptorSize = ReactorRec<REACTOR_SUSC_POCKET_SIZE$>
WorkOrders = Schedule_Services('GetAvailableWorkOrders', ReactorType, '', ReactorNo)
WorkOrders = SRP_Array('Rotate', WorkOrders)
Convert @FM to @TM in WorkOrders
Convert @VM to @STM in WorkOrders
Set_Property(@Window, '@UNSCHEDULED_WORK_ORDERS', WorkOrders)
end
EditLine = @Window : ';WO_NO'
Set_Property(@Window : '.OLE_SUBCLASS', 'OLE.ComboData[' : EditLine : ']', WorkOrders)
return
PopulateControls:
Set_Property(@Window, 'TEXT', 'Scheduler Actions - Add Work Order Event')
Set_Property(@Window : '.REACTOR_NO', 'NEXT', @Window : '.SCHEDULE_START_DTM')
Set_Property(@Window : '.DESCRIPTION', 'NEXT', @Window : '.REACTOR_NO')
WorkOrders = Get_Property(@Window, '@UNSCHEDULED_WORK_ORDERS')
WONo = ''
ScheduleKeyID = ''
GoSub UpdateWorkOrderList
GoSub UpdateScheduleDetails
GoSub UpdateReactorDetails
GoSub UpdateCustomerName
GoSub EnableSaveButton
Set_Property(@Window : '.REACTOR_NO', 'FOCUS', True$)
return
EnableSaveButton:
PSNBlocked = Get_Property(@Window:'.LBL_PSN_BLOCK', 'VISIBLE')
SchedQty = Get_Property(@Window : '.SCHEDULE_WAFERS', 'TEXT')
AvailQty = Get_Property(@Window : '.AVAILABLE_QTY', 'TEXT')
ButtonEnabled = ( (SchedQty NE '') and (SchedQty NE 0) and (AvailQty NE 0) and (SchedQty LE AvailQty) and (PSNBlocked EQ False$) )
Set_Property(@Window : '.SAVE_BUTTON', 'ENABLED', ButtonEnabled)
return