2848 lines
137 KiB
Plaintext
2848 lines
137 KiB
Plaintext
Compile function Signature_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 : Signature_Services
|
|
|
|
Description : Handler program for all module related services.
|
|
|
|
Notes : Service module to support environmental state issues. Environmental refers to the state of the
|
|
operating system, which includes version, client vs. server, and path to critical systems.
|
|
|
|
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)
|
|
11/07/19 djs Original programmer.
|
|
08/21/20 djs Updated GetSigInfo to support multiple CLEAN_INSP scans. The code will return the
|
|
signature info for the most recently signed scan.
|
|
07/13/21 djs Removed caching code (Memory_Services) so that users can sign multiple stages in quick
|
|
succession without causing issues related to caching the signature profile.
|
|
08/03/21 djs Restored caching code because it was causing the application to perform very poorly during
|
|
certain operations (e.g. releasing material). Added a UseCaching variable to all services,
|
|
so that developers can choose to use caching or not.
|
|
06/13/24 djm Add support for EPP signature profile.
|
|
|
|
***********************************************************************************************************************/
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$insert POPUP_EQUATES
|
|
$INSERT LOGICAL
|
|
$Insert WO_MAT_EQUATES
|
|
$insert SERVICE_SETUP
|
|
$insert RLIST_EQUATES
|
|
$insert WO_MAT_QA_EQUATES
|
|
$insert RDS_EQUATES
|
|
$insert COMPANY_EQUATES
|
|
$insert APP_INSERTS
|
|
$insert CLEAN_INSP_EQUATES
|
|
$insert NCR_EQUATES
|
|
$insert WM_OUT_EQUATES
|
|
|
|
Equ SS_PASS$ To 1
|
|
Equ SS_SIG$ To 2
|
|
Equ SS_DATA$ To 3
|
|
Equ SS_NA$ To 4
|
|
|
|
Equ COL$LOG_FILE to 1
|
|
Equ COL$LOG_DTM to 2
|
|
Equ COL$ACTION to 3
|
|
Equ COL$WH_CD to 4
|
|
Equ COL$LOC_CD to 5
|
|
Equ COL$WO_NOS to 6
|
|
Equ COL$CASS_NOS to 7
|
|
Equ COL$USER_ID to 8
|
|
Equ COL$TAGS to 9
|
|
Equ COL$TOOL_ID to 10
|
|
|
|
Declare function obj_Prod_Spec, RDS_Services, Error_Services, Signature_Services, Memory_Services, obj_RDS_Test
|
|
Declare function Database_Services, obj_WO_Mat, Dialog_Box, MemberOf, Msg, QA_Services, Datetime, Supplement_Services
|
|
Declare subroutine Error_Services, Popup, Memory_Services, SRP_Stopwatch, Set_Status, Database_Services, obj_WO_Mat
|
|
Declare subroutine Obj_Notes, Signature_Services, Obj_WO_Mat_Log, ErrMsg
|
|
|
|
PSNKey = ServiceKeyID
|
|
ReactorKey = ServiceKeyID
|
|
|
|
GoToService
|
|
|
|
Return Response or ""
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Service Parameter Options
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Options CI_STAGES = 'PREI,PREC,PRES,FWII,FWIC,FWIS,LWII,LWIC,LWIS,PSTI,PSTC,PSTS'
|
|
Options QA_STAGES = 'LOAD,UNLOAD,QA'
|
|
Options SLOTS = '1,2,3,4,5,6,F,L,A' ; // From SYSREPOSPOPUPS LSL2**TEST_SLOTS
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SERVICES
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
Service FQAReady(WOMatKey, UseCaching)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
Response = False$
|
|
SigProfile = Signature_Services('GetSigProfile', WOMatKey, UseCaching)
|
|
Stages = SigProfile<1>
|
|
Sigs = SigProfile<2>
|
|
SigDTMs = SigProfile<3>
|
|
NumStages = DCount(Stages, @VM)
|
|
If NumStages GT 1 then
|
|
Done = False$
|
|
For StageIndex = 1 to (NumStages - 1)
|
|
Stage = Stages<0, StageIndex>
|
|
StageComp = Signature_Services('CheckSignature', WOMatKey, Stage)
|
|
If StageComp EQ False$ then
|
|
Done = True$
|
|
ErrorMsg = 'Unable to sign FQA due to incomplete Signature Profile at ':Stage:' stage.'
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
Until Done EQ True$
|
|
Next StageIndex
|
|
end
|
|
|
|
If Error_Services('NoError') then Response = True$
|
|
|
|
end service
|
|
|
|
|
|
Service CheckQALabelStatus(WOMatKey)
|
|
|
|
rec = Xlate('WO_MAT', WoMatKey,'', '')
|
|
locRec = rec<WO_MAT_INV_LOCATION$>
|
|
actionRec = rec<WO_MAT_INV_ACTION$>
|
|
retVal = 0
|
|
Locate 'LBLCHK' In actionRec Using @VM Setting locIdx Then
|
|
Locate 'PKO' in locRec Using @VM Setting idx Then
|
|
if idx GE 1 then
|
|
If (rec<WO_MAT_INV_USER$, idx> NE '' AND rec<WO_MAT_INV_DTM$, idx> NE '') then
|
|
retVal = 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Response = retVal
|
|
|
|
end service
|
|
|
|
|
|
Service GetSigProfile(WOMatKey, UseCaching, RDSNo)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
|
|
SigProfile = ''
|
|
Signatures = ''
|
|
SigDTMs = ''
|
|
|
|
If RDSNo NE '' then
|
|
WONo = Xlate('RDS', RDSNo, 'WO', 'X')
|
|
end else
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
end
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
|
|
SigProfKey = PSNo:'*':WOMatKey:'*':RDSNo
|
|
ReactorKey = PSNo :'*Reactor'
|
|
|
|
If UseCaching and Memory_Services('IsValueCurrent', SigProfKey, 60, True$) then
|
|
SigProfile = Memory_Services('GetValue', SigProfKey)
|
|
end else
|
|
SigProfile = obj_Prod_Spec('GetSigProfile', PSNo:@RM:'':@RM:WOMatKey:@RM:RDSNo)
|
|
Memory_Services('SetValue', SigProfKey, SigProfile)
|
|
end
|
|
|
|
If UseCaching and Memory_Services('IsValueCurrent', ReactorKey, 60, True$) then
|
|
ReactorType = Memory_Services('GetValue', ReactorKey)
|
|
end else
|
|
ReactorType = Xlate('PROD_SPEC', PSNo, 'REACTOR_TYPE', 'X')
|
|
Memory_Services('SetValue', ReactorKey, ReactorType)
|
|
end
|
|
|
|
For each Stage in SigProfile using @VM setting LineNo
|
|
SigInfo = Signature_Services('GetSigInfo', WOMatKey, Stage, UseCaching, RDSNo)
|
|
Signatures<0, LineNo> = SigInfo<1>
|
|
SigDTMs<0, LineNo> = SigInfo<2>
|
|
Next Stage
|
|
|
|
SigDTMs = OCONV(SigDTMs,'DT4/^S')
|
|
Response = SigProfile:@FM:Signatures:@FM:SigDTMs
|
|
|
|
end service
|
|
|
|
|
|
Service FinalSigComp(WOMatKey, UseCaching)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
Response = False$
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
ReactorType = Xlate('WO_LOG', WONo, 'REACTOR_TYPE', 'X')
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
ReactorType = Xlate('PROD_SPEC', PSNo, 'REACTOR_TYPE', 'X')
|
|
SigProfile = Signature_Services('GetSigProfile', WOMatKey, UseCaching)
|
|
NumStages = DCount(SigProfile, @VM)
|
|
FinalStage = SigProfile<0, NumStages>
|
|
Response = Signature_Services('CheckSignature', WOMatKey, FinalStage, UseCaching)
|
|
|
|
end service
|
|
|
|
|
|
Service FinalSigDTM(WOMatKey, UseCaching)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
Response = False$
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
ReactorType = Xlate('WO_LOG', WONo, 'REACTOR_TYPE', 'X')
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
ReactorType = Xlate('PROD_SPEC', PSNo, 'REACTOR_TYPE', 'X')
|
|
SigProfile = Signature_Services('GetSigProfile', WOMatKey, UseCaching)
|
|
NumStages = DCount(SigProfile, @VM)
|
|
FinalStage = SigProfile<0, NumStages>
|
|
Response = Signature_Services('GetSigInfo', WOMatKey, FinalStage, UseCaching)<2>
|
|
|
|
end service
|
|
|
|
|
|
Service CheckSigOrder(WOMatKey, CurrStage, UseCaching, RDSNo)
|
|
If UseCaching EQ '' then UseCachine = True$
|
|
Response = False$
|
|
If RDSNo NE '' then
|
|
WONo = Xlate('RDS', RDSNo, 'WO', 'X')
|
|
end else
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
end
|
|
ReactorType = Xlate('WO_LOG', WONo, 'REACTOR_TYPE', 'X')
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
SigProfile = obj_Prod_Spec('GetSigProfile', PSNo:@RM:'':@RM:WOMatKey:@RM:RDSNo)
|
|
|
|
Locate CurrStage in SigProfile using @VM setting sPos then
|
|
If sPos GT 1 then
|
|
PrevStage = SigProfile<0, sPos-1>
|
|
end else
|
|
// There is no previous stage
|
|
PrevStage = ''
|
|
end
|
|
|
|
// Check previous stage is complete
|
|
If PrevStage NE '' then
|
|
PrevStageSigInfo = Signature_Services('GetSigInfo', WOMatKey, PrevStage, UseCaching, RDSNo)
|
|
PrevStageSig = PrevStageSigInfo<1>
|
|
PrevStageComp = (PrevStageSig NE '')
|
|
end else
|
|
PrevStageSig = ''
|
|
PrevStageComp = True$
|
|
end
|
|
CurrStageComp = Signature_Services('CheckSignature', WOMatKey, CurrStage, UseCaching, RDSNo)
|
|
|
|
Begin Case
|
|
Case ( Not(MemberOf(@User4, 'BYPASS') ) and ( (CurrStage EQ 'QA') or (CurrStage EQ 'MO_QA') ) and (PrevStageSig EQ @User4) )
|
|
ErrorMsg = 'FQA stage signature cannot match previous step ':PrevStage:' signature. ':WOMatKey:' (':Service:')'
|
|
Error_Services('Add', ErrorMsg)
|
|
Case PrevStageComp EQ False$
|
|
ErrorMsg = 'Previous step ':PrevStage:' is not signed. ':WOMatKey:' (':Service:')'
|
|
Error_Services('Add', ErrorMsg)
|
|
Case CurrStageComp EQ True$
|
|
// Allow user to re-sign. This may be necessary in certain cases such as when multiple surfscans
|
|
// have taken place and one still needs to be signed.
|
|
Response = True$
|
|
Case Error_Services('HasError') EQ True$
|
|
// Error message already in stack.
|
|
Null
|
|
Case Otherwise$
|
|
// Ok
|
|
Response = True$
|
|
End Case
|
|
end else
|
|
// Stage not prescribed in the PSN, so ignore the signature order.
|
|
Response = True$
|
|
end
|
|
|
|
End Service
|
|
|
|
|
|
Service CheckSignature(WOMatKey, Stage, UseCaching, RDSNo)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
Response = False$
|
|
SigInfo = Signature_Services('GetSigInfo', WOMatKey, Stage, UseCaching, RDSNo)
|
|
If Error_Services('NoError') then
|
|
Signature = SigInfo<1>
|
|
SigDTM = SigInfo<2>
|
|
If Signature NE '' then Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service GetSigInfo(WOMatKey, Stage, UseCaching, RDSNo)
|
|
|
|
If UseCaching EQ '' then UseCaching = True$
|
|
Signature = ''
|
|
SigDTM = ''
|
|
If RDSNo NE '' then
|
|
WONo = Xlate('RDS', RDSNo, 'WO', 'X')
|
|
end else
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
end
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
|
|
SigProfKey = PSNo:'*':WOMatKey:'*':RDSNo
|
|
ReactorKey = PSNo:'*Reactor'
|
|
|
|
If UseCaching and Memory_Services('IsValueCurrent', SigProfKey, 60, True$) then
|
|
SigProfile = Memory_Services('GetValue', SigProfKey)
|
|
end else
|
|
SigProfile = obj_Prod_Spec('GetSigProfile', PSNo:@RM:'':@RM:WOMatKey:@RM:RDSNo)
|
|
Memory_Services('SetValue', SigProfKey, SigProfile)
|
|
end
|
|
|
|
If UseCaching and Memory_Services('IsValueCurrent', ReactorKey, 60, True$) then
|
|
ReactorType = Memory_Services('GetValue', ReactorKey)
|
|
end else
|
|
ReactorType = Xlate('PROD_SPEC', PSNo, 'REACTOR_TYPE', 'X')
|
|
Memory_Services('SetValue', ReactorKey, ReactorType)
|
|
end
|
|
|
|
Locate Stage in SigProfile using @VM setting sPos then
|
|
|
|
Begin Case
|
|
* * EpiPro * *
|
|
Case ( (ReactorType EQ 'EPP') or (ReactorType EQ 'P') )
|
|
CassNo = Field(WOMatKey, '*', 2)
|
|
WMOKey = WONo:'*1*':CassNo
|
|
PostCINo = Xlate('WM_OUT', WMOKey, 'EPO_CI_NO', 'X')
|
|
Begin Case
|
|
|
|
* * Verify wafer quantity stage (aka PRE) * *
|
|
|
|
Case Stage EQ 'VER'
|
|
Signature = Xlate('RDS', RDSNo, 'PRE_EPI_SIG', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'PRE_EPI_SIG_DT', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'PRE_EPI_SIG_TIME', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Pre Epi Cleaning and Inspection Stages * *
|
|
|
|
Case Stage EQ 'PREC'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PREI'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PRES'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
* * Reactor Load * *
|
|
|
|
Case Stage EQ 'LOAD'
|
|
Signature = Xlate('RDS', RDSNo, 'OPERATOR_IN', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'DATE_IN', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'TIME_IN', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * First Wafer Inspection and Surfscan Stages * *
|
|
|
|
Case Stage EQ 'FWII'
|
|
FWICINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', FWICINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', FWICINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', FWICINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'FWIS'
|
|
FWICINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', FWICINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', FWICINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', FWICINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
* * Reactor Unload * *
|
|
|
|
Case Stage EQ 'UNLOAD'
|
|
Signature = Xlate('RDS', RDSNo, 'OPERATOR_OUT', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'DATE_OUT', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'TIME_OUT', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Last Wafer Inspection and Surfscan Stages * *
|
|
|
|
Case Stage EQ 'LWII'
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', LWICINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', LWICINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', LWICINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'LWIS'
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', LWICINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', LWICINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', LWICINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'POST'
|
|
Signature = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'POST_EPI_SIG_DATE', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'POST_EPI_SIG_TIME', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Post Epi Clean and Inspection Stages * *
|
|
|
|
Case Stage EQ 'PSTC'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PSTI'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PSTS'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
|
|
Case Stage EQ 'MO_PSTC'
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'MO_PSTI'
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'MO_PSTS'
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'SCAN_RECIPE', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'MO_QA'
|
|
Signature = Xlate('WM_OUT', WMOKey, 'SUP_VER_SIG', 'X')
|
|
SigDTM = Xlate('WM_OUT', WMOKey, 'SUP_VER_SIG_DTM', 'X')
|
|
|
|
End Case
|
|
|
|
|
|
* * GaN * *
|
|
Case (ReactorType EQ 'GAN')
|
|
|
|
If Stage EQ 'G_FQA' then
|
|
Signature = Xlate('WO_MAT', WOMatKey, 'CASS_FINAL_SIG', 'X')
|
|
SigDTM = Xlate('WO_MAT', WOMatKey, 'CASS_FINAL_SIG_DTM', 'X')
|
|
end
|
|
|
|
* * Silicon (aka Non-EpiPro) * *
|
|
Case Otherwise$
|
|
RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
|
|
Begin Case
|
|
|
|
* * Verify wafer quantity stage (aka PRE) * *
|
|
|
|
Case Stage EQ 'VER'
|
|
Signature = Xlate('RDS', RDSNo, 'PRE_EPI_SIG', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'PRE_EPI_SIG_DT', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'PRE_EPI_SIG_TIME', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Pre Epi Cleaning and Inspection Stages * *
|
|
|
|
Case Stage EQ 'PREC'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'CLEAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PREI'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PRES'
|
|
PreCINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PreCINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PreCINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PreCINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
* * Reactor Load * *
|
|
|
|
Case Stage EQ 'LOAD'
|
|
Signature = Xlate('RDS', RDSNo, 'OPERATOR_IN', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'DATE_IN', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'TIME_IN', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * First Wafer Inspection and Surfscan Stages * *
|
|
|
|
Case Stage EQ 'FWII'
|
|
FWICINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', FWICINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', FWICINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', FWICINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'FWIS'
|
|
FWICINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', FWICINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', FWICINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', FWICINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
* * Reactor Unload * *
|
|
|
|
Case Stage EQ 'UNLOAD'
|
|
Signature = Xlate('RDS', RDSNo, 'OPERATOR_OUT', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'DATE_OUT', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'TIME_OUT', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Last Wafer Inspection and Surfscan Stages * *
|
|
|
|
Case Stage EQ 'LWII'
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', LWICINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', LWICINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', LWICINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'LWIS'
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', LWICINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', LWICINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', LWICINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'POST'
|
|
Signature = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'POST_EPI_SIG_DATE', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'POST_EPI_SIG_TIME', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
* * Post Epi Clean and Inspection Stages * *
|
|
|
|
Case Stage EQ 'PSTC'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'CLEAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PSTI'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'INSP_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'INSP_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
Case Stage EQ 'PSTS'
|
|
PostCINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRows = Xlate('CLEAN_INSP', PostCINo, 'SCAN_TOOL', 'X')
|
|
Signatures = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG', 'X')
|
|
SigDTMs = Xlate('CLEAN_INSP', PostCINo, 'SCAN_SIG_DTM', 'X')
|
|
GoSub GetMostRecentSig
|
|
|
|
* * Final QA Stage * *
|
|
|
|
Case Stage EQ 'QA'
|
|
Signature = Xlate('RDS', RDSNo, 'SUP_VER_SIG', 'X')
|
|
SigDate = OConv(Xlate('RDS', RDSNo, 'SUP_VER_SIG_DATE', 'X'), 'D')
|
|
SigTime = OConv(Xlate('RDS', RDSNo, 'SUP_VER_SIG_TIME', 'X'), 'MTS')
|
|
SigDTM = IConv(SigDate:' ':SigTime, 'DT')
|
|
|
|
End Case
|
|
End Case
|
|
|
|
end else
|
|
ErrorMsg = Stage:' stage not found in signature profile. ':WOMatKey:' (':Service:')'
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
|
|
Response = Signature:@FM:SigDTM
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetStageSummary
|
|
//
|
|
// Input:
|
|
// WOMatKey - [Required]
|
|
// Stage - [Required]
|
|
//
|
|
// Output:
|
|
// Response<1> - True$ if stage passes all requirements, False$ otherwise.
|
|
// Response<2> - True$ if stage has been signed, False$ otherwise.
|
|
// Response<3> - True$ if stage requires data and has data, False$ otherwise.
|
|
// Response<4> - True$ if stage not defined in the PSN, False$ otherwise.
|
|
//
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetStageSummary(WOMatKey, Stage)
|
|
|
|
StageSummary = ''
|
|
Error = ''
|
|
RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
|
|
SigProf = Signature_Services('GetSigProfile', WOMatKey, False$)
|
|
SigProfStages = SigProf<1>
|
|
SigProfSigs = SigProf<2>
|
|
If (RowExists('WO_MAT', WOMatKey) and (Stage NE '') ) then
|
|
Begin Case
|
|
Case Stage EQ 'VER'
|
|
// Ensure "Verify Wafers" quantity is not null
|
|
// Ensure VER signature is not null
|
|
If RDSNo NE '' then
|
|
VerSig = Xlate('RDS', RDSNo, 'PRE_EPI_SIG', 'X')
|
|
VerifyQty = Xlate('RDS', RDSNo, 'VERIFY_QTY', 'X')
|
|
StageSummary<SS_PASS$> = ( (VerSig NE '') and (VerifyQty NE '') )
|
|
StageSummary<SS_SIG$> = (VerSig NE '')
|
|
StageSummary<SS_DATA$> = (VerifyQty NE '')
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'SUPP'
|
|
// Verify RDS supplement information has been acknowledged
|
|
If RDSNo NE '' then
|
|
SupplFlag = Xlate('RDS', RDSNo, 'SUPPLEMENT', 'X')
|
|
SupplAckReq = Xlate('RDS', RDSNo, 'SUPPL_ACK_REQ', 'X')
|
|
SupplSig = Xlate('RDS', RDSNo, 'SUPPL_SIG', 'X')
|
|
StageSummary<SS_PASS$> = (SupplFlag EQ True$) and (SupplAckReq EQ False$)
|
|
StageSummary<SS_SIG$> = (SupplSig NE '')
|
|
StageSummary<SS_DATA$> = (SupplFlag EQ True$)
|
|
StageSummary<SS_NA$> = (SupplFlag NE True$) ; // Stage only applicable if supplement flag is true
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'LOAD'
|
|
// Verify "Wafers In" quantity is not null
|
|
// Ensure LOAD signature is not null
|
|
If RDSNo NE '' then
|
|
LoadSig = Xlate('RDS', RDSNo, 'OPERATOR_IN', 'X')
|
|
WafersIn = Xlate('RDS', RDSNo, 'WAFERS_IN', 'X')
|
|
StageSummary<SS_PASS$> = ( (LoadSig NE '') and (WafersIn NE '') )
|
|
StageSummary<SS_SIG$> = (LoadSig NE '')
|
|
StageSummary<SS_DATA$> = (WafersIn NE '')
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'UNLOAD'
|
|
// Ensure UNLOAD signature is not null
|
|
If RDSNo NE '' then
|
|
UnloadSig = Xlate('RDS', RDSNo, 'OPERATOR_OUT', 'X')
|
|
StageSummary<SS_PASS$> = (UnloadSig NE '')
|
|
StageSummary<SS_SIG$> = (UnloadSig NE '')
|
|
StageSummary<SS_DATA$> = True$ ; // No data for this stage entered by user
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'POST'
|
|
// Ensure POST signature is not null
|
|
If RDSNo NE '' then
|
|
PostEpiSig = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X')
|
|
StageSummary<SS_PASS$> = (PostEpiSig NE '')
|
|
StageSummary<SS_SIG$> = (PostEpiSig NE '')
|
|
StageSummary<SS_DATA$> = True$ ; // No data for this stage entered by user
|
|
StageSummary<SS_NA$> = False$ ; // This stage is essentially never required by the PSN, but is required by some code.
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'QA'
|
|
// Verify QA signature is not null
|
|
If RDSNo NE '' then
|
|
FQASig = Xlate('RDS', RDSNo, 'SUP_VER_SIG', 'X')
|
|
StageSummary<SS_PASS$> = (FQASig NE '')
|
|
StageSummary<SS_SIG$> = (FQASig NE '')
|
|
StageSummary<SS_DATA$> = True$ ; //Signature_Services('QASigReady', RDSNo)
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
end else
|
|
Error = 'Error in ':Service:' service. Null RDSNo for WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
Case Stage EQ 'RDS_TEST'
|
|
// Gather RDS metrology information
|
|
StageComplete = False$
|
|
If RDSNo NE '' then
|
|
MetNo = Xlate('RDS', RDSNo, 'MET_KEYS', 'X')
|
|
If MetNo NE '' then
|
|
MetRec = Database_Services('ReadDataRow', 'RDS_TEST', MetNo)
|
|
TWSigned = obj_RDS_Test('TWSignedOff', MetNo:@RM:MetRec)
|
|
TestComp = obj_RDS_Test('TestComplete', MetNo:@RM:MetRec)
|
|
OutOfSpec = obj_RDS_Test('OutOfSpec', MetNo:@RM:MetRec)
|
|
StageSummary<SS_PASS$> = (TWSigned and TestComp and Not(OutOfSpec))
|
|
StageSummary<SS_SIG$> = TestComp
|
|
StageSummary<SS_DATA$> = TestComp
|
|
StageSummary<SS_NA$> = False$ ; // I think RDS metrology is always required.
|
|
end
|
|
end
|
|
Case Stage EQ 'PREI'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
If CINo NE '' then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'INSP_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'INSP_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'PREC'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'CLEAN_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'CLEAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'PRES'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
StageRx = StageSummary<SS_NA$>
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'SPEC_SURFSCAN_RECIPE', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'SCAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'FWII'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
If CINo NE '' then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'INSP_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'INSP_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'FWIC'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'CLEAN_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'CLEAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'FWIS'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
StageRx = StageSummary<SS_NA$>
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'SPEC_SURFSCAN_RECIPE', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'SCAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'LOAD_QA_MET'
|
|
// Gather load QA metrology information
|
|
NumTests = 0
|
|
TestSigs = ''
|
|
TestOOSs = ''
|
|
TestResults = ''
|
|
Error = ''
|
|
NotApplicable = True$
|
|
StageComplete = False$
|
|
DataComp = False$
|
|
SigsComp = False$
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
If RowExists('WO_MAT', WOMatKey) then
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
|
|
QAMetStages = WOMatQARec<WO_MAT_QA_STAGE$>
|
|
QAMetSigs = WOMatQARec<WO_MAT_QA_SIG$>
|
|
QAMetOOSs = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$>
|
|
QAMetResults = WOMatQARec<WO_MAT_QA_RESULT$>
|
|
For each QAMetStage in QAMetStages using @VM setting vPos
|
|
If QAMetStage EQ 'FWI' then
|
|
NumTests += 1
|
|
NotApplicable = False$
|
|
TestSig = QAMetSigs<0, vPos>
|
|
TestOOS = QAMetOOSs<0, vPos>
|
|
TestResult = QAMetResults<0, vPos>
|
|
TestSigs<0, vPos> = (TestSig NE '')
|
|
TestOOSs<0, vPos> = TestOOS
|
|
TestResults<0, vPos> = (TestResult NE '')
|
|
end
|
|
Next QAMetStage
|
|
DataComp = ( ( NumTests EQ Sum(TestResults) ) and (NumTests GT 0) )
|
|
SigsComp = ( ( NumTests EQ Sum(TestSigs) ) and (NumTests GT 0) )
|
|
end
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = NotApplicable
|
|
Case Stage EQ 'LWII'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
If CINo NE '' then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'INSP_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'INSP_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'LWIC'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'CLEAN_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'CLEAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'LWIS'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
StageRx = StageSummary<SS_NA$>
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'SPEC_SURFSCAN_RECIPE', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'SCAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'ROTR'
|
|
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'SPEC_SURFSCAN_RECIPE', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'SCAN_SIG', 'X')
|
|
ROTRAction = Xlate('CLEAN_INSP', CINo, 'RDS_ROTR_ACTION', 'X')
|
|
ROTRActionReason = Xlate('CLEAN_INSP', CINo, 'ROTR_ACTION_REASON', 'X')
|
|
Begin Case
|
|
Case ( (ROTRAction EQ 'F' ) and (CISig NE '') )
|
|
// ROTR Acceptance required
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
StageSummary<SS_NA$> = False$
|
|
Case ( (ROTRAction EQ 'F') and (CISig EQ '') and (ROTRActionReason EQ 'SurfScan signature is missing.') )
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
StageSummary<SS_NA$> = False$
|
|
Case ( (ROTRAction EQ 'F') and (CISig EQ '') )
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
StageSummary<SS_NA$> = False$
|
|
Case Otherwise$
|
|
// Pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
StageSummary<SS_NA$> = False$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'UNLOAD_QA_MET'
|
|
// Gather unload QA metrology information
|
|
NumTests = 0
|
|
TestSigs = ''
|
|
TestOOSs = ''
|
|
TestResults = ''
|
|
Error = ''
|
|
NotApplicable = True$
|
|
StageComplete = False$
|
|
DataComp = False$
|
|
SigsComp = False$
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
If RowExists('WO_MAT', WOMatKey) then
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
|
|
QAMetStages = WOMatQARec<WO_MAT_QA_STAGE$>
|
|
QAMetSigs = WOMatQARec<WO_MAT_QA_SIG$>
|
|
QAMetOOSs = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$>
|
|
QAMetResults = WOMatQARec<WO_MAT_QA_RESULT$>
|
|
For each QAMetStage in QAMetStages using @VM setting vPos
|
|
If QAMetStage EQ 'UNLOAD' then
|
|
NumTests += 1
|
|
NotApplicable = False$
|
|
TestSig = QAMetSigs<0, vPos>
|
|
TestOOS = QAMetOOSs<0, vPos>
|
|
TestResult = QAMetResults<0, vPos>
|
|
TestSigs<0, vPos> = (TestSig NE '')
|
|
TestOOSs<0, vPos> = TestOOS
|
|
TestResults<0, vPos> = (TestResult NE '')
|
|
end
|
|
Next QAMetStage
|
|
DataComp = ( ( NumTests EQ Sum(TestResults) ) and (NumTests GT 0) )
|
|
SigsComp = ( ( NumTests EQ Sum(TestSigs) ) and (NumTests GT 0) )
|
|
end
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = NotApplicable
|
|
Case Stage EQ 'PSTI'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
If CINo NE '' then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'INSP_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'INSP_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'PSTC'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
StageRx = StageSummary<SS_NA$>
|
|
CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'CLEAN_TOOL', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'CLEAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'PSTS'
|
|
Locate Stage in SigProfStages using @VM setting vPos then
|
|
StageSummary<SS_NA$> = False$
|
|
end else
|
|
StageSummary<SS_NA$> = True$
|
|
end
|
|
CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
StageRx = StageSummary<SS_NA$>
|
|
If (CINo NE '') then
|
|
CITool = Xlate('CLEAN_INSP', CINo, 'SPEC_SURFSCAN_RECIPE', 'X')
|
|
CISig = Xlate('CLEAN_INSP', CINo, 'SCAN_SIG', 'X')
|
|
Begin Case
|
|
Case ( (CITool EQ '') and (StageRx EQ True$) )
|
|
// Required data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = (CISig NE '')
|
|
StageSummary<SS_PASS$> = False$
|
|
Case ( (CITool NE '') and (CISig EQ '') )
|
|
// Data is present, but signature missing
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
Case Otherwise$
|
|
// Full pass
|
|
StageSummary<SS_DATA$> = True$
|
|
StageSummary<SS_SIG$> = True$
|
|
StageSummary<SS_PASS$> = True$
|
|
End Case
|
|
end else
|
|
If StageRx then
|
|
// Data is missing
|
|
StageSummary<SS_DATA$> = False$
|
|
StageSummary<SS_SIG$> = False$
|
|
StageSummary<SS_PASS$> = False$
|
|
end else
|
|
// Stage not applicable
|
|
StageSummary<SS_DATA$> = ''
|
|
StageSummary<SS_SIG$> = ''
|
|
StageSummary<SS_PASS$> = ''
|
|
end
|
|
end
|
|
Case Stage EQ 'POST_QA_MET'
|
|
// Gather post-epi QA metrology information
|
|
NumTests = 0
|
|
TestSigs = ''
|
|
TestOOSs = ''
|
|
TestResults = ''
|
|
Error = ''
|
|
NotApplicable = True$
|
|
StageComplete = False$
|
|
DataComp = False$
|
|
SigsComp = False$
|
|
If RowExists('WO_MAT', WOMatKey) then
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
|
|
QAMetStages = WOMatQARec<WO_MAT_QA_STAGE$>
|
|
QAMetSigs = WOMatQARec<WO_MAT_QA_SIG$>
|
|
QAMetOOSs = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$>
|
|
QAMetResults = WOMatQARec<WO_MAT_QA_RESULT$>
|
|
For each QAMetStage in QAMetStages using @VM setting vPos
|
|
If QAMetStage EQ 'QA' then
|
|
NumTests += 1
|
|
NotApplicable = False$
|
|
TestSig = QAMetSigs<0, vPos>
|
|
TestOOS = QAMetOOSs<0, vPos>
|
|
TestResult = QAMetResults<0, vPos>
|
|
TestSigs<0, vPos> = (TestSig NE '')
|
|
TestOOSs<0, vPos> = TestOOS
|
|
TestResults<0, vPos> = (TestResult NE '')
|
|
end
|
|
Next QAMetStage
|
|
DataComp = ( ( NumTests EQ Sum(TestResults) ) and (NumTests GT 0) )
|
|
SigsComp = ( ( NumTests EQ Sum(TestSigs) ) and (NumTests GT 0) )
|
|
end
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = NotApplicable
|
|
Case Stage EQ 'LBLCHK'
|
|
// Verify LBLCHK inv action exists in WO_MAT material log.
|
|
NotApplicable = False$
|
|
InvActions = Xlate('WO_MAT', WOMatKey, 'INV_ACTION', 'X')
|
|
Locate Stage in InvActions using @VM setting vPos then
|
|
DataComp = True$
|
|
SigsComp = True$
|
|
end else
|
|
DataComp = False$
|
|
SigsComp = False$
|
|
end
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = NotApplicable
|
|
Case Stage EQ 'NCR'
|
|
// Gather NCR information
|
|
NotApplicable = True$
|
|
DataComp = False$
|
|
SigsComp = False$
|
|
NumSigs = 0
|
|
NumData = 0
|
|
NCRKeys = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X')
|
|
NCRSigs = Xlate('WO_MAT', WOMatKey, 'NCR_FINAL_SIG', 'X')
|
|
If NCRKeys NE '' then
|
|
NotApplicable = False$
|
|
NumKeys = DCount(NCRKeys, @VM)
|
|
For each NCRNo in NCRKeys using @VM setting vPos
|
|
Sig = Xlate('NCR', NCRNo, 'AUTH_REJ_SIG', 'X')
|
|
If Sig NE '' then NumSigs += 1
|
|
Error = False$
|
|
ReqFields = 'SHIFT,DEPT,DEPT_RESP,LOSS_CODE,LOSS_COMMENTS,CONTAIN_ACTIONS,LOSS_STAGE,LOSS_BY'
|
|
For each ReqField in ReqFields using ',' setting cPos
|
|
Val = Xlate('NCR', NCRNo, ReqField, 'X')
|
|
If Val EQ '' then Error = True$
|
|
Until Error
|
|
Next ReqField
|
|
If Error EQ False$ then NumData += 1
|
|
Next NCRNo
|
|
SigsComp = (NumKeys EQ NumSigs)
|
|
DataComp = (NumKeys EQ NumData)
|
|
end
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = NotApplicable
|
|
Case Stage EQ 'SAP_BATCH_ID'
|
|
// Verify SAP Batch ID is not null
|
|
SAPBatchNo = Xlate('WO_MAT', WOMatKey, 'SAP_BATCH_NO', 'X')
|
|
DataComp = (SapBatchNo NE '')
|
|
SigsComp = DataComp
|
|
StageSummary<SS_DATA$> = DataComp
|
|
StageSummary<SS_SIG$> = SigsComp
|
|
StageSummary<SS_PASS$> = (DataComp and SigsComp)
|
|
StageSummary<SS_NA$> = False$
|
|
Case Otherwise$
|
|
// Check stage signature to determine if it is complete.
|
|
StageComplete = True$
|
|
SigInfo = Signature_Services('GetSigInfo', WOMatKey, Stage, False$)
|
|
If Error_Services('NoError') then
|
|
Sig = SigInfo<1>
|
|
StageComplete = (Sig NE '')
|
|
end else
|
|
// Stage may not apply to this cassette
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
NotApplicable = (IndexC(ErrorMessage, 'signature profile', 1) GT 0)
|
|
If NotApplicable EQ True$ then StageComplete = 2
|
|
end
|
|
If StageComplete EQ 0 then Error = Stage:' not signed.'
|
|
End Case
|
|
end
|
|
|
|
Response = StageSummary
|
|
|
|
end service
|
|
|
|
|
|
Service GetCassSummary(WOMatKey)
|
|
|
|
CassSummary = ''
|
|
If RowExists('WO_MAT', WOMatKey) then
|
|
// Collect signature and metrology pass/fail data.
|
|
Stages = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST')
|
|
For each Stage in Stages using @FM setting fPos
|
|
StageSummary = Signature_Services('GetStageSummary', WOMatKey, Stage)
|
|
CassSummary<fPos, 1> = Stage
|
|
CassSummary<fPos, 2> = StageSummary<SS_PASS$>
|
|
CassSummary<fPos, 3> = StageSummary<SS_SIG$>
|
|
CassSummary<fPos, 4> = StageSummary<SS_DATA$>
|
|
CassSummary<fPos, 5> = StageSummary<SS_NA$>
|
|
Next Stage
|
|
end
|
|
Response = CassSummary
|
|
|
|
end service
|
|
|
|
|
|
Service GetStageIDs()
|
|
|
|
Response = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST')
|
|
|
|
end service
|
|
|
|
|
|
Service PostEpiSigReady(RDSNo)
|
|
|
|
ErrCode = ''
|
|
ErrorMessage = ''
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
Reactor = RDSRec<RDS_REACTOR$>
|
|
WOStep = 1
|
|
WOMatKey = WONo:'*':CassNo
|
|
ReprocessedMat = XLATE('WO_MAT', WOMatKey, 'REPROCESSED_MAT', 'X')
|
|
WOMatCurrStatus = obj_WO_Mat('CurrStatus', WOMatKey)
|
|
If (WOMatCurrStatus NE 'HOLD') then
|
|
Set_Status(0)
|
|
obj_WO_Mat('MQAComp', WOMatKey:@RM:WOStep:@RM:'UNLOAD')
|
|
If Not(Get_Status(ErrCode)) then
|
|
Response = True$
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
end
|
|
end else
|
|
ErrorMessage = 'Cassette is on hold and may not be signed off.'
|
|
end
|
|
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
|
|
|
end service
|
|
|
|
|
|
Service SignPostEpiStage(RDSNo, User, WMOKey)
|
|
|
|
ErrorMessage = ''
|
|
Begin Case
|
|
Case (User EQ '')
|
|
ErrorMessage = 'Error in ':Service:' service. Null User passed into service.'
|
|
Case ( (RDSNo NE '') and (WMOKey NE '') )
|
|
ErrorMessage = 'Error in ':Service:' service. RDSNo and WMOKey cannot both be passed in.'
|
|
Case ( (RDSNo NE '') and (WMOKey EQ '') )
|
|
// Sign RDS post-epi signature
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
WOMatKey = WONo:'*':CassNo
|
|
MakeupBox = Xlate('RDS', RDSNo, 'MAKEUP_BOX', 'X')
|
|
|
|
RawSigDt = Date()
|
|
RawSigTm = Time()
|
|
SigDt = OConv(Date(), 'D2/')
|
|
SigTm = Time()
|
|
SigTmPlusOne = OConv(SigTm + 1, 'MTS')
|
|
SigTmPlusTwo = OConv(SigTm + 2, 'MTS')
|
|
SigTmPlusFive = OConv(SigTm + 5, 'MTS')
|
|
SigTmPlusTen = OConv(SigTm + 10, 'MTS')
|
|
SigTm = OConv(SigTm,'MTS')
|
|
SigBy = User
|
|
WOStep = 1
|
|
EventParms = ''
|
|
EventCnt = 1
|
|
|
|
ToolID = ''
|
|
WHCd = 'CR'
|
|
LocCD = 'QA'
|
|
Tag = ''
|
|
|
|
EventParms<COL$LOG_FILE> = 'WO_MAT'
|
|
EventParms<COL$LOG_DTM> = SigDt:' ':SigTm
|
|
EventParms<COL$ACTION> = WOStep:'POST'
|
|
EventParms<COL$WH_CD> = 'CR'
|
|
EventParms<COL$LOC_CD> = 'POST'
|
|
EventParms<COL$WO_NOS> = WONo
|
|
EventParms<COL$CASS_NOS> = CassNo
|
|
EventParms<COL$USER_ID> = User
|
|
EventParms<COL$TAGS> = ''
|
|
EventParms<COL$TOOL_ID> = ''
|
|
|
|
CONVERT @FM TO @RM IN EventParms
|
|
|
|
obj_WO_Mat_Log('Create', EventParms)
|
|
|
|
IF Get_Status(ErrCode) THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
END
|
|
|
|
If ErrorMessage EQ '' then
|
|
IF MakeupBox EQ True$ THEN
|
|
|
|
EventParms<COL$LOG_FILE> = 'WO_MAT'
|
|
EventParms<COL$LOG_DTM> = SigDt:' ':SigTmPlusTwo
|
|
EventParms<COL$ACTION> = 'RTU'
|
|
EventParms<COL$WH_CD> = 'CR'
|
|
EventParms<COL$LOC_CD> = 'MU'
|
|
EventParms<COL$WO_NOS> = WONo
|
|
EventParms<COL$CASS_NOS> = CassNo
|
|
EventParms<COL$USER_ID> = User
|
|
EventParms<COL$TAGS> = ''
|
|
EventParms<COL$TOOL_ID> = ''
|
|
|
|
CONVERT @FM TO @RM IN EventParms
|
|
|
|
obj_WO_Mat_Log('Create', EventParms) ;* * * * * INV EVENT LOG * * * * *
|
|
|
|
IF Get_Status(ErrCode) THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
END
|
|
END
|
|
|
|
If ErrorMessage EQ '' then
|
|
RDSRec<RDS_POST_EPI_SIG$> = User
|
|
RDSRec<RDS_POST_EPI_SIG_DATE$> = IConv(SigDt, 'D')
|
|
RDSRec<RDS_POST_EPI_SIG_TIME$> = IConv(SigTm, 'MT') + 1
|
|
Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, False$)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end
|
|
|
|
Case ( (RDSNo EQ '') and (WMOKey NE '') )
|
|
// Sign WM_OUT post-epi signature
|
|
WMORec = Database_Services('ReadDataRow', 'WM_OUT', WMOKey)
|
|
If Error_Services('NoError') then
|
|
WMORec<WM_OUT_POST_EPI_SIG$> = User
|
|
WMORec<WM_OUT_POST_EPI_SIG_DTM$> = Datetime()
|
|
Database_Services('WriteDataRow', 'WM_OUT', WMOKey, WMORec, True$, False$, True$)
|
|
end
|
|
End Case
|
|
|
|
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
|
|
|
end service
|
|
|
|
|
|
Service QASigReady(RDSNo)
|
|
|
|
ErrCode = ''
|
|
ErrorMessage = ''
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
Reactor = RDSRec<RDS_REACTOR$>
|
|
WOStep = 1
|
|
WOMatKey = WONo:'*':CassNo
|
|
ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X')
|
|
|
|
|
|
******************************************
|
|
* Verify if the Post-EPI has been signed *
|
|
******************************************
|
|
PostEpiSig = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X')
|
|
IF (PostEpiSig = '') THEN
|
|
ErrorMessage = 'Process Error':@SVM:'Technician Signature Required before Final QA Verification.'
|
|
END
|
|
|
|
If ErrorMessage EQ '' then
|
|
IF Not(MemberOf(@USER4,'BYPASS')) THEN
|
|
IF (PostEpiSig EQ @USER4) THEN
|
|
ErrorMessage = 'User ':QUOTE(PostEpiSig):' has signed this RDS for Post-Epi.'
|
|
ErrorMessage := 'Another qualified user must sign FQA verification'
|
|
END
|
|
END
|
|
end
|
|
|
|
***************************************
|
|
* Verify Metrology has been completed *
|
|
***************************************
|
|
If ErrorMessage EQ '' then
|
|
Set_Status(0)
|
|
obj_WO_Mat('MQAComp',WONo:'*':CassNo:@RM:WOStep:@RM:'QA')
|
|
ErrCode = ''
|
|
IF Get_Status(ErrCode) THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
END
|
|
end
|
|
|
|
***********************************************
|
|
* Verify RDS_TEST record has measurement data *
|
|
***********************************************
|
|
If ErrorMessage EQ '' then
|
|
ThickAvg = Xlate('RDS', RDSNo, 'TTHICK_AVG_ALL', 'X')
|
|
If ThickAvg EQ '' then
|
|
ErrorMessage = 'RDS metrology measurement data is missing. FQA cannot be signed.'
|
|
end
|
|
ResAvg = Xlate('RDS', RDSNo, 'TRES_AVG_ALL', 'X')
|
|
If ResAvg EQ '' then
|
|
ErrorMessage = 'RDS Resistivity measurement data is missing. FQA cannot be signed.'
|
|
Recipients = XLATE('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X')
|
|
SentFrom = 'OI Admin'
|
|
Subject = 'Missing Resistivity Avg data'
|
|
Message = RDSNo: ' failed FQA due to missing resistivity average data.'
|
|
AttachWindow = ''
|
|
AttachKey = ''
|
|
SendToGroup = ''
|
|
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
|
|
obj_Notes('Create',Parms)
|
|
end
|
|
end
|
|
|
|
************************************************
|
|
* Verify Signatures Profile has been fulfilled *
|
|
************************************************
|
|
If ErrorMessage EQ '' then
|
|
Signature_Services('CheckSigOrder', WOMatKey, 'QA')
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
Signature_Services('FQAReady', WOMatKey)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
|
|
WafersOut = Xlate('RDS', RDSNo, 'WFRS_OUT', 'X')
|
|
**********************************************
|
|
* Verify the FlatFinder information *
|
|
**********************************************
|
|
If ErrorMessage EQ '' then
|
|
EpiPartNo = Xlate('RDS', RDSNo, 'EPI_PART_NO', 'X')
|
|
WaferSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X')
|
|
WaferSizeInch = Field(WaferSize, ' ', 3, 1)
|
|
CustNo = Xlate('RDS', RDSNo, 'CUST_NO', 'X')
|
|
CompanyRow = Xlate('COMPANY', CustNo, '', 'X')
|
|
WaferFlatSizeInches = CompanyRow<COMPANY_WAFER_FLAT_WAFER_SIZE_INCH$>
|
|
WaferFlatLengthMins = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MIN$>, 'MD1')
|
|
WaferFlatLengthMaxes = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MAX$>, 'MD1')
|
|
Locate 6 in WaferFlatSizeInches using @VM setting vPos then
|
|
WaferFlatLengthMin = WaferFlatLengthMins<0, vPos>
|
|
WaferFlatLengthMax = WaferFlatLengthMaxes<0, vPos>
|
|
end else
|
|
WaferFlatLengthMin = ''
|
|
WaferFlatLengthMax = ''
|
|
end
|
|
WafersOut = Xlate('RDS', RDSNo, 'WFRS_OUT', 'X')
|
|
|
|
// Get FlatFinder Read Value
|
|
* FlatFinderWafersQty = RDSRec<RDS_FLATFINDER_WAFER_CNT$>
|
|
FlatFinderWaferLength = RDSRec<RDS_FLATFINDER_FLAT_LENGTH$>
|
|
|
|
|
|
If (WaferSizeInch EQ 6) then
|
|
****************************************
|
|
* FlatFinder - Wafers Quantity Section *
|
|
****************************************
|
|
* If (FlatFinderWafersQty NE '') then
|
|
* If (FlatFinderWafersQty NE WafersOut) then
|
|
* ErrMsg('Unable to sign FQA because Flat Finder and Wafers Out quantities do not match.')
|
|
* RETURN 0
|
|
* end
|
|
* end else
|
|
* ErrMsg('Unable to sign FQA because the Flat Finder quantity is missing.')
|
|
* RETURN 0
|
|
* end
|
|
************************************
|
|
* FlatFinder - Flat Length Section *
|
|
************************************
|
|
If (WaferFlatLengthMin NE '') AND (WaferFlatLengthMax NE '') then
|
|
If (FlatFinderWaferLength NE '') then
|
|
If (FlatFinderWaferLength GE WaferFlatLengthMin) AND (FlatFinderWaferLength LE WaferFlatLengthMax) then
|
|
end else
|
|
ErrMsg('Unable to sign FQA because Flat Finder wafer lengths are out of bounds.')
|
|
RETURN 0
|
|
end
|
|
end else
|
|
ErrMsg('Unable to sign FQA because the Flat Finder wafer length is missing.')
|
|
RETURN 0
|
|
end
|
|
end
|
|
end
|
|
|
|
Begin Case
|
|
|
|
Case WaferSizeInch = '6'
|
|
|
|
WaferFlatSizeInches = CompanyRow<COMPANY_WAFER_FLAT_WAFER_SIZE_INCH$>
|
|
WaferFlatLengthMins = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MIN$>, 'MD1')
|
|
WaferFlatLengthMaxes = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MAX$>, 'MD1')
|
|
|
|
Locate WaferSizeInch in WaferFlatSizeInches using @VM setting vPos then
|
|
WaferFlatLengthMin = WaferFlatLengthMins<0, vPos>
|
|
WaferFlatLengthMax = WaferFlatLengthMaxes<0, vPos>
|
|
end else
|
|
WaferFlatLengthMin = ''
|
|
WaferFlatLengthMax = ''
|
|
end
|
|
|
|
***************************************
|
|
* FlatFinder - Wafers Quatity Section *
|
|
***************************************
|
|
* If (FlatFinderWafersQty NE '') then
|
|
* If (FlatFinderWafersQty NE WafersOut) then
|
|
* ErrorMessage = 'Unable to sign FQA because Flat Finder and Wafers Out quantities do not match.'
|
|
* end
|
|
* end else
|
|
* ErrorMessage = 'Unable to sign FQA because the Flat Finder quantity is missing.'
|
|
* end
|
|
************************************
|
|
* FlatFinder - Flat Length Section *
|
|
************************************
|
|
If (WaferFlatLengthMin NE '') AND (WaferFlatLengthMax NE '') then
|
|
If (FlatFinderWaferLength NE '') then
|
|
If (FlatFinderWaferLength GE WaferFlatLengthMin) AND (FlatFinderWaferLength LE WaferFlatLengthMax) then
|
|
end else
|
|
ErrorMessage = 'Unable to sign FQA because Flat Finder wafer lengths are out of bounds.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to sign FQA because the Flat Finder wafer length is missing.'
|
|
end
|
|
end
|
|
|
|
Case WaferSizeInch = '8'
|
|
|
|
// Get NotchFinder Read Value
|
|
* NotchFinderWafersQty = FlatFinderWafersQty
|
|
|
|
***************************************
|
|
* NotchFinder - Wafers Quatity Section *
|
|
***************************************
|
|
* If (NotchFinderWafersQty NE '') then
|
|
* If (NotchFinderWafersQty NE WafersOut) then
|
|
* ErrorMsg = 'Unable to sign FQA because Notch Finder and Wafers Out quantities do not match.'
|
|
* Error_Services('Add', ErrorMsg)
|
|
* return
|
|
* end
|
|
* end else
|
|
* ErrorMsg = 'Unable to sign FQA because the Notch Finder quantity is missing.'
|
|
* Error_Services('Add', ErrorMsg)
|
|
* return
|
|
* end
|
|
|
|
Case Otherwise$
|
|
End Case
|
|
end
|
|
|
|
|
|
*************************
|
|
* Verify Wafer Quantity *
|
|
*************************
|
|
If ErrorMessage EQ '' then
|
|
CassSchedWafers = Xlate('RDS', RDSNo, 'WAFERS_SCHEDULED', 'X')
|
|
|
|
If CassSchedWafers NE WafersOut then
|
|
|
|
Message = 'Unable to sign FQA because the Scheduled' : CRLF$ : 'Qty does not equal the '
|
|
Message := 'Wafers Out Qty.' : CRLF$ : 'Lead or supervisor must override.'
|
|
LeadMessage = 'Scheduled Wafers Quantity does not equal the Wafers Out Quantity.'
|
|
|
|
If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
|
|
end else
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
|
|
end
|
|
|
|
Begin Case
|
|
Case Response EQ 1
|
|
Response = True$ ; // User Clicked Override
|
|
Case Response EQ 2
|
|
Response = False$ ; // User Clicked Cancel
|
|
Case Response EQ char(27)
|
|
Response = False$ ; // User Pressed Escape Key
|
|
End Case
|
|
|
|
If Response EQ True$ then
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : 'LEAD' : @VM : 'SUPERVISOR')
|
|
Valid = Response<1>
|
|
Username = Response<2>
|
|
If Valid then
|
|
RDSRec<RDS_WAFER_OUT_SIG$> = Username
|
|
RDSRec<RDS_WAFER_OUT_DATE$> = Date()
|
|
RDSRec<RDS_WAFER_OUT_TIME$> = Time()
|
|
Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to sign FQA because the Scheduled' : CRLF$ : 'Qty does not equal the '
|
|
ErrorMessage := 'Wafers Out Qty.' : CRLF$ : 'Lead or supervisor must override.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to sign FQA because the Scheduled' : CRLF$ : 'Qty does not equal the '
|
|
ErrorMessage := 'Wafers Out Qty.' : CRLF$ : 'Lead or supervisor must override.'
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
*********************************
|
|
* Verify NCR total >= USL Fails *
|
|
*********************************
|
|
If ErrorMessage EQ '' then
|
|
ROTREnabled = Xlate('REACTOR', Reactor, 'ENABLE_ROTR', 'X')
|
|
If (ROTREnabled EQ True$) then
|
|
LWICIKey = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
NumUSLFailValues = Xlate('CLEAN_INSP', LWICIKey, 'NUM_FAILED_WAFERS', 'X')
|
|
NumUSLFailCount = COUNT(NumUSLFailValues,@VM) + (NumUSLFailValues NE '')
|
|
NumUSLFail = NumUSLFailValues<1,NumUSLFailCount>
|
|
If NumUSLFail EQ '' then NumUSLFail = 0
|
|
TotalNCR = Xlate('RDS', RDSNo, 'TOT_REJ', 'X')
|
|
If TotalNCR EQ '' then TotalNCR = 0
|
|
|
|
If NumUSLFail GT TotalNCR then
|
|
Message = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '|
|
|
: 'number of wafers above the USL threshold.' : CRLF$ : 'A lead or supervisor must override.'
|
|
LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers above the USL threshold.'
|
|
|
|
If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
|
|
end else
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
|
|
end
|
|
|
|
Begin Case
|
|
Case Response EQ 1
|
|
Response = True$ ; // User Clicked Override
|
|
Case Response EQ 2
|
|
Response = False$ ; // User Clicked Cancel
|
|
Case Response EQ char(27)
|
|
Response = False$ ; // User Pressed Escape Key
|
|
End Case
|
|
|
|
If Response EQ True$ then
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR':@VM:'ENGINEER')
|
|
Valid = Response<1>
|
|
If NOT(Valid) then
|
|
ErrorMessage = Message
|
|
end
|
|
end else
|
|
ErrorMessage = Message
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
********************************************
|
|
* Verify NCR wafer qty >= Failed wafer qty *
|
|
********************************************
|
|
If ErrorMessage EQ '' then
|
|
NCRReq = QA_Services('GetNCRRequired', WOMatKey)
|
|
If NCRReq then
|
|
Message = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '|
|
|
: 'number of wafers that failed surfscan.' : CRLF$ : 'A lead or supervisor must override.'
|
|
LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers that failed surfscan.'
|
|
|
|
If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
|
|
end else
|
|
Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
|
|
end
|
|
|
|
Begin Case
|
|
Case Response EQ 1
|
|
Response = True$ ; // User Clicked Override
|
|
Case Response EQ 2
|
|
Response = False$ ; // User Clicked Cancel
|
|
Case Response EQ char(27)
|
|
Response = False$ ; // User Pressed Escape Key
|
|
End Case
|
|
|
|
If Response EQ True$ then
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR':@VM:'ENGINEER')
|
|
Valid = Response<1>
|
|
If NOT(Valid) then
|
|
ErrorMessage = Message
|
|
end
|
|
end else
|
|
ErrorMessage = Message
|
|
end
|
|
end
|
|
end
|
|
|
|
*************************
|
|
* Verify if Shift exist *
|
|
*************************
|
|
If ErrorMessage EQ '' then
|
|
Shift = RDSRec<RDS_SHIFT$>
|
|
IF Shift EQ '' THEN
|
|
ErrorMessage = 'Error in ':Service:' servce. Shift is required before signing.'
|
|
END
|
|
end
|
|
|
|
****************************
|
|
* Verify if lot is on Hold *
|
|
****************************
|
|
If ErrorMessage EQ '' then
|
|
WOMatCurrStatus = obj_WO_Mat('CurrStatus', WOMatKey)
|
|
IF WOMatCurrStatus EQ 'HOLD' THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Cassette is on Hold and may not be signed off.'
|
|
END
|
|
end
|
|
|
|
**********************
|
|
* Check ROTR Failure *
|
|
**********************
|
|
If ErrorMessage EQ '' then
|
|
ROTRAction = Xlate('RDS', RDSNo, 'ROTR_ACTION', 'X')
|
|
If (ROTRAction NE 'P') AND (ROTRAction NE 'A') AND (ROTRAction NE '') then
|
|
ErrorMessage = 'Error in ':Service:' service. ROTR does not meet all requirements.'
|
|
end
|
|
end
|
|
|
|
***************************************
|
|
* Verify Metrology has been completed *
|
|
***************************************
|
|
If ErrorMessage EQ '' then
|
|
QAMetTests = Xlate('RDS', RDSNo, 'MET_TEST_QA', 'X')
|
|
If QAMetTests NE '' then
|
|
QAMetMins = Xlate('RDS', RDSNo, 'MET_MIN_QA', 'X')
|
|
QAMetMaxes = Xlate('RDS', RDSNo, 'MET_MAX_QA', 'X')
|
|
QAMetResults = Xlate('RDS', RDSNo, 'MET_RESULT_QA', 'X')
|
|
QAMetSigs = Xlate('RDS', RDSNo, 'MET_SIG_QA', 'X')
|
|
For each QAMetTest in QAMetTests using @VM setting vPos
|
|
QAMetMin = QAMetMins<0, vPos>
|
|
QAMetMax = QAMetMaxes<0, vPos>
|
|
QAMetResult = QAMetResults<0, vPos>
|
|
QAMetSig = QAMetSigs<0, vPos>
|
|
If QAMetTest NE '' then
|
|
Begin Case
|
|
Case ( (QAMetMin EQ '') and (QAMetMax EQ '') )
|
|
Null
|
|
Case (QAMetResult EQ '')
|
|
ErrorMessage = 'Error in ':Service:' service. Required QA Metrology results have not been entered.'
|
|
Case ( (QAMetResult LT QAMetMin) or (QAMetResult GT QAMetMax) )
|
|
ErrorMessage = 'Error in ':Service:' service. One or more QA Metrology results is out of specification.'
|
|
Case ( (QAMetResult NE '') and (QAMetSig EQ '') )
|
|
ErrorMessage = 'Error in ':Service:' service. One or more QA Metrology results are not signed off.'
|
|
End Case
|
|
end
|
|
Next QAMetTest
|
|
end
|
|
end
|
|
|
|
******************************************
|
|
* Verify Unload Stage QA Metrology Tests *
|
|
******************************************
|
|
If ErrorMessage EQ '' then
|
|
DevelopmentFlag = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X')
|
|
If (DevelopmentFlag EQ True$) then
|
|
WOMatQAKey = WOMatKey
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
|
|
OutOfSpec = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$>
|
|
OutOfSpec = Sum(OutOfSpec)
|
|
If OutOfSpec GT 0 then
|
|
FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$>
|
|
ErrorMessage = 'Error in ':Service:' service. '
|
|
For each FailReason in FailReasons using @VM
|
|
ErrorMessage := FailReason:' '
|
|
Next FailReason
|
|
end
|
|
end
|
|
end
|
|
|
|
************************************************************************
|
|
* Prompt user to validate the Process Specification Stage Instructions *
|
|
************************************************************************
|
|
If ErrorMessage EQ '' then
|
|
PSNo = RDSRec<RDS_PROD_SPEC_ID$>
|
|
VerInst = Xlate('PRS_STAGE', PSNo:'*QA', 'INST', 'X')
|
|
VerInst = Trim(VerInst)
|
|
IF LEN(VerInst) > 5 THEN
|
|
Yes = Dialog_Box( 'RDS_VER', @WINDOW, VerInst )
|
|
IF NOT(Yes) THEN
|
|
ErrorMessage = 'Error in ':Service:'. PRS_STAGE instructions must be accepted.'
|
|
END
|
|
END
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Response = False$
|
|
Error_Services('Add', ErrorMessage)
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignQAStage(RDSNo, User)
|
|
|
|
ErrorMessage = ''
|
|
If RDSNo NE '' then
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
WOMatKey = WONo:'*':CassNo
|
|
MakeupBox = Xlate('RDS', RDSNo, 'MAKEUP_BOX', 'X')
|
|
|
|
RawSigDt = Date()
|
|
RawSigTm = Time()
|
|
SigDt = OConv(Date(), 'D2/')
|
|
SigTm = Time()
|
|
SigTmPlusOne = OConv(SigTm + 1, 'MTS')
|
|
SigTmPlusTwo = OConv(SigTm + 2, 'MTS')
|
|
SigTmPlusFive = OConv(SigTm + 5, 'MTS')
|
|
SigTmPlusTen = OConv(SigTm + 10, 'MTS')
|
|
SigTm = OConv(SigTm,'MTS')
|
|
SigBy = User
|
|
WOStep = 1
|
|
EventParms = ''
|
|
EventCnt = 1
|
|
|
|
ToolID = ''
|
|
WHCd = 'CR'
|
|
LocCD = 'QA'
|
|
Tag = ''
|
|
|
|
EventParms<COL$LOG_FILE> = 'WO_MAT'
|
|
EventParms<COL$LOG_DTM> = SigDt:' ':SigTm
|
|
EventParms<COL$ACTION> = WOStep:'QA'
|
|
EventParms<COL$WH_CD> = 'CR'
|
|
EventParms<COL$LOC_CD> = 'QA'
|
|
EventParms<COL$WO_NOS> = WONo
|
|
EventParms<COL$CASS_NOS> = CassNo
|
|
EventParms<COL$USER_ID> = User
|
|
EventParms<COL$TAGS> = ''
|
|
EventParms<COL$TOOL_ID> = ''
|
|
|
|
CONVERT @FM TO @RM IN EventParms
|
|
|
|
obj_WO_Mat_Log('Create', EventParms)
|
|
|
|
IF Get_Status(ErrCode) THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
END
|
|
|
|
If ErrorMessage EQ '' then
|
|
IF MakeupBox EQ True$ THEN
|
|
|
|
EventParms<COL$LOG_FILE> = 'WO_MAT'
|
|
EventParms<COL$LOG_DTM> = SigDt:' ':SigTmPlusTwo
|
|
EventParms<COL$ACTION> = 'RTU'
|
|
EventParms<COL$WH_CD> = 'CR'
|
|
EventParms<COL$LOC_CD> = 'MU'
|
|
EventParms<COL$WO_NOS> = WONo
|
|
EventParms<COL$CASS_NOS> = CassNo
|
|
EventParms<COL$USER_ID> = User
|
|
EventParms<COL$TAGS> = ''
|
|
EventParms<COL$TOOL_ID> = ''
|
|
|
|
CONVERT @FM TO @RM IN EventParms
|
|
|
|
obj_WO_Mat_Log('Create', EventParms) ;* * * * * INV EVENT LOG * * * * *
|
|
|
|
IF Get_Status(ErrCode) THEN
|
|
ErrorMessage = 'Error in ':Service:' service. Error code: ':ErrCode
|
|
END
|
|
END
|
|
|
|
If ErrorMessage EQ '' then
|
|
RDSRec<RDS_SUP_VER_SIG$> = User
|
|
RDSRec<RDS_SUP_VER_SIG_DATE$> = IConv(SigDt, 'D')
|
|
RDSRec<RDS_SUP_VER_SIG_TIME$> = IConv(SigTm, 'MT') + 1
|
|
Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, False$)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
|
|
|
end service
|
|
|
|
|
|
Service CleanInspSigReady(RDSNo, Stage)
|
|
|
|
ErrorMessage = ''
|
|
If ( (RDSNo NE '') and (Stage NE '') ) then
|
|
WONo = Xlate('RDS', RDSNo, 'WO', 'X')
|
|
CassNo = Xlate('RDS', RDSNo, 'CASS_NO', 'X')
|
|
WOMatKey = WONo:'*':CassNo
|
|
Signature_Services('CheckSigOrder', WOMatKey, Stage)
|
|
If Error_Services('HasError') then ErrorMessage = Error_Services('GetMessage')
|
|
Begin Case
|
|
Case ( (Stage EQ 'PREI') or (Stage EQ 'PREC') or (Stage EQ 'PRES') )
|
|
CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
Case ( (Stage EQ 'FWII') or (Stage EQ 'FWIC') or (Stage EQ 'FWIS') )
|
|
CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
Case ( (Stage EQ 'LWII') or (Stage EQ 'LWIC') or (Stage EQ 'LWIS') )
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
Case ( (Stage EQ 'PSTI') or (Stage EQ 'PSTC') or (Stage EQ 'PSTS') )
|
|
CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
Case Otherwise$
|
|
ErrorMessage = 'Error in ':Service:' service. Invalid stage ID passed into service.'
|
|
End Case
|
|
If ErrorMessage EQ '' then
|
|
If RowExists('CLEAN_INSP', CINo) then
|
|
CIRow = Database_Services('ReadDataRow', 'CLEAN_INSP', CINo)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No ':Stage:' record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end
|
|
Begin Case
|
|
Case ErrorMessage NE ''
|
|
Null
|
|
Case ( (Stage EQ 'PREI') or (Stage EQ 'FWII') or (Stage EQ 'LWII') or (Stage EQ 'PSTI') )
|
|
// Verify each inspection row has data.
|
|
// Front side data
|
|
InspTools = CIRow<CLEAN_INSP_INSP_TOOL$>
|
|
InspLPDs = CIRow<CLEAN_INSP_INSP_LPD$>
|
|
InspScratches = CIRow<CLEAN_INSP_INSP_SCRATCHES$>
|
|
InspScratchLengths = CIRow<CLEAN_INSP_INSP_SCRATCH_LEN$>
|
|
InspPits = CIRow<CLEAN_INSP_INSP_PITS$>
|
|
InspMounds = CIRow<CLEAN_INSP_INSP_MOUNDS$>
|
|
InspStackFaults = CIRow<CLEAN_INSP_INSP_STACK_FAULTS$>
|
|
InspSpikes = CIRow<CLEAN_INSP_INSP_SPIKES$>
|
|
InspSpots = CIRow<CLEAN_INSP_INSP_SPOTS$>
|
|
InspFOVs = CIRow<CLEAN_INSP_INSP_FOV$>
|
|
InspBLDefects = CIRow<CLEAN_INSP_INSP_BL_DEFECTS$>
|
|
InspSigs = CIRow<CLEAN_INSP_INSP_SIG$>
|
|
InspSigDTMs = CIRow<CLEAN_INSP_INSP_SIG_DTM$>
|
|
// Front side specs
|
|
SpecLPD = CIRow<CLEAN_INSP_SPEC_LPD$>
|
|
SpecScratches = CIRow<CLEAN_INSP_SPEC_SCRATCHES$>
|
|
SpecScratchLen = CIRow<CLEAN_INSP_SPEC_SCRATCH_LEN$>
|
|
SpecPits = CIRow<CLEAN_INSP_SPEC_PITS$>
|
|
SpecMounds = CIRow<CLEAN_INSP_SPEC_MOUNDS$>
|
|
SpecStackFaults = CIRow<CLEAN_INSP_SPEC_STACK_FAULTS$>
|
|
SpecSpikes = CIRow<CLEAN_INSP_SPEC_SPIKES$>
|
|
SpecSpots = CIRow<CLEAN_INSP_SPEC_SPOTS$>
|
|
SpecFOV = CIRow<CLEAN_INSP_SPEC_FOV$>
|
|
SpecBLDefects = CIRow<CLEAN_INSP_SPEC_BL_DEFECTS$>
|
|
// Backside data
|
|
InspBsideScratches = CIRow<CLEAN_INSP_INSP_BSIDE_SCRATCHES$>
|
|
InspBsideScratchLen = CIRow<CLEAN_INSP_INSP_BSIDE_SCRATCH_LEN$>
|
|
InspBsideNodules = CIRow<CLEAN_INSP_INSP_BSIDE_NODULES$>
|
|
InspBsideSpikes = CIRow<CLEAN_INSP_INSP_BSIDE_SPIKES$>
|
|
// Backside specs
|
|
SpecBsideScratches = CIRow<CLEAN_INSP_SPEC_BSIDE_SCRATCHES$>
|
|
SpecBsideScratchLen = CIRow<CLEAN_INSP_SPEC_BSIDE_SCRATCH_LEN$>
|
|
SpecBsideNodules = CIRow<CLEAN_INSP_SPEC_BSIDE_NODULES$>
|
|
SpecBsideSpikes = CIRow<CLEAN_INSP_SPEC_BSIDE_SPIKES$>
|
|
// Verify front side and back side data
|
|
NumRows = DCount(InspTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
RowLPD = InspLPDs<0, RowIndex>
|
|
RowScratches = InspScratches<0, RowIndex>
|
|
RowScratchLen = InspScratchLengths<0, RowIndex>
|
|
RowPits = InspPits<0, RowIndex>
|
|
RowMounds = InspMounds<0, RowIndex>
|
|
RowStackFaults = InspStackFaults<0, RowIndex>
|
|
RowSpikes = InspSpikes<0, RowIndex>
|
|
RowSpots = InspSpots<0, RowIndex>
|
|
RowFOV = InspFOVs<0, RowIndex>
|
|
RowBLDefects = InspBLDefects<0, RowIndex>
|
|
RowBsideScratches = InspBsideScratches<0, RowIndex>
|
|
RowBsideScratchLen = InspBsideScratchLen<0, RowIndex>
|
|
RowBsideNodules = InspBsideNodules<0, RowIndex>
|
|
RowBsideSpikes = InspBsideSpikes<0, RowIndex>
|
|
If ( (SpecLPD NE '') and (RowLPD EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection LPD data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecScratches NE '') and (RowScratches EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection scratches data is missing.'
|
|
end
|
|
If ( ( ErrorMessage EQ '') and (SpecScratchLen NE '') and (RowScratchLen EQ '' ) ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection scratches data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecPits NE '') and (RowPits EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection pits data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecMounds NE '') and (RowMounds EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection mounds data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecStackFaults NE '') and (RowStackFaults EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection stack faults data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecSpikes NE '') and (RowSpikes EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection spikes data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecSpots NE '') and (RowSpots EQ '' ) ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection spots data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecFOV NE '') and (RowFOV EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection FOV data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecBLDefects NE '') and (RowBLDefects EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection BL defects data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecBsideScratches NE '') and (RowBsideScratches EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection back side scratches data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecBsideScratchLen NE '') and (RowBsideScratchLen EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection back side scratch length data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecBsideNodules NE '') and (RowBsideNodules EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection back side nodules data is missing.'
|
|
end
|
|
If ( (ErrorMessage EQ '') and (SpecBsideSpikes NE '') and (RowBsideSpikes EQ '') ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Inspection back side spikes data is missing.'
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
|
|
Case ( (Stage EQ 'PREC') or (Stage EQ 'FWIC') or (Stage EQ 'LWIC') or (Stage EQ 'PSTC') )
|
|
// Verify each cleans row has a tool.
|
|
CleanTools = CIRow<CLEAN_INSP_CLEAN_TOOL$>
|
|
NumRows = DCount(CleanTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
RowTool = CleanTools<0, RowIndex>
|
|
If RowTool EQ '' then
|
|
ErrorMessage = 'Error in ':Service:' service. Clean tool ID is missing.'
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
Case ( (Stage EQ 'PRES') or (Stage EQ 'FWIS') or (Stage EQ 'LWIS') or (Stage EQ 'PSTS') )
|
|
// Verify surfscan row has a tool.
|
|
ScanTools = CIRow<CLEAN_INSP_SCAN_TOOL$>
|
|
NumRows = DCount(ScanTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
RowTool = ScanTools<0, RowIndex>
|
|
If RowTool EQ '' then
|
|
ErrorMessage = 'Error in ':Service:' service. Scan tool ID is missing.'
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
End Case
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
Response = True$
|
|
end else
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignCleanInsp(RDSNo, Stage=CI_STAGES, User)
|
|
|
|
ErrorMessage = ''
|
|
If ( (RDSNo NE '') and (Stage NE '') and (User NE '') ) then
|
|
SigDTM = Datetime()
|
|
WONo = Xlate('RDS', RDSNo, 'WO', 'X')
|
|
CassNo = Xlate('RDS', RDSNo, 'CASS_NO', 'X')
|
|
WOMatKey = WONo:'*':CassNo
|
|
Begin Case
|
|
Case ( (Stage EQ 'PREI') or (Stage EQ 'PREC') or (Stage EQ 'PRES') )
|
|
CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
|
|
Case ( (Stage EQ 'FWII') or (Stage EQ 'FWIC') or (Stage EQ 'FWIS') )
|
|
CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
|
|
Case ( (Stage EQ 'LWII') or (Stage EQ 'LWIC') or (Stage EQ 'LWIS') )
|
|
CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
Case ( (Stage EQ 'PSTI') or (Stage EQ 'PSTC') or (Stage EQ 'PSTS') )
|
|
CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
|
|
Case Otherwise$
|
|
ErrorMessage = 'Error in ':Service:' service. Invalid stage ID passed into service.'
|
|
End Case
|
|
If ErrorMessage EQ '' then
|
|
If RowExists('CLEAN_INSP', CINo) then
|
|
CIRow = Database_Services('ReadDataRow', 'CLEAN_INSP', CINo)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end else
|
|
OrigCIRow = CIRow
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No ':Stage:' record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end
|
|
Begin Case
|
|
Case ErrorMessage NE ''
|
|
Null
|
|
Case ( (Stage EQ 'PREI') or (Stage EQ 'FWII') or (Stage EQ 'LWII') or (Stage EQ 'PSTI') )
|
|
InspTools = CIRow<CLEAN_INSP_INSP_TOOL$>
|
|
InspSigs = CIRow<CLEAN_INSP_INSP_SIG$>
|
|
InspSigDTMs = CIRow<CLEAN_INSP_INSP_SIG_DTM$>
|
|
NumRows = DCount(InspTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
// Sign each row if no signature present
|
|
If InspSigs<0, RowIndex> EQ '' then
|
|
InspSigs<0, RowIndex> = User
|
|
InspSigDTMs<0, RowIndex> = SigDTM
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
CIRow<CLEAN_INSP_INSP_SIG$> = InspSigs
|
|
CIRow<CLEAN_INSP_INSP_SIG_DTM$> = InspSigDTMs
|
|
Case ( (Stage EQ 'PREC') or (Stage EQ 'FWIC') or (Stage EQ 'LWIC') or (Stage EQ 'PSTC') )
|
|
CleanTools = CIRow<CLEAN_INSP_CLEAN_TOOL$>
|
|
CleanSigs = CIRow<CLEAN_INSP_CLEAN_SIG$>
|
|
CleanSigDTMs = CIRow<CLEAN_INSP_CLEAN_SIG_DTM$>
|
|
NumRows = DCount(CleanTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
// Sign each row if no signature present
|
|
If CleanSigs<0, RowIndex> EQ '' then
|
|
CleanSigs<0, RowIndex> = User
|
|
CleanSigDTMs<0, RowIndex> = SigDTM
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
CIRow<CLEAN_INSP_CLEAN_SIG$> = CleanSigs
|
|
CIRow<CLEAN_INSP_CLEAN_SIG_DTM$> = CleanSigDTMs
|
|
Case ( (Stage EQ 'PRES') or (Stage EQ 'FWIS') or (Stage EQ 'LWIS') or (Stage EQ 'PSTS') )
|
|
ScanTools = CIRow<CLEAN_INSP_SCAN_TOOL$>
|
|
SurfSigs = CIRow<CLEAN_INSP_SCAN_SIG$>
|
|
SurfSigDTMs = CIRow<CLEAN_INSP_SCAN_SIG_DTM$>
|
|
NumRows = DCount(ScanTools, @VM)
|
|
If NumRows GT 0 then
|
|
For RowIndex = 1 to NumRows
|
|
// Sign each row if no signature present
|
|
If SurfSigs<0, RowIndex> EQ '' then
|
|
SurfSigs<0, RowIndex> = User
|
|
SurfSigDTMs<0, RowIndex> = SigDTM
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next RowIndex
|
|
end
|
|
CIRow<CLEAN_INSP_SCAN_SIG$> = SurfSigs
|
|
CIRow<CLEAN_INSP_SCAN_SIG_DTM$> = SurfSigDTMs
|
|
End Case
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo, user, or stage passed in.'
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
If CIRow NE OrigCIRow then Database_Services('WriteDataRow', 'CLEAN_INSP', CINo, CIRow)
|
|
If Error_Services('NoError') then
|
|
Response = True$
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end
|
|
end else
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service QAMetSigReady(RDSNo, QAStage=QA_STAGES, Slot=SLOTS, WOMatQAKey)
|
|
|
|
ErrorMessage = ''
|
|
If ( (RDSNo NE '' or WOMatQAKey NE '') and (QAStage NE '') and (Slot NE '') ) then
|
|
If RDSNo NE '' then
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
end else
|
|
WOMatKey = WOMatQAKey
|
|
end
|
|
If WOMatKey NE '' then
|
|
If RowExists('WO_MAT_QA', WOMatKey) then
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end else
|
|
WOMatQAStages = WOMatQARec<WO_MAT_QA_STAGE$>
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No WO_MAT_QA record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null WO_MAT_KEY returned for RDS ':RDSNo:'!'
|
|
end
|
|
Begin Case
|
|
Case ErrorMessage NE ''
|
|
Null
|
|
Case ( (QAStage EQ 'LOAD') or (QAStage EQ 'QA') or (QAStage EQ 'MO_QA') )
|
|
|
|
Done = False$
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
ReactorType = Xlate('WO_MAT', WOMatKey, 'REACTOR_TYPE', 'X')
|
|
TestSlots = WOMatQARec<WO_MAT_QA_SLOT$>
|
|
|
|
// Check for QA Stage Supplements
|
|
UnacknowledgedSupp = Supplement_Services('UnacknowledgedSupplementCheck', 'WO_MAT', WOMatKey, 'QA')
|
|
If UnacknowledgedSupp NE FALSE$ then
|
|
ErrorMessage = 'The QA stage supplements must be acknowledged before the load operation can be signed.'
|
|
end
|
|
|
|
If ReactorType EQ 'EPP' then
|
|
WMOKey = WOMatRec<WO_MAT_WMO_KEY$>
|
|
WMORec = Database_Services('ReadDataRow', 'WM_OUT', WMOKey)
|
|
MUWfrIDs = WOMatRec<WO_MAT_EPOS_REP_WAFER_ID$>
|
|
MUWfrResults = WMORec<WM_OUT_MU_WAFER_THK_RESULT$>
|
|
end else
|
|
MUWfrIDs = WOMatRec<WO_MAT_SLOT_REP_WAFER_ID$>
|
|
MUWfrResults = WOMatRec<WO_MAT_MU_WAFER_THK_RESULT$>
|
|
end
|
|
|
|
For each WOMatQAStage in WOMatQAStages using @VM setting vPos
|
|
TestSlot = TestSlots<0, vPos>
|
|
If ( (WOMatQAStage EQ QAStage) and (Slot EQ TestSlot) ) then
|
|
Done = True$
|
|
// Compare Met Result to Met Min and Met Max
|
|
TestProp = WOMatQARec<WO_MAT_QA_PROP$, vPos>
|
|
MetResult = WOMatQARec<WO_MAT_QA_RESULT$, vPos>
|
|
MetMin = WOMatQARec<WO_MAT_QA_MIN$, vPos>
|
|
MetMax = WOMatQARec<WO_MAT_QA_MAX$, vPos>
|
|
Begin Case
|
|
Case MetResult EQ ''
|
|
ErrorMessage = 'Error in ':Service:' service. Metrology result for stage ':QAStage:' slot ':Slot:' is missing.'
|
|
Case ( (MetResult LT MetMin) or (MetResult GT MetMax) )
|
|
ErrorMessage = 'Error in ':Service:' service. Metrology result is out of spec for stage ':QAStage:' slot ':Slot:'.'
|
|
End Case
|
|
// Compare Std Dev Result to Std Dev Max
|
|
StdDevResult = WOMatQARec<WO_MAT_QA_STD_RESULT$, vPos>
|
|
StdDevMax = WOMatQARec<WO_MAT_QA_STD_MAX$, vPos>
|
|
Begin Case
|
|
Case StdDevResult EQ ''
|
|
// Std Dev data is not always supplied.
|
|
Null
|
|
Case StdDevResult GT StdDevMax
|
|
ErrorMessage = 'Error in ':Service:' service. StdDev exceeds spec for stage ':QAStage:'.'
|
|
End Case
|
|
|
|
If TestProp EQ 'THICK' then
|
|
// Ensure makeup wafer thickness values are in spec and that at least one wafer
|
|
// from each makeup box has a thickness result.
|
|
|
|
// Build a list of unique makeup boxes
|
|
MUBoxes = ''
|
|
MUThickTests = ''
|
|
If MUWfrIDs NE '' then
|
|
For each MUWfrID in MUWfrIDs using @VM setting vPos
|
|
If MUWfrID NE '' then
|
|
MUBox = Field(MUWfrID, '.', 1, 2)
|
|
Locate MUBox in MUBoxes using @VM setting MUIndex else
|
|
MUBoxes<0, -1> = MUBox
|
|
end
|
|
end
|
|
Next MUWfrID
|
|
|
|
// Verify makeup wafers are also within spec
|
|
For each MUWfrID in MuWfrIDs using @VM setting vPos
|
|
If MUWfrID NE '' then
|
|
MUBox = Field(MUWfrID, '.', 1, 2)
|
|
MUWfrResult = MUWfrResults<0, vPos>
|
|
Locate MUBox in MUBoxes using @VM setting MUIndex then
|
|
MUThickTests<0, MUIndex> = True$
|
|
end
|
|
If MUWfrResult NE '' then
|
|
If ( (MUWfrResult LT MetMin) or (MUWfrResult GT MetMax) ) then
|
|
ErrorMessage = 'Error in ':Service:' service. Metrology result is out of spec for stage ':QAStage:' makeup wafer ID ':MUWfrID:'.'
|
|
end
|
|
end
|
|
end
|
|
Next MUWfrID
|
|
end
|
|
If MUBoxes NE '' then
|
|
// Verify each MU Box has at least one thickness result
|
|
For each MUBox in MUBoxes using @VM setting MUBoxIndex
|
|
If MUThickTests<0, MUBoxIndex> NE True$ then
|
|
ErrorMessage = 'Error in ':Service:' service. At least one metrology result is required for stage ':QAStage:' makeup box ID ':MUBox:'.'
|
|
end
|
|
Next MUBox
|
|
end
|
|
end
|
|
end
|
|
Until ( (ErrorMessage NE '') or (Done EQ True$) )
|
|
Next WOMatQAStage
|
|
Case QAStage EQ 'UNLOAD'
|
|
// Leverage fail reason column calculated by WO_MAT_QA_ACTIONS
|
|
For each WOMatQAStage in WOMatQAStages using @VM setting vPos
|
|
If WOMatQAStage EQ QAStage then
|
|
FailReason = WOMatQARec<WO_MAT_QA_FAIL_REASON$, vPos>
|
|
If ( (FailReason NE '') |
|
|
and (FailReason NE 'THICK_ONLY UNLOAD product measurement test has not been signed.') |
|
|
and (FailReason NE 'CRES UNLOAD product measurement test has not been signed.') |
|
|
and (FailReason NE 'UNLOAD LW_RHO product measurement test has not been signed.' ) ) then
|
|
ErrorMessage = 'Error in ':Service:' service. ':FailReason
|
|
end
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next WOMatQAStage
|
|
End Case
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo or stage passed in.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignQAMet(RDSNo, QAStage=QA_STAGES, User, Slot=SLOTS, WOMatQAKey)
|
|
|
|
ErrorMessage = ''
|
|
If ( (RDSNo NE '' or WOMatQAKey NE '') and (QAStage NE '') ) then
|
|
If RDSNo NE '' then
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
end else
|
|
WOMatKey = WOMatQAKey
|
|
end
|
|
If WOMatKey NE '' then
|
|
If RowExists('WO_MAT_QA', WOMatKey) then
|
|
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end else
|
|
WOMatQAStages = WOMatQARec<WO_MAT_QA_STAGE$>
|
|
WOMatQASlots = WOMatQARec<WO_MAT_QA_SLOT$>
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No WO_MAT_QA record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null WO_MAT_KEY returned for RDS ':RDSNo:'!'
|
|
end
|
|
If ErrorMessage EQ '' then
|
|
SigDTM = Datetime()
|
|
For each WOMatQAStage in WOMatQAStages using @VM setting vPos
|
|
TestSlot = WOMatQASlots<0, vPos>
|
|
If ( (WOMatQAStage EQ QAStage) and (TestSlot EQ Slot) ) then
|
|
// Sign each row if no signature present.
|
|
If WOMatQARec<WO_MAT_QA_SIG$, vPos> EQ '' then
|
|
WOMatQARec<WO_MAT_QA_SIG$, vPos> = User
|
|
WOMatQARec<WO_MAT_QA_SIG_DTM$, vPos> = SigDTM
|
|
end
|
|
end
|
|
Next WOMatQAStage
|
|
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatKey, WOMatQARec)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo or stage passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service ROTRSigReady(RDSNo)
|
|
|
|
ErrorMessage = ''
|
|
If RDSNo NE '' then
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
If LWICINo NE '' then
|
|
LWICIRec = Database_Services('ReadDataRow', 'CLEAN_INSP', LWICINo)
|
|
If Error_Services('NoError') then
|
|
ROTRAction = LWICIRec<CLEAN_INSP_ROTR_ACTION$>
|
|
If ROTRAction NE 'F' then
|
|
ErrorMessage = 'Error in ':Service:' service. ROTR does not require acceptance.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No LWI CLEAN_INSP record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignROTR(RDSNo, User, ROTRReason)
|
|
|
|
ErrorMessage = ''
|
|
If ( (RDSNo NE '') and (User NE '') and (ROTRReason NE '') ) then
|
|
LWICINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
|
|
If LWICINo NE '' then
|
|
LWICIRec = Database_Services('ReadDataRow', 'CLEAN_INSP', LWICINo)
|
|
If Error_Services('NoError') then
|
|
ROTRSig = LWICIRec<CLEAN_INSP_SIGN_ROTR_SIGNATURE$>
|
|
If ROTRSig EQ '' then
|
|
// Only sign ROTR Acceptance if no signature present.
|
|
LWICIRec<CLEAN_INSP_SIGN_ROTR_SIGNATURE$> = User
|
|
LWICIRec<CLEAN_INSP_SIGN_ROTR_DTM$> = Datetime()
|
|
LWICIRec<CLEAN_INSP_SIGN_ROTR_REASON$> = ROTRReason
|
|
LWICIRec<CLEAN_INSP_ROTR_ACTION$> = 'A' ; // Accepted
|
|
Database_Services('WriteDataRow', 'CLEAN_INSP', LWICINo, LWICIRec)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No LWI CLEAN_INSP record on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service NCRSigReady(RDSNo)
|
|
|
|
ErrorMessage = ''
|
|
If RDSNo NE '' then
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
If WOMatKey NE '' then
|
|
NCRKeys = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X')
|
|
If NCRKeys NE '' then
|
|
For each NCRKey in NCRKeys using @VM setting vPos
|
|
Error = False$
|
|
ReqFields = 'SHIFT,DEPT,DEPT_RESP,LOSS_CODE,LOSS_COMMENTS,CONTAIN_ACTIONS,LOSS_STAGE,LOSS_BY'
|
|
For each ReqField in ReqFields using ',' setting cPos
|
|
Val = Xlate('NCR', NCRKey, ReqField, 'X')
|
|
If Val EQ '' then
|
|
ErrorMessage = 'Error in ':Service:' service. No NCRs on file for RDS ':RDSNo:'!'
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next ReqField
|
|
Until ErrorMessage NE ''
|
|
Next NCRKey
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No NCRs on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No WO_MAT_KEY on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignNCRs(RDSNo, User)
|
|
|
|
ErrorMessage = ''
|
|
If RDSNo NE '' then
|
|
WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
|
|
If WOMatKey NE '' then
|
|
NCRKeys = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X')
|
|
If NCRKeys NE '' then
|
|
SigDTM = Datetime()
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
If Error_Services('NoError') then
|
|
For each NCRKey in NCRKeys using @VM setting vPos
|
|
// Sign each NCR
|
|
NCRRec = Database_Services('ReadDataRow', 'NCR', NCRKey)
|
|
If Error_Services('NoError') then
|
|
NCRRec<NCR_AUTH_SHIP_SIG$> = User
|
|
NCRRec<NCR_AUTH_REJ_SIG$> = User
|
|
NCRRec<NCR_AUTH_SHIP_SIG_DTM$> = SigDTM
|
|
NCRRec<NCR_STATUS$> = 'C'
|
|
Database_Services('WriteDataRow', 'NCR', NCRKey, NCRRec)
|
|
If Error_Services('NoError') then
|
|
// Sign WO_MAT NCR sig column
|
|
Locate NCRKey in WOMatRec<WO_MAT_NCR_KEYS$> using @VM setting Pos then
|
|
CurrSig = Trim(WOMatRec<WO_MAT_NCR_FINAL_SIG$, Pos>)
|
|
If CurrSig EQ '' then
|
|
WOMatRec<WO_MAT_NCR_FINAL_SIG$, Pos> = User
|
|
WOMatRec<WO_MAT_NCR_FINAL_SIG_DTM$, Pos> = SigDTM
|
|
Database_Services('WriteDataRow', 'WO_MAT', WOMatKey, WOMatRec)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Failed to locate NCR key ':NCRKey:' in WO_MAT record ':WOMatKey:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next NCRKey
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No NCRs on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. No WO_MAT_KEY on file for RDS ':RDSNo:'!'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignSupplement(RDSNo, User)
|
|
|
|
ErrorMessage = ''
|
|
If RDSNo NE '' then
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
|
If Error_Services('NoError') then
|
|
RDSRec<RDS_SUPPL_SIG$> = User
|
|
RDSRec<RDS_SUPPL_SIG_DATE$> = Date()
|
|
RDSRec<RDS_SUPPL_SIG_TIME$> = Time()
|
|
RDSRec<RDS_SUPPL_ACK$> = True$
|
|
Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, True$)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in ':Service:' service. Null RDSNo passed into service.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = False$
|
|
end else
|
|
Response = True$
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
GetMostRecentSig:
|
|
|
|
NumRows = DCount(StageRows, @VM)
|
|
SignatureFound = False$
|
|
For RowIndex = NumRows to 1 Step -1
|
|
Signature = Signatures<0, RowIndex>
|
|
SigDTM = SigDTMs<0, RowIndex>
|
|
If Signature NE '' then SignatureFound = True$
|
|
Until SignatureFound EQ True$
|
|
Next RowIndex
|
|
|
|
return
|
|
|
|
|