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 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 METROLOGY_DATA_EXAMPLE_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 If PrescribedSequence AND Num(PrescribedSequence) then If Lot_Operation_Services('CanUserAddLotOperation', 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 If ThisOperationSequence GE PrescribedSequence then NewOperationSequence = ThisOperationSequence + 1 ThisOperationRec = 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 Type = OperationRec Rework = OperationRec ThisNewOperationRec = Database_Services('ReadDataRow', 'OPERATION', OperationId) LotOperationRec = '' LotOperationRec = LotId LotOperationRec = OperationId LotOperationRec = PrescribedSequence LotOperationRec = Rework LotOperationRec = Type LotOperationRec = Class LotOperationRec = OperationRec LotOperationRec = OperationRec LotOperationRec = OperationRec LotOperationRec = OperationRec LotOperationRec = OperationRec IsOperationRework = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_REWORK$) Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec) If Error_Services('NoError') then Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'ADD_LOT_OPERATION', 'Added operation ' : Operation : ' 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 add operations to lots.' end end else ErrorMessage = 'Invalid operation sequence entered.' 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) // todo: add logging end end service Service RemoveLotOperation(LotOperationId, UserId) //Todo User permission check ErrorMessage = '' Success = False$ If RowExists('LOT_OPERATION', LotOperationId) then LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$) LotId = LotOperationRec MoveInTime = LotOperationRec MoveOutTime = LotOperationRec Sequence = LotOperationRec OperationId = LotOperationRec 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 = '';//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 Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REMOVE_LOT_OPERATION', 'Removed operation ' : OperationId : ' 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 = 'Lot Operation record not found' end If ErrorMessage NE '' then Error_Services('Add', 'Error in service ': Service : ' : ' : 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 NewSeq = OrigSeq - Offset ThisLotOperationRec = 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 ModifyLotOperationSequence(LotOperationId, NewSequence, UserId) ErrorMessage = '' If ErrorMessage NE '' then 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 OperationClass = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_CLASS_ID$) StartDtm = LotOperationRec If StartDTM EQ '' then If OperationClass NE 'RTF_DEFAULT' then AvailableSequences<1, -1> = Sequence + 1 end end Next LotOperationId end Response = AvailableSequences end service Service AddSpecsToLotOperation(LotOperationId) end service Service CanUserAddLotOperation(UserId) If UserId NE '' then Begin Case Case MemberOf(UserId, 'LEAD') Response = True$ Case MemberOf(UserId, 'SUPERVISOR') Response = True$ Case MemberOf(UserId, 'ENGINEER') Response = True$ Case MemberOf(UserId, 'ENG_TECH') Response = True$ Case Otherwise$ Response = False$ End Case end 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 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, 'String') SRP_JSON(objJSON, 'SetValue', 'DateTimeIn', OConv(LotOperationRec, 'DT'), 'String') SRP_JSON(objJSON, 'SetValue', 'DateTimeOut', OConv(LotOperationRec, 'DT'), 'String') EquipmentId = LotOperationRec SRP_JSON(objJSON, 'SetValue', 'EquipmentId', EquipmentId) SRP_JSON(objJSON, 'SetValue', 'WaferInQty', LotOperationRec, 'Number') SRP_JSON(objJSON, 'SetValue', 'WaferOutQty', LotOperationRec, 'Number') SRP_JSON(objJSON, 'SetValue', 'OperatorInId', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'OperatorOutId', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'OperationSequence', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'DateTimeStart', OConv(LotOperationRec, 'DT'), 'String') SRP_JSON(objJSON, 'SetValue', 'DateTimeStop', OConv(LotOperationRec, 'DT'), 'String') SRP_JSON(objJSON, 'SetValue', 'MetTestId', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'CleanId', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'PackagingId', LotOperationRec) SRP_JSON(objJSON, 'SetValue', 'WaferCounterId', LotOperationRec) SRP_JSON(objJson, 'SetValue', 'MetTestTypeRequired', LotOperationRec, 'STRING') SRP_JSON(objJson, 'SetValue', 'MetTestRequired', LotOperationRec, 'Boolean') SRP_JSON(objJson, 'SetValue', 'PackagingRequired', LotOperationRec, 'Boolean') SRP_JSON(objJson, 'SetValue', 'CleanRequired', LotOperationRec, 'Boolean') SRP_JSON(objJson, 'SetValue', 'WaferCounterRequired', LotOperationRec, 'Boolean') SRP_JSON(objJSON, 'SetValue', 'OperationType', LotOperationRec) //Add OPERATION Object OperationJson = Operation_Services('ConvertRecordToJSON', LotOperationRec) 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 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, '', EquipmentId, 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 //OperationType = LotOperationRec //MetTestTypeRequired = LotOperationRec Recipes = '' ShowThickRecipes = False$ ShowResRecipes = False$ ShowCleanRecipes = False$ ShowSurfscanRecipes = False$ IsMetTestReqd = LotOperationRec IsCleanRequired = LotOperationRec If IsMetTestReqd then MetTestTypeRequired = LotOperationRec 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('GetAllMetrologoyRecipes', 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', 'Styled') SRP_JSON(objJSON, 'Release') end Response = JsonString end service Service StartLotOperation(LotOperationId, UserId) //1. Validate that it can be moved into the operation passed in. //2. Move in the lot //3. Return true is move in successfully //4. Return false if error moving in 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 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) //1. Validate that the lot is moved into the operation //2. Validate that the lot 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 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 = '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 ValidateLotOperation(LotOperationId) ErrorMessage = '' IsValid = True$ If RowExists('LOT_OPERATION', LotOperationId) then LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$) OperationId = LotOperationRec MetTestRequired = LotOperationRec MetTestTypeRequired = LotOperationRec PackagingRequired = LotOperationRec CleanRequired = LotOperationRec WaferCountRequired = LotOperationRec If MetTestRequired then MetTestsInSpec = True$ AssociatedMetTestIds = LotOperationRec 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 then //ToDo Check that the met tests meet the requirements. 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 then end If CleanRequired then end If WaferCountRequired then end end else ErrorMessage = 'Lot Operation not found' end If ErrorMessage NE '' then IsValid = False$ Error_Services('Add', ErrorMessage) end Response = IsValid end service Service ValidateFQA(LotOperationId) Response = False$ LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$) LotId = LotOperationRec OperationStartDtm = LotOperationRec RelevantMetTests = '' MetTests = Met_Test_Services('GetMetTestsByLotId', LotId) For each MetTestId in MetTests using @VM ThisMetTestRec = Database_Services('ReadDataRow', 'MET_TEST', MetTestId, True$, 0, False$) Next MetTestId end service Service AssociateClean(LotOperationId, CleanId, UserId) end service Service GetFinalQAOperationJson(LotId, Stage) end service