Function PSN_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 : PSN_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/30/20 djs Original programmer. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert LOGICAL $insert SERVICE_SETUP $insert PROD_SPEC_EQUATES $insert PRS_STAGE_EQUATES $Insert WO_MAT_QA_EQUATES $Insert QA_MET_EQUATES $Insert RDS_TEST_EQUATES $Insert RDS_TEST_PROP_EQUATES $Insert PRS_LAYER_EQU Declare function Database_Services, Psn_Services, obj_Prod_Spec, Error_Services, SRP_JSON, Cust_Epi_Part_Services Declare function Prod_Ver_Services, PRS_Stage_Services Declare subroutine Database_Services, Psn_Services, Error_Services, SRP_JSON GoToService else Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') end Return Response OR '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options BOOLEAN = True$, False$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // InitializeCritParams // //---------------------------------------------------------------------------------------------------------------------- Service InitializeCritParams(PSNo) PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) PSRec = 100 PSRec = -40 PSRec = 50 Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) end service Service CheckPSNStages(PSNo, Stage) Begin Case Case Stage Eq 'PRE' CleansCheck = Psn_Services('CheckCleansParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end Case Stage Eq 'LOAD' InstructionsCheck = Psn_Services('CheckInstructionParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end Case Stage Eq 'FWI' VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end Case Stage Eq 'LWI' VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end SurfaceCheck = Psn_Services('CheckSurfaceParms',PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end Case Stage Eq 'POST' CleansCheck = Psn_Services('CheckCleansParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end SurfaceCheck = Psn_Services('CheckSurfaceParms',PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end Case Stage Eq 'QA' OR 'UNLOAD' QAMetCheck = Psn_Services('CheckQAMetParms', PSNo, Stage) IF Error_Services('GetMessage') NE '' then Return end End Case GoSub CheckAdHoc Return end service Service CheckCleansParms(PSNo, Stage) Response = 1 StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') IF StageRec EQ 1 then IF StageRec EQ '' then FailReason = 'Clean Tool not selected for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end If StageRec EQ '' then FailReason = 'Clean Recipe not selected for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end else IF Stage EQ 'PRE' OR Stage EQ 'POST' then FailReason = 'Cleans Signature Required for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end return end service Service CheckVisualParms(PSNo, Stage) Response = 1 StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') If StageRec EQ 1 then IF StageRec EQ 1 then IF StageRec EQ '' then FailReason = 'Frontside LPD limits must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side Scratch Count IF StageRec EQ '' then FailReason = 'Frontside Scratch Count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side Scratch Length IF StageRec EQ '' then FailReason = 'Frontside Scratch Length must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side Pits IF StageRec EQ '' then FailReason = 'Frontside Pits count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side Mounds IF StageRec EQ '' then FailReason = 'Frontside Mounds count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side Spots IF StageRec EQ '' then FailReason = 'Frontside Spots count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side FOV IF StageRec EQ '' then Response = 'Frontside FOV must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Front Side BL Defects IF StageRec EQ '' then FailReason = 'Frontside BL Defects must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end end else IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then FailReason = 'Microscope Inspection Required for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end IF StageRec EQ 1 then //Back Side Scratches IF StageRec EQ '' then FailReason = 'Backside Scratch Count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Back Side Scratch Length IF StageRec EQ '' then FailReason = 'Backside Scratch Length must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end end else IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then FailReason = 'Brightlight Inspection Required for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end end else IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then FailReason = 'Visual Inspection Signature Required for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end return end service Service CheckInstructionParms(PSNo, Stage) Response = 1 StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') //Currently the only place where instruction would be required is the LOAD stage IF Stage EQ 'LOAD' then IF StageRec EQ '' then FailReason = 'Instructions Missing for ':Stage:' stage.' Error_Services('Add', FailReason) return end end Return end service Service CheckSurfaceParms(PSNo, Stage) FailReason = 1 StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') IF StageRec EQ 1 then SSRecipes = StageRec IF SSRecipes NE '' then For RecipePos = 1 To DCOUNT(SSRecipes, @VM) IF StageRec EQ '' then FailReason = 'SurfScan Defect Count must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Surf Haze IF StageRec EQ '' then FailReason = 'SurfScan Haze must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end //Surf sample qty IF StageRec EQ '' then FailReason = 'SurfScan Cassette Sample Size must be set for ':Stage:' stage.' Error_Services('Add', FailReason) return end Next RecipePos end else FailReason = 'No SurfScan Recipe has been set for ' : Stage : 'stage.' Error_Services('Add', FailReason) return end end else IF Stage EQ 'POST' OR Stage EQ 'LWI' then FailReason = 'SurfScan signature must be set to "Required" for ' : Stage : 'stage.' Error_Services('Add', FailReason) return end end return end service Service CheckQAMetParms(PSNo, Stage) FailReason = 1 StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') QAMetTests = StageRec IF QAMetTests NE '' then For MetTest = 1 to DCount(QAMetTests, @VM) IF StageRec EQ '' then FailReason = 'QA Metrology Tool class must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Tool Recipe must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Tool Recipe Pattern must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Minimum must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Maximum must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology slot must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Wafer Quantity must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Wafer Interval must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' then FailReason = 'QA Metrology Start must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end IF StageRec EQ '' AND StageRec EQ 'CRES' then FailReason = 'QA Metrology Phase min must be set for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end Next MetTest end else IF Stage EQ 'QA' OR Stage EQ 'UNLOAD' then FailReason = 'No Metrology Tests exist for ' : Stage : ' stage.' Error_Services('Add', FailReason) return end end return end service //---------------------------------------------------------------------------------------------------------------------- // UpdateQAMetrologyLimits // // Purpose: Update the specification limits for a particular QA metrology test. //---------------------------------------------------------------------------------------------------------------------- Service UpdateQAMetrologyLimits(WOMatQAKey, QAMetStage, QAMetProfile, QAMetSlot) TestFound = False$ ErrorMsg = '' If ( (WOMatQAKey NE '') and (QAMetStage NE '') and (QAMetProfile NE '') and (QAMetSlot NE '') ) then // Ensure QAMetProfile is prepended with a '1'. If QAMetProfile[1, 1] NE 1 then QAMetProfile = 1:QAMetProfile WOStepKey = Field(WOMatQAKey, '*', 1) : '*1' PSNo = Xlate('WO_STEP', WOStepKey, 'PROD_SPEC_ID', 'X') If PSNo NE '' then PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) If Error_Services('NoError') then // Retrieve new QA metrology data from PSN. SpecQAMetData = obj_Prod_Spec('GetQAMet',PSNo:@RM:PSRec) If SpecQAMetData NE '' then WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) If Error_Services('NoError') then RecQAMetStages = WOMatQARec RecQAMetTests = WOMatQARec RecQAMetSlots = WOMatQARec // Locate the desired stage, profile/test, and slot in the record. RecPos = '' For each RecQAMetStage in RecQAMetStages using @VM setting vPos RecQAMetTest = RecQAMetTests<0, vPos> RecQAMetSlot = RecQAMetSlots<0, vPos> If ( (RecQAMetStage EQ QAMetStage) and (RecQAMetTest EQ QAMetProfile) and (RecQAMetSlot EQ QAMetSlot) ) then // Found the position in the record RecPos = vPos end Until RecPos Next RecQAMetStage If RecPos then // Locate the desired stage, profile/test, and slot in the spec QAMetData structure. SpecQAMetStages = SpecQAMetData SpecQAMetTests = SpecQAMetData SpecQAMetSlots = SpecQAMetData For each SpecQAMetStage in SpecQAMetStages using @VM setting vPos SpecQAMetTest = SpecQAMetTests<0, vPos> SpecQAMetSlot = SpecQAMetSlots<0, vPos> SpecQAMetProfile = 1:SpecQAMetTest SpecPos = '' If ( (SpecQAMetStage EQ QAMetStage) and (SpecQAMetProfile EQ QAMetProfile) and (SpecQAMetSlot EQ QAMetSlot) ) then // Found the posotion in the spec QAMetData structure SpecPos = vPos end Until SpecPos Next SpecQAMetStage If SpecPos then // Update the limits and recipe WOMatQARec = SpecQAMetData WOMatQARec = SpecQAMetData WOMatQARec = SpecQAMetData WOMatQARec = SpecQAMetData WOMatQARec = SpecQAMetData WOMatQARec = SpecQAMetData Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, True$, True$) If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage') end else ErrorMsg = 'Failed to find desired stage, test, and slot in spec QAMetData structure.' end end else ErrorMsg = 'Failed to find desired stage, test, and slot in WO_MAT_QA record.' end end else // Error reading WO_MAT_QA record ErrorMsg = Error_Services('GetMessage') end end else ErrorMsg = 'Error retrieving QAMetData from obj_Prod_Spec.' end end else // Error reading PROD_SPEC record ErrorMsg = Error_Services('GetMessage') end end else ErrorMsg = 'Failed to find PSNo in WO_STEP record ':WOStepKey:'.' end end else ErrorMsg = 'Null WOMatQAKey, QAMetStage, QAMetProfile, or QAMetSlot passed into service.' end If ErrorMsg EQ '' then Response = True$ end else Response = False$ Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg) end End Service Service UpdateAllQAMetrologyLimits(WOMatQAKey) ErrorMsg = '' If WOMatQAKey NE '' then WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) RecStages = WOMatQARec RecProfiles = WOMatQARec RecSlots = WOMatQARec For each RecStage in RecStages using @VM setting vPos RecProfile = RecProfiles<0, vPos> RecSlot = RecSlots<0, vPos> PSN_Services('UpdateQAMetrologyLimits', WOMatQAKey, RecStage, RecProfile, RecSlot) If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage') Next RecStage end else ErrorMsg = 'Null WOMatQAKey passed into service.' end If ErrorMsg EQ '' then Response = True$ end else Response = False$ Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg) end end service Service UpdateAllQAMetrologyRecord(WOMatQAKey, stageToUpdate) ErrorMsg = '' If WOMatQAKey NE '' then WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) WOStepKey = Field(WOMatQAKey, '*', 1) : '*1' PSNo = Xlate('WO_STEP', WOStepKey, 'PROD_SPEC_ID', 'X') PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) CurrTestCount = DCOUNT(WOMatQARec<1>, @VM) SpecQAMetData = obj_Prod_Spec('GetQAMet',PSNo:@RM:PSRec) for each SpecTest in SpecQAMetData<1> using @VM setting vPos then If (WOMatQARec<1,vPos> EQ 'QA' OR WOMatQARec<1,vPos> EQ '') then WOMatQARec<1,vPos> = SpecQAMetData<1,vPos> if SpecQAMetData<2,vPos> EQ 'ADE' then SpecQAMetData<2,vPos> = '1ADE' if SpecQAMetData<2,vPos> EQ 'THICK_ONLY' then SpecQAMetData<2,vPos> = '1THICK_ONLY' if SpecQAMetData<2,vPos> EQ 'CRES' then SpecQAMetData<2,vPos> = '1CRES' WOMatQARec<2,vPos> = SpecQAMetData<2,vPos> WOMatQARec<3,vPos> = SpecQAMetData<3,vPos> WOMatQARec<4,vPos> = SpecQAMetData<4,vPos> WOMatQARec<5,vPos> = SpecQAMetData<5,vPos> WOMatQARec<6,vPos> = SpecQAMetData<6,vPos> WOMatQARec<7,vPos> = SpecQAMetData<7,vPos> WOMatQARec<8,vPos> = SpecQAMetData<8,vPos> WOMatQARec<9,vPos> = SpecQAMetData<9,vPos> WOMatQARec<16,vPos> = SpecQAMetData<14,vPos> WOMatQARec<26,vPos> = 0 end Next SpecTest Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, True$, True$) end else ErrorMsg = 'Null WOMatQAKey passed into service.' end If ErrorMsg EQ '' then Response = True$ end else Response = False$ Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg) end end service Service UpdateRDSMetrologyLimits(RDSNo) If RDSNo NE '' then If RowExists('RDS', RDSNo) then PSNo = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') If PSNo NE '' then RDSTestKeys = Xlate('RDS', RDSNo, 'RDS_TEST_KEYS', 'X') If RDSTestKeys NE '' then For each RDSTestKey in RDSTestKeys using @VM setting vPos // Code below adapted from obj_RDS_Test('Create') RDSTestRec = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKey) If Error_Services('NoError') then LayerSet = RDSTestRec Zone = RDSTestRec LayerSpecs = obj_Prod_Spec('GetLayerProp',PSNo:@RM:LayerSet:@RM:1) ;* Last parameter specifies no output conversion on return data LayerSpecs = FIELD(LayerSpecs,@FM,2,99) ;* Returns with the layer set ID in the first field of each line IF Not(Get_Status(errCode)) then WaferSize = XLATE( 'PROD_SPEC', PSNo, 'SUB_WAFER_SIZE', 'X' ) SubOrientation = XLATE('PROD_SPEC',PSNo,'SUB_ORIENTATION','X') ResUnits = LayerSpecs ReactorType = XLATE('PROD_SPEC',PSNo,PROD_SPEC_REACTOR_TYPE$,'X') ThickFilmMet = XLATE('PROD_SPEC',PSNo,PROD_SPEC_THICKFILM_MET$,'X') ;* Added 1/16/2009 JCH RDSTestRec = RDSNo RDSTestRec = LayerSet RDSTestRec = Zone RDSTestRec = WaferSize RDSTestRec = SubOrientation RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs FOR A = 11 TO 19 RDSTestRec = LayerSpecs NEXT A FOR A = 24 TO 32 RDSTestRec = LayerSpecs NEXT A FOR A = 37 TO 45 RDSTestRec = LayerSpecs NEXT A FOR A = 50 to 58 RDSTestRec = LayerSpecs NEXT A FOR A = 121 TO 129 RDSTestRec = LayerSpecs NEXT A RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = ReactorType IF ReactorType = 'P' OR ReactorType = 'EPP' OR ThickFilmMet = 1 THEN SpecMap = XLATE('PROD_SPEC',PSNo,PROD_SPEC_TEST_POINT_MAP$,'X') ;* Added 4/8/2009 JCH new field in PROD_SPEC IF SpecMap NE '' THEN RDSTestRec = SpecMap END ELSE ;* Added ThickFilmMet check - 1/16/2009 JCH AllTargetThicks = XLATE('PROD_SPEC',PSNo,'THICK_TARGET_ALL','X') TargetCnt = COUNT(AllTargetThicks,@VM) + (AllTargetThicks NE '') BEGIN CASE CASE TargetCnt = 2 CombinedThick = SUM(AllTargetThicks) CASE TargetCnt = 1 OR TargetCnt = 3 CombinedThick = AllTargetThicks[-1,'B':@VM] END CASE IF OCONV(CombinedThick,'MD2') > '65.0' THEN RDSTestRec = 'FTIR_T' END ELSE RDSTestRec = 'FTIR' END END END ELSE RDSTestRec = 'ASM17' ;* 17 Point linear test pattern until PROD_SPEC is updated support other types END Database_Services('WriteDataRow', 'RDS_TEST', RDSTestKey, RDSTestRec) end else Error_Services('Add', 'Error in ':Service:' service. Error calling obj_Prod_Spec("GetLayerProp")') end end Next RDSTestKey end else Error_Services('Add', 'Error in ':Service:' serivce. No RDS_TEST records found for RDS record ':RDSNo:'.') end end else Error_Services('Add', 'Error in ':Service:' serivce. Null PSNo returned for RDS record ':RDSNo:'.') end end else Error_Services('Add', 'Error in ':Service:' serivce. RDS record ':RDSNo:' does not exist.') end end else Error_Services('Add', 'Error in ':Service:' serivce. Null RDSNo passed in.') end end service Service ConvertRecordToJSON(KeyID, Record, ItemURL) jsonRecord = '' If KeyID NE '' then If Record EQ '' then Record = Database_Services('ReadDataRow', 'PROD_SPEC', KeyID) If Error_Services('NoError') then @DICT = Database_Services('GetTableHandle', 'DICT.PROD_SPEC') @ID = KeyID @RECORD = Record If SRP_JSON(objJSON, 'New', 'Object') then If SRP_JSON(objProdSpec, 'New', 'Object') then SRP_JSON(objProdSpec, 'SetValue', 'keyId', @ID) SRP_JSON(objProdSpec, 'SetValue', 'specType', OConv({SPEC_TYPE}, '[SPEC_TYPE_CONV]')) SRP_JSON(objProdSpec, 'SetValue', 'status', OConv({STATUS}, '[PROD_SPEC_STATUS_CONV]')) SRP_JSON(objProdSpec, 'SetValue', 'minutesPerWafer', OConv({MINUTES_PER_WAFER}, 'MD3')) SRP_JSON(objProdSpec, 'SetValue', 'proveInTime', OConv({PROVEIN_MIN}, 'MD3,')) SRP_JSON(objProdSpec, 'SetValue', 'layerType', {LAYER_TYPE}) SRP_JSON(objProdSpec, 'SetValue', 'reactorType', OConv({REACTOR_TYPE}, '[REACT_TYPE_CONV,OPSREF]')) SRP_JSON(objProdSpec, 'SetValue', 'susceptorType', {SUSCEPTOR_TYPE}) SRP_JSON(objProdSpec, 'SetValue', 'tubePressureType', {TUBE_PRESSURE_TYPE}) ProdVerNos = {PROD_VER_NO} CustEpiKeys = {CEP_KEYS} StageKeys = {STAGE} QAMetStages = {QA_MET_STAGE} QAMetTests = {QA_MET_TEST} QAMetProps = {QA_MET_PROP} QAMetPropDescs = {QA_MET_PROP_DESC} QAMetToolClasses = {QA_MET_TOOL_CLASS} QAMetRecipes = {QA_MET_RECIPE} QAMetRecipePatterns = {QA_MET_RECIPE_PATTERN} QAMetMins = {QA_MET_MIN} QAMetMaxes = {QA_MET_MAX} QAPhaseMins = {QA_MET_PHASE_MIN} QAMetSlots = {QA_MET_SLOT} QAMetWfrQtys = {QA_MET_WFR_QTY} QAMetReactScheds = {QA_MET_REACT_SCHED} QAMetIntervals = {QA_MET_INTERVAL} QAMetStarts = {QA_MET_START} QAMetSeqs = {QA_MET_SEQUENCE} // Add recipe layer object array If SRP_JSON(objLayerArray, 'New', 'Array') then LayerNos = {LAYER_NO} LayerIDs = {LS_ID} LayerTypes = {LS_TYPE} LayerRecipes = {LS_RECIPE} LayerDopants = {LS_DOPANT} LayerThickMins = OConv({LS_THICK_MIN}, '[MET_PROP_CONV,THICK]') LayerThickTargets = OConv({LS_THICK_TARG}, '[MET_PROP_CONV,THICK]') LayerThickMaxes = OConv({LS_THICK_MAX}, '[MET_PROP_CONV,THICK]') LayerThickUnits = {LS_THICK_UNITS} LayerThickAMins = OConv({LS_THICKA_MIN}, '[MET_PROP_CONV,THICKA]') LayerThickATargets = OConv({LS_THICKA_TARG}, '[MET_PROP_CONV,THICKA]') LayerThickAMaxes = OConv({LS_THICKA_MAX}, '[MET_PROP_CONV,THICKA]') LayerThickAUnits = {LS_THICKA_UNITS} LayerResMins = OConv({LS_RES_MIN}, '[MET_PROP_CONV,RES]') LayerResTargets = OConv({LS_RES_TARG}, '[MET_PROP_CONV,RES]') LayerResMaxes = OConv({LS_RES_MAX}, '[MET_PROP_CONV,RES]') LayerResUnits = {LS_RES_UNITS} LayerSResMins = OConv({LS_SRES_MIN}, '[MET_PROP_CONV,SRES]') LayerSResTargets = OConv({LS_SRES_TARG}, '[MET_PROP_CONV,SRES]') LayerSResMaxes = OConv({LS_SRES_MAX}, '[MET_PROP_CONV,SRES]') LayerSResUnits = {LS_SRES_UNITS} If LayerNos NE '' then For each LayerNo in LayerNos using @VM setting vPos If SRP_JSON(objLayer, 'New', 'Object') then SRP_JSON(objLayer, 'SetValue', 'layerNo', layerNo) SRP_JSON(objLayer, 'SetValue', 'layerId', LayerIDs<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerType', LayerTypes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerRecipe', LayerRecipes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerDopant', LayerDopants<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickMin', LayerThickMins<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickTarget', LayerThickTargets<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickMax', LayerThickMaxes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickUnits', LayerThickUnits<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickAMin', LayerThickAMins<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickATarget', LayerThickATargets<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickAMaxes', LayerThickAMaxes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerThickAUnits', LayerThickAUnits<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerResMin', LayerResMins<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerResTarget', LayerResTargets<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerResMax', LayerResMaxes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerResUnits', LayerResUnits<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerSResMin', LayerSResMins<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerSResTarget', LayerSResTargets<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerSResMax', LayerSResMaxes<0, vPos>) SRP_JSON(objLayer, 'SetValue', 'layerSResUnits', LayerSResUnits<0, vPos>) SRP_JSON(objLayerArray, 'Add', objLayer) SRP_JSON(objLayer, 'Release') end Next LayerNo end SRP_JSON(objProdSpec, 'Set', 'recipeLayers', objLayerArray) SRP_JSON(objLayerArray, 'Release') end // Add Prod Ver object array If ProdVerNos NE '' then If SRP_JSON(objProdVerArray, 'New', 'Array') then For each ProdVerNo in ProdVerNos using @VM ProdVerJSON = Prod_Ver_Services('ConvertRecordToJSON', ProdVerNo) If SRP_JSON(objProdVer, 'Parse', ProdVerJSON) EQ '' then objTemp = SRP_JSON(objProdVer, 'Get', 'prodVer') SRP_JSON(objProdVerArray, 'Add', objTemp) SRP_JSON(objTemp, 'Release') SRP_JSON(objProdVer, 'Release') end Next ProdVerNo SRP_JSON(objProdSpec, 'Set', 'prodVers', objProdVerArray) SRP_JSON(objProdVerArray, 'Release') end end // Epi Part object array EpiPartNo = {EPI_PART_NO} If EpiPartNo NE '' then If SRP_JSON(objEpiPart, 'New', 'Object') then SRP_JSON(objEpiPart, 'SetValue', 'keyID', EpiPartNo) WaferSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X') SRP_JSON(objEpiPart, 'SetValue', 'waferSize', WaferSize) SRP_JSON(objProdSpec, 'Set', 'epiPart', objEpiPart) SRP_JSON(objEpiPart, 'Release') end end // Cust Epi Part object array If CustEpiKeys NE '' then If SRP_JSON(objCustEpiArray, 'New', 'Array') then For each CustEpiKey in CustEpiKeys using @VM CustEpiJSON = Cust_Epi_Part_Services('ConvertRecordToJSON', CustEpiKey) If SRP_JSON(objCustEpi, 'Parse', CustEpiJSON) EQ '' then objTemp = SRP_JSON(objCustEpi, 'Get', 'custEpiPart') SRP_JSON(objCustEpiArray, 'Add', objTemp) SRP_JSON(objTemp, 'Release') SRP_JSON(objCustEpi, 'Release') end Next CustEpiKey end SRP_JSON(objProdSpec, 'Set', 'custEpiParts', objCustEpiArray) SRP_JSON(objCustEpiArray, 'Release') end // Add PRS Stage (Run Stage) object array If StageKeys NE '' then If SRP_JSON(objStageArray, 'New', 'Array') then For each StageKey in StageKeys using @VM PRSKey = KeyID:'*':StageKey PRSStageJSON = PRS_Stage_Services('ConvertRecordToJSON', PRSKey) If SRP_JSON(objPRSStage, 'Parse', PRSStageJSON) EQ '' then objTemp = SRP_JSON(objPRSStage, 'Get', 'prsStage') SRP_JSON(objStageArray, 'Add', objTemp) SRP_JSON(objTemp, 'Release') SRP_JSON(objPRSStage, 'Release') end Next StageKey end SRP_JSON(objProdSpec, 'Set', 'prsStages', objStageArray) SRP_JSON(objStageArray, 'Release') end SRP_JSON(objJSON, 'Set', 'prodSpec', objProdSpec) SRP_JSON(objProdSpec, 'Release') end If itemURL NE '' then // The itemURL was passed in so add HAL+JSON properties. // Create the _links property and then all link objects needed for this resource. If SRP_JSON(objLinks, 'New', 'Object') then // Create a self link. If SRP_JSON(objLink, 'New', 'Object') then SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String') SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String') SRP_JSON(objLinks, 'Set', 'self', objLink) SRP_JSON(objLink, 'Release') end SRP_JSON(objJSON, 'Set', '_links', objLinks) SRP_JSON(objLinks, 'Release') end // Create the _class property for this resource. SRP_JSON(objJSON, 'SetValue', '_class', 'resource') end jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled') SRP_JSON(objJSON, 'Release') end else Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.') end end end else Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.') end Response = jsonRecord end service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// * * * * * * CheckAdHoc: * * * * * * StageRecKey = PSNo: '*' : Stage StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X') IF StageRec EQ 1 then GoSub CheckCleansParms IF Error_Services('GetMessage') NE '' then Return end end IF StageRec EQ 1 then GoSub CheckVisualParms IF Error_Services('GetMessage') NE '' then Return end end IF StageRec EQ 1 then GoSub CheckSurfaceParms IF Error_Services('GetMessage') NE '' then Return end end QAMetTests = StageRec IF QAMetTests<1,1> NE '' then GoSub CheckQAMetParms IF Error_Services('GetMessage') NE '' then Return end end return