added LSL2 stored procedures
This commit is contained in:
581
LSL2/STPROC/WO_MAT_QA_ACTIONS.txt
Normal file
581
LSL2/STPROC/WO_MAT_QA_ACTIONS.txt
Normal file
@ -0,0 +1,581 @@
|
||||
Function WO_MAT_QA_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)
|
||||
/***********************************************************************************************************************
|
||||
|
||||
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
||||
permission from Infineon.
|
||||
|
||||
Name : WO_MAT_QA_Actions
|
||||
|
||||
Description : Handles calculated columns and MFS calls for the current table.
|
||||
|
||||
Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly.
|
||||
If called from outside of a calculated column these will need to be set and restored.
|
||||
|
||||
Parameters :
|
||||
Action [in] -- Name of the action to be taken
|
||||
CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be
|
||||
populated when the CalcField action is being used.
|
||||
FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM
|
||||
delimited array, with the current MFS name as the first value in the array, and the BFS
|
||||
name as the last value. Normally set by a calling MFS.
|
||||
Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the
|
||||
entire handle structure that the Basic+ Open statement would provide. Normally set by a
|
||||
calling MFS.
|
||||
Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS.
|
||||
FMC [in] -- Various functions. Normally set by a calling MFS.
|
||||
Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for
|
||||
"get handle" functions). Normally set by a calling MFS.
|
||||
Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but
|
||||
for some actions can be set by the action handler to indicate failure.
|
||||
OrigRecord [in] -- Original content of the record being processed by the current action. This is
|
||||
automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within
|
||||
BASE_MFS.
|
||||
Param1-10 [in/out] -- Additional request parameter holders
|
||||
ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.)
|
||||
Can also be used to return a special value, such as the results of the CalcField
|
||||
method.
|
||||
|
||||
History : (Date, Initials, Notes)
|
||||
10/22/18 djs Original programmer.
|
||||
|
||||
|
||||
***********************************************************************************************************************/
|
||||
|
||||
#pragma precomp SRP_PreCompiler
|
||||
|
||||
$insert LOGICAL
|
||||
$insert FILE.SYSTEM.EQUATES
|
||||
$insert ACTION_SETUP
|
||||
$insert RDS_TEST_EQUATES
|
||||
$insert RDS_EQUATES
|
||||
$insert WO_LOG_EQUATES
|
||||
$insert WM_OUT_EQUATES
|
||||
$insert WM_IN_EQUATES
|
||||
$insert WO_MAT_EQUATES
|
||||
$insert WO_MAT_QA_EQUATES
|
||||
$insert PRS_STAGE_EQUATES
|
||||
$insert TOOL_CLASS_EQUATES
|
||||
|
||||
Declare function Database_Services, obj_NCR, obj_SAP, Qa_Services, SRP_Trim, Environment_Services, Logging_Services
|
||||
Declare subroutine Error_Services, Database_Services, obj_NCR, obj_SAP, Post_Metrology_Manual_Data_Entry_Log
|
||||
Declare subroutine Logging_Services, obj_Notes
|
||||
|
||||
Equ CRLF$ to \0D0A\
|
||||
|
||||
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_MAT_QA'
|
||||
LogDate = Oconv(Date(), 'D4/')
|
||||
LogTime = Oconv(Time(), 'MTS')
|
||||
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WO_MAT_QA Log.csv'
|
||||
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Key ID' : @FM : 'Call Stack' : @FM : 'Record'
|
||||
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
||||
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
||||
|
||||
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\FQABlocked'
|
||||
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' FQA Log.csv'
|
||||
Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'Table' : @FM : 'Key' : @FM : 'Notes'
|
||||
FQAobjLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
||||
|
||||
If KeyID then GoSub Initialize_System_Variables
|
||||
|
||||
Begin Case
|
||||
|
||||
Case Action _EQC 'CalcField' ; GoSub Calc_Field
|
||||
Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE
|
||||
Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD
|
||||
Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE
|
||||
Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD
|
||||
Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE
|
||||
Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD
|
||||
Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE
|
||||
Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD
|
||||
Case Otherwise$ ; Status = 'Invalid Action'
|
||||
|
||||
End Case
|
||||
|
||||
If KeyID then GoSub Restore_System_Variables
|
||||
|
||||
If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$
|
||||
|
||||
Return ActionFlow
|
||||
|
||||
|
||||
// ----- Calculated Columns --------------------------------------------------------------------------------------------
|
||||
//
|
||||
// The typical structure of a calculated column will look like this:
|
||||
//
|
||||
// Declare function TableName_Actions
|
||||
//
|
||||
// A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated.
|
||||
//
|
||||
// @ANS = TableName_Actions('CalcField', 'CalcColName')
|
||||
//
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Calc_Field:
|
||||
// Make sure the ActionFlow return variable is cleared in case nothing is calculated.
|
||||
ActionFlow = ''
|
||||
|
||||
return
|
||||
|
||||
|
||||
// ----- MFS calls -----------------------------------------------------------------------------------------------------
|
||||
|
||||
READ_RECORD_PRE:
|
||||
// In order to stop a record from being read in this action these lines of code must be used:
|
||||
//
|
||||
// OrigFileError = 100 : @FM : KeyID
|
||||
// Status = 0
|
||||
// Record = ''
|
||||
// ActionFlow = ACTION_STOP$
|
||||
return
|
||||
|
||||
READ_RECORD:
|
||||
// In order to stop a record from being read in this action these lines of code must be used:
|
||||
//
|
||||
// OrigFileError = 100 : @FM : KeyID
|
||||
// Status = 0
|
||||
// Record = ''
|
||||
return
|
||||
|
||||
READONLY_RECORD_PRE:
|
||||
// In order to stop a record from being read in this action these lines of code must be used:
|
||||
//
|
||||
// OrigFileError = 100 : @FM : KeyID
|
||||
// Status = 0
|
||||
// Record = ''
|
||||
// ActionFlow = ACTION_STOP$
|
||||
return
|
||||
|
||||
READONLY_RECORD:
|
||||
// In order to stop a record from being read in this action these lines of code must be used:
|
||||
//
|
||||
// OrigFileError = 100 : @FM : KeyID
|
||||
// Status = 0
|
||||
// Record = ''
|
||||
return
|
||||
|
||||
WRITE_RECORD_PRE:
|
||||
|
||||
WorkOrderNo = Field(Name, '*', 1, 1)
|
||||
CassNo = Field(Name, '*', 2, 1)
|
||||
WOMatKey = WorkOrderNo : '*' : CassNo
|
||||
FinalQA = False$
|
||||
WorkOrderRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
|
||||
ReactType = WorkOrderRow<WO_LOG_REACT_TYPE$>
|
||||
// Check to see if the Final QA signature is in place.
|
||||
If ReactType EQ 'EPP' then
|
||||
WMOutKey = WorkOrderNo : '*1*' : CassNo
|
||||
WMOutRow = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey)
|
||||
If WMOutRow<WM_OUT_SUP_VER_SIG$> NE '' then
|
||||
FinalQA = True$
|
||||
end
|
||||
end else
|
||||
RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
|
||||
RDSRow = Database_Services('ReadDataRow', 'RDS', RDSNo)
|
||||
If RDSRow<RDS_SUP_VER_SIG$> NE '' then
|
||||
FinalQA = True$
|
||||
end
|
||||
end
|
||||
|
||||
Begin Case
|
||||
|
||||
Case Record EQ ''
|
||||
|
||||
// Unscheduled record write attempt. Block the write and log the event.
|
||||
ErrorMessage = 'Empty WO_MAT_QA profile. Unscheduled record write attempt!'
|
||||
Error_Services('Add', 'FS104: ':ErrorMessage)
|
||||
OrigFileError = 104 : @FM : ErrorMessage
|
||||
Stack = RetStack()
|
||||
Swap @FM with ' || ' in Stack
|
||||
RecordSnapshot = Record
|
||||
Swap @FM with CRLF$ in RecordSnapshot
|
||||
Swap @VM with ' @VM ' in RecordSnapshot
|
||||
Swap @SVM with ' @SVM ' in RecordSnapshot
|
||||
Swap @TM with ' @TM ' in RecordSnapshot
|
||||
Swap @STM with ' @STM ' in RecordSnapshot
|
||||
LogData = ''
|
||||
LogData<1> = LoggingDTM
|
||||
LogData<2> = @User4
|
||||
LogData<3> = Name
|
||||
LogData<4> = Stack
|
||||
LogData<5> = CRLF$:RecordSnapshot:CRLF$
|
||||
LogData<6> = 'FS104: ':ErrorMessage
|
||||
|
||||
// Sending a null message will send the LogData instead
|
||||
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, '', '', '')
|
||||
|
||||
// Send an internal OI message to OI admins
|
||||
Recipients = Xlate('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X')
|
||||
SentFrom = 'SYSTEM'
|
||||
Subject = 'Unscheduled WO_MAT_QA record write attempt.'
|
||||
Message = ErrorMessage
|
||||
AttachWindow = ''
|
||||
AttachKey = ''
|
||||
SendToGroup = ''
|
||||
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
|
||||
obj_Notes('Create',Parms)
|
||||
|
||||
Status = 0
|
||||
Record = ''
|
||||
ActionFlow = ACTION_STOP$
|
||||
|
||||
Case FinalQA EQ True$
|
||||
|
||||
// User is attempting to modify this row. Set the FS104 error and log the event.
|
||||
OrigFileError = 104 : @FM : 'FQA has already been signed. WO_MAT_QA record cannot be updated!'
|
||||
LogData = ''
|
||||
LogData<1> = LoggingDTM
|
||||
LogData<2> = @User4
|
||||
LogData<3> = WOMatKey
|
||||
LogData<4> = 'WO_MAT_QA'
|
||||
LogData<5> = Name
|
||||
LogData<6> = 'FS104:FQA has already been signed. WO_MAT_QA record cannot be updated!'
|
||||
Logging_Services('AppendLog', FQAobjLog, LogData, @RM, @FM)
|
||||
Status = 0
|
||||
Record = ''
|
||||
ActionFlow = ACTION_STOP$
|
||||
Error_Services('Add', 'FS104:FQA has already been signed. WO_MAT_QA record cannot be updated!')
|
||||
|
||||
Case Otherwise$
|
||||
// Validate metrology data
|
||||
|
||||
// Current values in record
|
||||
OrigDataPoints = OrigRecord<WO_MAT_QA_DATA_POINTS$>
|
||||
OrigProfiles = OrigRecord<WO_MAT_QA_PROFILE$>
|
||||
OrigResult = OrigRecord<WO_MAT_QA_RESULT$>
|
||||
OrigSigs = OrigRecord<WO_MAT_QA_SIG$>
|
||||
OrigSpecMin = OrigRecord<WO_MAT_QA_MIN$>
|
||||
OrigSpecMax = OrigRecord<WO_MAT_QA_MAX$>
|
||||
|
||||
// New values to be saved
|
||||
DataPoints = Record<WO_MAT_QA_DATA_POINTS$>
|
||||
Profiles = Record<WO_MAT_QA_PROFILE$> ; // THICK_ONLY, CRES
|
||||
Sigs = Record<WO_MAT_QA_SIG$>
|
||||
SigDTMS = Record<WO_MAT_QA_SIG_DTM$>
|
||||
Result = Record<WO_MAT_QA_RESULT$> ; // Average of Data Points
|
||||
MinResult = Record<WO_MAT_QA_MIN_RESULT$> ; // Min of Data Points
|
||||
MaxResult = Record<WO_MAT_QA_MAX_RESULT$> ; // Max of Data Points
|
||||
RangePctResult = Record<WO_MAT_QA_RANGE_PCT_RESULT$> ; // Range % of Data Points
|
||||
EdgeMeanResult = Record<WO_MAT_QA_EDGE_MEAN_RESULT$> ; // Edge Mean Delta of Data Points
|
||||
SpecMin = Record<WO_MAT_QA_MIN$>
|
||||
SpecMax = Record<WO_MAT_QA_MAX$>
|
||||
SpecPhaseMin = Record<WO_MAT_QA_PHASE_MIN$>
|
||||
OutOfSpec = Record<WO_MAT_QA_OUT_OF_SPEC$>
|
||||
FailReasons = Record<WO_MAT_QA_FAIL_REASON$>
|
||||
ScanRecipes = Record<WO_MAT_QA_RECIPE$>
|
||||
Stages = Record<WO_MAT_QA_STAGE$>
|
||||
PSN = {PS_NO}
|
||||
RawThicknessData = ''
|
||||
RawHgCVData = ''
|
||||
RawPhaseData = ''
|
||||
|
||||
// Only enter validation code below if relevant data has changed.
|
||||
If ( (OrigDataPoints NE DataPoints) or (OrigProfiles NE Profiles) or (OrigResult NE Result) |
|
||||
or (OrigSigs NE Sigs) or (OrigSpecMin NE SpecMin) or (OrigSpecMax NE SpecMax) ) then
|
||||
|
||||
Profile = ''
|
||||
For each Profile in Profiles using @VM setting ProfileIndex
|
||||
Stage = Stages<1, ProfileIndex>
|
||||
PRSStageKey = PSN:'*':Stage
|
||||
PRSStageRec = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey)
|
||||
SpecRecipes = PRSStageRec<PRS_STAGE_MET_RECIPE$>
|
||||
SpecProfiles = PRSStageRec<PRS_STAGE_MET_TEST$>
|
||||
Begin Case
|
||||
Case ( (Profile EQ '1THICK_ONLY') and (Stage EQ 'UNLOAD') )
|
||||
FailReason = ''
|
||||
ThickOutOfSpec = False$
|
||||
ToolClassID = Record<WO_MAT_QA_TOOL_CLASS$, ProfileIndex>
|
||||
ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClassID)
|
||||
RecipePattern = Record<WO_MAT_QA_RECIPE_PATTERN$, ProfileIndex>
|
||||
RequiredDataPoints = ''
|
||||
Locate RecipePattern in ToolClassRec<TOOL_CLASS_PATTERN$> setting rPos then
|
||||
RequiredDataPoints = ToolClassRec<TOOL_CLASS_PATTERN_SIZE$, rPos>
|
||||
end
|
||||
ScanProfile = Profile
|
||||
ScanProfile[1,1] = ''
|
||||
Locate ScanProfile in SpecProfiles using @VM setting vPos then
|
||||
SpecRecipe = SpecRecipes<1, vPos>
|
||||
ScanRecipe = ScanRecipes<1, ProfileIndex>
|
||||
If ScanRecipe NE SpecRecipe then
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Scanned THICK_ONLY UNLOAD recipe, ':ScanRecipe:', does not match spec ' |
|
||||
: 'recipe, ':SpecRecipe:'.'
|
||||
end
|
||||
end
|
||||
SaveList = ''
|
||||
ThickSig = Sigs<1, ProfileIndex>
|
||||
ThickSigDTM = SigDTMS<1, ProfileIndex>
|
||||
ThickSpecMin = SpecMin<1, ProfileIndex>
|
||||
ThickSpecMax = SpecMax<1, ProfileIndex>
|
||||
ThicknessData = DataPoints<1, ProfileIndex>
|
||||
ResAvg = Result<1, ProfileIndex>
|
||||
ThicknessDataCount = 0
|
||||
For each DataPoint in ThicknessData using @SVM setting ThickIndex
|
||||
Until DataPoint EQ ''
|
||||
Begin Case
|
||||
Case ThickIndex GT 10
|
||||
Null
|
||||
Case (DataPoint EQ '')
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Thickness data point ':ThickIndex:' is missing.'
|
||||
Case (DataPoint GT ThickSpecMax) OR (DataPoint LT ThickSpecMin)
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Thickness data point ':ThickIndex:' is out of bounds.'
|
||||
End Case
|
||||
SaveList<1, 1, ThickIndex> = DataPoint
|
||||
RawThicknessData<1, ThickIndex> = DataPoint
|
||||
ThicknessDataCount += 1
|
||||
Next DataPoint
|
||||
DataPoints<1, ProfileIndex> = SaveList
|
||||
|
||||
If ThicknessDataCount LT RequiredDataPoints then
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Number of data points is less than the required amount of ' : RequiredDataPoints : '!'
|
||||
end
|
||||
|
||||
If RawThicknessData NE '' then
|
||||
Response = QA_Services('CalculateThickData', RawThicknessData)
|
||||
ThickAvg = Response<1,1>
|
||||
ThickMin = Response<1,2>
|
||||
ThickMax = Response<1,3>
|
||||
Result<1, ProfileIndex> = ThickAvg
|
||||
MinResult<1, ProfileIndex> = ThickMin
|
||||
MaxResult<1, ProfileIndex> = ThickMax
|
||||
end else
|
||||
// Lead/Supervisor/Engineer is overriding the typical workflow and is
|
||||
// entering the Thickness average only.
|
||||
ThickAvg = ResAvg
|
||||
Begin Case
|
||||
Case (ThickAvg EQ '')
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Thickness average is missing.'
|
||||
Case (ThickAvg GT ThickSpecMax) OR (ThickAvg LT ThickSpecMin)
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'Thickness average is out of bounds.'
|
||||
End Case
|
||||
end
|
||||
If ThickOutOfSpec EQ False$ then
|
||||
// Final failure check. Only check if a previous failure reason has not been set as to not
|
||||
// ovewrite the previous failure reason.
|
||||
If (ThickSig EQ '') or (ThickSigDTM EQ '') then
|
||||
ThickOutOfSpec = True$
|
||||
FailReason = 'THICK_ONLY UNLOAD product measurement test has not been signed.'
|
||||
end
|
||||
end
|
||||
OutOfSpec<1, ProfileIndex> = ThickOutOfSpec
|
||||
FailReasons<1, ProfileIndex> = FailReason
|
||||
|
||||
Case ( (Profile EQ '1CRES') and (Stage EQ 'UNLOAD') )
|
||||
|
||||
CresOutOfSpec = False$
|
||||
FailReason = ''
|
||||
ToolClassID = Record<WO_MAT_QA_TOOL_CLASS$, ProfileIndex>
|
||||
ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClassID)
|
||||
RecipePattern = Record<WO_MAT_QA_RECIPE_PATTERN$, ProfileIndex>
|
||||
RequiredDataPoints = ''
|
||||
Locate RecipePattern in ToolClassRec<TOOL_CLASS_PATTERN$> setting rPos then
|
||||
RequiredDataPoints = ToolClassRec<TOOL_CLASS_PATTERN_SIZE$, rPos>
|
||||
end
|
||||
ScanProfile = Profile
|
||||
ScanProfile[1,1] = ''
|
||||
Locate ScanProfile in SpecProfiles using @VM setting vPos then
|
||||
SpecRecipe = SpecRecipes<1, vPos>
|
||||
ScanRecipe = ScanRecipes<1, ProfileIndex>
|
||||
If ScanRecipe NE SpecRecipe then
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Scanned CRES UNLOAD recipe, ':ScanRecipe:', does not match spec ' |
|
||||
: 'recipe, ':SpecRecipe:'.'
|
||||
end
|
||||
end
|
||||
SaveList = ''
|
||||
CriticalPoints = '1,2,5,6,9'
|
||||
CRESSig = Sigs<1, ProfileIndex>
|
||||
CRESSigDTM = SigDTMS<1, ProfileIndex>
|
||||
HgCVSpecMin = SpecMin<1, ProfileIndex>
|
||||
HgCVSpecMax = SpecMax<1, ProfileIndex>
|
||||
ThisPhaseMin = SpecPhaseMin<1, ProfileIndex>
|
||||
HgCVData = DataPoints<1, ProfileIndex>
|
||||
|
||||
// Adding Result Average here in the case that a lead manually only enters the averages.
|
||||
ResAvg = Result<1, ProfileIndex>
|
||||
If ThisPhaseMin EQ '' then
|
||||
// Spec Phase Min was not added when the record initially created, so add it here.
|
||||
PSN = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X')
|
||||
If PSN NE '' then
|
||||
PRSStageKey = PSN:'*UNLOAD'
|
||||
PRSStageRec = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey)
|
||||
MetProps = PRSStageRec<PRS_STAGE_MET_PROP$>
|
||||
Locate 'CRES' in MetProps using @VM setting PropPos then
|
||||
SpecPhaseMinCol = PRSStageRec<PRS_STAGE_MET_PHASE_MIN$>
|
||||
ThisPhaseMin = SpecPhaseMinCol<1, PropPos>
|
||||
SpecPhaseMin<1, ProfileIndex> = ThisPhaseMin
|
||||
Record<WO_MAT_QA_PHASE_MIN$> = SpecPhaseMin
|
||||
end
|
||||
end
|
||||
end
|
||||
ResDataCount = 0
|
||||
For each DataPoint in HgCVData using @SVM setting CresIndex
|
||||
Until DataPoint EQ ''
|
||||
HgCVDataPoint = DataPoint[1, 'F':@TM]
|
||||
PhaseDataPoint = DataPoint[-1, 'B':@TM]
|
||||
CriticalPoint = Index(CriticalPoints, CresIndex, 1)
|
||||
Begin Case
|
||||
Case (HgCVDataPoint EQ '') and CriticalPoint
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'HgCV data point: ':CresIndex:' is missing data.'
|
||||
Case (PhaseDataPoint EQ '') and CriticalPoint
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Phase data point: ':CresIndex:' is missing data.'
|
||||
Case (HgCVDataPoint GT HgCVSpecMax) OR (HgCVDataPoint LT HgCVSpecMin) and CriticalPoint
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'HgCV data point: ':CresIndex:' is out of bounds.'
|
||||
Case (PhaseDataPoint LT ThisPhaseMin) and CriticalPoint
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Phase data point: ':CresIndex:' is out of bounds.'
|
||||
End Case
|
||||
RawHgCVData<1, CresIndex> = HgCVDataPoint
|
||||
RawPhaseData<1, CresIndex> = PhaseDataPoint
|
||||
ResDataCount += 1
|
||||
Next DataPoint
|
||||
If ResDataCount LT RequiredDataPoints then
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Number of data points is less than the required amount of ' : RequiredDataPoints : '!'
|
||||
end
|
||||
If (RawHgCVData NE '') AND (RawPhaseData NE '') then
|
||||
|
||||
Response = QA_Services('CalculateHgCVData', RawHgCVData)
|
||||
HgCVAvg = Response<1,1>
|
||||
HgCVMin = Response<1,2>
|
||||
HgCVMax = Response<1,3>
|
||||
HgCVEdgeMean = Response<1,4>
|
||||
HgCVRangePct = Response<1,5>
|
||||
Response = QA_Services('CalculateHgCVData', RawPhaseData)
|
||||
PhaseAvg = Response<1,1>
|
||||
PhaseMin = Response<1,2>
|
||||
PhaseMax = Response<1,3>
|
||||
PhaseEdgeMean = Response<1,4>
|
||||
PhaseRangePct = Response<1,5>
|
||||
DataPoints<1, ProfileIndex> = HgCVData
|
||||
Result<1, ProfileIndex> = HgCVAvg : @SVM : PhaseAvg
|
||||
MinResult<1, ProfileIndex> = HgCVMin : @SVM : PhaseMin
|
||||
MaxResult<1, ProfileIndex> = HgCVMax : @SVM : PhaseMax
|
||||
EdgeMeanResult<1, ProfileIndex> = HgCVEdgeMean : @SVM : PhaseEdgeMean
|
||||
RangePctResult<1, ProfileIndex> = HgCVRangePct : @SVM : PhaseRangePct
|
||||
|
||||
end else
|
||||
// Lead/Supervisor/Engineer is overriding the typical workflow and is
|
||||
// entering the HgCV average and Phase average only.
|
||||
HgCVAvg = ResAvg<1, 1, 1>
|
||||
PhaseAvg = ResAvg<1, 1, 2>
|
||||
Begin Case
|
||||
Case (HgCVAvg EQ '')
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'HgCV average is missing.'
|
||||
Case (PhaseAvg EQ '')
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Phase average is missing.'
|
||||
Case (HgCVAvg GT HgCVSpecMax) OR (HgCVAvg LT HgCVSpecMin)
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'HgCV is out of bounds.'
|
||||
Case (PhaseAvg LT ThisPhaseMin)
|
||||
CresOutOfSpec = True$
|
||||
FailReason = 'Phase is out of bounds.'
|
||||
End Case
|
||||
end
|
||||
|
||||
If CresOutOfSpec EQ False$ then
|
||||
// Final failure check. Only check if a previous failure reason has not been set as to not
|
||||
// overwrite the previous failure reason.
|
||||
If (CRESSig EQ '') or (CRESSigDTM EQ '') then
|
||||
CresOutofSpec = True$
|
||||
FailReason = 'CRES UNLOAD product measurement test has not been signed.'
|
||||
end
|
||||
end
|
||||
|
||||
OutOfSpec<1, ProfileIndex> = CresOutOfSpec
|
||||
FailReasons<1, ProfileIndex> = FailReason
|
||||
|
||||
OrigHgCVAvg = OrigRecord<WO_MAT_QA_RESULT$, ProfileIndex, 1>
|
||||
If HgCVAvg NE OrigHgCVAvg then
|
||||
Post_Metrology_Manual_Data_Entry_Log(@USER4, 'HgCRes', RDSNo : ' / ' : WorkOrderNo : '*' : CassNo)
|
||||
end
|
||||
|
||||
Case Otherwise$
|
||||
// This profile & stage do not currently have any validation code associated with them.
|
||||
// Ensure 'out of spec' flag and 'fail reason' field for this profile are clear.
|
||||
OutOfSpec<1, ProfileIndex> = False$
|
||||
FailReasons<1, ProfileIndex> = ''
|
||||
|
||||
End Case
|
||||
|
||||
Next Profile
|
||||
Record<WO_MAT_QA_DATA_POINTS$> = DataPoints
|
||||
Record<WO_MAT_QA_RESULT$> = Result
|
||||
Record<WO_MAT_QA_MIN_RESULT$> = MinResult
|
||||
Record<WO_MAT_QA_MAX_RESULT$> = MaxResult
|
||||
Record<WO_MAT_QA_EDGE_MEAN_RESULT$> = EdgeMeanResult
|
||||
Record<WO_MAT_QA_RANGE_PCT_RESULT$> = RangePctResult
|
||||
Record<WO_MAT_QA_OUT_OF_SPEC$> = OutOfSpec
|
||||
Record<WO_MAT_QA_FAIL_REASON$> = FailReasons
|
||||
SaveRecord = Record
|
||||
end
|
||||
|
||||
End Case
|
||||
return
|
||||
|
||||
WRITE_RECORD:
|
||||
return
|
||||
|
||||
DELETE_RECORD_PRE:
|
||||
return
|
||||
|
||||
DELETE_RECORD:
|
||||
return
|
||||
|
||||
|
||||
// ----- Internal Methods ----------------------------------------------------------------------------------------------
|
||||
|
||||
Initialize_System_Variables:
|
||||
// Save these for restoration later
|
||||
SaveDict = @DICT
|
||||
SaveID = @ID
|
||||
SaveRecord = @RECORD
|
||||
OrigFileError = @FILE.ERROR
|
||||
|
||||
// Now make sure @DICT, ID, and @RECORD are populated
|
||||
CurrentDictName = ''
|
||||
If @DICT then
|
||||
DictHandle = @DICT<1, 2>
|
||||
Locate DictHandle in @TABLES(5) Using @FM Setting fPos then
|
||||
CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
|
||||
end
|
||||
end
|
||||
|
||||
If CurrentDictName NE DictName then
|
||||
Open DictName to @DICT else Status = 'Unable to initialize @DICT'
|
||||
end
|
||||
|
||||
@ID = KeyID
|
||||
If Record else
|
||||
// Record might not have been passed in. Read the record from the database table just to make sure.
|
||||
@FILE.ERROR = ''
|
||||
Open TableName to hTable then
|
||||
FullFSList = hTable[1, 'F' : @VM]
|
||||
BFS = FullFSList[-1, 'B' : @SVM]
|
||||
LastHandle = hTable[-1, 'B' : \0D\]
|
||||
FileHandle = \0D\ : LastHandle[1, @VM]
|
||||
|
||||
Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus)
|
||||
end
|
||||
end
|
||||
@RECORD = Record
|
||||
return
|
||||
|
||||
Restore_System_Variables:
|
||||
Transfer SaveDict to @DICT
|
||||
Transfer SaveID to @ID
|
||||
Transfer SaveRecord to @RECORD
|
||||
@FILE.ERROR = OrigFileError
|
||||
return
|
||||
|
||||
|
Reference in New Issue
Block a user