open-insight/LSL2/STPROC/WORK_ORDER_SERVICES.txt
Ouellette Jonathan (CSC FI SPS MESLEO) 781274c395 Merged PR 15044: Created a routine to determine lot eligible to be peeled off. Modified form l...
Created a routine to determine lot eligible to be peeled off. Modified form logic to allow for lots to be selected out of order.

Related work items: #252918
2025-04-14 23:28:55 +02:00

1561 lines
69 KiB
Plaintext

Function Work_Order_Services(@Service, @Params)
/***********************************************************************************************************************
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 SRP Computer Solutions, Inc.
Name : Work_Order_Services
Description : Handler program for all module related services.
Notes : The generic parameters should contain all the necessary information to process the services. Often
this will be information like the data Record and Key ID.
Parameters :
Service [in] -- Name of the service being requested
Param1-10 [in/out] -- Additional request parameter holders
Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure
Metadata :
History : (Date, Initials, Notes)
06/16/17 dmb Original programmer. - [EPIOI-8]
11/23/20 djs Added CreateOutbound service.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
$insert APP_INSERTS
$insert SERVICE_SETUP
$insert WO_LOG_EQUATES
$insert EPI_PART_EQUATES
$insert WO_MAT_EQUATES
$insert WO_STEP_EQUATES
$insert WO_SCHEDULE_EQUATES
$insert WO_SCHEDULE_NG_EQUATES
$insert RDS_EQUATES
$insert PROD_SPEC_EQUATES
$insert PRS_LAYER_EQU
$insert PROD_VER_EQUATES
$insert WO_MAT_WFR_EQUATES
$insert MSG_EQUATES
$insert POPUP_EQUATES
$insert LOGICAL
$insert RLIST_EQUATES
$insert COMPANY_EQUATES
$Insert NOTIFICATION_EQUATES
$Insert WM_IN_EQUATES
$Insert WM_OUT_EQUATES
Declare subroutine Error_Services, Work_Order_Services, Memory_Services, RList, Database_Services, SRP_JSON
Declare subroutine Btree.Extract, Set_Status, obj_WO_Log, obj_Notes, Print_Wo_Mat_In_Labels, Print_Wo_Mat_Out_Labels
Declare subroutine Print_Wmi_Labels, Print_Wmo_Labels, ErrMsg, Print_Cass_Labels, Logging_Services, Service_Services
Declare subroutine obj_WO_Mat_Log, WO_Mat_Services, Work_Order_Services
Declare function SRP_Array, Work_Order_Services, Memory_Services, Database_Services, SRP_Sort_Array, SRP_JSON
Declare function Company_Services, obj_Prod_Spec, Schedule_Services, Datetime, obj_WO_Log, obj_WO_Step, Memberof
Declare function Environment_Services, Logging_Services, Hold_Services, Signature_Services
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Release Log.csv'
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Notes'
objReleaseLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Void Log.csv'
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'CassetteId' : @FM : 'Notes'
objVoidLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
GoToService else
Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
end
Return Response else ''
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Parameter Options
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Options BOOLEAN = True$, False$
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Services
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------------------------------------
// GetUnscheduledWorkOrders
//
// Returns an array of unscheduled work order details based on the arguments provided.
//----------------------------------------------------------------------------------------------------------------------
Service GetUnscheduledWorkOrders(ReactorType, SusceptorSize, ReactorNo)
WorkOrders = ''
// Select WO_LOG rows that do not have a closed date.
OpenWOLogKeyIDs = Database_Services('SearchIndex', 'WO_LOG', 'CLOSE_DATE', '=', True$)
// Check each WO_LOG Key ID against the WO_SCHEDULE table. If the row does not exist or if the row does not have any
// SCED_DET Key IDs, exists then it is not scheduled an should be included.
WOLogKeyIDs = Str(\00\, 100000)
If OpenWOLogKeyIDs NE '' then
hWOSchedule = Database_Services('GetTableHandle', 'WO_SCHEDULE')
If Error_Services('NoError') then
cPos = 1
For Each WOLogKeyID in OpenWOLogKeyIDs using @FM
Read WOScheduleRow from hWOSchedule, WOLogKeyID then
If WOScheduleRow<WO_SCHEDULE_SCHED_DET_KEY_IDS$> EQ '' then
WOLogKeyIDs[cPos, Len(WOLogKeyID) + 1] = WOLogKeyID : @FM
cPos += Len(WOLogKeyID) + 1
end
end else
WOLogKeyIDs[cPos, Len(WOLogKeyID) + 1] = WOLogKeyID : @FM
cPos += Len(WOLogKeyID) + 1
end
Next WOLogKeyID
end
end
Convert \00\ to '' in WOLogKeyIDs
WOLogKeyIDs[-1, 1] = ''
If Error_Services('NoError') then
For Each WOLogKeyID in WOLogKeyIDs using @FM setting fPos
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WOLogKeyID)
EpiPartNo = WOLogRow<WO_LOG_EPI_PART_NO$>
ProdVerNo = WOLogRow<WO_LOG_PROD_VER_NO$>
ProdVerRow = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo)
PSN = ProdVerRow<PROD_VER_PROC_STEP_PSN$>
ProdSpecRow = Database_Services('ReadDataRow', 'PROD_SPEC', PSN)
BlockedReactors = ProdSpecRow<PROD_SPEC_BLOCKED_REACTS$>
PSNBlock = False$
If EpiPartNo NE '' then
AcceptWorkOrder = True$ ; // Assume this work order is acceptable for now.
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
// The following two lines of code are temporary but necessary to allows work orders
// for ASM to be scheduled on ASM+ and vice-versa.
If ReactType _EQC 'ASM+' then ReactType = 'ASM'
If ReactorType _EQC 'ASM+' then ReactorType = 'ASM'
If (ReactorType NE '') AND (ReactType NE ReactorType) then
// The reactor type for this work order does not match the required reactor type.
AcceptWorkOrder = False$
end
If AcceptWorkOrder AND SusceptorSize NE '' then
EpiPart = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo)
SuscSize = EpiPart<EPI_PART_SUB_WAFER_SIZE$>
If SuscSize NE SusceptorSize then
// The susceptor size for this work order does not match the required susceptor size.
AcceptWorkOrder = False$
end
end
If (BlockedReactors NE '') AND (ReactorNo NE '') then
// This work order uses a part spec that is blocked on the current reactor.
Locate ReactorNo in BlockedReactors using @VM setting vPos then PSNBlock = True$
end
If AcceptWorkOrder then
CustNo = WOLogRow<WO_LOG_CUST_NO$>
CompanyRow = Database_Services('ReadDataRow', 'COMPANY', CustNo)
CustName = CompanyRow<42>
Swap True$ with 'Yes' in PSNBlock
Swap False$ with '' in PSNBlock
WorkOrders := WOLogKeyID : @VM : EpiPartNo : @VM : CustName : @VM : ReactType : @VM : PSNBlock : @FM
end
end
Next WOLogKeyID
WorkOrders[-1, 1] = ''
WorkOrders = SRP_Array('SortRows', WorkOrders, 'AR1' : @FM : 'AR2', 'LIST', @FM, @VM)
end
Response = WorkOrders
end service
//----------------------------------------------------------------------------------------------------------------------
// GetWorkOrderLogDetail
//
// Returns the WO_LOG row for the indicated Key ID.
//----------------------------------------------------------------------------------------------------------------------
Service GetWorkOrderLogDetail(WorkOrderLogID)
WorkOrderDetail = ''
TableName = 'WO_LOG'
If WorkOrderLogID NE '' then
WorkOrderDetail = Database_Services('ReadDataRow', Tablename, WorkOrderLogID)
end else
Error_Services('Add', 'WorkOrderLogID argument was missing from the ' : Service : ' service.')
end
Response = WorkOrderDetail
end service
//----------------------------------------------------------------------------------------------------------------------
// GetWorkOrder
//
// Returns a JSON formatted object of information related to the indicated work order number. The ExtendedData argument
// determines if extended data related to wafers, product versions, and recipe should be included. The default is false.
//----------------------------------------------------------------------------------------------------------------------
Service GetWorkOrder(WorkOrderNo, ExtendedData)
SRP_Stopwatch('Start', Service)
If ExtendedData NE True$ then ExtendedData = False$
ServiceKeyID := '*' : WorkOrderNo
WorkOrder = ''
If Memory_Services('IsValueCurrent', ServiceKeyID, 15, True$) then
WorkOrder = Memory_Services('GetValue', ServiceKeyID)
end else
If WorkOrderNo NE '' then
WorkOrderRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo, True$, 15)
objWorkOrder = ''
If SRP_JSON(objWorkOrder, 'NEW', 'OBJECT') then
SRP_JSON(objWorkOrder, 'SETVALUE', 'WorkOrderNumber', WorkOrderNo, 'STRING')
SRP_JSON(objWorkOrder, 'SETVALUE', 'EpiPartNumber', WorkOrderRow<WO_LOG_EPI_PART_NO$>, 'STRING')
SRP_JSON(objWorkOrder, 'SETVALUE', 'ReactorType', WorkOrderRow<WO_LOG_REACT_TYPE$>, 'STRING')
ProdVerNo = WorkOrderRow<WO_LOG_PROD_VER_NO$>
SRP_JSON(objWorkOrder, 'SETVALUE', 'ProdVerNumber', ProdVerNo, 'STRING')
TotalWafers = WorkOrderRow<WO_LOG_WO_QTY$>
SRP_JSON(objWorkOrder, 'SETVALUE', 'TotalWafers', TotalWafers, 'STRING')
SRP_JSON(objWorkOrder, 'SETVALUE', 'Closed', Oconv(WorkOrderRow<WO_LOG_CLOSE_DATE$> NE '', 'BYes,No'), 'STRING')
SRP_JSON(objWorkOrder, 'SETVALUE', 'ClosedDate', Oconv(WorkOrderRow<WO_LOG_CLOSE_DATE$>, 'D4/'), 'STRING')
SRP_JSON(objWorkOrder, 'SETVALUE', 'HotLot', Oconv(WorkOrderRow<WO_LOG_HOT_FLAG$> NE '', 'BYes,No'), 'STRING')
CustomerNo = WorkOrderRow<WO_LOG_CUST_NO$>
Company = Company_Services('GetCompany', CustomerNo)
objCompany = ''
If SRP_JSON(objCompany, 'PARSE', Company) EQ '' then
SRP_JSON(objWorkOrder, 'SET', 'Company', objCompany)
SRP_JSON(objCompany, 'RELEASE')
end
If ExtendedData EQ True$ then
WafersRemaining = Work_Order_Services('GetRemainingWafers', WorkOrderNo)
SRP_JSON(objWorkOrder, 'SETVALUE', 'WafersRemaining', WafersRemaining, 'STRING')
If TotalWafers GT 0 then
PercentComplete = (TotalWafers - WafersRemaining) / TotalWafers * 100
end else
PercentComplete = 0
end
PercentComplete = Oconv(Iconv(PercentComplete, 'MD2'), 'MD2%S')
SRP_JSON(objWorkOrder, 'SETVALUE', 'PercentComplete', PercentComplete, 'STRING')
ProdVerRow = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo, True$, 15)
PSN = ProdVerRow<PROD_VER_PROC_STEP_PSN$>
SRP_JSON(objWorkOrder, 'SETVALUE', 'PSN', PSN, 'STRING')
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
Recipe = LayerSpec<PRS_LAYER_RECIPE$>
SRP_JSON(objWorkOrder, 'SETVALUE', 'Recipe', Recipe, 'STRING')
end
WorkOrder = SRP_JSON(objWorkOrder, 'STRINGIFY', 'FAST')
Memory_Services('SetValue', ServiceKeyID, WorkOrder)
SRP_JSON(objWorkOrder, 'RELEASE')
end else
Error_Services('Add', 'Error creating objWorkOrder in the ' : Service : ' service.')
end
end else
Error_Services('Add', 'WorkOrder argument was missing from the ' : Service : ' service.')
end
end
Response = WorkOrder
SRP_Stopwatch('Stop', Service)
end service
//----------------------------------------------------------------------------------------------------------------------
// GetRemainingWafers
//
// Returns the number of remaining wafers needed to be scheduled for the indicated work order.
//----------------------------------------------------------------------------------------------------------------------
Service GetRemainingWafers(WorkOrderNo)
RemainingWafers = ''
If WorkOrderNo NE '' then
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
If Error_Services('NoError') then
// Get the total number of unreleased work orders.
TotalWafers = WOLogRow<WO_LOG_WO_QTY$>
TotalReleased = 0
WOMatKeys = WOLogRow<WO_LOG_WO_MAT_KEY$>
For Each WOMatKey in WOMatKeys using @VM
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
TotalReleased += WOMatRec<WO_MAT_WAFER_QTY$>
Next WOMatKey
TotalUnreleased = TotalWafers - TotalReleased
WOStepKeys = WOLogRow<WO_LOG_WO_STEP_KEY$>
TotalUnprocessed = 0
If WOStepKeys NE '' then
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
For Each WOStepKey in WOStepKeys using @VM
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
If Error_Services('NoError') then
// Get the total released but unprocessed.
If ReactorType EQ 'EPP' then
// EpiPro work orders have their own way of calculating.
StatusCodes = Xlate('WM_IN', WOStepRec<WO_STEP_WM_IN_KEYS$>, 'CURR_STATUS', 'X')
RFWCnt = Count(StatusCodes, 'RFW')
TotalUnprocessed = RFWCnt * 25
end else
// All other reactor types use this method.
RDSKeys = WOStepRec<WO_STEP_RDS_KEY$>
If RDSKeys NE '' then
For Each RDSKey in RDSKeys using @VM
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
If RDSRec<RDS_DATE_IN$> EQ '' then
TotalUnprocessed += 25
end
Next RDSKey
end
end
end
Next WOStepKey
end
// Add the two.
RemainingWafers = TotalUnreleased + TotalUnprocessed
end
end else
Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.')
end
Response = RemainingWafers
end service
! This service should be deprecated as it returns inaccurate information for EpiPro.
! Use GetRemainingWafers service insead.
//----------------------------------------------------------------------------------------------------------------------
// GetUnprocessedWafers
//
// Returns the number of released wafers that have not yet been processed.
//----------------------------------------------------------------------------------------------------------------------
Service GetUnprocessedWafers(WorkOrderNo)
RemainingWafers = ''
If WorkOrderNo NE '' then
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
If Error_Services('NoError') then
// Get the total number of unreleased work orders.
TotalWafers = WOLogRow<WO_LOG_WO_QTY$>
TotalReleased = 0
WOMatKeys = WOLogRow<WO_LOG_WO_MAT_KEY$>
For Each WOMatKey in WOMatKeys using @VM
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
TotalReleased += WOMatRec<WO_MAT_WAFER_QTY$>
Next WOMatKey
TotalUnreleased = TotalWafers - TotalReleased
WOStepKeys = WOLogRow<WO_LOG_WO_STEP_KEY$>
TotalUnprocessed = 0
If WOStepKeys NE '' then
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
For Each WOStepKey in WOStepKeys using @VM
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
If Error_Services('NoError') then
// Get the total released but unprocessed.
RDSKeys = WOStepRec<WO_STEP_RDS_KEY$>
If RDSKeys NE '' then
For Each RDSKey in RDSKeys using @VM
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
WOMatKey = Xlate('RDS', RDSKey, 'WO_MAT_KEY', 'X')
CurrStatus = Xlate('WO_MAT', WOMatKey, 'CURR_STATUS', 'X')
If ( (RDSRec<RDS_DATE_OUT$> EQ '') and (CurrStatus NE 'REJ') and (CurrStatus NE 'MT') ) then
TotalUnprocessed += RDSRec<RDS_CASS_WAFER_QTY$>
end
Next RDSKey
end
end
Next WOStepKey
end
// Add the two.
RemainingWafers = TotalUnreleased + TotalUnprocessed
end
end else
Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.')
end
Response = RemainingWafers
end service
//----------------------------------------------------------------------------------------------------------------------
// GetCurrCassNo
//
// Returns the next cassette number to be unloaded.
//----------------------------------------------------------------------------------------------------------------------
Service GetCurrCassNo(WorkOrderNo)
If RowExists('WO_LOG', WorkOrderNo) then
CurrCassNo = ''
DateIn = ''
RDSKeys = Xlate('WO_STEP', WorkOrderNo:'*1', 'RDS_KEY', 'X')
NumKeys = DCount(RDSKeys, @VM)
For KeyIndex = NumKeys to 1 Step -1
RDSKey = RDSKeys<0, KeyIndex>
DateIn = Xlate('RDS', RDSKey, 'DATE_IN', 'X')
Until DateIn NE ''
Next KeyIndex
If DateIn NE '' then CurrCassNo = Xlate('RDS', RDSKey, 'CASS_NO', 'X')
Response = CurrCassNo
end
end service
//----------------------------------------------------------------------------------------------------------------------
// GetLastCassOut
//
// Returns the last cassette number unloaded.
//----------------------------------------------------------------------------------------------------------------------
Service GetLastCassOut(WorkOrderNo)
If RowExists('WO_LOG', WorkOrderNo) then
LastCassOut = ''
DateOut = ''
RDSKeys = Xlate('WO_STEP', WorkOrderNo:'*1', 'RDS_KEY', 'X')
NumKeys = DCount(RDSKeys, @VM)
For KeyIndex = NumKeys to 1 Step -1
RDSKey = RDSKeys<0, KeyIndex>
DateOut = Xlate('RDS', RDSKey, 'DATE_OUT', 'X')
Until DateOut NE ''
Next KeyIndex
If DateOut NE '' then LastCassOut = Xlate('RDS', RDSKey, 'CASS_NO', 'X')
Response = LastCassOut
end
end service
//----------------------------------------------------------------------------------------------------------------------
// GetNextRunNo
//
// Returns the next run number in the work order.
//----------------------------------------------------------------------------------------------------------------------
Service GetNextRunNo(WorkOrderNo, WorkOrderStep)
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
HaveLock = False$
TimeElapsed = 0
RequestTime = Time()
If WorkOrderNo NE '' then
Loop
Lock hSysLists, ServiceKeyID then
HaveLock = True$
If WorkOrderStep = '' then WorkOrderStep = 1
StepRDSNos = XLATE('WO_STEP', WorkOrderNo:'*':WorkOrderStep, 'RDS_KEY', 'X')
CurrRuns = 0
NumRDS = DCount(StepRDSNos, @VM)
For I = 1 to NumRDS
If RowExists('RDS', StepRDSNos<1,I>) then
CurrRuns += 1
end
next I
NextRunNo = CurrRuns + 1
Response = NextRunNo
Unlock hSysLists, ServiceKeyID else Null
end
TimeElapsed = Time() - RequestTime
Until HaveLock EQ True$ or TimeElapsed GT 60
Repeat
end
If TimeElapsed GT 60 then
Error_Services('Add', 'Error occurred within the ':Service:' service module')
end
end service
//----------------------------------------------------------------------------------------------------------------------
// CreateOutbound
//
// Creates an empty outbound cassette for a GaN work order.
//----------------------------------------------------------------------------------------------------------------------
Service CreateOutbound(WONo)
If WONo NE '' then
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
CassNos = WORec<WO_LOG_WO_MAT_KEY$>
LastCassNo = DCount(CassNos, @VM)
NextCassNo = LastCassNo + 1
LastCassID = WONo : '*' : LastCassNo
NewCassID = WONo : '*' : NextCassNo
SchedCassQty = Xlate('WO_MAT', LastCassID, 'SCHED_QTY', 'X')
WOMatWfrRec = Database_Services('ReadDataRow', 'WO_MAT_WFR', NewCassID)
If WOMatWfrRec EQ '' then
for WfrCount = 1 to SchedCassQty
WOMatWfrRec<WO_MAT_WFR_OUT_PREV_WFR_ID$,WfrCount> = NewCassID : '*' : WfrCount
Next WfrCount
Database_Services('WriteDataRow', 'WO_MAT_WFR', NewCassID, WOMatWfrRec)
WOMatRecToCopy = Database_Services('ReadDataRow', 'WO_MAT', LastCassID)
WOMatRecToCopy<WO_MAT_RDS_FINAL_SIG_ORG$> = ''
WOMatRecToCopy<WO_MAT_CASS_FINAL_SIG_DTM$> = ''
Database_Services('WriteDataRow', 'WO_MAT', NewCassID, WOMatRecToCopy)
WORec = Insert(WORec, WO_LOG_WO_MAT_KEY$, -1, 0, NewCassID)
Database_Services('WriteDataRow', 'WO_LOG', WONo, WORec)
end else
ErrorMessage = 'Error in service ':Service:'. WO_MAT_WFR record ':NewCassID:' already exists!'
Error_Services('Add', ErrorMessage)
end
end
end service
Service UpdateUnscheduledQuantities(WOList)
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
Lock hSysLists, ServiceKeyID then
SchedList = Database_Services('ReadDataRow', 'APP_INFO', 'SCHED_WO_LIST')
// Select WO_LOG rows that do not have a closed date.
OpenWOLogKeyIDs = ''
If WOList NE '' then OpenWOLogKeyIDs = WOList
If OpenWOLogKeyIDs EQ '' then
Open 'DICT.WO_LOG' to hWOLogDict then
Set_Status(0)
Flag = ''
Btree.Extract('CLOSE_DATE' : @VM : '' : @FM, 'WO_LOG', hWOLogDict, OpenWOLogKeyIDs, 'S', Flag)
If Flag NE 0 then
Status = Get_Status(errCode)
Error_Services('Add', 'Error in ':Service:' service. Error code ':errCode:'.')
end
end
end
If ( Error_Services('NoError') and (OpenWOLogKeyIDs NE '') ) then
SchedList = SRP_Array('Rotate', SchedList, @FM, @VM)
For Each WONo in OpenWOLogKeyIDs using @VM setting fPos
UnscheduledWfrQty = Schedule_Services('GetUnscheduledWfrQty', WONo)
WONos = SchedList<1>
If UnscheduledWfrQty GT 0 then
Locate WONo in WONos using @VM setting vPos else vPos = -1
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
EpiPartNo = WOLogRow<WO_LOG_EPI_PART_NO$>
CustNo = WOLogRow<WO_LOG_CUST_NO$>
CompanyRow = Database_Services('ReadDataRow', 'COMPANY', CustNo)
CustName = CompanyRow<COMPANY_ABBREV$>
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
SchedList<1, vPos> = WONo
SchedList<2, vPos> = EpiPartNo
SchedList<3, vPos> = CustName
SchedList<4, vPos> = ReactorType
WOSchedRec = Database_Services('ReadDataRow', 'WO_SCHEDULE_NG', WONo)
CurrVal = WOSchedRec<WO_SCHEDULE_NG.UNSCHED_QTY$>
If CurrVal NE UnscheduledWfrQty then
WOSchedRec<WO_SCHEDULE_NG.UNSCHED_QTY$> = UnscheduledWfrQty
Database_Services('WriteDataRow', 'WO_SCHEDULE_NG', WONo, WOSchedRec, True$, False$, True$)
end
end else
Locate WONo in WONos using @VM setting vPos then
SchedList = Delete(SchedList, 1, vPos, 0)
SchedList = Delete(SchedList, 2, vPos, 0)
SchedList = Delete(SchedList, 3, vPos, 0)
SchedList = Delete(SchedList, 4, vPos, 0)
Database_Services('DeleteDataRow', 'WO_SCHEDULE_NG', WONo)
end
end
Next WONo
end
SchedList = SRP_Array('Rotate', SchedList, @FM, @VM)
If WOList EQ '' then
// Clear out WO_SCHEDULE_NG table of work orders that no longer have any wafers left to schedule.
EOF = False$
Query = 'SELECT WO_SCHEDULE_NG WITH UNSCHED_QTY EQ 0'
RList(Query, TARGET_ACTIVELIST$, '', '', '')
Loop
Readnext WOLogKeyID else EOF = True$
Until EOF = True$
Database_Services('DeleteDataRow', 'WO_SCHEDULE_NG', WOLogKeyID)
Repeat
end
SchedList = SRP_Array('SortSimpleList', SchedList, 'DescendingNumbers', @FM)
Database_Services('WriteDataRow', 'APP_INFO', 'SCHED_WO_LIST', SchedList)
Unlock hSysLists, ServiceKeyID else Null
end
end service
Service ReleaseCassettes(WONo)
NumRelCass = 0
ErrorMsg = ''
If WONo NE '' then
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
PSMode = Xlate('PROD_SPEC',PSNo,'SPEC_TYPE','X')
If PSMode = 'Q' OR PSMode = 'U' then
ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X')
If ReactType = 'EPP' OR ReactType = 'EpiPro' then
OutLoadQty = Xlate('WO_LOG', WONo, 'CUST_EPI_PART_WMO_LOAD_CNT', 'X')
If OutLoadQty = '' then
ErrorMsg = 'Outbound Load Cnt is required for ':OCONV(PSMode,'[PROD_SPEC_MODE_CONV]'):' Work Orders.'
end
end else
OutLoadQty = Xlate('WO_LOG', WONo, 'CUST_EPI_PART_SHIP_QTY', 'X')
If OutLoadQty = '' then
ErrorMsg = 'Cass Ship Qty is required for ':OCONV(PSMode,'[PROD_SPEC_MODE_CONV]'):' Work Orders.'
end
end
end
If ErrorMsg EQ '' then
CassList = Xlate('WO_LOG', WONo, 'WO_MAT_CASS_NO', 'X')
RelDTMs = Xlate('WO_LOG', WONo, 'WO_MAT_REL_DTM', 'X')
SAPCassIDs = Xlate('WO_LOG', WONo, 'WO_MAT_CASS_ID_SAP', 'X')
CassStatus = Xlate('WO_LOG', WONo, 'WO_MAT_CURR_STATUS', 'X')
Loop
LastLine = CassList[-1,'B':@VM]
Until LastLine<1,1> NE '' OR LastLine = ''
CassList[COL1(),COL2()] = ''
Repeat
CassCnt = DCount(CassList, @VM)
UnReleasedCassNos = ''
For I = 1 to CassCnt
If ( (RelDTMs<0, I> = '') and (CassStatus<0, I> EQ '') ) then
ErrorMsg = 'Error in obj_WO_Log("ReleaseCassettes"). Cass status is null for ':CassList<0, I>:'!'
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = @USER4
LogData<3> = ErrorMsg
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
end
If ErrorMsg EQ '' then
// Log work order, cassette number, status, and release DTM in the event that a release
// issue occurs again.
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = @User4
LogData<3> = WONo
LogData<4> = CassList<0, I> ; // CassNo
LogData<5> = CassStatus<0, I> ; // Cass Status
LogData<6> = Quote(RelDTMs<0, I>) ; // Release DTM
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
If ( (RelDTMs<0, I> = '') and ( (CassStatus<0, I> = 'RX') or (CassStatus<0, I> = 'MT'))) then
UnReleasedCassNos<1,-1> = CassList<0, I>
end
end
Until ErrorMsg NE ''
Next I
If ErrorMsg EQ '' then
TempWONo = WONo
Set_Status(0)
obj_WO_Log('ReleaseCassettes',TempWONo:@RM:UnReleasedCassNos) ;* This variable gets changed down the line
errCode = ''
If Get_Status(errCode) then
ErrorMsg = 'Error in obj_WO_Log("ReleaseCassettes"). Error code ':errCode:'.'
Database_Services('ReleaseKeyIDLock', 'WO_LOG', WONo)
end else
NumRelCass = CassCnt
OrderNo = Get_Property(@WINDOW:'.ORD_NO','TEXT')
Recipients = XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
SentFrom = @USER4
Subject = 'Work Order Released ':WONo
Message = 'Work Order Released to Production.'
NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
If NewForm then
AttachWindow = 'NDW_WO_LOG'
end else
AttachWindow = 'WO_LOG2'
end
AttachKey = WONo
SendToGroup = ''
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
obj_Notes('Create',Parms)
end
end
end
end
Work_Order_Services('UpdateReleasedQty', WONo)
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
Response = DCount(UnReleasedCassNos, @VM)
end service
Service PrintLabels(WONo)
If WONo NE '' then
WOSteps = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
If INDEX(WOSteps,@VM,1) then
Buttons = ''
FOR I = 1 TO COUNT(WOSteps,@VM) + (WOSteps NE '')
Buttons<I> = 'Step ':I
NEXT I
SWAP @FM WITH ',' IN Buttons
Buttons = 'B':Buttons
TypeOver = ''
TypeOver<MTEXT$> = 'Which Work Order step do you wish to print labels for?'
TypeOver<MTYPE$> = Buttons
TypeOver<MICON$> = '?'
TypeOver<MCAPTION$> = 'MultiStep WorkOrder Selection'
WOStep = Msg(@window, TypeOver)
MultiStepFlag = WOStep
end ELSE
WOStep = 1
MultiStepFlag = 0
end
If WOStep = 1 then
PSNo = XLATE('WO_STEP',WONo:'*1',WO_STEP_PROD_SPEC_ID$,'X')
ReactorType = XLATE('PROD_SPEC',PSNo,PROD_SPEC_REACTOR_TYPE$,'X')
If ReactorType = 'GAN' then
Print_WO_Mat_In_Labels(WONo,'')
Print_WO_Mat_Out_Labels(WONo,'')
end
If ReactorType = 'EPP' OR ReactorType = 'P' then
Print_WMI_Labels(WONo,1)
Print_WMO_Labels(WONo,1)
end
end
NonEpiPro = ( (ReactorType NE 'GAN') and (ReactorType NE 'EPP') and (ReactorType NE 'P') )
If NonEpiPro then
If WOStep > 1 then
Def = ""
Def<MTEXT$> = "Adjusting Step ":WOStep:" Scheduled Quantities..."
Def<MTYPE$> = "U"
MsgUp = Msg(@window, Def)
RDSNos = obj_WO_Step('AdjStepRDSQtys', WOStep:@RM:WOSteps)
If Get_Status(errCode) then
ErrMsg(errCode) ;* Display error from the update
Msg(@WINDOW,MsgUp) ;* Take down the processing message
RETURN
end
Msg(@WINDOW,MsgUp)
end ELSE
RDSNos = XLATE('WO_STEP',WOSteps<1,1>,WO_STEP_RDS_KEY$,'X')
end
If MemberOf(@USER4,'OI_ADMIN') then
WOMatKeys = XLATE('WO_LOG',WONo,WO_LOG_WO_MAT_KEY$,'X')
CONVERT @VM TO @FM IN WOMatKeys
AllRDSNos = XLATE('WO_MAT',WOMatKeys,WO_MAT_RDS_NO$,'X')
RDSNos = ''
LOOP
CassRDSNos = AllRDSNos[1,@FM]
AllRDSNos[1,COL2()] = ''
UNTIL CassRdsNos = ''
RDSNos := CassRdsNos<1,WOStep>:@VM
REPEAT
RDSNos[-1,1] = ''
end
If INDEX(RDSNos,@VM,1) then
TypeOver = ''
TypeOver<PDISPLAY$> = RDSNos
TypeOver<PFIELD$> = 2
TypeOver<PTYPE$> = 'K'
RDSKeys = Popup(@WINDOW,TypeOver,'WO_LOG_RTS')
end ELSE
RDSKeys = RDSNos
end
If RDSKeys = '' then
ErrMsg('No RDS Numbers Selected or Work Order Not Yet Released to Production.')
end ELSE
CONVERT @VM TO @FM IN RDSKeys
Print_Cass_Labels(RDSKeys,MultiStepFlag) ;* Updated labels with Akrion Bar Codes
end
end
end
end service
Service UpdateWOStepStatus(WONo)
If WONo NE '' then
WOStepKey = WONo:'*':1
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
WOStepCurrStatus = obj_WO_Step('CurrStatus', WOStepKey:@RM:WOStepRec)
// Get a fresh copy of the record
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
WOStepCurrStatusStatic = WOStepRec<WO_STEP_CURR_STATUS_STATIC$>
If WOStepCurrStatus NE WOStepCurrStatusStatic then
WOStepRec<WO_STEP_CURR_STATUS_STATIC$> = WOStepCurrStatus
Database_Services('WriteDataRow', 'WO_STEP', WOStepKey, WOStepRec, True$, False$, True$)
end
Database_Services('ReleaseKeyIDLock', 'WO_STEP', WOStepKey)
end
end service
Service PostWOStepUpdateRequest(WONo)
If WONo NE '' then
StepNo = 1
WOStepKey = WONo:'*':StepNo
// Look for a pre-existing request in the queue
If (RowExists('WO_STEP', WOStepKey) EQ False$) then
// This is a new request
RequestKeyID = WOStepKey
RequestRow = ''
RequestRow<WO_STEP_CURR_STATUS_STATIC$> = Datetime()
Database_Services('WriteDataRow', 'WO_STEP_QUEUE', RequestKeyID, RequestRow, False$, False$, False$)
end else
// Duplicate request
Null
end
end else
Error_Services('Add', 'Null parameter passed into service call. All parameters are required.')
end
end service
Service ProcessWOStepUpdateRequests()
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
Lock hSysLists, ServiceKeyID then
Open 'WO_STEP_QUEUE' to hTable then
Select hTable
EOF = False$
Loop
ReadNext RequestKeyID else EOF = True$
Until EOF EQ True$
WONo = Field(RequestKeyID, '*', 1)
Work_Order_Services('UpdateWOStepStatus', WONo)
If Error_Services('NoError') then
// Successfully updated the current status, so delete the request from the queue.
Database_Services('DeleteDataRow', 'WO_STEP_QUEUE', RequestKeyID, True$, True$)
end
Repeat
end else
ErrorMsg = 'Error opening WO_STEP_QUEUE in ':Service:' service.'
end
Unlock hSysLists, ServiceKeyID else Null
end
end service
Service SetHotFlag(WONo, HotFlag=BOOLEAN)
If ( ( RowExists('WO_LOG', WONo) and ( (HotFlag EQ True$) or (HotFlag EQ False$) ) ) ) then
Open 'WO_LOG' to hTable then
WriteV HotFlag on hTable, WONo, WO_LOG_HOT_FLAG$ else
Error_Services('Add', 'Error in ':Service:' service. File error: ':@File_Error)
end
end
end else
Error_Services('Add', 'Error in ':Service:' service. Invalid parameters passed into service.')
end
end service
Service GetHotFlag(WONo)
HotFlag = ''
If RowExists('WO_LOG', WONo) then
Open 'WO_LOG' to hTable then
ReadV HotFlag from hTable, WONo, WO_LOG_HOT_FLAG$ else
Error_Services('Add', 'Error in ':Service:' service. File error: ':@File_Error)
end
end
end else
Error_Services('Add', 'Error in ':Service:' service. Invalid parameters passed into service.')
end
Response = HotFlag
end service
Service UpdateReleasedQty(WONo)
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Released Qty Log.csv'
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
objUpRelLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
ErrorMsg = ''
If WONo NE '' then
If RowExists('WO_LOG', WONo) then
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
If Error_Services('NoError') then
RelQty = obj_WO_Log('RelQty', WONo:@RM:WORec)
WOQty = WORec<WO_LOG_QTY$>
If RelQty GT WOQty then
UnRelQty = 0
end else
UnRelQty = WOQty - RelQty
end
Open 'WO_LOG' to hTable then
WriteV RelQty on hTable, WONo, WO_LOG_REL_QTY_STATIC$ then
WriteV UnRelQty on hTable, WONo, WO_LOG_UNREL_QTY_STATIC$ else
ErrorMsg = 'Error in ':Service:' service. Failed to write unreleased quantity ':UnRelQty
ErrorMsg := ' to the UNREL_QTY_STATIC field of WO_LOG record ':WONo:'.'
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to write released quantity ':RelQty
ErrorMsg := ' to the REL_QTY_STATIC field of WO_LOG record ':WONo:'.'
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
end
end else
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
end
LogData = ''
LogData<1> = LoggingDtm
LogData<2> = WONo
If ErrorMsg EQ '' then
LogResult = 'Successfully updated WO_LOG record ':WONo:' field REL_QTY_STATIC with released quantity ':RelQty
LogResult := ' and field UNREL_QTY_STATIC with unreleased quantity ':UnRelQty:'.'
LogData<3> = LogResult
Logging_Services('AppendLog', objUpRelLog, LogData, @RM, @FM)
end else
LogResult = 'Failed to update WO_LOG record ':WONo:' field REL_QTY_STATIC with released quantity ':RelQty
LogResult := ' or field UNREL_QTY_STATIC with unreleased quantity ':UnRelQty:'. Error message: ':ErrorMsg
LogData<3> = LogResult
Logging_Services('AppendLog', objUpRelLog, LogData, @RM, @FM)
Error_Services('Add', ErrorMsg)
end
end service
Service UpdateReceivedQty(WONo)
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Received Qty Log.csv'
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
objUpRecLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
ErrorMsg = ''
If WONo NE '' then
If RowExists('WO_LOG', WONo) then
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
If Error_Services('NoError') then
RXQty = obj_WO_Log('RxQty', WONo:@RM:WORec)
Open 'WO_LOG' to hTable then
WriteV RXQty on hTable, WONo, WO_LOG_RX_QTY_STATIC$ else
ErrorMsg = 'Error in ':Service:' service. Failed to write received quantity ':RXQty
ErrorMsg := ' to the RX_QTY_STATIC field of WO_LOG record ':WONo:'.'
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
end
end else
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
end
LogData = ''
LogData<1> = LoggingDtm
LogData<2> = WONo
If ErrorMsg EQ '' then
LogData<3> = 'Successfully updated WO_LOG record ':WONo:' field RX_QTY_STATIC with received quantity ':RXQty:'.'
Logging_Services('AppendLog', objUpRecLog, LogData, @RM, @FM)
end else
LogResult = 'Failed to update WO_LOG record ':WONo:' field RX_QTY_STATIC with received quantity ':RXQty
LogResult := '. Error message: ':ErrorMsg
LogData<3> = LogResult
Logging_Services('AppendLog', objUpRecLog, LogData, @RM, @FM)
Error_Services('Add', ErrorMsg)
end
end service
Service UpdateShippedQty(WONo)
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Shipped Qty Log.csv'
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
objUpShipLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
ErrorMsg = ''
If WONo NE '' then
If RowExists('WO_LOG', WONo) then
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
If Error_Services('NoError') then
ShipQty = obj_WO_Log('ShipQty', WONo:@RM:WORec)
Open 'WO_LOG' to hTable then
WriteV ShipQty on hTable, WONo, WO_LOG_SHIP_QTY_STATIC$ else
ErrorMsg = 'Error in ':Service:' service. Failed to write ':ShipQty
ErrorMsg := ' to the SHIP_QTY_STATIC field of WO_LOG record ':WONo:'.'
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
end
end else
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
end
end else
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
end
LogData = ''
LogData<1> = LoggingDtm
LogData<2> = WONo
If ErrorMsg EQ '' then
LogResult = 'Successfully updated WO_LOG record ':WONo:' field SHIP_QTY_STATIC '
LogResult := 'with shipped quantity ':ShipQty:'.'
LogData<3> = LogResult
Logging_Services('AppendLog', objUpShipLog, LogData, @RM, @FM)
end else
LogResult = 'Failed to update WO_LOG record ':WONo:' field SHIP_QTY_STATIC with shipped quantity '
LogResult := ShipQty:'. Error message: ':ErrorMsg
LogData<3> = LogResult
Logging_Services('AppendLog', objUpShipLog, LogData, @RM, @FM)
Error_Services('Add', ErrorMsg)
end
end service
Service ConvertRecordToJSON(WONo, Record, ItemURL)
jsonRecord = ''
IF WONo NE '' then
If Record EQ '' then Record = Database_Services('ReadDataRow', 'WO_LOG', WONo)
If Error_Services('NoError') then
@DICT = Database_Services('GetTableHandle', 'DICT.WO_LOG')
@ID = WONo
@RECORD = Record
objJSON = ''
If SRP_JSON(objJSON, 'New', 'Object') then
objWOLog = ''
If SRP_JSON(objWOLog, 'New', 'Object') then
SRP_JSON(objWOLog, 'SetValue', 'KeyId', @ID)
SRP_JSON(objWOLog, 'SetValue', 'ProdOrdNo', {PROD_ORD_NO})
SRP_JSON(objWOLog, 'SetValue', 'PSN', {PROD_SPEC_ID})
SRP_JSON(objWOLog, 'SetValue', 'EpiPartNo', {EPI_PART_NO})
SRP_JSON(objWOLog, 'SetValue', 'HOT_FLAG', {HOT_FLAG})
//Create a list of cassettes
CassIDs = {WO_MAT_KEY}
objChildCassettes = ''
If SRP_JSON(objChildCassettes, 'New', 'Array') then
If CassIDs NE '' then
for each Cass in CassIDs using @VM setting vPos
SAPBatchNo = XLATE('WO_MAT', Cass, WO_MAT_SAP_BATCH_NO$, 'X')
SAPTXDtm = XLATE('WO_MAT', Cass, WO_MAT_SAP_TX_DTM$, 'X')
RDSNo = XLATE('WO_MAT', Cass, WO_MAT_RDS_NO$, 'X')
ShipNo = XLATE('WO_MAT', Cass, WO_MAT_SHIP_NO$, 'X')
//Add in each indv. cassette object
objChildCassette = ''
If SRP_JSON(objChildCassette, 'New', 'Object') then
SRP_JSON(objChildCassette, 'SetValue', 'KeyId', Cass)
SRP_JSON(objChildCassette, 'SetValue', 'SAPBatchNo', SAPBatchNo)
SRP_JSON(objChildCassette, 'SetValue', 'SAPTXDtm', OCONV(SAPTXDtm, 'DT'))
SRP_JSON(objChildCassette, 'SetValue', 'RDSNo', RDSNo)
SRP_JSON(objChildCassette, 'SetValue', 'ShipNo', ShipNo)
SRP_JSON(objChildCassettes, 'Add', objChildCassette)
SRP_JSON(objChildCassette, 'Release')
end
Next Cass
end else
SRP_JSON(objWOLog, 'SetValue', 'ChildCassettes', '')
end
SRP_JSON(objWOLog, 'Set', 'ChildCassettes', objChildCassettes)
SRP_JSON(objChildCassettes, 'Release')
end
SRP_JSON(objJSON, 'Set', 'WO_Log', objWOLog)
SRP_JSON(objWOLog, 'Release')
end
If itemURL NE '' then
// The itemURL was passed in so add HAL+JSON properties.
// Create the _links property and then all link objects needed for this resource.
objLinks = ''
If SRP_JSON(objLinks, 'New', 'Object') then
// Create a self link.
objLink = ''
If SRP_JSON(objLink, 'New', 'Object') then
SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String')
SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String')
SRP_JSON(objLinks, 'Set', 'self', objLink)
SRP_JSON(objLink, 'Release')
end
SRP_JSON(objJSON, 'Set', '_links', objLinks)
SRP_JSON(objLinks, 'Release')
end
// Create the _class property for this resource.
SRP_JSON(objJSON, 'SetValue', '_class', 'resource')
end
jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled')
SRP_JSON(objJSON, 'Release')
end else
Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.')
end
end
end else
Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.')
end
Response = jsonRecord
end service
Service RemoveWoMatCassetteFromWO(WoMatKey, Username)
ErrorMessage = ''
If RowExists('WO_MAT', WoMatKey) then
WoNo = Field(WoMatKey, '*', 1)
WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WoNo, True$, 0, False$)
If Error_Services('NoError') then
WoMatKeys = WOLogRecord<WO_LOG_WO_MAT_KEY$>
Locate WoMatKey in WoMatKeys using @VM setting CassPos then
WoLogRecord<WO_LOG_WO_MAT_KEY$> = Delete(WOLogRecord<WO_LOG_WO_MAT_KEY$>, 1, CassPos, 0)
Database_Services('WriteDataRow', 'WO_LOG', WoNo, WoLogRecord)
If Error_Services('NoError') then
Work_Order_Services('UpdateReceivedQty', WONo)
Work_Order_Services('UpdateReleasedQty', WONo)
Work_Order_Services('UpdateUnscheduledQuantities')
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = "Unable to locate cass no " : WoMatKey : ' in the WO_LOG ' : WoNo : ' Record.'
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = 'Invalid WoMat Key ' : WoMatKey : ' passed to RemoveWoMatCassetteFromWO routine.'
end
If ErrorMessage NE '' then
Error_Services('Add', ErrorMessage)
end
end service
Service SignVoidNonEpp(WOMatKey, Username)
ErrorMessage = ''
WONo = Field(WOMatKey, '*', 1)
CassNo = Field(WoMatKey, '*', 2)
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
If ReactType EQ 'ASM' OR ReactType EQ 'ASM+' OR ReactType EQ 'HTR' then
RDSNo = Database_Services('ReadDataColumn', 'WO_MAT', WoMatKey, WO_MAT_RDS_NO$, True$, 0, False$)
If Error_Services('NoError') then
WoMatRec = Database_Services('ReadDataRow', 'WO_MAT', WoMatKey, True$, 0, False$)
IsVoided = WoMatRec<WO_MAT_VOID$>
If Not(IsVoided) then
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
If Not(IsOnHold) then
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES', 'RemoveWoMatCassetteFromWO':@vm:WOMatKey:@vm:Username)
If Error_Services('NoError') then
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@vm:WOMatKey:@VM:Username)
if Error_Services('NoError') then
Service_Services('PostProcedure', 'RDS_SERVICES', 'DetachRDSFromWO':@vm:RDSNo)
If Error_Services('NoError') then
LotEventParams = ''
LotEventParams<1,1> = 'CreateLotEvent'
LotEventParams<1,4> = DateTime()
LotEventParams<1,5> = 'VOID'
LotEventParams<1,6> = 'Lot voided by ' : Username
LotEventParams<1,11> = Username
If RDSNo NE '' then
LotEventParams<1,2> = RDSNo
LotEventParams<1,3> = 'RDS'
Service_Services('PostProcedure', 'LOT_SERVICES', LotEventParams)
end else
LotEventParams<1,2> = WoMatKey
LotEventParams<1,3> = 'WO_MAT'
Service_Services('PostProcedure', 'LOT_SERVICES', LotEventParams)
end
If Error_Services('NoError') then
//Add inventory transaction
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Unable to void lot as it is already voided.'
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
end
If ErrorMessage NE '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WOMatKey
LogData<4> = ErrorMessage
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WOMatKey
LogData<4> = 'Void queued successfully.'
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service SignVoidWMI(WMInKey, Username)
ErrorMessage = ''
WONo = Field(WMInKey, '*', 1)
CassNo = Field(WMInKey, '*', 3)
WoStepKey = Xlate('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
WoMatKey = WONo : '*' : CassNo
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
If ReactType EQ 'EPP' then
WMInRec = Database_Services('ReadDataRow', 'WM_IN', WMInKey, True$, 0, False$)
IsVoided = WMInRec<WM_IN_VOID$>
If Not(IsVoided) then
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
If Not(IsOnHold) then
Service_Services('PostProcedure', 'WM_IN_SERVICES', 'SetVoidFlag':@vm:WMInKey:@VM:Username)
If Error_Services('NoError') then
LotEventParams = ''
LotEventParams<1,1> = 'CreateLotEvent'
LotEventParams<1,4> = DateTime()
LotEventParams<1,5> = 'VOID'
LotEventParams<1,6> = 'Lot voided by ' : Username
LotEventParams<1,11> = Username
LotEventParams<1,2> = WMInKey
LotEventParams<1,3> = 'WM_IN'
Service_Services('PostProcedure', 'LOT_SERVICES', LotEventParams)
If Error_Services('NoError') then
//Check if WMO is also voided. If it is, remove it from the WO_MAT_KEY field in WO_LOG, and void the WO_MAT record
WMOKey = WMInKey; //the paired WMO key is the same as the WMIKey
IsWMOVoided = Database_Services('ReadDataColumn', 'WM_OUT', WMOKey, WM_OUT_VOID$)
If IsWMOVoided then
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@VM:WoMatKey:@VM:Username)
If Error_Services('NoError') then
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES','RemoveWoMatCassetteFromWO':@VM:WoMatKey:@VM:Username)
If Error_Services('HasError') then
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Unable to void lot as it is already voided.'
end
end else
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
end
If ErrorMessage NE '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WMInKey
LogData<4> = ErrorMessage
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WMInKey
LogData<4> = 'Void queued successfully.'
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service SignVoidWMO(WMOutKey, Username)
ErrorMessage = ''
WONo = Field(WMOutKey, '*', 1)
CassNo = Field(WMOutKey, '*', 3)
WoStepKey = Xlate('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
WoMatKey = WONo : '*' : CassNo
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
If ReactType EQ 'EPP' then
WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey, True$, 0, False$)
IsVoided = WMOutRec<WM_OUT_VOID$>
If Not(IsVoided) then
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
If Not(IsOnHold) then
Service_Services('PostProcedure', 'WM_OUT_SERVICES', 'SetVoidFlag':@vm:WMOutKey:@VM:Username)
If Error_Services('NoError') then
LotEventParams = ''
LotEventParams<1,1> = 'CreateLotEvent'
LotEventParams<1,4> = DateTime()
LotEventParams<1,5> = 'VOID'
LotEventParams<1,6> = 'Lot voided by ' : Username
LotEventParams<1,11> = Username
LotEventParams<1,2> = WMOutKey
LotEventParams<1,3> = 'WM_OUT'
Service_Services('PostProcedure', 'LOT_SERVICES', LotEventParams)
If Error_Services('NoError') then
//Check if WMI is also voided. If it is, remove it from the WO_MAT_KEY field in WO_LOG, and void the WO_MAT record
WMIKey = WMOutKey; //the paired WMO key is the same as the WMIKey
IsWMIVoided = Database_Services('ReadDataColumn', 'WM_IN', WMIKey, WM_IN_VOID$)
If IsWMIVoided then
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@VM:WoMatKey:@VM:Username)
If Error_Services('NoError') then
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES','RemoveWoMatCassetteFromWO':@VM:WoMatKey:@VM:Username)
If Error_Services('HasError') then
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Unable to void lot as it is already voided.'
end
end else
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
end
If ErrorMessage NE '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WMOutKey
LogData<4> = ErrorMessage
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = Username
LogData<3> = WMOutKey
LogData<4> = 'Void queued successfully.'
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType)
ErrorMessage = ''
EligibleCassIds = ''
If RowExists('WO_LOG', WONo) then
Begin Case
Case EntityType EQ 'RDS'
CassIds = Database_Services('ReadDataColumn', 'WO_LOG', WONo, WO_LOG_WO_MAT_KEY$, True$, 0, False$)
for each CassId in CassIds using @VM
RDSNo = XLATE('WO_MAT', CassId, WO_MAT_RDS_NO$, 'X')
Signatures = Signature_Services('GetSigProfile', CassId, 0, RDSNo)
Eligible = True$
for each Signature in Signatures<1> using @VM setting SigPos
SignatureDtm = Signatures<3, SigPos>
If SignatureDtm NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next Signature
If Eligible then EligibleCassIds<1, -1> = CassId
Next CassId
Case EntityType EQ 'WM_OUT'
//WM_OUTS can be voided when
//1. There are no RDS Nos associated
//2. There have never been any wafers in them
WOStepKey = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
CassIds = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_OUT_KEYS$, True$, 0, False$)
for each CassId in CassIds using @VM
WMORec = Database_Services('ReadDataRow', 'WM_OUT', CassId, True$, 0, False);//XLATE('WM_OUT',WMOutKeys<1,I>,'','X')
WMO_RdsNos = WMORec<WM_OUT_RDS$>
WMO_NCRNos = WMORec<WM_OUT_SLOT_NCR$>
WMO_UMWCassIDs = WMORec<WM_OUT_UMW_CASS_ID$>
Eligible = True$
//Loop through RDS list to see if there is an RDS attached. If there are any RDS No's attached it is not eligible.
for each RDSNo in WMO_RDSNos using @VM
If RDSNo NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next RDSNo
//Loop through NCR list to see if there are any NCR's associated. If there are any NCR No's attached it is not eligible.
If Eligible then
For Each NCRNo in WMO_NCRNos using @VM
If NCRNo NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next NCR
end
//Loop through MU Wafer Usage list to see if there are any MU wafer's taken from this lot. If there are any Makeup Wafers attached it is not eligible.
If Eligible then
For Each UMWCass in WMO_UMWCassIDs using @VM
If UMWCass NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next UMWCass
end
If Eligible then EligibleCassIds<1, -1> = CassId
Next CassId
Case EntityType EQ 'WM_IN'
WOStepKey = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
CassIds = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_IN_KEYS$, True$, 0, False$)
for each CassId in CassIds using @VM
Eligible = True$
WMIRec = Database_Services('ReadDataRow', 'WM_IN', CassId, True$, 0, False);//XLATE('WM_OUT',WMOutKeys<1,I>,'','X')
WMI_RdsNos = WMIRec<WM_IN_RDS_NO$>
WMI_NCRNos = WMIRec<WM_IN_NCR_NO$>
Eligible = True$
//Loop through RDS list to see if there is an RDS attached. If there are any RDS No's attached it is not eligible.
for each RDSNo in WMI_RDSNos using @VM
If RDSNo NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next RDSNo
//Loop through NCR list to see if there are any NCR's associated. If there are any NCR No's attached it is not eligible.
If Eligible then
For Each NCRNo in WMI_NCRNos using @VM
If NCRNo NE '' then
Eligible = False$
end
Until Eligible EQ False$
Next NCR
end
If Eligible then EligibleCassIds<1, -1> = CassId
Next CassId
Case EntityType EQ ''
ErrorMessage = 'Entity type parameter was invalid.'
Case Otherwise$
ErrorMessage = 'Entity type parameter was null.'
End Case
end else
ErrorMessage = 'WO# ' : WONo : ' not found in WO_LOG table.'
end
If ErrorMessage NE '' then
Error_Services('Add', 'Error in ' : Service : '. ' : ErrorMessage)
end
Response = EligibleCassIds
end service
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ClearCursors:
For counter = 0 to 8
ClearSelect counter
Next counter
return