Function Epi_Part_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 : Epi_Part_Services Description : Handler program for all module related services. Notes : The generic parameters should contain all the necessary information to process the services. Often this will be information like the data Record and Key ID. 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) 06/29/17 dmb Original programmer. - [EPIOI-8] ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert APP_INSERTS $insert SERVICE_SETUP $insert WO_LOG_EQUATES $insert EPI_PART_EQUATES $insert PROD_VER_EQUATES $insert PROD_SPEC_EQUATES $insert RLIST_EQUATES Declare subroutine Error_Services, Epi_Part_Services, Memory_Services, RList, Database_Services Declare function SRP_Array, Epi_Part_Services, Memory_Services, Database_Services, SRP_Sort_Array GoToService else Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') end Return Response else '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options REACTORTYPES = 'ASM', 'ASM+', 'HTR', 'EpiPro', 'GaN' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // SetReactorUtilization // // Sets the utilization constant for the indicated reactor type. //---------------------------------------------------------------------------------------------------------------------- Service SetReactorUtilization(ReactorType=REACTORTYPES, ReactorUtilization) Convert @Lower_Case to @Upper_Case in ReactorType If ReactorType NE '' AND ReactorUtilization NE '' then Database_Services('WriteDataRow', 'CONFIG', 'ReactUtil*' : ReactorType, ReactorUtilization, True$) If Error_Services('NoError') then Memory_Services('SetValue', ServiceModule : '*GetReactorUtilization*' : ReactorType, ReactorUtilization) end end else Error_Services('Add', 'ReactorType or ReactorUtilization argument was missing from the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // GetReactorUtilization // // Returns the utilization constant for the indicated reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetReactorUtilization(ReactorType=REACTORTYPES) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : ReactorType ReactorUtilization = Memory_Services('GetValue', ServiceKeyID) If ReactorUtilization EQ '' then If ReactorType NE '' then ReactorUtilization = Database_Services('ReadDataRow', 'CONFIG', 'ReactUtil*' : ReactorType) If Error_Services('NoError') then Memory_Services('SetValue', ServiceKeyID, ReactorUtilization) end end else Error_Services('Add', 'ReactorType argument was missing from the ' : Service : ' service.') end end Response = ReactorUtilization end service //---------------------------------------------------------------------------------------------------------------------- // GetProdVerNo // // Returns the minutes per wafer associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetProdVerNo(EpiPartNo, ReactorType=REACTORTYPES) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType ProdVerNo = Memory_Services('GetValue', ServiceKeyID) If ProdVerNo EQ '' then If EpiPartNo NE '' AND ReactorType NE '' then EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo) If Error_Services('NoError') then // Convert the friendly reactor type name to the internal one used in the database. Begin Case Case ReactorType _EQC 'EpiPro' ; ReactorType = 'EPP' Case ReactorType _EQC 'ASM' ; ReactorType = 'EPS' End Case ProdVerNos = EpiPartRec NumProdVers = DCount(ProdVerNos, @VM) FoundProdVer = False$ For ProdVerCnt = NumProdVers to 1 Step -1 ProdVerNo = ProdVerNos<0, ProdVerCnt> ProdVerRec = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo) If Error_Services('NoError') then ProdVerReactorType = ProdVerRec If ProdVerReactorType _EQC ReactorType then FoundProdVer = True$ end Until FoundProdVer Next ProdVerCnt If FoundProdVer then Memory_Services('SetValue', ServiceKeyID, ProdVerNo) end end end else Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end Response = ProdVerNo end service //---------------------------------------------------------------------------------------------------------------------- // GetMinutesPerWaferCost // // Returns the minutes per wafer needed for costing associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetMinutesPerWaferCost(EpiPartNo, ReactorType=REACTORTYPES) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType MinutesPerWafer = Memory_Services('GetValue', ServiceKeyID) If MinutesPerWafer EQ '' then If EpiPartNo NE '' AND ReactorType NE '' then ProdVerNo = Epi_Part_Services('GetProdVerNo', EpiPartNo, ReactorType) If Error_Services('NoError') then ProdVerRec = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo) If Error_Services('NoError') then ProdSpecNo = ProdVerRec[-1, 'B' : @VM] ; // Always get the last Prod Spec No to use. ProdSpecRec = Database_Services('ReadDataRow', 'PROD_SPEC', ProdSpecNo) If Error_Services('NoError') then MinutesPerWafer = ProdSpecRec MinutesPerWafer = Oconv(MinutesPerWafer, 'MD3') Memory_Services('SetValue', ServiceKeyID, MinutesPerWafer) end end end end else Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end Response = MinutesPerWafer end service //---------------------------------------------------------------------------------------------------------------------- // SetMinutesPerWaferScheduler // // Sets the minutes per wafer needed for scheduling associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service SetMinutesPerWaferScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer) Convert @Lower_Case to @Upper_Case in ReactorType * If EpiPartNo NE '' AND ReactorType NE '' AND MinutesPerWafer NE '' then If EpiPartNo NE '' AND ReactorType NE '' then EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo) If Error_Services('NoError') then ReactorTypes = 'ASM,ASM+,HTR,EPIPRO,GAN' Locate ReactorType in ReactorTypes using ',' setting cPos then If MinutesPerWafer NE '' then MinutesPerWafer = Iconv(MinutesPerWafer, 'MD3') EpiPartRec = MinutesPerWafer Database_Services('WriteDataRow', 'EPI_PART', EpiPartNo, EpiPartRec, True$) If Error_Services('NoError') then Memory_Services('SetValue', ServiceModule : '*GetMinutesPerWaferScheduler*' : EpiPartNo : '*' : ReactorType, Oconv(MinutesPerWafer, 'MD3')) end end end end else * Error_Services('Add', 'EpiPartNo, ReactorType or MinutesPerWafer argument was missing from the ' : Service : ' service.') Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // GetMinutesPerWaferScheduler // // Returns the minutes per wafer needed for scheduling associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetMinutesPerWaferScheduler(EpiPartNo, ReactorType=REACTORTYPES) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType MinutesPerWafer = Memory_Services('GetValue', ServiceKeyID) If MinutesPerWafer EQ '' then If EpiPartNo NE '' AND ReactorType NE '' then EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo) If Error_Services('NoError') then ReactorTypes = 'ASM,ASM+,HTR,EPIPRO,GAN' Locate ReactorType in ReactorTypes using ',' setting cPos then MinutesPerWafer = EpiPartRec If (MinutesPerWafer + 0) NE 0 then MinutesPerWafer = Oconv(MinutesPerWafer, 'MD3') Memory_Services('SetValue', ServiceKeyID, MinutesPerWafer) end else Error_Services('Add', 'Minutes per wafer for Epi Part #' : EpiPartNo : ' is zero. Reactor Type: ' : ReactorType) end end end end else Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end Response = MinutesPerWafer end service //---------------------------------------------------------------------------------------------------------------------- // GetIdealWafersPerDayScheduler // // Returns the ideal number of wafers per day associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetIdealWafersPerDayScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType : '*' : MinutesPerWafer WafersPerDay = Memory_Services('GetValue', ServiceKeyID) If WafersPerDay EQ '' then If EpiPartNo NE '' AND ReactorType NE '' then If MinutesPerWafer EQ '' then MinutesPerWafer = Epi_Part_Services('GetMinutesPerWaferScheduler', EpiPartNo, ReactorType) If MinutesPerWafer EQ '' OR MinutesPerWafer EQ 0 then Error_Services('Add', 'Unexpected minutes per wafer value in EPI_PART #' : EpiPartNo) end If Error_Services('NoError') then WafersPerDay = 1440 / MinutesPerWafer WafersPerDay = Oconv(Iconv(WafersPerDay, 'MD2'), 'MD2') Memory_Services('SetValue', ServiceKeyID, WafersPerDay) end end else Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end Response = WafersPerDay end service //---------------------------------------------------------------------------------------------------------------------- // GetAdjustedWafersPerDayScheduler // // Returns the adjusted number of wafers per day associated to the indicated Epi Part and reactor type. //---------------------------------------------------------------------------------------------------------------------- Service GetAdjustedWafersPerDayScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer) Convert @Lower_Case to @Upper_Case in ReactorType ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType WafersPerDay = Memory_Services('GetValue', ServiceKeyID) If WafersPerDay EQ '' then If EpiPartNo NE '' AND ReactorType NE '' then If MinutesPerWafer EQ '' then MinutesPerWafer = Epi_Part_Services('GetMinutesPerWaferScheduler', EpiPartNo, ReactorType) If Error_Services('NoError') then Utilization = Epi_Part_Services('GetReactorUtilization', ReactorType) If Error_Services('NoError') then IdealWafersPerDay = Epi_Part_Services('GetIdealWafersPerDayScheduler', EpiPartNo, ReactorType, MinutesPerWafer) WafersPerDay = IdealWafersPerDay * (Utilization / 100) WafersPerDay = Oconv(Iconv(WafersPerDay, 'MD2'), 'MD2') If ReactorType _EQC 'EpiPro' then WafersPerDay = WafersPerDay * 2 Memory_Services('SetValue', ServiceKeyID, WafersPerDay) end end end else Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.') end end Response = WafersPerDay end service //---------------------------------------------------------------------------------------------------------------------- // GetEpiParts // // Input: ReactType // // Output: A @FM delimited list of Epi Part keys. //---------------------------------------------------------------------------------------------------------------------- Service GetEpiParts(ReactType=REACTORTYPES) ErrorMsg = '' EpiPartList = '' If ReactType NE '' then If ReactType EQ 'EpiPro' then ReactType = 'EPP' EpiPartList = '' Query = 'SELECT EPI_PART WITH REACT_TYPE EQ ':Quote(ReactType) RList(Query, TARGET_ACTIVELIST$, '', '', '') StatusCode = '' If Not(Get_Status(StatusCode)) then EOF = False$ Loop Readnext EpiPartKey else EOF = True$ Until EOF EpiPartList<-1> = EpiPartKey Repeat end else ErrorMsg = 'Error in ':Service:' service. RList call failed. Error code: ':StatusCode:'.' end end else ErrorMsg = 'Error in ':Service:' service. Null ReactType passed in!' end If ErrorMsg EQ '' then Response = EpiPartList end else Error_Services('Add', ErrorMsg) end End Service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////