Added in a check for the active flag when adding an operation to a lot. Added in material handler group to the CanUserModifyLot check. Given the addition of a check for the active flag to allow adding an operation. I checked all OPERATION records to ensure that flag has already been set. The only operations that had a value other than true were the OPERATION records related to Return To Fab Lot processing. Tested and verified creating test wafer lots, and creating RTF forms.
513 lines
25 KiB
Plaintext
513 lines
25 KiB
Plaintext
Compile function Lot_Operation_Services(@Service, @Params)
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
Declare function Lot_Services, Database_Services, Error_Services, Srp_Sort_Array, Lot_Operation_Services
|
|
Declare function RTI_CreateGUID, MemberOf, SRP_JSON, Operation_Services, Datetime, Met_Test_Services, PSN_Services
|
|
Declare function Date_Services
|
|
Declare subroutine Database_Services, Error_Services, SRP_JSON, Lot_Services, Lot_Event_Services, Lot_Operation_Services
|
|
|
|
$insert LOGICAL
|
|
$insert LOT_EQUATES
|
|
$Insert LOT_OPERATION_EQUATES
|
|
$Insert OPERATION_EQUATES
|
|
$Insert MET_TEST_EQUATES
|
|
$Insert WAFER_COUNTER_EQUATES
|
|
|
|
Options OPERATION_TYPE = 'CLEAN', 'THICK_METROLOGY', 'RES_METROLOGY', 'SURFACE_METROLOGY', 'VISUAL_INSPECTION', 'PACKAGING'
|
|
|
|
GoToService
|
|
|
|
Return Response or ""
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SERVICES
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Service AddOperationToLot(LotId, OperationId, PrescribedSequence, UserId)
|
|
|
|
Operation = ''
|
|
ErrorMessage = ''
|
|
If RowExists('LOT', LotId) then
|
|
If RowExists('OPERATION', OperationId) then
|
|
OperationActive = XLATE('OPERATION', OperationId, OPERATION_ACTIVE$, 'X')
|
|
If OperationActive then
|
|
If PrescribedSequence AND Num(PrescribedSequence) then
|
|
If Lot_Services('CanUserModifyLot', UserId) then
|
|
LotCurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
|
|
CurrOperationSequence = Xlate('LOT_OPERATION', LotCurrOperation, LOT_OPERATION_OPERATION_SEQUENCE$, 'X')
|
|
If CurrOperationSequence LT PrescribedSequence then
|
|
//Get Curr Operation Sequence
|
|
Done = False$
|
|
LotCurrOperationSequence = Lot_Services('GetLotOperationSequence', LotId)
|
|
for each Operation in LotCurrOperationSequence using @Fm setting OpPos
|
|
ThisOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', Operation)
|
|
ThisOperationSequence = ThisOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>
|
|
If ThisOperationSequence GE PrescribedSequence then
|
|
NewOperationSequence = ThisOperationSequence + 1
|
|
ThisOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = NewOperationSequence
|
|
Database_Services('WriteDataRow', 'LOT_OPERATION', Operation, ThisOperationRec)
|
|
If Error_Services('HasError') then
|
|
Done = True$
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
Until Done
|
|
Next Operation
|
|
If ErrorMessage EQ '' then
|
|
LotOperationRecID = RTI_CreateGUID()
|
|
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
|
|
OperationRec = Database_Services('ReadDataRow', 'OPERATION', OperationId)
|
|
Class = OperationRec<OPERATION_CLASS_ID$>
|
|
Type = OperationRec<OPERATION_TYPE$>
|
|
Rework = OperationRec<OPERATION_REWORK$>
|
|
ThisNewOperationRec = Database_Services('ReadDataRow', 'OPERATION', OperationId)
|
|
LotOperationRec = ''
|
|
LotOperationRec<LOT_OPERATION_LOT_ID$> = LotId
|
|
LotOperationRec<LOT_OPERATION_OPERATION_ID$> = OperationId
|
|
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = PrescribedSequence
|
|
LotOperationRec<LOT_OPERATION_REWORK$> = Rework
|
|
LotOperationRec<LOT_OPERATION_OPERATION_TYPE$> = Type
|
|
LotOperationRec<LOT_OPERATION_OPERATION_CLASS$> = Class
|
|
LotOperationRec<LOT_OPERATION_MET_TEST_TYPE_REQUIRED$> = OperationRec<OPERATION_MET_TEST_TYPE_REQUIRED$>
|
|
LotOperationRec<LOT_OPERATION_MET_TEST_REQUIRED$> = OperationRec<OPERATION_MET_TEST_REQUIRED$>
|
|
LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$> = OperationRec<OPERATION_PACKAGING_REQUIRED$>
|
|
LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$> = OperationRec<OPERATION_CLEAN_REQUIRED$>
|
|
LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$> = OperationRec<OPERATION_WAFER_COUNTER_REQUIRED$>
|
|
IsOperationRework = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_REWORK$)
|
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
|
|
If Error_Services('NoError') then
|
|
OperationDesc = XLATE('OPERATION', OperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'ADD_LOT_OPERATION', 'Added operation ' : Quote(OperationDesc) : ' to lot.', '', UserId)
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot Operation already existed, cannot overwrite'
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Not allowed to add new operations prior to current operation'
|
|
end
|
|
end else
|
|
ErrorMessage = 'User ' : UserId : ' does not have permission to modify lots.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid operation sequence entered.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Operation is inactive. Unable to add.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Operation ' : OperationId : 'not found in OPERATION table.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot ' : LotId : ' not found in LOT table.'
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
Response = Operation
|
|
end else
|
|
Error_Services('Add', 'Error in ' : Service : '.' : ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service RemoveLotOperation(LotOperationId, UserId)
|
|
|
|
//Todo User permission check
|
|
ErrorMessage = ''
|
|
Success = False$
|
|
|
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
|
If Lot_Services('CanUserModifyLot', UserId) then
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
|
MoveInTime = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
|
MoveOutTime = LotOperationRec<LOT_OPERATION_DATETIME_OUT$>
|
|
Sequence = LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>
|
|
OperationId = LotOperationRec<LOT_OPERATION_OPERATION_ID$>
|
|
OperationClass = XLATE('OPERATION', OperationId, OPERATION_CLASS_ID$, 'X')
|
|
If OperationClass NE 'RTF_DEFAULT' AND OperationClass NE 'RTF_DEFAULT_END' then
|
|
If MoveInTime EQ '' AND MoveOutTime EQ '' then
|
|
LotOperationRec<LOT_OPERATION_LOT_ID$> = '';//Nulling this value out should disassociated the lot operation record from the lot.
|
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, LotOperationRec)
|
|
If Error_Services('NoError') then
|
|
Lot_Operation_Services('UpdateLotOperationSequence', LotId, Sequence)
|
|
If Error_Services('NoError') then
|
|
Success = True$
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
OperationDesc = XLATE('OPERATION', OperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REMOVE_LOT_OPERATION', 'Removed operation ' : Quote(OperationDesc) : ' from lot.', '', UserId)
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot has already started processing on operation ' : OperationId
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to remove default operations.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'User ' : UserId : ' does not have permission modify lots.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot Operation record not found'
|
|
end
|
|
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
Response = Success
|
|
|
|
end service
|
|
|
|
Service UpdateLotOperationSequence(LotId, StartSequence)
|
|
|
|
ErrorMessage = ''
|
|
If StartSequence EQ '' then
|
|
StartSequence = 1
|
|
end
|
|
|
|
If RowExists('LOT', LotId) then
|
|
LotOperationSequence = Lot_Services('GetLotOperationSequence', LotId)
|
|
Offset = 0
|
|
for each LotOperationId in LotOperationSequence using @FM setting SeqPos
|
|
If LotOperationId NE '' then
|
|
ThisLotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
OrigSeq = ThisLotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>
|
|
NewSeq = OrigSeq - Offset
|
|
ThisLotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = NewSeq
|
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, ThisLotOperationRec)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
Offset += 1
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next LotOperation
|
|
end else
|
|
ErrorMessage = 'Lot Id not found'
|
|
end
|
|
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', 'Error in ' : Service : ' : ' : ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service GetAvailableSequences(LotId)
|
|
AvailableSequences = ''
|
|
|
|
If RowExists('LOT', LotId) then
|
|
CurrentLotOperations = Lot_Services('GetLotOperationSequence', LotId)
|
|
For each LotOperationId in CurrentLotOperations using @FM setting Sequence
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
OperationId = LotOperationRec<LOT_OPERATION_OPERATION_ID$>
|
|
OperationClass = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_CLASS_ID$)
|
|
StartDtm = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
|
If StartDTM EQ '' then
|
|
AvailableSequences<1, -1> = Sequence + 1
|
|
end
|
|
Next LotOperationId
|
|
end
|
|
|
|
Response = AvailableSequences
|
|
end service
|
|
|
|
Service ConvertRecordToJson(LotOperationId)
|
|
|
|
JsonString = ''
|
|
objJSON = ''
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
If SRP_JSON(objJSON, 'New', 'Object') then
|
|
SRP_JSON(objJSON, 'SetValue', 'LotOperationId', LotOperationId)
|
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
|
LegacyLotId = Database_Services('ReadDataColumn', 'LOT', LotId, LOT_LEGACY_LOT_ID$, True$, 0, False$)
|
|
SRP_JSON(objJSON, 'SetValue', 'LotOperationId', LotOperationId)
|
|
SRP_JSON(objJSON, 'SetValue', 'LotId', LotId, 'String')
|
|
SRP_JSON(objJSON, 'SetValue', 'LegacyLotId', LegacyLotId, 'String')
|
|
SRP_JSON(objJSON, 'SetValue', 'OperationId', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, 'String')
|
|
OperationDesc = XLATE('OPERATION', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
|
SRP_JSON(objJSON, 'SetValue', 'Description', OperationDesc, 'String')
|
|
OperationClass = XLATE('OPERATION', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, OPERATION_CLASS_ID$, 'X')
|
|
SRP_JSON(objJSON, 'SetValue', 'OperationClass', OperationClass)
|
|
DatetimeIn = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_IN$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeIn', DatetimeIn)
|
|
DatetimeOut = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_OUT$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeOut', DatetimeOut)
|
|
EquipmentId = LotOperationRec<LOT_OPERATION_EQUIPMENT_ID$>
|
|
SRP_JSON(objJSON, 'SetValue', 'EquipmentId', EquipmentId)
|
|
SRP_JSON(objJSON, 'SetValue', 'WaferInQty', LotOperationRec<LOT_OPERATION_WAFER_IN_QTY$>, 'Number')
|
|
SRP_JSON(objJSON, 'SetValue', 'WaferOutQty', LotOperationRec<LOT_OPERATION_WAFER_OUT_QTY$>, 'Number')
|
|
SRP_JSON(objJSON, 'SetValue', 'OperatorInId', LotOperationRec<LOT_OPERATION_OPERATOR_IN_ID$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'OperatorOutId', LotOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'OperationSequence', LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>)
|
|
DatetimeStart = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_START$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeStart', DatetimeStart)
|
|
DatetimeStop = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_STOP$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeStop', DatetimeStop)
|
|
SRP_JSON(objJSON, 'SetValue', 'MetTestId', LotOperationRec<LOT_OPERATION_MET_TEST_ID$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'CleanId', LotOperationRec<LOT_OPERATION_CLEAN_ID$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'PackagingId', LotOperationRec<LOT_OPERATION_PACKAGING_ID$>)
|
|
SRP_JSON(objJSON, 'SetValue', 'WaferCounterId', LotOperationRec<LOT_OPERATION_WAFER_COUNTER_ID$>)
|
|
SRP_JSON(objJson, 'SetValue', 'MetTestTypeRequired', LotOperationRec<LOT_OPERATION_MET_TEST_TYPE_REQUIRED$>, 'STRING')
|
|
SRP_JSON(objJson, 'SetValue', 'MetTestRequired', LotOperationRec<LOT_OPERATION_MET_TEST_REQUIRED$>, 'Boolean')
|
|
SRP_JSON(objJson, 'SetValue', 'PackagingRequired', LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>, 'Boolean')
|
|
SRP_JSON(objJson, 'SetValue', 'CleanRequired', LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>, 'Boolean')
|
|
SRP_JSON(objJson, 'SetValue', 'WaferCounterRequired', LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>, 'Boolean')
|
|
PSNo = Xlate('LOT', LotId, LOT_PROD_SPEC_ID$, 'X')
|
|
RecipeToolInfo = PSN_Services('GetAllMetrologyRecipes', PSNo, True$, True$, True$, True$)
|
|
objRecipeInfo = ''
|
|
If SRP_Json(objRecipeInfo, 'New', 'Array') then
|
|
for each RecipeLine in RecipeToolInfo using @FM
|
|
If SRP_Json(objRecipeLine, 'New', 'Object') then
|
|
SRP_Json(objRecipeLine, 'SetValue', 'ToolClass', RecipeLine<1,1>, 'String')
|
|
SRP_Json(objRecipeLine, 'SetValue', 'Recipe', RecipeLine<1,2>, 'String')
|
|
SRP_Json(objRecipeLine, 'SetValue', 'Stage', RecipeLine<1,3>, 'String')
|
|
SRP_Json(objRecipeInfo, 'Add', objRecipeLine)
|
|
SRP_Json(objRecipeLine, 'Release')
|
|
end
|
|
Next RecipeLine
|
|
SRP_Json(objJSON, 'Set', 'RecipeInfo', objRecipeInfo)
|
|
SRP_Json(objRecipeInfo, 'Release')
|
|
end
|
|
SRP_JSON(objJSON, 'SetValue', 'OperationType', LotOperationRec<LOT_OPERATION_OPERATION_TYPE$>)
|
|
//Add OPERATION Object
|
|
OperationJson = Operation_Services('ConvertRecordToJSON', LotOperationRec<LOT_OPERATION_OPERATION_ID$>)
|
|
If SRP_JSON(objOperationJson, 'Parse', OperationJson) EQ '' then
|
|
SRP_Json(objJSON, 'Set', 'OperationInfo',objOperationJson)
|
|
SRP_Json(objOperationJson, 'Release')
|
|
end
|
|
//Add Associated MET_TEST JSON Object
|
|
AssocMetTestIds = LotOperationRec<LOT_OPERATION_MET_TEST_ID$>
|
|
objAssocMetTest = ''
|
|
If SRP_Json(objAssocMetTest, 'New', 'Array') then
|
|
for each MetTestId in AssocMetTestIds using @VM
|
|
MetTestJson = Met_Test_Services('ConvertRecordToJson', MetTestId)
|
|
If SRP_Json(objMetTest, 'Parse', MetTestJson) EQ '' then
|
|
SRP_Json(objAssocMetTest, 'Add', objMetTest)
|
|
SRP_Json(objMetTest, 'Release')
|
|
end
|
|
Next MetTestId
|
|
SRP_Json(objJSON, 'Set', 'AssociatedMetTests', objAssocMetTest)
|
|
SRP_Json(objAssocMetTest, 'Release')
|
|
end
|
|
|
|
//Add Available Met Test Record
|
|
AvailMetTestIds = Met_Test_Services('GetMetTests', LotId, LegacyLotId, '', '', True$)
|
|
objAvailMetTest = ''
|
|
If SRP_Json(objAvailMetTest, 'New', 'Array') then
|
|
for each MetTestId in AvailMetTestIds using @VM
|
|
MetTestJson = Met_Test_Services('ConvertRecordToJson', MetTestId)
|
|
If SRP_Json(objMetTest, 'Parse', MetTestJson) EQ '' then
|
|
SRP_Json(objAvailMetTest, 'Add', objMetTest)
|
|
SRP_Json(objMetTest, 'Release')
|
|
end
|
|
Next MetTestId
|
|
SRP_Json(objJSON, 'Set', 'AvailMetTests', objAvailMetTest)
|
|
SRP_Json(objAvailMetTest, 'Release')
|
|
end
|
|
//Add in relevant recipes
|
|
Recipes = ''
|
|
ShowThickRecipes = False$
|
|
ShowResRecipes = False$
|
|
ShowCleanRecipes = False$
|
|
ShowSurfscanRecipes = False$
|
|
IsMetTestReqd = LotOperationRec<LOT_OPERATION_MET_TEST_REQUIRED$>
|
|
IsCleanRequired = LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>
|
|
If IsMetTestReqd then
|
|
MetTestTypeRequired = LotOperationRec<LOT_OPERATION_MET_TEST_TYPE_REQUIRED$>
|
|
Begin Case
|
|
Case MetTestTypeRequired EQ 'TENCOR'
|
|
ShowSurfscanRecipes = True$
|
|
Case MetTestTypeRequired EQ 'THICK'
|
|
ShowThickRecipes = True$
|
|
Case MetTestTypeRequired EQ 'RES'
|
|
ShowResRecipes = True$
|
|
End Case
|
|
end
|
|
If IsCleanRequired then
|
|
ShowCleanRecipes = True$
|
|
end
|
|
ProdSpecNo = XLATE('LOT', LotId, LOT_PROD_SPEC_ID$, 'X')
|
|
Recipes = PSN_Services('GetAllMetrologyRecipes', ProdSpecNo, ShowSurfscanRecipes, ShowCleanRecipes, ShowResRecipes, ShowThickRecipes)
|
|
If SRP_JSON(objRecipes, 'New', 'Array') then
|
|
for each Recipe in Recipes using @FM
|
|
//ToolClass : @VM : Recipe : @VM : Stage
|
|
ToolClass = Recipe<1,1>
|
|
RecipeName = Recipe<1,2>
|
|
Stage = Recipe<1,3>
|
|
If SRP_JSON(objRecipe, 'New', 'Object') then
|
|
SRP_JSON(objRecipe, 'SetValue', 'ToolClass', ToolClass, 'String')
|
|
SRP_JSON(objRecipe, 'SetValue', 'RecipeName', RecipeName, 'String')
|
|
SRP_JSON(objRecipe, 'SetValue', 'StageName', Stage, 'String')
|
|
SRP_JSON(objRecipes, 'Add', objRecipe)
|
|
SRP_JSON(objRecipe, 'Release')
|
|
end
|
|
Next Recipe
|
|
SRP_JSON(objJSON, 'Set', 'RecipeParams', objRecipes)
|
|
SRP_JSON(objRecipes, 'Release')
|
|
end
|
|
JsonString = SRP_JSON(objJSON, 'Stringify', 'Fast')
|
|
SRP_JSON(objJSON, 'Release')
|
|
end
|
|
|
|
Response = JsonString
|
|
end service
|
|
|
|
|
|
|
|
Service StartLotOperation(LotOperationId, UserId)
|
|
|
|
ErrorMessage = ''
|
|
|
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
|
If RowExists('LSL_USERS', UserId) then
|
|
//We can also add additional checks like security checks, training checks, etc here if needed.
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
|
LotCurrentLotOpId = Lot_Services('GetLotCurrOperationId', LotId)
|
|
If LotOperationId EQ LotCurrentLotOpId then
|
|
LotMovedIn = Lot_Services('IsLotMovedIn', LotId)
|
|
If Not(LotMovedIn) then
|
|
Lot_Services('MoveInLot', LotId, UserId)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot is already moved into this operation.'
|
|
end
|
|
end else
|
|
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid user passed to routine.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid Lot Operation passed to routine.'
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
Response = True$
|
|
end else
|
|
Response = False$
|
|
Error_Services('Add', 'Error in ' : Service : '. ' : ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service CompleteLotOperation(LotOperationId, UserId)
|
|
|
|
ErrorMessage = ''
|
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
|
If RowExists('LSL_USERS', UserId) then
|
|
//We can also add additional checks like security checks, training checks, etc here if needed.
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
|
LotCurrentLotOpId = Lot_Services('GetLotCurrOperationId', LotId)
|
|
If LotOperationId EQ LotCurrentLotOpId then
|
|
LotMovedIn = Lot_Services('IsLotMovedIn', LotId)
|
|
If LotMovedIn then
|
|
//Perform Validation for the particular operation here.
|
|
OperationValid = Lot_Operation_Services('ValidateLotOperation', LotOperationId)
|
|
If OperationValid then
|
|
Lot_Services('MoveOutLot', LotId, UserId)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot Operation has not finished processing and cannot be moved out.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Cannot complete operation because lot is not currently moved in.'
|
|
end
|
|
end else
|
|
CurrOperationId = Xlate('LOT_OPERATION', LotCurrentLotOpId, LOT_OPERATION_OPERATION_ID$, 'X')
|
|
CurrOperationDesc = Xlate('OPERATION', CurrOperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
|
ErrorMessage = 'Cannot complete operation. Lot is currently at ' : CurrOperationDesc
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid user passed to routine.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid Lot Operation passed to routine.'
|
|
end
|
|
|
|
If ErrorMessage EQ '' then
|
|
Response = True$
|
|
end else
|
|
Response = False$
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service ValidateLotOperation(LotOperationId)
|
|
|
|
ErrorMessage = ''
|
|
IsValid = True$
|
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
OperationId = LotOperationRec<LOT_OPERATION_OPERATION_ID$>
|
|
MetTestRequired = LotOperationRec<LOT_OPERATION_MET_TEST_REQUIRED$>
|
|
MetTestTypeRequired = LotOperationRec<LOT_OPERATION_MET_TEST_TYPE_REQUIRED$>
|
|
PackagingRequired = LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>
|
|
CleanRequired = LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>
|
|
WaferCountRequired = LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>
|
|
OperationClass = XLATE('OPERATION', OperationId, OPERATION_CLASS_ID$, 'X')
|
|
If MetTestRequired then
|
|
MetTestsInSpec = True$
|
|
AssociatedMetTestIds = LotOperationRec<LOT_OPERATION_MET_TEST_ID$>
|
|
If AssociatedMetTestIds NE '' then
|
|
for each MetTestId in AssociatedMetTestIds using @VM
|
|
MetTestOoS = Database_Services('ReadDataColumn', 'MET_TEST', MetTestId, MET_TEST.OUT_OF_SPEC$, True$, 0, False)
|
|
If MetTestOoS AND OperationClass NE 'RTF' AND OperationClass NE 'RTF_DEFAULT' then
|
|
MetTestsInSpec = False$
|
|
ErrorMessage = 'An associated Met test record is out of spec.'
|
|
end
|
|
Until MetTestsInSpec EQ False$
|
|
Next MetTestId
|
|
end else
|
|
IsValid = False$
|
|
ErrorMessage = 'Met tests are required and none are assigned.'
|
|
end
|
|
end
|
|
If PackagingRequired AND IsValid then
|
|
AssociatedPackagingIds = LotOperationRec<LOT_OPERATION_PACKAGING_ID$>
|
|
If AssociatedPackagingIds NE '' then
|
|
|
|
end else
|
|
IsValid = False$
|
|
end
|
|
end
|
|
If CleanRequired AND IsValid then
|
|
AssociatedCleanIds = LotOperationRec<LOT_OPERATION_CLEAN_ID$>
|
|
If AssociatedCleanIds NE '' then
|
|
IsValid = True$
|
|
end else
|
|
IsValid = False$
|
|
end
|
|
end
|
|
If WaferCountRequired AND IsValid then
|
|
AssociatedWaferCountIds = LotOperationRec<LOT_OPERATION_WAFER_COUNTER_ID$>
|
|
If AssociatedWaferCountIds NE '' then
|
|
IsValid = True$
|
|
end else
|
|
IsValid = False$
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Lot Operation not found'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
IsValid = False$
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
Response = IsValid
|
|
|
|
end service
|