COMPILE FUNCTION obj_React_Run(Method,Parms)
#pragma precomp SRP_PreCompiler

/*
	Methods for REACT_RUN table
    
	02/20/2004 JCH - Initial Coding
     
    Properties:
     
    Methods:
    
    Create(DataStruct)		;* Create new record
	
	
*/

DECLARE SUBROUTINE Set_Status, Msg, obj_Tables, Send_Dyn, obj_WO_Step, obj_RDS_Layer, obj_RDS_Test, obj_WM_In
DECLARE SUBROUTINE obj_Clean_Insp, Btree.Extract, Send_Info, obj_WO_Wfr, ErrMsg, obj_Post_Log, Logging_Services

DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, NextKey,  obj_Prod_Spec, Send_Dyn, obj_Clean_Insp
DECLARE FUNCTION obj_RDS_Test, obj_Test_Point_Map, obj_Popup, obj_WO_Wfr, Logging_Services, Environment_Services
Declare function Return_To_Fab_Services

$INSERT APP_INSERTS
$INSERT REACT_RUN_EQUATES
$INSERT REACTOR_EQUATES
$INSERT MSG_EQUATES
$INSERT WO_VERIFY_EQU
$INSERT WO_LOG_EQUATES
$INSERT WO_WFR_EQUATES
$INSERT RDS_LAYER_EQUATES
$INSERT RDS_TEST_EQUATES
$INSERT RUN_STAGE_EQUATES
$INSERT RUN_STAGE_WFR_EQUATES
$INSERT TOOL_EQUATES
$INSERT TOOL_CLASS_EQUATES
$INSERT POPUP_EQUATES
$INSERT LOGICAL
$INSERT QUOTE_SPEC_EQU
$INSERT PROD_SPEC_EQUATES
$INSERT WO_STEP_EQU
$INSERT WO_MAT_EQUATES


EQU COL$POCKET		TO 1	;* Susceptor Load columns
EQU COL$USAGE		TO 2
EQU COL$ZONE		TO 3
EQU COL$SAT_ID		TO 4
EQU COL$WAFER_TYPE	TO 5
EQU COL$IN_SLOT_ID 	TO 6
EQU COL$WFR_ID		TO 7
EQU COL$OUT_SLOT_ID	TO 8


EQU COL$WO_NO				TO 1	;* Data structure equates for EpiMetData
EQU COL$RDS_NO				TO 2
EQU COL$REACTOR				TO 3
EQU COL$Z1_MET_NO			TO 4
EQU COL$Z1_THICKNESS		TO 5
EQU COL$Z1_4PP_SHEET_RHO	TO 6
EQU COL$Z1_HGCV_RESL1		TO 7
EQU COL$Z1_HGCV_RESL2		TO 8
EQU COL$Z2_MET_NO			TO 9
EQU COL$Z2_THICKNESS		TO 10
EQU COL$Z2_4PP_SHEET_RHO	TO 11
EQU COL$Z2_HGCV_RESL1		TO 12
EQU COL$Z2_HGCV_RESL2		TO 13

EQU GWS$STAGE		TO 1		;* Used to extract data from 'GAN_WFR_STAGE' popup
EQU GWS$DESC		TO 2
EQU GWS$CHAR		TO 3
EQU GWS$TOOL_CLASS	TO 4

$INSERT PRS_LAYER_EQU	;* Used to return obj_Prod_Spec values

LogPath     = Environment_Services('GetApplicationRootPath') : '\LogFiles\REACT_RUN'
LogDate     = Oconv(Date(), 'D4/')
LogTime     = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LOAD_WFR_CNT.csv'
Headers     = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'LOAD_WFR_CNT'
objLog      = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM

ErrTitle = 'Error in Stored Procedure "obj_React_Run"'
ErrorMsg = ''
ErrCode  = ''

IF NOT(ASSIGNED(Method))	THEN ErrorMsg = 'Unassigned parameter "Method" passed to subroutine'
IF NOT(ASSIGNED(Parms))		THEN Parms = ''

IF ErrorMsg NE '' THEN
	Set_Status(-1,ErrTitle:@SVM:ErrorMsg)
	RETURN ''
END


Result = ''

BEGIN CASE

	CASE Method = 'RunStatus'		; GOSUB RunStatus
	CASE Method = 'Create'			; GOSUB Create
	CASE Method = 'GetMetKeys'		; GOSUB GetMetKeys
	CASE Method = 'Delete'			; GOSUB Delete
	CASE Method = 'ChangeFlag'		; GOSUB ChangeFlag
	CASE Method = 'EpiMetData'		; GOSUB EpiMetData
	CASE Method = 'SetSchedQty'		; GOSUB SetSchedQty
	CASE Method = 'WafersUnloaded'	; GOSUB WafersUnloaded
	CASE Method = 'Zone'			; GOSUB Zone
	CASE Method = 'SigProfile'		; GOSUB SigProfile
	CASE Method = 'SigBy'			; GOSUB SigBy
	CASE Method = 'SigDTM'			; GOSUB SigDTM
	CASE Method = 'WfrsUnloadedDt'	; GOSUB WfrsUnloadedDt
	CASE Method = 'AddCI'			; GOSUB AddCI
	CASE Method = 'GetCINo'			; GOSUB GetCINo
	CASE Method = 'LoadMat'			; GOSUB LoadMat
	CASE Method = 'ReturnMat'		; GOSUB ReturnMat
	CASE Method = 'UnloadMat'		; GOSUB UnloadMat
	CASE Method = 'ReloadMat'		; GOSUB ReloadMat
	CASE Method = 'UnloadGan'		; GOSUB UnloadGan
	CASE Method = 'ReloadGan'		; GOSUB ReloadGan
	CASE Method = 'SplitWfr'		; GOSUB SplitWfr
	CASE Method = 'UnSplitWfr'		; GOSUB UnSplitWfr
	CASE Method = 'GetWfrSigKeys'	; GOSUB GetWfrSigKeys
	CASE Method = 'NextWfrStage'	; GOSUB NextWfrStage
	CASE Method = 'ShipGANWfrs'		; GOSUB ShipGANWfrs
	CASE Method = 'UnShipGANWfrs'	; GOSUB UnShipGANWfrs
	CASE Method = 'CharWfrDest'		; GOSUB CharWfrDest
	CASE Method = 'CharWfrStatus'	; GOSUB CharWfrStatus
	CASE Method = 'ClearCarrNCR'	; GOSUB ClearCarrNCR
	CASE Method = 'GaNDispStatus'	; GOSUB GaNDispStatus
	Case Method = 'WfrStageUnloadQ'	; Gosub WfrStageUnloadQ
	CASE Method = 'StageUnloadQ'	; GOSUB StageUnloadQ
	
	CASE 1
		
END CASE

IF ErrorMsg NE '' THEN
	Set_Status(-1,ErrTitle:@SVM:ErrorMsg)
END

RETURN Result

* * * * * * *
Create:
* * * * * * *

WONo			= Parms[1,@RM]
WOStep			= Parms[COL2()+1,@RM]
CassNo			= Parms[COL2()+1,@RM]
PSNo			= Parms[COL2()+1,@RM]

IF WONo = ''		THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')'
IF WOStep = ''		THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')'
IF CassNo = ''		THEN ErrorMsg = 'Null Parameter "CassNo" passed to routine. (':Method:')'
IF PSNo = ''		THEN ErrorMsg = 'Null Parameter "PSNo" passed to routine. (':Method:')'


IF ErrorMsg NE '' THEN RETURN

RunNo = NextKey('REACT_RUN')


RunRec = ''

RunRec<REACT_RUN_WO_NO$>		= WONo
RunRec<REACT_RUN_WO_STEP$>		= WOStep
RunRec<REACT_RUN_CASS_NO$>		= CassNo
RunRec<REACT_RUN_ENTER_BY$>		= @USER4
RunRec<REACT_RUN_ENTER_DTM$>	= ICONV(OCONV(Date(),'D4/'):' ':OCONV(Time(),'MT'),'DT')


PSRec = XLATE('PROD_SPEC',PSNo,'','X')

ReactorType = PSRec<PROD_SPEC_REACTOR_TYPE$>

RunRec<REACT_RUN_SPECIAL_INST$>	= PSRec<Prod_Spec_Spec_Substrate$,QSSubInstructions$>

LayerSpecs = obj_Prod_Spec('GetLayerProp',PSNo:@RM:@RM:1)	;* Returns specs for all layers in internal format


* LayerSpecs is @RM between layers, @FM between fields, LayerSet ID is in the first Field and needs to peeled off
* before the equates match up correctly

* Prod_Spec table has layer specs all in one field
* RDS has First layer stuff in individual fields and then has 2 and 3 shoved into Field 33 (Layer Info)

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<PRS_LAYER_RECIPE$>
RecipeRec = XLATE('RECIPE',RecipeNo,'','X')			;* This used in 2nd and 3rd layer stuff (in error it appears)


FOR I = 1 TO COUNT(LayerSpecs,@RM) + (LayerSpecs NE '')
	LayerSpec	= FIELD(LayerSpecs,@RM,I)		;* Take the Ith Layer
	LayerSet	= FIELD(LayerSpec,@FM,1)
	LayerSpec	= FIELD(LayerSpec,@FM,2,99)		;* LayerSpec without the LayerSet 
	
	obj_RDS_Layer('Create',RunNo:@RM:LayerSet:@RM:PSNo)

	RunRec<REACT_RUN_RDS_LAYER_KEYS$,I> = RunNo:'*':LayerSet

	obj_RDS_Test('Create',RunNo:@RM:LayerSet:@RM:PSNo)
	
NEXT I


************************
psCnt = COUNT(PRSStageKeys,@VM) + (PRSStageKeys NE '')

FOR N = 1 TO psCnt
	Stage = FIELD(PRSStageKey<1,N>,'*',2)
	
	IF Stage = 'PRE' AND ReactorType NE 'EPP' THEN
		
		CINo = obj_Clean_Insp('Create',RunNo:@RM:Stage:@RM:PSNo:@RM:PSRec)		;* This is a new CLEAN_INSP record
		RunRec = INSERT(RunRec,REACT_RUN_CI_NO$,Pos,0,CINo)
		RunRec = INSERT(RunRec,REACT_RUN_CI_STAGE$,Pos,0,Stage)
		
	END	;* End of check for EpiPRO reactor
	
	

IF INDEX(PRSStageKeys,'WI',1) THEN 
	WfrCINo = obj_Clean_Insp('Create',RunNo:@RM:'WFR':@RM:PSNo:@RM:PSRec)		;* This is a new CLEAN_INSP record
	RunRec<REACT_RUN_WFR_CI_NO$> = WfrCINo
END

IF ReactorType NE 'EPP' THEN
	
	IF INDEX(PRSStageKeys,'POST',1) THEN
		PostCINo = obj_Clean_Insp('Create',RunNo:@RM:'POST':@RM:PSNo:@RM:PSRec)		;* This is a new CLEAN_INSP record
		RunRec<REACT_RUN_POST_CI_NO$> = PostCINo
	END
END	;* End of check for EpiPRO reactor
NEXT N

obj_Tables('WriteRec','REACT_RUN':@RM:RunNo:@RM:@RM:RunRec)

Result = RunNo

RETURN


* * * * * * *
RunStatus:
* * * * * * *

IF NOT(ASSIGNED(RDSNo)) THEN
	RDSNo		= Parms[1,@RM]
	ReactRunRec = Parms[COL2()+1,@RM]
END

IF RDSNo = '' THEN RETURN

IF ReactRunRec = '' THEN
	ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END

LSKeys = ReactRunRec<REACT_RUN_RDS_LAYER_KEYS$>

OpenRTF = Return_To_Fab_Services('GetOpenReturnToFabRecordIdByCassId', RDSNo)
		
IF OpenRTF NE '' THEN
    Result = 'RTF'				;* Open RTF on WO_MAT *
    RETURN
END

MetOutOfSpec = SUM(XLATE('RDS_LAYER',LSKeys,'TEST_OUT_OF_SPEC','X'))		;* Updated for Metrology update 4/16/2006 JCH

IF MetOutOfSpec > 0 THEN
	Result = 'SPEC'
	RETURN
END

ReactType = XLATE('REACTOR',ReactRunRec<REACT_RUN_REACTOR$>,REACTOR_REACT_TYPE$,'X')

IF ReactType = 'EPP' THEN

	PocketChars	= ReactRunRec<REACT_RUN_POCKET_CHAR$>
	InCassNos	= ReactRunRec<REACT_RUN_IN_CASS_NO$>
	OutCassNos	= ReactRunRec<REACT_RUN_OUT_CASS_NO$>
	WaferChars	= ReactRunRec<REACT_RUN_WAFER_CHAR$>
	UnloadSig	= ReactRunRec<REACT_RUN_UNLOAD_SIG$>

	TestFlag = 0
	ProdTestFlag = 0
	ProductionWafersLoaded = 0
	ProductionWafersUnloaded = 0

	FOR I = 1 TO COUNT(InCassNos,@VM) + (InCassNos NE '')
		PocketChar = PocketChars<1,I>
		WaferChar = WaferChars<1,I>
		IF PocketChar = 'TEST'  THEN
			IF WaferChar = 'PROD' THEN ProdTestFlag = 1
			IF WaferChar = 'TEST' THEN TestFlag = 1
		END ELSE
			IF PocketChar = '' THEN
				IF InCassNos<1,I> NE '' THEN ProductionWafersLoaded += 1
				IF OutCassNos<1,I> NE '' THEN ProductionWafersUnloaded += 1
			END
		END
	NEXT I
	
	MetEntered = XLATE('RDS_LAYER',LSKeys,'TEST_MET_ENTERED','X')
	IF INDEX(MetEntered,'0',1) THEN
		MetComplete = 0
	END ELSE
		MetComplete = 1
	END
	
	BEGIN CASE
		CASE ProductionWafersLoaded = 0 AND (TestFlag = 1 OR ProdTestFlag = 1) AND UnloadSig = ''		; Result = 'TLOAD'
		CASE ProductionWafersLoaded = 0 AND (TestFlag = 1 OR ProdTestFlag = 1) AND UnloadSig NE ''		; Result = 'TULOAD'
		CASE ProductionWafersLoaded = 0 AND TestFlag = 0 												; Result = 'RLOAD'
		CASE ProductionWafersLoaded > 0 AND ProductionWafersUnloaded = 0								; Result = 'LOAD'
		CASE ProductionWafersLoaded = ProductionWafersUnloaded AND MetComplete = 1						; Result = 'ULOAD'
		CASE ProductionWafersLoaded = ProductionWafersUnloaded AND MetComplete	= 0				  		; Result = 'ULMET'
		CASE 1																							; *Result = 'UNK'

	END CASE

END ELSE

		WONo	= ReactRunRec<REACT_RUN_WO_NO$>
		CassNo	= ReactRunRec<REACT_RUN_CASS_NO$>
		WOStep	= ReactRunRec<REACT_RUN_WO_STEP$>

		WOMatRec = XLATE('WO_MAT',WONo:'*':CassNo,'','X')

		RDSKeys = ''
		RSCnt = 0
		RunSigProfs		= ''
		RunSignatures	= ''
		RunSigDTMs		= ''

		AllSigs = WOMatRec<WO_MAT_SIG_PROFILE$>

		asCnt = COUNT(AllSigs,@VM) + (AllSigs NE '')

		FOR I = 1 TO asCnt
			IF AllSigs<1,I>[1,1] = WOStep THEN
				RSCnt += 1
				RunSigProfs<1,RSCnt>	= AllSigs<1,I>
				RunSignatures<1,RSCnt>	= WOMatRec<WO_MAT_SIGNATURE$,I>
				RunSigDTMs<1,RSCnt>		= WOMatRec<WO_MAT_SIG_DTM$,I>
			END
		NEXT I

		ProcessStart = 0
		ProcessComp	= 0

		LOOP
			RunSignature	= RunSignatures<1,1>
			RunSigProf		= RunSigProfs<1,1>
		UNTIL RunSignature = ''
			ProcessStart = 1
			RunSignatures	= DELETE(RunSignatures,1,1,0)
			RunSigProfs		= DELETE(RunSigProfs,1,1,0)
		REPEAT
		
		IF RunSignature = '' AND RunSigProf = '' AND ProcessStart = 1 THEN
			Result = 'COMP'
			RETURN
		END ELSE
			Result = RunSigProf[2,20]
			RETURN
		END
	
END

// ROTR inspection failure check -> Set status to PSTC (PostCleans)
If Result EQ 'ULOAD' then
    RotrAction = XLATE('REACT_RUN',RDSNo,'ROTR_ACTION','X')
    
    IF RotrAction = 'F' Then				;* Drive the CURR_STATUS to PostEpi Clean if the ROTR fails 
        Result = 'PSTC'
        RETURN
    END
end
			

RETURN



* * * * * * *
GetMetKeys:
* * * * * * *

* Returns data structure of 'LSID*ZONE' - @VM in first column associated RDS_TEST numbers in 2nd Column.

RdsNo  = Parms[1,@RM]

IF RdsNo = '' THEN RETURN

SortedLSKeys = XLATE('REACT_RUN',RdsNo,'RDS_LS_SORTED','X')
CONVERT @VM TO @FM IN SortedLSKeys

IF SortedLSKeys NE '' THEN
	LSMetKeys = XLATE('RDS_LAYER',SortedLSKeys,RDS_LAYER_RDS_TEST_KEYS$,'X')
	RDSMetZones = XLATE('RDS_TEST',LSMetKeys,RDS_TEST_ZONE$,'X')
	ResultLine = 0
	FOR I = 1 TO COUNT(SortedLSKeys,@FM) + (SortedLSKeys NE '')
		SortedLSKey = SortedLSKeys<I>
		LSMetKey = LSMetKeys<I>
		
		FOR N = 1 TO COUNT(LSMetKey,@VM) + (LSMetKey NE '')
			ResultLine += 1
			Result<1,ResultLine> = FIELD(SortedLSKey,'*',2):'*':RDSMetZones<I,N>
			Result<2,ResultLine> = LSMetKeys<I,N>
		NEXT N
	NEXT I
END

RETURN



* * * * * * *
Delete:
* * * * * * *

RdsNos		= Parms[1,@RM]
TableVar	= Parms[COL2()+1,@RM]


IF RdsNos = '' THEN RETURN
IF TableVar = '' THEN RETURN		;* Lock set should be called just prior to this to lock all the RDS's for deletion

RdsDTMs = XLATE('REACT_RUN',RdsNos,REACT_RUN_VER_SIG_DTM$,'X')

CONVERT @FM TO @VM IN RdsDTMs

TestString = RdsDTMs

CONVERT @VM TO '' IN TestString

IF TestString NE '' THEN
	FOR I = 1 TO COUNT(RdsDTMs,@VM) + (RdsDTMs NE '')
		IF RdsDTMs<1,I> NE '' THEN
			Result<1,-1> = RdsNos<1,I>			;* Return list of RdsNos that have started processing and cannot be deleted
		END
	NEXT I
	ErrorMsg = 'Production started on one or more RDS No(s).'
	RETURN
END

FOR I = 1 TO COUNT(RdsNos,@VM) + (RdsNos NE '')
	RdsNo = RdsNos<1,I>
	ReactRunRec = XLATE('REACT_RUN',RdsNo,'','X')
	
	LSKeys = ReactRunRec<REACT_RUN_RDS_LAYER_KEYS$>
	MetKeys = XLATE('RDS_LAYER',LSKeys,RDS_LAYER_RDS_TEST_KEYS$,'X')
	
	RTParms = 'REACT_RUN':@RM:RdsNo:@RM:TableVar:@RM
	obj_Tables('UnlockRec',RTParms)
	
	IF ReactRunRec<REACT_RUN_PRE_CI_NO$> NE '' THEN
		obj_Clean_Insp('Delete',ReactRunRec<REACT_RUN_PRE_CI_NO$>)
	END
	
	IF ReactRunRec<REACT_RUN_WFR_CI_NO$> NE '' THEN
		obj_Clean_Insp('Delete',ReactRunRec<REACT_RUN_WFR_CI_NO$>)
	END
	
	IF ReactRunRec<REACT_RUN_POST_CI_NO$> NE '' THEN
		obj_Clean_Insp('Delete',ReactRunRec<REACT_RUN_POST_CI_NO$>)
	END
	
	obj_RDS_Test('Delete',MetKeys)
	
	obj_RDS_Layer('Delete',LSKeys)
	
	obj_Tables('DeleteRec','REACT_RUN':RTParms)				;* Deletes and removes the lock
NEXT I

RETURN


* * * * * * *
ChangeFlag:
* * * * * * *

RDSNo	= Parms[1,@RM]
FieldNo		= Parms[COL2()+1,@RM]
Value		= Parms[COL2()+1,@RM]

IF RDSNo 	= '' THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'
IF FieldNo  = '' THEN ErrorMsg = 'Null parameter "Property" passed to routine. (':Method:')'

IF Value = '' OR Value = '0' OR Value = '1' ELSE
	ErrorMsg = 'Invalid Flag ':QUOTE(Value):' passed to routine. (':Method:')'
END

IF ErrorMsg NE '' THEN RETURN

otParms = 'REACT_RUN':@RM:RDSNo
ReactRunRec = obj_Tables('ReadRec',otParms)

IF Get_Status(errCode) THEN RETURN	;* Probably locked -> return 

ReactRunRec<FieldNo> = Value
 
otParms = FieldStore(OtParms,@RM,4,0,ReactRunRec)	;* Put record in 4th field of OtParms

obj_Tables('WriteRec',otParms) 


RETURN


* * * * * * *
SetSchedQty:
* * * * * * *

* This looks like it isn't finished JCH 1/6/2009 JCH **************************

RDSNo		= Parms[1,@RM]

IF RDSNo 	= '' THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'

IF ErrorMsg NE '' THEN RETURN

otParms = 'REACT_RUN':@RM:RDSNo
ReactRunRec = obj_Tables('ReadRec',otParms)

IF Get_Status(errCode) THEN RETURN	;* Probably locked -> return 

IF ReactRunRec<REACT_RUN_WO_STEP$> = 1 OR ReactRunRec<REACT_RUN_VER_WFR_CNT$> NE '' THEN
	obj_Tables('UnlockRec',otParms)	
	RETURN
END

WONo = ReactRunRec<REACT_RUN_WO_NO$>
CassNo = ReactRunRec<REACT_RUN_CASS_NO$> 

WOMatRec = ''
 
otParms = FieldStore(OtParms,@RM,4,0,ReactRunRec)	;* Put record in 4th field of OtParms

obj_Tables('WriteRec',otParms) 


RETURN


* * * * * * *
EpiMetData:
* * * * * * *

RDSNo		= Parms[1,@RM]
ReactRunRec = Parms[COL2()+1,@RM]


IF RDSNo = '' THEN RETURN

IF ReactRunRec = '' THEN
	ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END

IF ReactRunRec = '' THEN RETURN

Reactor = ReactRunRec<REACT_RUN_REACTOR$>
ReactType = XLATE('REACTOR',Reactor,1,'X')

IF ReactType NE 'EPP' THEN RETURN



DataArray = ''

DataArray<1,COL$WO_NO>				= 'WO No'
DataArray<1,COL$RDS_NO>				= 'RDS No'
DataArray<1,COL$REACTOR>			= 'Reactor'
DataArray<1,COL$Z1_MET_NO>			= 'Z1 Met No'
DataArray<1,COL$Z1_THICKNESS>		= 'Z1 Thickness'
DataArray<1,COL$Z1_4PP_SHEET_RHO>	= 'Z1 4PP Sheet Rho'
DataArray<1,COL$Z1_HGCV_RESL1>		= 'Z1 HgCV Res L1'
DataArray<1,COL$Z1_HGCV_RESL2>		= 'Z1 HgCV Res L2'
DataArray<1,COL$Z2_MET_NO>			= 'Z2 Met No'
DataArray<1,COL$Z2_THICKNESS>		= 'Z2 Thickness'
DataArray<1,COL$Z2_4PP_SHEET_RHO>	= 'Z2 4PP Sheet Rho'
DataArray<1,COL$Z2_HGCV_RESL1>		= 'Z2 HgCV Res L1'
DataArray<1,COL$Z2_HGCV_RESL2>		= 'Z2 HgCV Res L2'


NextLine = 2


WONo		= ReactRunRec<REACT_RUN_WO_NO$>
WOStep		= ReactRunRec<REACT_RUN_WO_STEP$>

LSKeys		= ReactRunRec<REACT_RUN_RDS_LAYER_KEYS$>
Z1MetKeys	= {MET_KEYS_Z1}
Z2MetKeys	= {MET_KEYS_Z2}
Z1MetNo		= Z1MetKeys[-1,'B':@VM]
Z2MetNo		= Z2MetKeys[-1,'B':@VM]
               
Z1MetRec = XLATE('RDS_TEST',Z1MetNo,'','X')
Z2MetRec = XLATE('RDS_TEST',Z2MetNo,'','X')

Z1TestPointMap = Z1MetRec<RDS_TEST_TEST_POINT_MAP$>
Z2TestPointMap = Z2MetRec<RDS_TEST_TEST_POINT_MAP$>

Z1MetReadings = ''
Z2MetReadings = ''
Z1Results = ''
Z2Results = ''

Z1MetKeyCnt = COUNT(Z1MetKeys,@VM) + (Z1MetKeys NE '')

FOR I = 1 TO Z1MetKeyCnt
	
	Z1MetKey = Z1MetKeys<1,I>
	Z1LMetReadings = obj_RDS_Test('GetReadSet',Z1MetKey)
	
	IF I = 1 THEN
		Z1MetReadings<1> = Z1LMetReadings<1>		;* Line Numbers
		Z1MetReadings<3> = Z1LMetReadings<3>		;* SheetRho
		Z1MetReadings<4> = Z1LMetReadings<4>		;* Hgcv
	END
	
	IF Z1MetKeyCnt = 1 THEN
		Z1MetReadings<2> = Z1LMetReadings<2>		;* Thickness readings
	END ELSE
		IF I = 2 THEN Z1MetReadings<5> = Z1LMetReadings<4>		;* Hgcv
		IF I = 3 THEN Z1MetReadings<2> = Z1LMetReadings<2>		;* Thickness readings
	END
	
NEXT I

IF Z1MetReadings<1> NE '' THEN
	CONVERT @FM TO @RM IN Z1MetReadings
	oTPM_Parms = Z1TestPointMap:@RM:Z1MetReadings
	Z1Results = obj_Test_Point_Map('PointToResult',oTPM_Parms)
END


Z2MetKeyCnt = COUNT(Z2MetKeys,@VM) + (Z2MetKeys NE '')

FOR I = 1 TO Z2MetKeyCnt
	
	Z2MetKey = Z2MetKeys<1,I>
	
	Z2LMetReadings = obj_RDS_Test('GetReadSet',Z2MetKey)
	
	IF I = 1 THEN
		Z2MetReadings<1> = Z2LMetReadings<1>		;* Line Numbers
		Z2MetReadings<3> = Z2LMetReadings<3>		;* SheetRho
		Z2MetReadings<4> = Z2LMetReadings<4>		;* Hgcv
	END
	
	IF Z2MetKeyCnt = 1 THEN
		 Z2MetReadings<2> = Z2LMetReadings<2>		;* Thickness readings
	END ELSE
		IF I = 2 THEN Z2MetReadings<5> = Z2LMetReadings<4>		;* Hgcv
		IF I = 3 THEN Z2MetReadings<2> = Z2LMetReadings<2>		;* Thickness readings
	END
		
NEXT I

IF Z2MetReadings<1> NE '' THEN
	CONVERT @FM TO @RM IN Z2MetReadings
	oTPM_Parms = Z2TestPointMap:@RM:Z2MetReadings
	Z2Results = obj_Test_Point_Map('PointToResult',oTPM_Parms)
END

Z1Cnt = COUNT(Z1Results<1>,@VM) + (Z1Results<1> NE '')
Z2Cnt = COUNT(Z2Results<1>,@VM) + (Z2Results<1> NE '')
ResultCnt = Z1Cnt
IF Z2Cnt > ResultCnt THEN ResultCnt = Z2Cnt

IF ResultCnt = 0 THEN
	DataArray<NextLine,COL$WO_NO>				= WONo
	DataArray<NextLine,COL$REACTOR>				= Reactor
	DataArray<NextLine,COL$RDS_NO>				= @ID
	DataArray<NextLine,COL$Z1_MET_NO>			= Z1MetNo
	DataArray<NextLine,COL$Z2_MET_NO>			= Z2MetNo
	NextLine += 1
END

FOR N = 1 TO ResultCnt
	IF N = 1 THEN
		DataArray<NextLine,COL$WO_NO>			= WONo
		DataArray<NextLine,COL$REACTOR>			= Reactor
		DataArray<NextLine,COL$RDS_NO>			= @ID
		DataArray<NextLine,COL$Z1_MET_NO>		= Z1MetNo
		DataArray<NextLine,COL$Z2_MET_NO>		= Z2MetNo
	END
	
	DataArray<NextLine,COL$Z1_THICKNESS>		= Z1Results<2,N>
	DataArray<NextLine,COL$Z1_4PP_SHEET_RHO>	= Z1Results<3,N>
	DataArray<NextLine,COL$Z1_HGCV_RESL1>		= Z1Results<4,N>
	DataArray<NextLine,COL$Z1_HGCV_RESL2>		= Z1Results<5,N>
	
	DataArray<NextLine,COL$Z2_THICKNESS>		= Z2Results<2,N>
	DataArray<NextLine,COL$Z2_4PP_SHEET_RHO>	= Z2Results<3,N>
	DataArray<NextLine,COL$Z2_HGCV_RESL1>		= Z2Results<4,N>
	DataArray<NextLine,COL$Z2_HGCV_RESL2>		= Z2Results<5,N>
	
	NextLine += 1
NEXT N

Result = DataArray

RETURN


* * * * * * *
WafersUnloaded:
* * * * * * *

IF NOT(ASSIGNED(RDSNo))			THEN RDSNo			= Parms[1,@RM]
IF NOT(ASSIGNED(ReactRunRec))	THEN ReactRunRec	= Parms[COL2()+1,@RM]


IF RDSNo		= '' THEN RETURN
IF ReactRunRec	= '' THEN ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')


ReactNo = ReactRunRec<REACT_RUN_REACTOR$>

ReactType = XLATE('REACTOR',ReactNo,REACTOR_REACT_TYPE$,'X')

IF ReactType = 'EPP' THEN
	* EpiPro run
	OutCassNos = ReactRunRec<REACT_RUN_OUT_CASS_NO$>
	OutCassCnt = COUNT(OutCassNos,@VM) + (OutCassNos NE '')
	UnloadQty = ''
	FOR I = 1 TO OutCassCnt
	     IF OutCassNos<1,I> NE '' THEN UnloadQty += 1
	NEXT I
	
	Result = UnloadQty		;* Qty unloaded into WMO cassette (no product test wafers)
	
	
END ELSE
	* ASM run
	WafersIn	= ReactRunRec<REACT_RUN_LOAD_WFR_CNT$>		;* Operator verified wafer qty loaded into reactor
    If Not(Num(WafersIn)) then
        // Log the WafersIn value
        LogData    = ''
        LogData<1> = LoggingDTM
        LogData<2> = RDSNo
        LogData<3> = WafersIn
        Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
        WafersIn   = WafersIn<1, 1, 1>
    end
	
	TestKeys	= XLATE('RDS_LAYER',ReactRunRec<REACT_RUN_RDS_LAYER_KEYS$>,3,'X')
	TWProd		= obj_RDS_Test('ProdTestCount',TestKeys)
	IF WafersIn > 0 AND TWProd <= WafersIn THEN
		Result = WafersIn - TWProd
	END ELSE
		Result = ''
	END
	
END


RETURN

* * * * * * *
Zone:
* * * * * * *

RunIDs = Parms[1,@RM]

IF RunIDs = '' THEN RETURN

ItemCnt = Count(RunIDs,@VM) + (RunIDs NE '')

PrevRDS	= ''
Ans		= ''

FOR I = 1 TO ItemCnt

	RunID = RunIDs<1,I>
	RDSNo = RunID[1,'.']
	Pocket = RunID[COL2()+1,'.']
	
	IF RDSNo NE PrevRDS THEN
		PreRDS = RDSNo
		ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
	END
	
	ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
	
	LOCATE Pocket IN ReactRunRec<REACT_RUN_POCKET$> USING @VM SETTING Pos THEN
		Result<1,I> = ReactRunRec<REACT_RUN_ZONE$,Pos>
	END
	
NEXT I

RETURN


* * * * * * *
SigProfile:
* * * * * * *

RDSNo	= Parms[1,@RM]
RRunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RRunRec = '' THEN
	RRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END
		
IF RRunRec = '' THEN RETURN

ReactType = XLATE('REACT_RUN',RDSNo,'PS_REACT_TYPE_CODE','X')

WONo 	= RRunRec<REACT_RUN_WO_NO$>
WOStep	= RRunRec<REACT_RUN_WO_STEP$>

IF ReactType = 'GAN' THEN

	SigProfile = RRunRec<REACT_RUN_RUN_STAGE_KEY$>
	
	SWAP RDSNo:'*' WITH '' IN SigProfile
	

END ELSE

	CassNo	= RRunRec<REACT_RUN_CASS_NO$>

	AllSigProfile = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIG_PROFILE$,'X')

	SigProfile = ''
	ASigCnt = COUNT(AllSigProfile,@VM) + (AllSigProfile NE '')
	FOR I = 1 TO ASigCnt
	       IF AllSigProfile<1,I>[1,1] = WOStep THEN
	             SigProfile<1,-1> = AllSigProfile<1,I>
	       END
	NEXT I

END	;* End of check for ReactType


Result = SigProfile

RETURN


* * * * * * *
SigBy:
* * * * * * *

RDSNo	= Parms[1,@RM]
RRunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RRunRec = '' THEN
	RRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END
		
IF RRunRec = '' THEN RETURN

ReactType = XLATE('REACT_RUN',RDSNo,'PS_REACT_TYPE_CODE','X')

WONo 	= RRunRec<REACT_RUN_WO_NO$>
WOStep	= RRunRec<REACT_RUN_WO_STEP$>

IF ReactType = 'GAN' THEN

	StageKeys =  RRunRec<REACT_RUN_RUN_STAGE_KEY$>
	
	SigBys = XLATE('RUN_STAGE',StageKeys,RUN_STAGE_COMP_BY$,'X')

END ELSE

	CassNo	= RRunRec<REACT_RUN_CASS_NO$>

	AllSigProfile	= XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIG_PROFILE$,'X')
	AllSigBys		= XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIGNATURE$,'X')

	SigBys = ''
	ASigCnt = COUNT(AllSigProfile,@VM) + (AllSigProfile NE '')
	FOR I = 1 TO ASigCnt
	       IF AllSigProfile<1,I>[1,1] = WOStep THEN
	             SigBys<1,-1> = AllSigBys<1,I>
	       END
	NEXT I

END	;* End of check for ReactType

Result = SigBys

RETURN


* * * * * * *
SigDTM:
* * * * * * *


RDSNo	= Parms[1,@RM]
RRunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RRunRec = '' THEN
	RRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END
		
IF RRunRec = '' THEN RETURN

ReactType = XLATE('REACT_RUN',RDSNo,'PS_REACT_TYPE_CODE','X')

WONo 	= RRunRec<REACT_RUN_WO_NO$>
WOStep	= RRunRec<REACT_RUN_WO_STEP$>

IF ReactType = 'GAN' THEN

	StageKeys = RRunRec<REACT_RUN_RUN_STAGE_KEY$>		
	SigDTMs = XLATE('RUN_STAGE',StageKeys,RUN_STAGE_COMP_DTM$,'X')

END ELSE

	CassNo	= RRunRec<REACT_RUN_CASS_NO$>

	AllSigProfile	= XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIG_PROFILE$,'X')
	AllSigDtms		= XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIG_DTM$,'X')

	SigDtms = ''
	ASigCnt = COUNT(AllSigProfile,@VM) + (AllSigProfile NE '')
	FOR I = 1 TO ASigCnt
	       IF AllSigProfile<1,I>[1,1] = WOStep THEN
	             SigDTMs<1,-1> = AllSigDTMs<1,I>
	       END
	NEXT I

END	;* End of check for ReactType

Result = SigDTMs

RETURN

* * * * * * *
WfrsUnloadedDt:
* * * * * * * 

ReactNo  	= Parms[1,@RM]
UnloadDt	= Parms[COL2()+1,@RM]

IF ReactNo	= '' THEN RETURN
IF UnloadDt = '' THEN UnloadDt = OCONV(Date(),'D4/')		;* Default to today's date

thisUnloadDt = ICONV(UnloadDt,'D')

IF thisUnloadDt = '' THEN
	RETURN
END


OPEN 'DICT.REACT_RUN' TO DictVar ELSE
	ErrorMsg = 'Unable to open "DICT.REACT_RUN" for lookup'
	RETURN
END

SearchString  = 'REACT_NO_UNLOAD_DT':@VM:ReactNo:'.':thisUnloadDt:@FM


Option = ''
Flag = ''

Btree.Extract(SearchString,'REACT_RUN',DictVar,ReactRunKeys,Option,Flag)

RunCnt = COUNT(ReactRunKeys,@VM) + (ReactRunKeys NE '')

TotWfrsUnloaded = 0

FOR RKPos = 1 TO RunCnt
	RDSNo = ReactRunKeys<1,RKPos>
	ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
	
	GOSUB WafersUnloaded
	
	TotWfrsUnloaded += Result
	
	Result = ''

NEXT RKPos

Result = TotWfrsUnloaded

RETURN


* * * * * * *
AddCI:
* * * * * * *

RDSNo	= Parms[1,@RM]
Stage	= Parms[COL2()+1,@RM]
CINo	= Parms[COL2()+1,@RM]

IF RDSNo = ''	THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'
IF Stage = ''	THEN ErrorMsg = 'Null parameter "Stage" passed to routine. (':Method:')'
IF CINo = ''	THEN ErrorMsg = 'Null parameter "CINo" passed to routine. (':Method:')'

IF ErrorMsg NE '' THEN RETURN


otParms = 'REACT_RUN':@RM:RDSNo

RunRec = obj_Tables('ReadRec',otParms)

IF Get_Status(errCode) THEN RETURN


RunRec = INSERT(RunRec,REACT_RUN_CI_NO$,1,0,CINo)
RunRec = INSERT(RunRec,REACT_RUN_CI_STAGE$,1,0,Stage)


otParms = FieldStore(OtParms,@RM,4,0,RunRec)	;* Put record in 4th field of OtParms

obj_Tables('WriteRec',otParms)

RETURN

* * * * * * *
GetCINo:
* * * * * * *

RDSNo		= Parms[1,@RM]
ReactRunRec = Parms[COL2()+1,@RM]
Stage		= Parms[COL2()+1,@RM]


IF RDSNo = ''	THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'
IF Stage = ''	THEN ErrorMsg = 'Null parameter "Stage" passed to routine. (':Method:')'

IF ErrorMsg NE '' THEN RETURN

IF ReactRunRec = '' THEN
	ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
END

IF ReactRunRec = '' THEN RETURN

LOCATE Stage IN ReactRunRec<REACT_RUN_CI_STAGE$> USING @VM SETTING Pos THEN
	Result = ReactRunRec<REACT_RUN_CI_NO$,Pos>
END

RETURN


* * * * * * *
LoadMat:
* * * * * * *

RdsNo		= Parms[1,@RM]
ToolID		= Parms[COL2()+1,@RM]
ReactorList	= Parms[COL2()+1,@RM]	;* Contains susceptor load configuration 
SlotWfrKeys	= Parms[COL2()+1,@RM]	;* Contains SlotInID:@VM:WfrID:@VM:Scribe on each line

IF RdsNo		= ''	THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'
IF ReactorList	= ''	THEN ErrorMsg = 'Null parameter "ReactorList" passeed to routine.'
IF SlotWfrKeys	= ''	THEN ErrorMsg = 'Null parameter "SlotWfrKeys" passeed to routine.'
IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading REACT_RUN ':RdsNo:'...')
		
lCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')
FOR I = lCnt TO 1 STEP -1
	TestVal  = ReactorList<I,1>
UNTIL TestVal NE ''
	ReactorList = DELETE(ReactorList,I,0,0)		;* Strip empty lines from the user interface edit table
NEXT I

Set_Status(0)
RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)


IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read REACT_RUN ':QUOTE(RdsNo):' for UnloadEpi update.'
	RETURN
END


CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

rCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')

WfrIDs 		= ''
RunLocs		= ''
CurrSlotIDS	= ''
Scribes		= ''



swPointer = 1

FOR I = 1 TO rCnt

	IF ReactorList<I,COL$IN_SLOT_ID> = '' AND ReactorList<I,COL$WAFER_TYPE> = '' AND ReactorList<I,COL$USAGE> NE 'DUMMY' THEN
	
		* Empty Pocket and needs a wafer
		
		CurrSlot 	= SlotWfrKeys<swPointer,1>
		WfrID		= SlotWfrKeys<swPointer,2>
		Scribe		= SlotWfrKeys<swPointer,3>
		
		NewSlot		= ''
		RunLoc		= RDSNo:'.':ReactorList<I,COL$POCKET>:'.':ReactorList<I,COL$ZONE>
		
		WfrIDs<1,-1>		= WfrID
		RunLocs<1,-1>		= RunLoc
		CurrSlotIDs<1,-1>	= CurrSlot
		Scribes<1,-1> 		= Scribe
		
		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'LOAD':@RM				;* Event
		owwParms	:= '':@RM					;* New Slot ID
		owwParms	:= RunLoc:@RM				;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= CurrSlot:@RM				;* Current Slot ID
		owwParms	:= ToolID:@RM				;* New ToolID
		owwParms	:= '':@RM					;* Curr Tool ID
		owwParms 	:= '':@RM					;* NewInvLoc
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'I':@RM					;* Wfr Side
		owwParms	:= '':@RM					;* NewCarrLocs
		owwParms	:= '':@RM					;* CurrCarrLocs
		owwParms	:= Scribe					;* Scribe			;* Added 9/7/2016 JCH
			
		obj_WO_Wfr('AddEvent',owwParms)
		
		RR_Rec<REACT_RUN_IN_SLOT_ID$,I>		= CurrSlot
		RR_Rec<REACT_RUN_IN_WFR_ID$,I>		= WfrID
		RR_Rec<REACT_RUN_IN_WFR_CHAR$,I>	= 'PROD'
		
		swPointer += 1
	
	END ELSE
	
		RR_Rec<REACT_RUN_IN_SLOT_ID$,I>		= ''
		RR_Rec<REACT_RUN_IN_WFR_ID$,I>		= ''
		RR_Rec<REACT_RUN_IN_WFR_CHAR$,I>	= ReactorList<I,COL$WAFER_TYPE>
		
	END
		
	RR_Rec<REACT_RUN_RUN_PKT$,I>		= ReactorList<I,COL$POCKET>
	RR_Rec<REACT_RUN_RUN_ZONE$,I>		= ReactorList<I,COL$ZONE>
	RR_Rec<REACT_RUN_PKT_CHAR$,I>		= ReactorList<I,COL$USAGE>
	RR_Rec<REACT_RUN_PKT_SAT_ID$,I>		= ReactorList<I,COL$SAT_ID>
	RR_Rec<REACT_RUN_OUT_SLOT_ID$,I>	= ''
	
		
NEXT I

ReactNo = ToolID[2,20]

RR_Rec<REACT_RUN_REACTOR$> = ReactNo

RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)


RETURN

* * * * * * *
ReturnMat:
* * * * * * *

RdsNo	= Parms[1,@RM]
ToolID	= Parms[COL2()+1,@RM]

IF RdsNo = '' THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading RDS Record ':RdsNo:'...')

Set_Status(0)

RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read RDS ':QUOTE(RdsNo):' for ReturnMat update.'
	RETURN
END

WONo	= RR_Rec<REACT_RUN_WO_NO$>
WOStep	= RR_Rec<REACT_RUN_WO_STEP$>

RLCnt = COUNT(RR_Rec<REACT_RUN_RUN_PKT$>,@VM) + (RR_Rec<REACT_RUN_RUN_PKT$> NE '')

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

FOR I = 1 TO RLCnt

	WfrID	= RR_Rec<REACT_RUN_IN_WFR_ID$,I>
	NewSlot = RR_Rec<REACT_RUN_IN_SLOT_ID$,I>

	IF WfrID NE '' THEN

		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'REPLACE':@RM			;* Event
		owwParms	:= NewSlot:@RM				;* New Slot ID
		owwParms	:= '':@RM					;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= '':@RM					;* Current Slot ID
		owwParms	:= '':@RM					;* NewToolID (Load Tool)
		owwParms	:= ToolID:@RM				;* CurrToolD (Unload Tool)
		owwParms 	:= '':@RM					;* NewInvLoc
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'I'						;* Wfr Side
			
		obj_WO_Wfr('AddEvent',owwParms)
		
	END
	
	RR_Rec<REACT_RUN_RUN_PKT$,I>		= ''
	RR_Rec<REACT_RUN_RUN_ZONE$,I>		= ''
	RR_Rec<REACT_RUN_PKT_CHAR$,I>		= ''
	RR_Rec<REACT_RUN_IN_WFR_CHAR$,I>	= ''
	RR_Rec<REACT_RUN_IN_SLOT_ID$,I>		= ''
	RR_Rec<REACT_RUN_IN_WFR_ID$,I>		= ''
	RR_Rec<REACT_RUN_OUT_SLOT_ID$,I>	= ''

NEXT I


RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)
	
	
RETURN


* * * * * * * 
UnloadMat:
* * * * * * * 

RdsNo		= Parms[1,@RM]
ToolID		= Parms[COL2()+1,@RM]
ReactorList	= Parms[COL2()+1,@RM]	;* Contains susceptor load configuration 
UnloadSlots	= Parms[COL2()+1,@RM]	;* Contains SlotInID:@VM:WfrID:@VM:Scribe on each line

IF RdsNo		= ''	THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'
IF ReactorList	= ''	THEN ErrorMsg = 'Null parameter "ReactorList" passeed to routine.'
IF UnloadSlots	= ''	THEN ErrorMsg = 'Null parameter "UnloadSlots" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading REACT_RUN ':RdsNo:'...')

lCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')
FOR I = lCnt TO 1 STEP -1
	TestVal  = ReactorList<I,1>
UNTIL TestVal NE ''
	ReactorList = DELETE(ReactorList,I,0,0)		;* Strip empty lines from the user interface edit table
NEXT I

Set_Status(0)
RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)		;* REACT_RUN is locked here

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read REACT_RUN ':QUOTE(RdsNo):' for UnloadEpi update.'
	RETURN
END

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

rCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')

ulPointer = 1

FOR I = 1 TO rCnt

	IF ReactorList<I,REACT_RUN_OUT_SLOT_ID$> = '' AND ReactorList<I,COL$WAFER_TYPE> = 'PROD' AND ReactorList<I,COL$USAGE> = '' THEN
	
		* Empty Pocket and needs a wafer
		
		NewSlot 	= UnloadSlots<ulPointer,1>
		WfrID		= ReactorList<I,COL$WFR_ID>
		
		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'UNLOAD':@RM				;* Event
		owwParms	:= NewSlot:@RM				;* New Slot ID
		owwParms	:= '':@RM					;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= '':@RM					;* Current Slot ID
		owwParms	:= '':@RM					;* New ToolID
		owwParms	:= ToolID:@RM				;* Curr Tool ID
		owwParms 	:= '':@RM					;* NewInvLoc
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'O'						;* Wfr Side
			
		obj_WO_Wfr('AddEvent',owwParms)
		
		RR_Rec<REACT_RUN_OUT_SLOT_ID$,I>	= NewSlot
		
		ulPointer += 1
	
	END
		
NEXT I

RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)


RETURN


* * * * * * *
ShipGANWfrs:
* * * * * * *

RDSNo		= Parms[1,@RM]
ShipSlots	= Parms[COL2()+1,@RM]
ShipWfrs	= Parms[COL2()+1,@RM]

IF RDSNo		= ''	THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'
IF ShipSlots	= ''	THEN ErrorMsg = 'Null parameter "ShipSlots" passeed to routine.'
IF ShipWfrs		= ''	THEN ErrorMsg = 'Null parameter "ShipWfrs" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN


Set_Status(0)
RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)		;* REACT_RUN is locked here

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read REACT_RUN ':QUOTE(RdsNo):' for UnloadEpi update.'
	RETURN
END

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

wCnt = COUNT(ShipWfrs,@VM) + (ShipWfrs NE '')


FOR I = 1 TO wCnt
	WfrID = ShipWfrs<1,I>
	NewSlot = ShipSlots<1,I>
	
	LOCATE WfrID IN RR_Rec<REACT_RUN_IN_WFR_ID$> USING @VM SETTING Pos THEN
		RR_Rec<REACT_RUN_OUT_SLOT_ID$,Pos> = ShipSlots<1,I>
	END
	
	LOCATE WfrID IN RR_Rec<REACT_RUN_CARR_WFR_ID$> USING @VM SETTING cPos THEN
		CurrCarrSlot = RR_Rec<REACT_RUN_CARR_SLOT_ID$,cPos>

	END ELSE 
		CurrCarrSlot = ''
	END

	CurrInvLoc = obj_WO_Wfr('CurrLoc',WfrID)<1,4>

	owwParms	 = WfrID:@RM				;* WfrID
	owwParms	:= CurrDTM:@RM				;* EventDtm
	owwParms	:= @USER4:@RM				;* EventBy
	owwParms	:= 'DISP':@RM				;* Event
	owwParms	:= NewSlot:@RM				;* New Slot ID
	owwParms	:= '':@RM					;* RPZ (RDSNo*Pocket*Zone)
	owwParms	:= '':@RM					;* NCRNo
	owwParms	:= '':@RM					;* TWUse ID 
	owwParms	:= '':@RM					;* Current Slot ID
	owwParms	:= '':@RM					;* New ToolID
	owwParms	:= '':@RM					;* Curr Tool ID
	owwParms 	:= '':@RM					;* NewInvLoc
	owwParms	:= CurrInvLoc:@RM			;* CurrInvLoc				;* GaN Disposition Queue
	owwParms 	:= 'O':@RM					;* Wfr Side
	owwParms	:= '':@RM					;* New Carrier Loc
	owwParms	:= CurrCarrSlot				;* Curr Carrier Loc
		
	obj_WO_Wfr('AddEvent',owwParms)


NEXT I

RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)

RETURN



* * * * * * *
UnShipGANWfrs:
* * * * * * *

RDSNo		= Parms[1,@RM]
ShipSlots	= Parms[COL2()+1,@RM]
ShipWfrs	= Parms[COL2()+1,@RM]

IF RDSNo		= ''	THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'
IF ShipSlots	= ''	THEN ErrorMsg = 'Null parameter "ShipSlots" passeed to routine.'
IF ShipWfrs		= ''	THEN ErrorMsg = 'Null parameter "ShipWfrs" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Set_Status(0)
RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)		;* REACT_RUN is locked here

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read REACT_RUN ':QUOTE(RdsNo):' for UnloadEpi update.'
	RETURN
END

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

wCnt = COUNT(ShipWfrs,@VM) + (ShipWfrs NE '')

FOR I = 1 TO wCnt
	WfrID = ShipWfrs<1,I>
	CurrSlot = ShipSlots<1,I>
	
	LOCATE WfrID IN RR_Rec<REACT_RUN_IN_WFR_ID$> USING @VM SETTING Pos THEN
		RR_Rec<REACT_RUN_OUT_SLOT_ID$,Pos> = ''
	END

	CurrCarrSlot = ''

	owwParms	 = WfrID:@RM				;* WfrID
	owwParms	:= CurrDTM:@RM				;* EventDtm
	owwParms	:= @USER4:@RM				;* EventBy
	owwParms	:= 'DISP':@RM				;* Event
	owwParms	:= '':@RM					;* New Slot ID
	owwParms	:= '':@RM					;* RPZ (RDSNo*Pocket*Zone)
	owwParms	:= '':@RM					;* NCRNo
	owwParms	:= '':@RM					;* TWUse ID 
	owwParms	:= CurrSlot:@RM				;* Current Slot ID
	owwParms	:= '':@RM					;* New ToolID
	owwParms	:= '':@RM					;* Curr Tool ID
	owwParms 	:= 'GCH*Q_PACK':@RM			;* NewInvLoc				;* GaN Disposition Queue
	owwParms	:= '':@RM					;* CurrInvLoc
	owwParms 	:= 'O':@RM					;* Wfr Side
	owwParms	:= '':@RM					;* New Carrier Loc
	owwParms	:= CurrCarrSlot				;* Curr Carrier Loc
		
	obj_WO_Wfr('AddEvent',owwParms)

NEXT I

RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)


RETURN


* * * * * * *
ReloadMat:
* * * * * * *

RdsNo	= Parms[1,@RM]
ToolID	= Parms[COL2()+1,@RM]

IF RdsNo = '' THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading RDS Record ':RdsNo:'...')

Set_Status(0)

RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)
*RR_Rec	= XLATE('REACT_RUN',RDSNo,'','X')

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read RDS ':QUOTE(RdsNo):' for ReturnMat update.'
	RETURN
END


RLCnt = COUNT(RR_Rec<REACT_RUN_RUN_PKT$>,@VM) + (RR_Rec<REACT_RUN_RUN_PKT$> NE '')

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

FOR I = 1 TO RLCnt

	WfrID		= RR_Rec<REACT_RUN_IN_WFR_ID$,I>
	OutSlotID	= RR_Rec<REACT_RUN_OUT_SLOT_ID$,I>
	
	RunLoc		= RDSNo:'.':RR_Rec<REACT_RUN_RUN_PKT$,I>:'.':RR_Rec<REACT_RUN_RUN_ZONE$,I>

	IF OutSlotID NE '' THEN

		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'RELOAD':@RM				;* Event
		owwParms	:= '':@RM					;* New Slot ID
		owwParms	:= RunLoc:@RM				;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= OutSlotID:@RM			;* Current Slot ID
		owwParms	:= ToolID:@RM				;* NewToolID (Load Tool)
		owwParms	:= '':@RM					;* CurrToolD (Unload Tool)
		owwParms 	:= '':@RM					;* NewInvLoc
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'O'						;* Wfr Side
			
		obj_WO_Wfr('AddEvent',owwParms)
		
	END
	
	RR_Rec<REACT_RUN_OUT_SLOT_ID$,I>	= ''

NEXT I


RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)

RETURN


* * * * * These CarrWfrID methods are not used. Leave until done with development  * * * * * * *

* * * * * * *
SetCarrWfrID:
* * * * * * *

RDSNo	= Parms[1,@RM]
WfrID	= Parms[COL2()+1,@RM]

If RDSNol = ''		THEN ErrorMsg = 'Null Parameter "RDSNo" passed to routine. (':Method:')'
If WfrID = ''		THEN ErrorMsg = 'Null Parameter "WfrID" passed to routine. (':Method:')'

If ErrorMsg NE '' Then Return 

otParms = 'REACT_RUN':@RM:RDSNo
RRunRec = obj_Tables('ReadRec',otParms)

Locate WfrID In RRunRec<REACT_RUN_CARR_WFR_ID$> USING @VM SETTING Pos Then
	obj_Tables('UnlockRec',otParms)
End Else 
	RRunRec = Insert(RRunRec,REACT_RUN_CARR_WFR_ID$ ,-1,0, WfrID)  				;* Wafer ID is added to the END of the list i.e. no sort order
	otParms  = FieldStore(otParms,@RM,4,0,RRunRec)
	obj_Tables('WriteRec',otParms)
END


RETURN


* * * * * * *
ClearCarrWfrID:
* * * * * * *

RDSNo	= Parms[1,@RM]
WfrID	= Parms[COL2()+1,@RM]

If RDSNo = ''		THEN ErrorMsg = 'Null Parameter "RDSNo" passed to routine. (':Method:')'
If WfrID = ''		THEN ErrorMsg = 'Null Parameter "WfrID" passed to routine. (':Method:')'

If ErrorMsg NE '' Then Return 

otParms = 'REACT_RUN':@RM:RDSNo
RRunRec = obj_Tables('ReadRec',otParms)

Locate WfrID In RRunRec<REACT_RUN_CARR_WFR_ID$> USING @VM SETTING Pos Then
	RRunRec = Delete(RRunRec,REACT_RUN_CARR_WFR_ID$,Pos,0)
	otParms  = FieldStore(otParms,@RM,4,0,RRunRec)
	obj_Tables('WriteRec',otParms)
End Else 
	obj_Tables('UnlockRec',otParms)
END

RETURN


* * * * * * *
ClearCarrNCR:
* * * * * * *
! deprecated 2/24/20 - djs - do not use !
RDSNo	= Parms[1,@RM]
NCRNo	= Parms[COL2()+1,@RM]

If RDSNo = ''		THEN ErrorMsg = 'Null Parameter "RDSNo" passed to routine. (':Method:')'
If NCRNo = ''		THEN ErrorMsg = 'Null Parameter "NCRNo" passed to routine. (':Method:')'

If ErrorMsg NE '' Then Return

otParms = 'REACT_RUN':@RM:RDSNo
RRunRec = obj_Tables('ReadRec',otParms)

sCnt = COUNT(RRunRec<REACT_RUN_CARR_SLOT_NO$>,@VM) + (RRunRec<REACT_RUN_CARR_SLOT_NO$> NE '')

WriteFlag = ''
FOR I = 1 TO sCnt
	IF RRunRec<REACT_RUN_CARR_NCR_NO$,I> = NCRNo THEN
		WriteFlag = 1
		RRunRec<REACT_RUN_CARR_WFR_ID$,I> = RRunRec<REACT_RUN_CARR_PREV_WFR_ID$,I>
		RRunRec<REACT_RUN_CARR_NCR_NO$,I> = ''
	END
NEXT I

IF WriteFlag = 1 THEN
	otParms  = FieldStore(otParms,@RM,4,0,RRunRec)
	obj_Tables('WriteRec',otParms)
END ELSE
	obj_Tables('UnlockRec',otParms)
END

RETURN


* * * * * End of CarrWfrID methods.   * * * * * * *


* * * * * * * 
UnloadGan:
* * * * * * * 

RdsNo		= Parms[1,@RM]
ToolID		= Parms[COL2()+1,@RM]
ReactorList	= Parms[COL2()+1,@RM]	;* Contains susceptor load configuration 
UnloadSlots	= Parms[COL2()+1,@RM]	;* Contains CarrSlotNo:@FM:RDSNo:'.':CarrSlotNo for each wafer being "unloaded"

IF RdsNo		= ''	THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'
IF ReactorList	= ''	THEN ErrorMsg = 'Null parameter "ReactorList" passeed to routine.'
IF UnloadSlots	= ''	THEN ErrorMsg = 'Null parameter "UnloadSlots" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading REACT_RUN ':RdsNo:'...')

lCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')
FOR I = lCnt TO 1 STEP -1
	TestVal  = ReactorList<I,1>
UNTIL TestVal NE ''
	ReactorList = DELETE(ReactorList,I,0,0)		;* Strip empty lines from the user interface edit table
NEXT I

Set_Status(0)
RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)		;* REACT_RUN is locked here

IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read REACT_RUN ':QUOTE(RdsNo):' for UnloadEpi update.'
	RETURN
END

ToolRec = XLATE('TOOL',ToolID,'','X')


* Get QOutKey for Reactor or Reactor Class

QOutKey = ''

WHCd	= ToolRec<TOOL_QOUT_WH$>
LocCd	= ToolRec<TOOL_QOUT_LOC$>

IF WHCd NE '' AND LocCd NE '' THEN
	QOutKey = WHCd:'*':LocCd
END ELSE

	ToolClassRec = XLATE('TOOL_CLASS',ToolRec<TOOL_CLASS$>,'','X')
	
	WHCd	= ToolClassRec<TOOL_CLASS_QOUT_WH$>
	LocCd	= ToolClassRec<TOOL_CLASS_QOUT_LOC$>
	
	IF WHCd NE '' AND LocCd NE '' THEN
		QOutKey = WHCd:'*':LocCd
	END 
	
END

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

rCnt = COUNT(ReactorList,@FM) + (ReactorList NE '')

FOR I = 1 TO rCnt

	IF ReactorList<I,REACT_RUN_OUT_SLOT_ID$> = '' AND ReactorList<I,COL$WAFER_TYPE> = 'PROD' AND ReactorList<I,COL$USAGE> = '' THEN
	
		* Empty Pocket and needs a wafer
		* Wafers are "placed" into a carrier slot AND into the Dispo Queue
		
		
		CarrSlotID	= UnloadSlots<I,2>
		CarrSlotNo 	= UnloadSlots<I,1>
		
		WfrID		= ReactorList<I,COL$WFR_ID>
		
		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'UNLOAD':@RM				;* Event
		owwParms	:= '':@RM					;* New Slot ID
		owwParms	:= '':@RM					;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= '':@RM					;* Current Slot ID
		owwParms	:= '':@RM					;* New ToolID
		owwParms	:= ToolID:@RM				;* Curr Tool ID
		owwParms 	:= QOutKey:@RM				;* NewInvLoc			;* Outbound Que for tool
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'O':@RM					;* Wfr Side
		owwParms	:= CarrSlotID:@RM			;* New Carrier Slot
		owwParms	:= ''						;* Curr Carrier Slot
			
		obj_WO_Wfr('AddEvent',owwParms)
		
		LOCATE WfrID IN RR_Rec<REACT_RUN_IN_WFR_ID$> USING @VM SETTING Pos THEN
			RR_Rec<REACT_RUN_CARR_SLOT_ID$,Pos> = CarrSlotID
		END
		
		RR_Rec<REACT_RUN_CARR_WFR_ID$,Pos>	= WfrID
		RR_Rec<REACT_RUN_CARR_SLOT_NO$,Pos>	= CarrSlotNo
	
	END
		
NEXT I

RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)


RETURN


* * * * * * *
ReloadGan:
* * * * * * *

RdsNo	= Parms[1,@RM]
ToolID	= Parms[COL2()+1,@RM]

IF RdsNo = '' THEN ErrorMsg = 'Null parameter "RdsNo" passeed to routine.'

IF ErrorMsg NE '' THEN RETURN

Send_Info('Reading RDS Record ':RdsNo:'...')

Set_Status(0)

RTParms = 'REACT_RUN':@RM:RdsNo
RR_Rec = obj_Tables('ReadRec',RTParms)


IF Get_Status(errCode) THEN
	ErrorMsg = 'Unable to read RDS ':QUOTE(RdsNo):' for ReturnMat update.'
	RETURN
END

RLCnt = COUNT(RR_Rec<REACT_RUN_RUN_PKT$>,@VM) + (RR_Rec<REACT_RUN_RUN_PKT$> NE '')

CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')

FOR I = 1 TO RLCnt

	WfrID			= RR_Rec<REACT_RUN_IN_WFR_ID$,I>
	CurrCarrSlotID	= RR_Rec<REACT_RUN_CARR_SLOT_ID$,I>
	
	RunLoc		= RDSNo:'.':RR_Rec<REACT_RUN_RUN_PKT$,I>:'.':RR_Rec<REACT_RUN_RUN_ZONE$,I>

	IF CurrCarrSlotID NE '' THEN

		owwParms	 = WfrID:@RM				;* WfrID
		owwParms	:= CurrDTM:@RM				;* EventDtm
		owwParms	:= @USER4:@RM				;* EventBy
		owwParms	:= 'RELOAD':@RM				;* Event
		owwParms	:= '':@RM					;* New Slot ID
		owwParms	:= RunLoc:@RM				;* RPZ (RDSNo*Pocket*Zone)
		owwParms	:= '':@RM					;* NCRNo
		owwParms	:= '':@RM					;* TWUse ID 
		owwParms	:= '':@RM					;* Current Slot ID
		owwParms	:= ToolID:@RM				;* NewToolID (Load Tool)
		owwParms	:= '':@RM					;* CurrToolD (Unload Tool)
		owwParms 	:= '':@RM					;* NewInvLoc
		owwParms	:= '':@RM					;* CurrInvLoc
		owwParms 	:= 'O':@RM					;* Wfr Side
		owwParms	:= '':@RM					;* New Carrier Slot
		owwParms	:= CurrCarrSlotID			;* Curr Carrier Slot
			
		obj_WO_Wfr('AddEvent',owwParms)
		
	END

	RR_Rec<REACT_RUN_CARR_WFR_ID$,I>	= ''
	RR_Rec<REACT_RUN_CARR_SLOT_ID$,I>	= ''

NEXT I


RTParms = FieldStore(RTParms, @RM, 4, 1, RR_Rec)
obj_Tables('WriteRec',RTParms)

RETURN



* * * * * * *
SplitWfr:
* * * * * * *
! Deprecated 11/06/2019 DJS
* RDSNo	= Parms[1,@RM]
* WfrID	= Parms[COL2()+1,@RM]
* 
* IF RDSNo = ''	THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'
* IF WfrID = ''	THEN ErrorMsg = 'Null parameter "WfrID" passed to routine. (':Method:')'
* 
* IF ErrorMsg NE '' THEN RETURN
* 
* otParms = 'REACT_RUN':@RM:RDSNo
* 
* RunRec = obj_Tables('ReadRec',otParms)
* 
* IF Get_Status(errCode) THEN RETURN
* 
* LOCATE WfrID IN RunRec<REACT_RUN_CARR_WFR_ID$> USING @VM SETTING Pos THEN
* 
* 	RunRec<REACT_RUN_CARR_PREV_WFR_ID$,Pos> = WfrID
* 	RunRec<REACT_RUN_CARR_WFR_ID$,Pos>		= ''
* 	
* 	
* 	chCnt = COUNT(RunRec<REACT_RUN_CHAR_WFR_ID$>,@VM) + (RunRec<REACT_RUN_CHAR_WFR_ID$> NE '')
* 	NextLine = chCnt + 1
*		
* 	SplitBy = @USER4
* 
* 	IF SplitBy = '' THEN SplitBy = 'UNKNOWN'
* 
* 	SplitDTM = ICONV(OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS'),'DT')
* 
* 	RunRec<REACT_RUN_CHAR_WFR_ID$,NextLine>		= WfrID
* 	RunRec<REACT_RUN_CHAR_SPLIT_BY$,NextLine>	= SplitBy
* 	RunRec<REACT_RUN_CHAR_SPLIT_DTM$,NextLine>	= SplitDTM
* 
* 	otParms = FieldStore(OtParms,@RM,4,0,RunRec)	;* Put record in 4th field of OtParms
* 	obj_Tables('WriteRec',otParms)
* 	
* END ELSE
* 	obj_Tables('UnlockRec',otParms)
* END
* 
RETURN


* * * * * * *
UnSplitWfr:
* * * * * * *
! Deprecated 11/06/2019 DJS
* RDSNo	= Parms[1,@RM]
* WfrID	= Parms[COL2()+1,@RM]
* 
* IF RDSNo = ''	THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine. (':Method:')'
* IF WfrID = ''	THEN ErrorMsg = 'Null parameter "WfrID" passed to routine. (':Method:')'
* 
* IF ErrorMsg NE '' THEN RETURN
* 
* otParms = 'REACT_RUN':@RM:RDSNo
* 
* RunRec = obj_Tables('ReadRec',otParms)
* 
* IF Get_Status(errCode) THEN RETURN
* 
* LOCATE WfrID IN RunRec<REACT_RUN_CARR_PREV_WFR_ID$> USING @VM SETTING Pos THEN
* 
* 	RunRec<REACT_RUN_CARR_PREV_WFR_ID$,Pos> = ''
* 	RunRec<REACT_RUN_CARR_WFR_ID$,Pos>		= WfrID
* 	
* 	LOCATE WfrID IN RunRec<REACT_RUN_CHAR_WFR_ID$> USING @VM SETTING cPos THEN
*			
*		UnSplitBy = @USER4
* 
*		IF UnSplitBy = '' THEN UnSplitBy = 'UNKNOWN'
* 
*		UnSplitDTM = ICONV(OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS'),'DT')
* 
*		RunRec<REACT_RUN_CHAR_RETURN_BY$,cPos>	= UnSplitBy
*		RunRec<REACT_RUN_CHAR_RETURN_DTM$,cPos>	= UnSplitDTM
*		
* 	END
* 
* 	otParms = FieldStore(OtParms,@RM,4,0,RunRec)	;* Put record in 4th field of OtParms
* 	obj_Tables('WriteRec',otParms)
* 	
* END ELSE
* 	obj_Tables('UnlockRec',otParms)
* END

RETURN

* * * * * * *
GetWfrSigKeys:
* * * * * * *


IF NOT(Assigned(RDSNo))		THEN RDSNo = Parms[1,@RM]
IF NOT(Assigned(WfrIDs))	THEN WfrIDs = Parms[COL2()+1,@RM]


IF RDSNo = '' THEN RETURN
IF WfrIDs = '' THEN RETURN

FirstWfrID = WfrIDs<1,1>

WONo = FirstWfrID<1,1>[1,'*']
WOMatKey = FIELD(FirstWfrID,'*',1,2)

SigProfile = XLATE('REACT_RUN',RDSNo, REACT_RUN_WFR_STAGE$,'X')

spCnt = COUNT(SigProfile,@VM) + (SigProfile NE '')

WfrSigKeys = ''
wfrCnt = COUNT(WfrIDs,@VM) + (WfrIDs NE '')

FOR W = 1 TO wfrCnt
	WfrID = WfrIDs<1,W>
	
	IF WfrID NE '' THEN
		FOR I = 1 TO spCnt
			Stage = SigProfile<1,I>
			WfrKID = WfrID
			CONVERT '*' TO '.' IN WfrKID
			
			WfrSigKeys<W,I> = RDSNo:'*':Stage:'*':WfrKID
			
		NEXT I
	END
NEXT W

Result = WfrSigKeys

RETURN


* * * * * * * 
NextWfrStage:
* * * * * * *

RDSNo	= Parms[1,@RM]
RunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RunRec = '' THEN 
	RunRec = XLATE('REACT_RUN',RDSNo,'','X')
	IF RunRec = '' THEN RETURN
END

WfrIDs = RunRec<REACT_RUN_CHAR_WFR_ID$>

GOSUB GetWfrSigKeys

AllWfrStageKeys = Result

Result = ''

WfrCnt = COUNT(AllWfrStageKeys,@FM) + (AllWfrStageKeys NE '')

FOR I = 1 TO WfrCnt

	WfrStageKeys = AllWfrStageKeys<I>
	
	StageCompSigs = XLATE('RUN_STAGE_WFR',WfrStageKeys,RUN_STAGE_WFR_COMP_BY$,'X')
	
	scCnt = COUNT(StageCompSigs,@VM) + (StageCompSigs NE '')
	
	NextWfrStage = ''
	FOR S = scCnt TO 1 STEP -1
	UNTIL StageCompSigs<1,S> NE ''
		NextWfrStage = WfrStageKeys<1,S>
	NEXT S	
	
	IF NextWfrStage = '' THEN
		Result<1,I> = '-'
	END ELSE
		Result<1,I> = FIELD(NextWfrStage,'*',2)
	END

NEXT I


RETURN


* * * * * * *
CharWfrDest:
* * * * * * *

RDSNo	= Parms[1,@RM]
RunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RunRec = '' THEN 
	RunRec = XLATE('REACT_RUN',RDSNo,'','X')
	IF RunRec = '' THEN RETURN
END

WfrIDs = RunRec<REACT_RUN_CHAR_WFR_ID$>

GOSUB GetWfrSigKeys
AllWfrStageKeys = Result
Result = ''

WfrCnt = COUNT(AllWfrStageKeys,@FM) + (AllWfrStageKeys NE '')


FOR I = 1 TO WfrCnt

	WfrStageKeys = AllWfrStageKeys<I>
	
	StageDestTests	= XLATE('RUN_STAGE_WFR',WfrStageKeys,'DEST_TEST','X')
	StageCompSigs	= XLATE('RUN_STAGE_WFR',WfrStageKeys,RUN_STAGE_WFR_COMP_BY$,'X')
	
	scCnt = COUNT(StageCompSigs,@VM) + (StageCompSigs NE '')
	
	
	Destroyed = ''
	FOR S = scCnt TO 1 STEP -1
		IF StageDestTests<1,S> = 1 AND StageCompSigs<1,S> NE '' THEN
			Destroyed = 1
		END
	UNTIL Destroyed
	NEXT S	
	
	Result<1,I> = Destroyed

NEXT I


RETURN

* * * * * * *
CharWfrStatus:
* * * * * * *

RDSNo	= Parms[1,@RM]
RunRec	= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RunRec = '' THEN 
	RunRec = XLATE('REACT_RUN',RDSNo,'','X')
	IF RunRec = '' THEN RETURN
END

WfrIDs = RunRec<REACT_RUN_CHAR_WFR_ID$>

wCnt = COUNT( WfrIDs,@VM) + (WfrIDs NE '')

WfrStatuses = ''


GOSUB NextWfrStage

NextWfrStages = Result
Result = ''

FOR M = 1 TO wCnt
	WfrID = WfrIDs<1,M>
	
	NextWfrStage = NextWfrStages<1,M>
	
	IF NextWfrStage NE '-' THEN
		CONVERT '*' TO '.' IN WfrID
		
		NextWfrStageKey = RDSNo:'*':NextWfrStage:'*':WfrID
		
		WfrStatuses<1,M> = XLATE('RUN_STAGE_WFR',NextWfrStageKey,'CURR_STATUS','X')
	END ELSE
		WfrStatuses<1,M> = 'COMP'
	END
NEXT I

Result = WfrStatuses


Return

* * * * * * *
WfrStageUnloadQ:
* * * * * * *

ErrMsg('Notify FI TEAM if you get this message')

RETURN


RDSNo   = Parms[1,@RM]
RunRec  = Parms[COL2()+1,@RM]
StageID = Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN

IF RunRec = '' THEN
   RunRec = XLATE('REACT_RUN',RDSNo,'','X')
   IF RunRec = '' THEN RETURN
End

* Get Next Stages and Add 'DISP' stage to the end

RunWfrStages    = RunRec<REACT_RUN_WFR_STAGE$>

ValidStages = obj_Popup('AllCodes','GAN_WIP_STAGES')        ;* List of all valid GaN WIP Stage codes from the popup

WfrStages   = ''
InLocIDs    = ''

rwsCnt = COUNT(RunWfrStages,@VM) + (RunWfrStages NE '')

ResCnt = 0

FOR I = 1 TO rwsCnt

   LOCATE RunWfrStages<1,I> IN ValidStages USING @VM Setting Pos THEN

       NextStage = RunWfrStages<1,I+1>
       
       ColToReturn = 4
       
       ToolClass = obj_Popup('CodeDesc','GAN_WIP_STAGES':@RM:NextStage:@RM:ColToReturn)
       
       TCRec = XLATE('TOOL_CLASS',ToolClass,'','X')
       
       QInWH   = TCRec<TOOL_CLASS_QIN_WH$>
       QInLoc  = TCRec<TOOL_CLASS_QIN_LOC$>
       
       IF QInWH NE '' AND QInLoc NE '' THEN
       
           ResCnt += 1
           InLocIDs<1,ResCnt>  = QInWH:'*':QInLoc              ;* * Have a good location to unload into
           WfrStages<1,ResCnt> = RunWfrStages<1,I>
               
       END ELSE
       
           ResCnt += 1
           WfrStages<1,ResCnt> = RunWfrStages<1,I> ;* Disposition Stage
           InLocIDs<1,ResCnt> = 'GGR*Q_DISP'       ;* Unload into DISP(osition) Queue
               
       END
   END

NEXT I

IF StageID NE '' THEN
   LOCATE StageID IN WfrStages USING @VM SETTING RetPos THEN
       Result = InLocIDs<1,RetPos>
   END
END ELSE
   Result = InLocIDs
END

   
RETURN


* * * * * * *
StageUnloadQ:
* * * * * * *

* *  Returns Unload Location for GaN Run or Wfr processing stage code   * *

RDSNo 		= Parms[1,@RM]
RunRec		= Parms[COL2()+1,@RM]
StageID		= Parms[COL2()+1,@RM]

IF RDSNo = '' THEN RETURN
IF StageID = '' THEN RETURN

IF RunRec = '' THEN
	RunRec = XLATE('REACT_RUN',RDSNo,'','X')
	IF RunRec = '' THEN RETURN
End

AllStageData = Xlate('SYSREPOSPOPUPS','LSL2**GAN_WIP_STAGES',PDISPLAY$,'X')	;* Raw Data from Popup

CONVERT @VM:@SVM TO @FM:@VM IN AllStageData

AllStages		= ''
AllChars		= ''
AllToolClasses	= ''

aCnt = 0

LOOP

	StageLine = AllStageData[1,@FM]
	AllStageData[1,COL2()] = ''
	
UNTIL StageLine = ''

	IF StageLine<1,GWS$STAGE> NE '' AND StageLine<1,GWS$TOOL_CLASS> NE '' THEN
		aCnt += 1
		AllStages<1,aCnt>		= StageLine<1,GWS$STAGE>
		AllChars<1,aCnt>		= StageLine<1,GWS$CHAR>
		AllToolClasses<1,aCnt>	= StageLine<1,GWS$TOOL_CLASS>
	END
	
REPEAT

NextQ = ''

LOCATE StageID IN AllStages USING @VM SETTING Pos THEN

	IF AllChars<1,Pos> = 1 THEN
		ReactRunStages = RunRec<REACT_RUN_WFR_STAGE$>
	END ELSE
		ReactRunStages = RunRec<REACT_RUN_RUN_STAGE_KEY$>
		
		SWAP RDSNo:'*' WITH '' IN ReactRunStages			;* Strips "RDSNo*" from keys leaving just the stage
	END
END ELSE
	RETURN		;* No material movements specified
END


rrCnt = COUNT(ReactRunStages,@VM) + (ReactRunStages NE '')

IReactRunStages = ''
IReactRunToolClasses = ''

iCnt = 0

FOR I = 1 TO rrCnt

	ReactRunStage = ReactRunStages<1,I>
	
	LOCATE ReactRunStage IN AllStages USING @VM SETTING Pos THEN
		IF AllToolClasses<1,I> NE '' THEN
			iCnt += 1
			IReactRunStages<1,iCnt> = ReactRunStage
			IReactRunToolClasses<1,iCnt> = AllToolClasses<1,Pos>
		END
	END

NEXT I

LOCATE StageID IN IReactRunStages USING @VM SETTING RPos THEN
	NextStage		= IReactRunStages<1,RPos+1>
	NextToolClass	= IReactRunToolClasses<1,RPos+1>

	IF NextStage = '' THEN
		NextQ = 'GGR*Q_DISP'
	END ELSE			
		TCRec	= XLATE('TOOL_CLASS',NextToolClass,'','X')
		NextQ = TCRec<TOOL_CLASS_QIN_WH$>:'*':TCRec<TOOL_CLASS_QIN_LOC$>
	END
END

Result = NextQ
	
RETURN



* * * * * * *
GaNDispStatus:
* * * * * * *

RDSNo 	= Parms[1,@RM]
RunRec	= Parms[COL2()+1,@RM]


IF RDSNo = '' THEN RETURN

IF RunRec = '' THEN
	RunRec = XLATE('REACT_RUN',RDSNo,'','X')
	IF RunRec = '' THEN RETURN
END


RETURN


