Compare commits
	
		
			11 Commits
		
	
	
		
			e5f0e9b7f1
			...
			f6ba173f47
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f6ba173f47 | |||
| 98e02f8c40 | |||
| de6296b1d3 | |||
| ebd8b36d13 | |||
| 803f946c7e | |||
| 16c7bc6926 | |||
| 216df9b4ef | |||
| 5eec9386c2 | |||
| f3ad7adfa8 | |||
| c4fbf7c1d9 | |||
| 2a28c4b743 | 
| @ -581,171 +581,131 @@ Refresh: | ||||
|     // RDS_UNLOAD | ||||
|      | ||||
|     If @WINDOW EQ 'RDS_UNLOAD' then | ||||
|          | ||||
|         DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
|              | ||||
| 		CtrlName       = @WINDOW:'.EDT_QA_MET' | ||||
| 		Set_Property(@Window : '.MET_TEST', 'VISIBLE', False$) | ||||
| 		Set_Property(CtrlName, 'VISIBLE', True$) | ||||
| 		MetList        = Get_Property(CtrlName,'LIST') | ||||
| 		ThickOutOfSpec = False$ | ||||
| 		CresOutOfSpec  = False$ | ||||
| 		MLCnt          = COUNT(MetList,@FM) + (MetList NE '') | ||||
| 		FOR Line = 1 TO MLCnt | ||||
| 			IF MetList<Line,COL$UL_MET_TEST> NE '' THEN | ||||
| 				MetResult        = MetList<Line,COL$UL_MET_RESULT> | ||||
| 				MetMin           = MetList<Line,COL$UL_MET_MIN> | ||||
| 				MetMax           = MetList<Line,COL$UL_MET_MAX> | ||||
| 				PhaseMin         = MetList<Line,COL$UL_MET_PHASE_MIN> | ||||
| 				PhaseResult      = MetList<Line,COL$UL_MET_PHASE_RESULT> | ||||
| 				ScanRecipe       = MetList<Line,COL$UL_MET_RECIPE> | ||||
| 				PSN              = Get_Property(@Window : '.PSN', 'TEXT') | ||||
| 				PRSStageKey      = PSN:'*UNLOAD' | ||||
| 				MetTest          = MetList<Line,COL$UL_MET_TEST> | ||||
| 				PRSStageRec      = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey) | ||||
| 				SpecTests        = PRSStageRec<PRS_STAGE_MET_TEST$> | ||||
| 				SpecRecipe       = '' | ||||
| 				RDSNo            = Get_Property(@Window:'.RDS_NO', 'TEXT') | ||||
| 				QAMetKey         = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') | ||||
| 				WOMatQARec       = Database_Services('ReadDataRow', 'WO_MAT_QA', QAMetKey) | ||||
| 				DataPoints       = WOMatQARec<WO_MAT_QA_DATA_POINTS$, Line> | ||||
| 				Begin Case | ||||
| 					Case MetTest EQ 'THICK_ONLY' | ||||
| 						// Check each point to see if any are out of spec | ||||
| 						For each DataPoint in DataPoints using @SVM setting ThickIndex | ||||
| 						Until DataPoint EQ '' | ||||
| 							Begin Case | ||||
| 								Case ThickIndex GT 10 | ||||
| 									Null | ||||
| 								Case (DataPoint EQ '') | ||||
| 									ThickOutOfSpec = True$ | ||||
| 								Case (DataPoint GT MetMax) OR (DataPoint LT MetMin) | ||||
| 									ThickOutOfSpec = True$ | ||||
| 							End Case | ||||
| 						Next DataPoint | ||||
| 						 | ||||
| 					Case MetTest EQ 'CRES' | ||||
| 						// Check critical points to see if any are out of spec (both HgCV and Phase) | ||||
| 						CriticalPoints = '1,2,5,6,9' | ||||
| 						For each DataPoint in DataPoints 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$ | ||||
| 								Case (PhaseDataPoint EQ '') and CriticalPoint | ||||
| 									CresOutOfSpec = True$ | ||||
| 								Case (HgCVDataPoint GT MetMax) OR (HgCVDataPoint LT MetMin) and CriticalPoint | ||||
| 									CresOutOfSpec = True$ | ||||
| 								Case (PhaseDataPoint LT PhaseMin) and CriticalPoint | ||||
| 									CresOutOfSpec = True$ | ||||
| 							End Case | ||||
| 						Next DataPoint | ||||
| 				End Case | ||||
| 				QAMetOutofSpec = (ThickOutOfSpec or CresOutOfSpec) | ||||
| 				Locate MetTest in SpecTests using @VM setting vPos then | ||||
| 					SpecRecipe = PRSStageRec<PRS_STAGE_MET_RECIPE$, vPos> | ||||
| 				end                 | ||||
| 				NoError = True$ | ||||
|  | ||||
|         If (DevelopmentFlag EQ True$) then | ||||
|              | ||||
|             CtrlName       = @WINDOW:'.EDT_QA_MET' | ||||
|             Set_Property(@Window : '.MET_TEST', 'VISIBLE', False$) | ||||
|             Set_Property(CtrlName, 'VISIBLE', True$) | ||||
|             MetList        = Get_Property(CtrlName,'LIST') | ||||
|             ThickOutOfSpec = False$ | ||||
|             CresOutOfSpec  = False$ | ||||
|             MLCnt          = COUNT(MetList,@FM) + (MetList NE '') | ||||
|             FOR Line = 1 TO MLCnt | ||||
|                 IF MetList<Line,COL$UL_MET_TEST> NE '' THEN | ||||
|                     MetResult        = MetList<Line,COL$UL_MET_RESULT> | ||||
|                     MetMin           = MetList<Line,COL$UL_MET_MIN> | ||||
|                     MetMax           = MetList<Line,COL$UL_MET_MAX> | ||||
|                     PhaseMin         = MetList<Line,COL$UL_MET_PHASE_MIN> | ||||
|                     PhaseResult      = MetList<Line,COL$UL_MET_PHASE_RESULT> | ||||
|                     ScanRecipe       = MetList<Line,COL$UL_MET_RECIPE> | ||||
|                     PSN              = Get_Property(@Window : '.PSN', 'TEXT') | ||||
|                     PRSStageKey      = PSN:'*UNLOAD' | ||||
|                     MetTest          = MetList<Line,COL$UL_MET_TEST> | ||||
|                     PRSStageRec      = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey) | ||||
|                     SpecTests        = PRSStageRec<PRS_STAGE_MET_TEST$> | ||||
|                     SpecRecipe       = '' | ||||
|                     RDSNo            = Get_Property(@Window:'.RDS_NO', 'TEXT') | ||||
|                     QAMetKey         = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') | ||||
|                     WOMatQARec       = Database_Services('ReadDataRow', 'WO_MAT_QA', QAMetKey) | ||||
|                     DataPoints       = WOMatQARec<WO_MAT_QA_DATA_POINTS$, Line> | ||||
|                     Begin Case | ||||
|                         Case MetTest EQ 'THICK_ONLY' | ||||
|                             // Check each point to see if any are out of spec | ||||
|                             For each DataPoint in DataPoints using @SVM setting ThickIndex | ||||
|                             Until DataPoint EQ '' | ||||
|                                 Begin Case | ||||
|                                     Case ThickIndex GT 10 | ||||
|                                         Null | ||||
|                                     Case (DataPoint EQ '') | ||||
|                                         ThickOutOfSpec = True$ | ||||
|                                     Case (DataPoint GT MetMax) OR (DataPoint LT MetMin) | ||||
|                                         ThickOutOfSpec = True$ | ||||
|                                 End Case | ||||
|                             Next DataPoint | ||||
|                              | ||||
|                         Case MetTest EQ 'CRES' | ||||
|                             // Check critical points to see if any are out of spec (both HgCV and Phase) | ||||
|                             CriticalPoints = '1,2,5,6,9' | ||||
|                             For each DataPoint in DataPoints 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$ | ||||
|                                     Case (PhaseDataPoint EQ '') and CriticalPoint | ||||
|                                         CresOutOfSpec = True$ | ||||
|                                     Case (HgCVDataPoint GT MetMax) OR (HgCVDataPoint LT MetMin) and CriticalPoint | ||||
|                                         CresOutOfSpec = True$ | ||||
|                                     Case (PhaseDataPoint LT PhaseMin) and CriticalPoint | ||||
|                                         CresOutOfSpec = True$ | ||||
|                                 End Case | ||||
|                             Next DataPoint | ||||
|                     End Case | ||||
|                     QAMetOutofSpec = (ThickOutOfSpec or CresOutOfSpec) | ||||
|                     Locate MetTest in SpecTests using @VM setting vPos then | ||||
|                         SpecRecipe = PRSStageRec<PRS_STAGE_MET_RECIPE$, vPos> | ||||
|                     end                 | ||||
|                     NoError = True$ | ||||
|  | ||||
|                     If (MetList<Line,COL$UL_MET_RESULT> EQ '') then | ||||
|                         Color = YELLOW$ | ||||
|                         stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     If QAMetOutofSpec EQ True$ then | ||||
|                         Color   = BYELLOW$:@FM:BLACK$:@FM:BYELLOW$:@FM:BLACK$ | ||||
|                         stat    = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     If (MetResult LT MetMin) then | ||||
|                         Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
|                         stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     If (MetResult GT MetMax) then | ||||
|                         Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
|                         stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     If (PhaseResult LT PhaseMin) then | ||||
|                         Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
|                         stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_PHASE_RESULT, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     QAFailReason = WOMatQARec<WO_MAT_QA_FAIL_REASON$, Line> | ||||
|                     DetectedFail = Index(QAFailReason, 'Number of data points is less than the required amount', 1) | ||||
|                     If (ScanRecipe NE SpecRecipe) OR (DetectedFail) then | ||||
|                         Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
|                         stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RECIPE, Line, Color) | ||||
|                         NoError = False$ | ||||
|                     end | ||||
|                      | ||||
|                     If (NoError EQ True$) then | ||||
|                         Color = GREEN$ | ||||
|                         stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color) | ||||
|                     end | ||||
|                      | ||||
|                 END	ELSE | ||||
|                     Color = GREEN$ | ||||
|                     stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color) | ||||
|                 END | ||||
|                  | ||||
|             NEXT Line | ||||
|              | ||||
|             Set_Property(@WINDOW:'.BUTTON_11','ENABLED',EnableUnloadButton) | ||||
|              | ||||
|             IF MemberOf(@USER4, 'OI_ADMIN') THEN | ||||
|                 Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',1) | ||||
|             END ELSE | ||||
|                 Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',0) | ||||
|             END | ||||
|              | ||||
|              | ||||
|         end else | ||||
|              | ||||
|             CtrlName = @WINDOW:'.MET_TEST'                 | ||||
|             Set_Property(@Window : '.EDT_QA_MET', 'VISIBLE', False$) | ||||
|             Set_Property(CtrlName, 'VISIBLE', True$) | ||||
|             MetList = Get_Property(CtrlName,'LIST') | ||||
|              | ||||
|             MLCnt = COUNT(MetList,@FM) + (MetList NE '') | ||||
|             FOR Line = 1 TO MLCnt | ||||
|                 IF MetList<Line,COL$MET_TEST> NE '' THEN | ||||
|                     BEGIN CASE | ||||
|                         CASE MetList<Line,COL$MET_RESULT> = ''  | ||||
|                             Color = YELLOW$ | ||||
|                         CASE MetList<Line,COL$MET_RESULT> < MetList<Line,COL$MET_MIN> OR MetList<Line,COL$MET_RESULT> > MetList<Line,COL$MET_MAX> | ||||
|                             Color = RED$ | ||||
|                         CASE 1 | ||||
|                             Color = GREEN$ | ||||
|                     END CASE | ||||
|                      | ||||
|                 END	ELSE | ||||
|                     Color = GREEN$ | ||||
|                 END;* End of check for Met Test on the current line | ||||
|                  | ||||
|                 stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color) | ||||
|             NEXT Line | ||||
|              | ||||
|             Set_Property(@WINDOW:'.BUTTON_11','ENABLED',EnableUnloadButton) | ||||
|              | ||||
|             IF MemberOf(@USER4, 'OI_ADMIN') THEN | ||||
|                 Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',1) | ||||
|             END ELSE | ||||
|                 Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',0) | ||||
|             END | ||||
|         end	 | ||||
|     end | ||||
| 				If (MetList<Line,COL$UL_MET_RESULT> EQ '') then | ||||
| 					Color = YELLOW$ | ||||
| 					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				If QAMetOutofSpec EQ True$ then | ||||
| 					Color   = BYELLOW$:@FM:BLACK$:@FM:BYELLOW$:@FM:BLACK$ | ||||
| 					stat    = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				If (MetResult LT MetMin) then | ||||
| 					Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
| 					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				If (MetResult GT MetMax) then | ||||
| 					Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
| 					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				If (PhaseResult LT PhaseMin) then | ||||
| 					Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
| 					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_PHASE_RESULT, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				QAFailReason = WOMatQARec<WO_MAT_QA_FAIL_REASON$, Line> | ||||
| 				DetectedFail = Index(QAFailReason, 'Number of data points is less than the required amount', 1) | ||||
| 				If (ScanRecipe NE SpecRecipe) OR (DetectedFail) then | ||||
| 					Color = RED$:@FM:'':@FM:BRED$:@FM:'' | ||||
| 					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RECIPE, Line, Color) | ||||
| 					NoError = False$ | ||||
| 				end | ||||
| 				 | ||||
| 				If (NoError EQ True$) then | ||||
| 					Color = GREEN$ | ||||
| 					stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color) | ||||
| 				end | ||||
| 				 | ||||
| 			END	ELSE | ||||
| 				Color = GREEN$ | ||||
| 				stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color) | ||||
| 			END | ||||
| 			 | ||||
| 		NEXT Line | ||||
| 		 | ||||
| 		Set_Property(@WINDOW:'.BUTTON_11','ENABLED',EnableUnloadButton) | ||||
| 		 | ||||
| 		IF MemberOf(@USER4, 'OI_ADMIN') THEN | ||||
| 			Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',1) | ||||
| 		END ELSE | ||||
| 			Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',0) | ||||
| 		END | ||||
| 	end | ||||
|     * End of check for Unload OR Post_Epi windows | ||||
|      | ||||
|     **************************************************************************************************************************************** | ||||
| @ -2669,9 +2629,8 @@ MetTestDC: | ||||
|     Lines	  = Get_Property(@WINDOW:'.MET_TEST', 'LIST') | ||||
|     TestLine  = Lines<CurrRow> | ||||
|     LWRHOTest = Indexc(TestLine, 'LW_RHO', 1) | ||||
|     DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
|      | ||||
|     If (DevelopmentFlag EQ True$) and (@Window EQ 'RDS_UNLOAD') and (LWRHOTest EQ False$)  then | ||||
|     If (@Window EQ 'RDS_UNLOAD') and (LWRHOTest EQ False$)  then | ||||
|         Ctrls := @WINDOW:'.EDT_QA_MET':@RM	; Props := 'SELPOS':@RM | ||||
|         Ctrls := @WINDOW:'.EDT_QA_MET'		; Props := 'LIST' | ||||
|     end else | ||||
| @ -2708,8 +2667,7 @@ MetTestDC: | ||||
|     BEGIN CASE | ||||
|         CASE MetTest EQ '' | ||||
|             Null | ||||
|          | ||||
|         CASE (@WINDOW = 'RDS_UNLOAD') and (DevelopmentFlag EQ True$) and (LWRHOTest EQ False$) | ||||
|         CASE (@WINDOW = 'RDS_UNLOAD') and (LWRHOTest EQ False$) | ||||
|             ReturnVal = Dialog_Box('NDW_QA_MET_RESULT', @WINDOW, CassID) | ||||
|             Send_Event(@Window, "READ") | ||||
|         CASE Otherwise$ | ||||
| @ -2863,57 +2821,47 @@ return | ||||
|  | ||||
| RefreshWaferCounterData: | ||||
|  | ||||
|     WCCheckEnabled = Xlate('APP_INFO', 'WAFER_COUNTER_CHECK', '', 'X') | ||||
|     If WCCheckEnabled then | ||||
|          | ||||
|         Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
|         Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', True$)             | ||||
| 		QtyBackColor = GREEN$ | ||||
|         RDSNo        = Get_Property(@Window : '.RDS_NO','DEFPROP') | ||||
|         If RDSNo NE '' then  | ||||
| 			FqaWcRec        = Wafer_Counter_Services('GetLastScan', RDSNo, 'QA') | ||||
| 			WaferCounterQty = FqaWcRec<WAFER_COUNTER.SCAN_QTY$> | ||||
| 			Set_Property(@Window, '@ORIG_WFR_CTR_QTY', WaferCounterQty) | ||||
| 			WafersOut       = Get_Property(@WINDOW:'.WAFERS_OUT','TEXT') | ||||
| 			Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP', WaferCounterQty) | ||||
| 	Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
| 	Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', True$)             | ||||
| 	QtyBackColor = GREEN$ | ||||
| 	RDSNo        = Get_Property(@Window : '.RDS_NO','DEFPROP') | ||||
| 	If RDSNo NE '' then  | ||||
| 		FqaWcRec        = Wafer_Counter_Services('GetLastScan', RDSNo, 'QA') | ||||
| 		WaferCounterQty = FqaWcRec<WAFER_COUNTER.SCAN_QTY$> | ||||
| 		Set_Property(@Window, '@ORIG_WFR_CTR_QTY', WaferCounterQty) | ||||
| 		WafersOut       = Get_Property(@WINDOW:'.WAFERS_OUT','TEXT') | ||||
| 		Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP', WaferCounterQty) | ||||
|  | ||||
| 			***************************************** | ||||
| 			* WaferCounter - Wafers Quantity Section * | ||||
| 			***************************************** | ||||
| 			If (WaferCounterQty NE '') then | ||||
| 				If (WaferCounterQty NE WafersOut) then QtyBackColor = RED$ | ||||
| 			end else | ||||
| 				QtyBackColor = ORANGE$ | ||||
| 			end			 | ||||
| 			 | ||||
| 			WaferSize = Xlate('RDS', RDSNo, 'WAFER_SIZE', 'X') | ||||
| 			WaferSize = Field(WaferSize, ' ', 3, 1) | ||||
| 			If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then | ||||
| 				WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', 'QA') | ||||
| 				If Error_Services('NoError') then  | ||||
| 					WCCurrMode = '' | ||||
| 					If RowExists('TOOL', WCToolID) then | ||||
| 						WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X') | ||||
| 						WCCurrMode    = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X') | ||||
| 						Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY', 'ENABLED', (WCCurrMode NE 'PROD')) | ||||
| 					end else | ||||
| 						ErrMsg('Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".') | ||||
| 					end | ||||
| 		***************************************** | ||||
| 		* WaferCounter - Wafers Quantity Section * | ||||
| 		***************************************** | ||||
| 		If (WaferCounterQty NE '') then | ||||
| 			If (WaferCounterQty NE WafersOut) then QtyBackColor = RED$ | ||||
| 		end else | ||||
| 			QtyBackColor = ORANGE$ | ||||
| 		end			 | ||||
| 		 | ||||
| 		WaferSize = Xlate('RDS', RDSNo, 'WAFER_SIZE', 'X') | ||||
| 		WaferSize = Field(WaferSize, ' ', 3, 1) | ||||
| 		If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then | ||||
| 			WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', 'QA') | ||||
| 			If Error_Services('NoError') then  | ||||
| 				WCCurrMode = '' | ||||
| 				If RowExists('TOOL', WCToolID) then | ||||
| 					WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X') | ||||
| 					WCCurrMode    = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X') | ||||
| 					Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY', 'ENABLED', (WCCurrMode NE 'PROD')) | ||||
| 				end else | ||||
| 					ErrMsg(Error_Services('GetMessage')) | ||||
| 					ErrMsg('Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".') | ||||
| 				end | ||||
| 			end else | ||||
| 				ErrMsg('Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for RDS "':RDSNo:'".') | ||||
| 			end			 | ||||
| 		end | ||||
| 		Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','BACKCOLOR', QtyBackColor) | ||||
|          | ||||
|     end else | ||||
|         Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', False$) | ||||
|         Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', False$) | ||||
|     end | ||||
| 				ErrMsg(Error_Services('GetMessage')) | ||||
| 			end | ||||
| 		end else | ||||
| 			ErrMsg('Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for RDS "':RDSNo:'".') | ||||
| 		end			 | ||||
| 	end | ||||
| 	Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','BACKCOLOR', QtyBackColor) | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1107,29 +1107,25 @@ SignSupVer: | ||||
|         END | ||||
|     END | ||||
|  | ||||
|     WCCheckEnabled = Xlate('APP_INFO', 'WAFER_COUNTER_CHECK', '', 'X') | ||||
|     If WCCheckEnabled then | ||||
|          | ||||
|         **************************************** | ||||
|         * Verify the Wafer Counter information * | ||||
|         **************************************** | ||||
| 	**************************************** | ||||
| 	* Verify the Wafer Counter information * | ||||
| 	**************************************** | ||||
|  | ||||
|         WafersOut       = Get_Property(@WINDOW:'.WAFER_CNT','TEXT')         | ||||
|         WaferCounterQty = Get_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP') | ||||
|          | ||||
|         ************************************ | ||||
|         * Wafer Counter - Quantity Section * | ||||
|         ************************************ | ||||
|         If (WaferCounterQty NE '') then | ||||
|             If (WaferCounterQty NE WafersOut) then | ||||
|                 ErrMsg('Unable to sign FQA because Wafer Counter and Wafers Filled quantities do not match.') | ||||
|                 RETURN 0 | ||||
|             end | ||||
|         end else | ||||
|             ErrMsg('Unable to sign FQA because the Wafer Counter quantity is missing.') | ||||
|             RETURN 0 | ||||
|         end | ||||
|     end | ||||
| 	WafersOut       = Get_Property(@WINDOW:'.WAFER_CNT','TEXT')         | ||||
| 	WaferCounterQty = Get_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP') | ||||
| 	 | ||||
| 	************************************ | ||||
| 	* Wafer Counter - Quantity Section * | ||||
| 	************************************ | ||||
| 	If (WaferCounterQty NE '') then | ||||
| 		If (WaferCounterQty NE WafersOut) then | ||||
| 			ErrMsg('Unable to sign FQA because Wafer Counter and Wafers Filled quantities do not match.') | ||||
| 			RETURN 0 | ||||
| 		end | ||||
| 	end else | ||||
| 		ErrMsg('Unable to sign FQA because the Wafer Counter quantity is missing.') | ||||
| 		RETURN 0 | ||||
| 	end | ||||
|      | ||||
|     ************************** | ||||
|     * Verify user's password * | ||||
| @ -2293,58 +2289,50 @@ return | ||||
|  | ||||
|  | ||||
| RefreshWaferCounterData: | ||||
|      | ||||
|     WCCheckEnabled = Xlate('APP_INFO', 'WAFER_COUNTER_CHECK', '', 'X') | ||||
|     If WCCheckEnabled then | ||||
|          | ||||
|         Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
|         Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
|         QtyBackColor = GREEN$ | ||||
|         WONo         = Get_Property(@Window : '.WO_NO', 'TEXT') | ||||
|         Cassette     = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') | ||||
|         WMOKey       = WONo:'*1*':Cassette | ||||
|         If WMOKey NE '*1*' then | ||||
| 			FqaWcRec        = Wafer_Counter_Services('GetLastScan', WMOKey, 'QA') | ||||
| 			WaferCounterQty = FqaWcRec<WAFER_COUNTER.SCAN_QTY$> | ||||
| 			Set_Property(@Window, '@ORIG_WFR_CTR_QTY', WaferCounterQty) | ||||
| 			WafersFilled    = Get_Property(@WINDOW:'.WAFER_CNT','TEXT') | ||||
| 			Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP', WaferCounterQty) | ||||
| 			 | ||||
| 			************************************ | ||||
| 			* Wafer Counter - Quantity Section * | ||||
| 			************************************ | ||||
| 			If (WaferCounterQty NE '') then | ||||
| 				If (WaferCounterQty NE WafersFilled) then QtyBackColor = RED$ | ||||
| 			end else | ||||
| 				QtyBackColor = ORANGE$ | ||||
| 			end | ||||
| 			WaferSize   = Xlate('WM_OUT', WMOKey, 'WAFER_SIZE', 'X') | ||||
| 			WaferSize   = Field(WaferSize, ' ', 3, 1) | ||||
| 			If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then | ||||
| 				WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', 'QA') | ||||
| 				If Error_Services('NoError') then  | ||||
| 					WCCurrMode = '' | ||||
| 					If RowExists('TOOL', WCToolID) then | ||||
| 						WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X') | ||||
| 						WCCurrMode    = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X') | ||||
| 						Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY', 'ENABLED', (WCCurrMode NE 'PROD')) | ||||
| 					end else | ||||
| 						ErrMsg('Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".') | ||||
| 					end | ||||
| 	Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
| 	Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', True$) | ||||
| 	QtyBackColor = GREEN$ | ||||
| 	WONo         = Get_Property(@Window : '.WO_NO', 'TEXT') | ||||
| 	Cassette     = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') | ||||
| 	WMOKey       = WONo:'*1*':Cassette | ||||
| 	If WMOKey NE '*1*' then | ||||
| 		FqaWcRec        = Wafer_Counter_Services('GetLastScan', WMOKey, 'QA') | ||||
| 		WaferCounterQty = FqaWcRec<WAFER_COUNTER.SCAN_QTY$> | ||||
| 		Set_Property(@Window, '@ORIG_WFR_CTR_QTY', WaferCounterQty) | ||||
| 		WafersFilled    = Get_Property(@WINDOW:'.WAFER_CNT','TEXT') | ||||
| 		Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP', WaferCounterQty) | ||||
| 		 | ||||
| 		************************************ | ||||
| 		* Wafer Counter - Quantity Section * | ||||
| 		************************************ | ||||
| 		If (WaferCounterQty NE '') then | ||||
| 			If (WaferCounterQty NE WafersFilled) then QtyBackColor = RED$ | ||||
| 		end else | ||||
| 			QtyBackColor = ORANGE$ | ||||
| 		end | ||||
| 		WaferSize   = Xlate('WM_OUT', WMOKey, 'WAFER_SIZE', 'X') | ||||
| 		WaferSize   = Field(WaferSize, ' ', 3, 1) | ||||
| 		If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then | ||||
| 			WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', 'QA') | ||||
| 			If Error_Services('NoError') then  | ||||
| 				WCCurrMode = '' | ||||
| 				If RowExists('TOOL', WCToolID) then | ||||
| 					WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X') | ||||
| 					WCCurrMode    = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X') | ||||
| 					Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY', 'ENABLED', (WCCurrMode NE 'PROD')) | ||||
| 				end else | ||||
| 					ErrMsg(Error_Services('GetMessage')) | ||||
| 					ErrMsg('Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".') | ||||
| 				end | ||||
| 			end else | ||||
| 				ErrMsg('Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for WMO "':WMOKey:'".') | ||||
| 				ErrMsg(Error_Services('GetMessage')) | ||||
| 			end | ||||
|         end | ||||
| 		end else | ||||
| 			ErrMsg('Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for WMO "':WMOKey:'".') | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','BACKCOLOR', QtyBackColor) | ||||
|  | ||||
|         Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','BACKCOLOR', QtyBackColor) | ||||
|          | ||||
|     end else | ||||
|         Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', False$) | ||||
|         Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', False$) | ||||
|     end     | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
| @ -881,24 +881,19 @@ Event SIGN_BUTTON.CLICK() | ||||
|     ****************************************** | ||||
|     * Verify Unload Stage QA Metrology Tests * | ||||
|     ****************************************** | ||||
|  | ||||
|     DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
|  | ||||
|     If (DevelopmentFlag EQ True$) then | ||||
|         WOMatQAKey  = WONo : '*' : CassNo | ||||
|         WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
|         OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
|         OutOfSpec   = Sum(OutOfSpec) | ||||
|         If OutOfSpec GT 0 then | ||||
|             FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
|             ErrorMsg = 'Process Error':@SVM | ||||
|             For each FailReason in FailReasons using @VM | ||||
|                 ErrorMsg := FailReason:CRLF$ | ||||
|             Next FailReason | ||||
|             ErrMsg(ErrorMsg) | ||||
|             Return | ||||
|         end | ||||
|     end | ||||
| 	WOMatQAKey  = WONo : '*' : CassNo | ||||
| 	WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
| 	OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
| 	OutOfSpec   = Sum(OutOfSpec) | ||||
| 	If OutOfSpec GT 0 then | ||||
| 		FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
| 		ErrorMsg = 'Process Error':@SVM | ||||
| 		For each FailReason in FailReasons using @VM | ||||
| 			ErrorMsg := FailReason:CRLF$ | ||||
| 		Next FailReason | ||||
| 		ErrMsg(ErrorMsg) | ||||
| 		Return | ||||
| 	end | ||||
|  | ||||
|     ******************************************* | ||||
|     * Verify if all steps have been completed * | ||||
| @ -1965,7 +1960,3 @@ ClearForm: | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -259,7 +259,7 @@ end service | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service GetWaferMapProductionPath() | ||||
|  | ||||
|     ProductionPath = '\\mesfs.infineon.com\EC_Metrology_Si\MetrologyAttachments\TencorRunData' | ||||
|     ProductionPath = '\\mesfs.infineon.com\EC_Metrology_Si\MetrologyAttachments\TencorRunData_' | ||||
|     Response       = ProductionPath | ||||
|  | ||||
| end service | ||||
|  | ||||
| @ -2,9 +2,9 @@ Compile function Lot_Services(@Service, @Params) | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| Declare function TEST_WAFER_PROD_SERVICES, SRP_Datetime, Datetime, Database_Services, Lot_Services, Error_Services, RTI_CREATEGUID | ||||
| Declare function SRP_Array, SRP_Json, Environment_Services, Logging_Services, MemberOf, Lot_Event_Services | ||||
| Declare function SRP_Array, SRP_Json, Environment_Services, Logging_Services, MemberOf, Lot_Event_Services, GetTickCount | ||||
| Declare subroutine Database_Services, Btree.Extract, Lot_Services, Error_Services, Labeling_Services, SRP_Json, Logging_Services | ||||
| Declare subroutine SRP_Run_Command, Service_Services, obj_notes, Lot_Event_Services | ||||
| Declare subroutine SRP_Run_Command, Service_Services, obj_notes, Lot_Event_Services, Mona_Services | ||||
| $insert APP_INSERTS | ||||
| $Insert LOT_EQUATES | ||||
| $Insert TEST_WAFER_PROD_EQUATES | ||||
| @ -38,6 +38,13 @@ objLotClosureLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', | ||||
| Options EVENT_TYPES = 'MOVE_IN', 'MOVE_OUT', 'HOLD_ON', 'HOLD_OFF', 'REDUCE_WAFER_QTY', 'BONUS_WAFER_QTY', 'COMMENT', 'LOCATION', 'LOAD', 'UNSIGN_LOAD', 'TW_USE', 'CLOSE' | ||||
| Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT' | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_LOTSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_LOTSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService | ||||
|  | ||||
| Return Response or "" | ||||
| @ -113,6 +120,9 @@ Service GenerateNewLotId(LotType) | ||||
| end service | ||||
|  | ||||
| Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType) | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'GetLotIdByLegacyLotIdAndType' | ||||
| 	 | ||||
| 	Open 'DICT.LOT' to DictLot then | ||||
|          | ||||
|         SearchString    = '' | ||||
| @ -130,10 +140,16 @@ Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType) | ||||
|     end else | ||||
|         ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.' | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, VendorCode, Username, PrinterID, LotId) | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'CreateNewLot' | ||||
| 	 | ||||
|     CreatedLotNumber = '' | ||||
|     ErrorMessage     = '' | ||||
|     Begin Case | ||||
| @ -279,6 +295,8 @@ Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, Vendo | ||||
|     end | ||||
|     Response = CreatedLotNumber | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| End Service | ||||
|  | ||||
|  | ||||
| @ -484,6 +502,9 @@ end service | ||||
|  | ||||
| //Returns a @FM delimited list of operations in sequence | ||||
| Service GetLotOperationSequence(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetLotOperationSequence' | ||||
| 	 | ||||
|     LotOperationsInSequence = '' | ||||
|     If LotID NE '' then | ||||
|         //Get Operations | ||||
| @ -496,9 +517,15 @@ Service GetLotOperationSequence(LotId) | ||||
|         //error: lot id was null | ||||
|     end | ||||
|     Response = LotOperationsInSequence | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetLotCurrOperationId(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetLotCurrOperationId' | ||||
| 	 | ||||
|     CurrOperation = '' | ||||
|     If LotID NE '' then | ||||
|         //Get them in sequence first | ||||
| @ -515,9 +542,15 @@ Service GetLotCurrOperationId(LotId) | ||||
|         //error: lot id was null | ||||
|     end | ||||
|     Response = CurrOperation | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetLotCurrOperationName(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetLotCurrOperationName' | ||||
| 	 | ||||
|     CurrOperationId   = '' | ||||
|     CurrOperationName = '' | ||||
|     If LotID NE '' then | ||||
| @ -536,6 +569,9 @@ Service GetLotCurrOperationName(LotId) | ||||
|         //error: lot id was null | ||||
|     end | ||||
|     Response = CurrOperationName | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service AddLotOperationIntoSequence(LotId, NewOperationId, NewSequence, Rework) | ||||
| @ -591,6 +627,9 @@ Service AddLotOperationIntoSequence(LotId, NewOperationId, NewSequence, Rework) | ||||
| end service | ||||
|  | ||||
| Service IsLotMovedIn(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'IsLotMovedIn' | ||||
| 	 | ||||
|     Response = '' | ||||
|     If RowExists('LOT', LotId) then | ||||
|         CurrOperId    = Lot_Services('GetLotCurrOperationId', LotId) | ||||
| @ -601,6 +640,9 @@ Service IsLotMovedIn(LotId) | ||||
|             Response = False$ | ||||
|         end | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service IsOperationCompleted(LotOperationId) | ||||
| @ -619,6 +661,8 @@ Service IsOperationCompleted(LotOperationId) | ||||
| end service | ||||
|  | ||||
| Service MoveInLot(LotID, Operator) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'MoveInLot' | ||||
|  | ||||
|     ErrorMessage           = '' | ||||
|     ThisLotCurrOperationID = '' | ||||
| @ -667,9 +711,15 @@ Service MoveInLot(LotID, Operator) | ||||
|          Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$) | ||||
|          Error_Services('Add', ErrorMessage) | ||||
|      end | ||||
|       | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service MoveOutLot(LotID, Operator) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'MoveOutLot' | ||||
| 	 | ||||
| 	ErrorMessage           = '' | ||||
| 	ThisLotCurrOperationID = '' | ||||
| 	If LotId NE '' then | ||||
| @ -729,6 +779,9 @@ Service MoveOutLot(LotID, Operator) | ||||
| 		Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$) | ||||
| 		Error_Services('Add', ErrorMessage) | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN) | ||||
| @ -855,6 +908,9 @@ Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN) | ||||
| end service | ||||
|  | ||||
| Service OpenLot(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'OpenLot' | ||||
| 	 | ||||
|     ErrorMessage = '' | ||||
|     If RowExists('LOT', LotId) then | ||||
|         LotRec            = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$) | ||||
| @ -871,9 +927,15 @@ Service OpenLot(LotId) | ||||
|     If ErrorMessage NE ''  then | ||||
|         Error_Services('Add', ErrorMessage) | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service CloseLot(LotId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CloseLot' | ||||
| 	 | ||||
|     ErrorMessage = '' | ||||
|     If RowExists('LOT', LotId) then | ||||
|         LotRec            = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$) | ||||
| @ -890,6 +952,9 @@ Service CloseLot(LotId) | ||||
|     If ErrorMessage NE ''  then | ||||
|         Error_Services('Add', ErrorMessage) | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service AutoCloseTestWaferLot(LotId, CloseUserId) | ||||
| @ -989,15 +1054,26 @@ Service AutoCloseTestWaferLot(LotId, CloseUserId) | ||||
| end service | ||||
|  | ||||
| Service HoldLot(LotId, OperatorId) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'HoldLot' | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service UnholdLot(LotId, OperatorId) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'UnholdLot' | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service ReduceLotWaferCount(LotId, ReductionQty, OperatorId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'ReduceLotWaferCount' | ||||
| 	 | ||||
| 	ErrorMessage = '' | ||||
| 	If RowExists('LOT', LotId) then | ||||
| 		LotRec        = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$) | ||||
| @ -1043,9 +1119,15 @@ Service ReduceLotWaferCount(LotId, ReductionQty, OperatorId) | ||||
| 	if ErrorMessage NE '' then | ||||
| 		Error_Services('Add', ErrorMessage) | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service IncreaseLotWaferCount(LotId, IncreaseQty, OperatorId) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'IncreaseLotWaferCount' | ||||
| 	 | ||||
|     ErrorMessage = '' | ||||
|     If RowExists('LOT', LotId) then | ||||
|         LotRec        = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$) | ||||
| @ -1087,6 +1169,8 @@ Service IncreaseLotWaferCount(LotId, IncreaseQty, OperatorId) | ||||
|         Error_Services('Add', ErrorMessage) | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service OpenOIWizardCreateTWLotInBrowser() | ||||
| @ -1095,6 +1179,9 @@ Service OpenOIWizardCreateTWLotInBrowser() | ||||
| end service | ||||
|  | ||||
| Service CreateNewVoidedLotRecord(LotId, LegacyLotId, LotType=LOT_TYPES, Username) | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'CreateNewVoidedLotRecord' | ||||
| 	 | ||||
| 	ErrorMessage = '' | ||||
| 	If RowExists('LSL_USERS', Username) then | ||||
| 		If LotType NE '' then | ||||
| @ -1165,16 +1252,8 @@ Service CreateNewVoidedLotRecord(LotId, LegacyLotId, LotType=LOT_TYPES, Username | ||||
| 	If ErrorMessage NE ''  then | ||||
| 		//Todo Log Error Message | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -388,6 +388,7 @@ end service | ||||
| // Looks for available Metrology files that are ready to be imported into the MES system. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ImportMetrologyFiles(Machine) | ||||
| 	 | ||||
| 	If Machine NE '' then | ||||
| 		hSysLists       = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
| 		Lock hSysLists, ServiceKeyID:'*':Machine then | ||||
| @ -935,14 +936,8 @@ Service ImportBioRadData(RunData, FileName) | ||||
| 			RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID) | ||||
| 			If Error_Services('NoError') then | ||||
| 				WorkOrderNo     = RDSRec<RDS_WO$> | ||||
|  | ||||
| 				// HgCV Project Development Code ------------------------------------------------------------------------------- | ||||
| 				DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
| 				If (DevelopmentFlag EQ True$) then  | ||||
| 					IsProdTest = ( Indexc(ScanRecipe, 'PROD', 1) GT 0 ) | ||||
| 					If IsProdTest EQ True$ then Metrology_Services('LogResults',RDSKeyID,Machine,'HgCV','Product test recognized. Recipe name: ':ScanRecipe) | ||||
| 				end | ||||
| 				// -------------------------------------------------------------------------------------------------------------      | ||||
| 				IsProdTest = ( Indexc(ScanRecipe, 'PROD', 1) GT 0 ) | ||||
| 				If IsProdTest EQ True$ then Metrology_Services('LogResults',RDSKeyID,Machine,'HgCV','Product test recognized. Recipe name: ':ScanRecipe) | ||||
| 				CassNo          = RDSRec<RDS_CASS_NO$> | ||||
| 				WorkOrder       = Work_Order_Services('GetWorkOrder', WorkOrderNo, False$) | ||||
| 				GoSub ParseWorkOrder | ||||
| @ -1288,14 +1283,9 @@ Service ImportCDEData(RunData, FileName) | ||||
| 		RDSNo@            = RDSKeyID | ||||
| 		RDSRec            = Database_Services('ReadDataRow', 'RDS', RDSKeyID) | ||||
| 		If Error_Services('NoError') then | ||||
|  | ||||
| 			// HgCV Project Development Code ------------------------------------------------------------------------------- | ||||
| 			DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
| 			If (DevelopmentFlag EQ True$) then  | ||||
| 				IsProdTest = ( Indexc(ScanRecipe, 'PROD', 1) GT 0 ) | ||||
| 				If IsProdTest EQ True$ then Metrology_Services('LogResults',RDSKeyID,Machine,'HgCV','Product test recognized. Recipe name: ':ScanRecipe) | ||||
| 			end | ||||
| 			// ------------------------------------------------------------------------------------------------------------- | ||||
| 			 | ||||
| 			IsProdTest = ( Indexc(ScanRecipe, 'PROD', 1) GT 0 ) | ||||
| 			If IsProdTest EQ True$ then Metrology_Services('LogResults',RDSKeyID,Machine,'HgCV','Product test recognized. Recipe name: ':ScanRecipe) | ||||
|  | ||||
| 			WorkOrderNo     = RDSRec<RDS_WO$> | ||||
| 			CassNo          = RDSRec<RDS_CASS_NO$> | ||||
| @ -3253,5 +3243,3 @@ LoadRunDataToDatabase: | ||||
|  | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -18,7 +18,7 @@ Parm3: | ||||
|     -For Metric updates this represents the numeric data that you wish to send. | ||||
| ***************************************************************/ | ||||
|  | ||||
| Declare Subroutine Errmsg, Error_Services, Delay, Mona_Services | ||||
| Declare Subroutine Errmsg, Error_Services, Delay, Mona_Services, Service_Services | ||||
| Declare function Get_Status, SRP_Datetime, Environment_Services, Httpclient_Services | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| @ -44,17 +44,31 @@ Options STATES       = 'OK', 'WARNING', 'CRITICAL' | ||||
|  | ||||
| Service SendStatus(MonitorName=MONITORS, StatusName, CurrentState=STATES) | ||||
| 	 | ||||
| 	Mona_Services("SendBufferedStatus", MonitorName, StatusName, CurrentState) | ||||
| 	Mona_Services("PostStatus", MonitorName, StatusName, CurrentState) | ||||
| 	 | ||||
| end service | ||||
|  | ||||
| Service PostStatus(MonitorName, StatusName, CurrentState=STATES) | ||||
| 	Service_Services('PostProcedure', 'MONA_SERVICES', 'SendBufferedStatus':@VM:MonitorName:@VM:StatusName:@VM:CurrentState) | ||||
| end service | ||||
|  | ||||
| Service SendMetric(MonitorName=MONITORS, MetricName, Number) | ||||
| 	 | ||||
| 	Mona_Services("SendBufferedAverageMetric", MonitorName, MetricName, Number) | ||||
| 	Mona_Services("PostAverageMetric", MonitorName, MetricName, Number) | ||||
| 	 | ||||
| end Service | ||||
|  | ||||
| Service PostAverageMetric(MonitorName, MetricName, Number) | ||||
| 	Service_Services('PostProcedure', 'MONA_SERVICES', 'SendBufferedAverageMetric':@VM:MonitorName:@VM:MetricName:@VM:Number) | ||||
| end service | ||||
|  | ||||
| Service SendCountMetric(MonitorName=MONITORS, MetricName, Number) | ||||
| 	Mona_Services("PostCountMetric", MonitorName, MetricName, Number) | ||||
| end Service | ||||
|  | ||||
| Service PostCountMetric(MonitorName, MetricName, Number) | ||||
| 	Service_Services('PostProcedure', 'MONA_SERVICES', 'SendBufferedCountMetric':@VM:MonitorName:@VM:MetricName:@VM:Number) | ||||
| end service | ||||
|  | ||||
| Service SendBufferedStatus(MonaResource, StatusName, StatusValue) | ||||
| 	 | ||||
| @ -172,6 +186,67 @@ Service SendBufferedAverageMetric(MonaResource, MetricName, MetricValue) | ||||
| 	 | ||||
| end service | ||||
|  | ||||
| Service SendBufferedCountMetric(MonaResource, MetricName, MetricValue) | ||||
| 	 | ||||
| 	If MonaResource EQ '' then | ||||
| 		MonaResource = Environment_Services("GetMonaResource") | ||||
| 	end | ||||
| 	 | ||||
| 	DateTime = SRP_DateTime('Now') | ||||
| 	Year = SRP_Datetime("Year", DateTime) | ||||
| 	Month = SRP_Datetime("Month", DateTime) | ||||
| 	If Len(Month) EQ 1 then | ||||
| 		Month = '0':Month | ||||
| 	end | ||||
| 	Day = SRP_Datetime("Day", DateTime) | ||||
| 	If Len(Day) EQ 1 then | ||||
| 		Day = '0':Day | ||||
| 	end | ||||
| 	Hour = SRP_Datetime("Hour", DateTime) | ||||
| 	If Len(Hour) EQ 1 then | ||||
| 		Hour = '0':Hour | ||||
| 	end | ||||
| 	Minute = SRP_Datetime("Minute", DateTime) | ||||
| 	If Len(Minute) EQ 1 then | ||||
| 		Minute = '0':Minute | ||||
| 	end | ||||
| 	Second = SRP_Datetime("Second", DateTime) | ||||
| 	If Len(Second) EQ 1 then | ||||
| 		Second = '0':Second | ||||
| 	end | ||||
| 	 | ||||
| 	RequestBodyJson = '{ "resource": "':MonaResource:'"' | ||||
| 	RequestBodyJson = RequestBodyJson:', "dateTime": "':Year:'-':Month:'-':Day:'T':Hour:':':Minute:':':Second:'Z"' | ||||
| 	RequestBodyJson = RequestBodyJson:', "metricName": "':MetricName:'"' | ||||
| 	RequestBodyJson = RequestBodyJson:', "metricValue": "':MetricValue:'" }' | ||||
| 	 | ||||
| 	ApiUrl = Environment_Services("GetMonInBufferedWorkerApiUrl"):'/count' | ||||
| 	 | ||||
| 	retries = 3 | ||||
| 	backoffSeconds = 1 | ||||
| 	isSuccessful = False$ | ||||
| 	 | ||||
| 	Loop | ||||
| 		while (isSuccessful EQ False$ and retries GT 0) | ||||
| 			waitSeconds = (3 - retries) * backoffSeconds | ||||
| 			Delay(waitSeconds) | ||||
| 			 | ||||
| 			retries = retries - 1 | ||||
|  | ||||
| 			response = Httpclient_Services('SendHTTPRequest', 'POST', ApiUrl, 'Content-Type':@VM:'application/json':@FM:'Accept':@VM:'*/*', RequestBodyJson, '', '', False$, False$, '') | ||||
|  | ||||
| 			If response EQ '"Request queued for processing"' then | ||||
| 				isSuccessful = True$ | ||||
| 			end | ||||
| 	Repeat | ||||
| 	 | ||||
| end service | ||||
|  | ||||
| Service QueueLatencyAndCountMetrics(MonaResource, MetricName, StartTick, EndTick) | ||||
| 	Diff = EndTick - StartTick | ||||
|     Mona_Services('SendMetric', MonaResource, MetricName:'_LATENCY', Diff) | ||||
|     Mona_Services('SendCountMetric', MonaResource, MetricName:'_COUNT', 1) | ||||
| end service | ||||
|  | ||||
| SwapResourceNames: | ||||
| 	 | ||||
| @ -195,3 +270,4 @@ SwapResourceNames: | ||||
| 	 | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -50,11 +50,13 @@ Return Response or "" | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Service Parameter Options | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| Options BOOLEAN        = True$, False$ | ||||
| Options ENTITY_TYPES   = 'REACTOR','REACTOR_LOG' | ||||
| Options ORDER_TYPES    = 'INTRUSIVE_MAINT','CHANGEOVER','INITIATE_IDLE','IDLE','ASM_HTR_TUBE_CHANGE','ASM_HTR_ANNUAL_PM','ASM_HTR_SEMIANNUAL_PM','ASM_HTR_FIVE_AND_TEN_YEAR_PM','IQS_HGCV_ALARM','ABORT_ALARM' | ||||
| Options ORDER_STATUSES = 'new','creating','not-started','in-progress','cancelled','done' | ||||
| Options REACTOR_TYPES  = 'ASM','ASM+','HTR','EPP' | ||||
| Options BOOLEAN                  = True$, False$ | ||||
| Options ENTITY_TYPES             = 'REACTOR','REACTOR_LOG' | ||||
| Options ORDER_TYPES              = 'INTRUSIVE_MAINT','CHANGEOVER','INITIATE_IDLE','IDLE','ASM_HTR_TUBE_CHANGE','ASM_HTR_ANNUAL_PM','ASM_HTR_SEMIANNUAL_PM','ASM_HTR_FIVE_AND_TEN_YEAR_PM','IQS_HGCV_ALARM','ABORT_ALARM' | ||||
| Options ORDER_STATUSES           = 'new','in-edit','creating','not-started','in-progress','cancelled','done' | ||||
| Options REACTOR_TYPES            = 'ASM','ASM+','HTR','EPP' | ||||
| Options ORDER_CHECKLIST_STATUSES = 'not-started','in-progress','paused','done' | ||||
| Options NICA_CHECKLISTS          = 'PROCESS_INTERRUPTION_FLOW_C_PRE','PROCESS_INTERRUPTION_FLOW_A_PRE','PROCESS_INTERRUPTION_FLOW_B_PRE','PROCESS_INTERRUPTION_LAST_KNOWN_PRODUCT_THICKNESS_SHEETRHO','PROCESS_INTERRUPTION_LAST_KNOWN_PRODUCT_VISUAL_INSPECTION','PROCESS_INTERRUPTION_TEST_WAFER','PROCESS_INTERRUPTION_ASM_PARTICLE_QUAL_VISUAL_INSPECTION','PROCESS_INTERRUPTION_HTR_PARTICLE_QUAL_VISUAL_INSPECTION','SUSCEPTOR_PREP','1_PCRC','2_PCRC','BD','INTRINSIC','SPV-FE','CLEANUP','TEST_WAFER_VERIFICATION','PARTICLE_QUAL_ASM','PARTICLE_QUAL_HTR','FIRST_PRODUCT_RUN_HGCV','FIRST_PRODUCT_RUN_THICK','PROCESS_INTERRUPTION_FLOW_B_POST' | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // SERVICES | ||||
| @ -85,6 +87,7 @@ Service GetOrderIds(EntityType=ENTITY_TYPES, EntityID, OrderTypes=ORDER_TYPES, O | ||||
| 				For each Val in IsComplete using @VM | ||||
| 					Query := @VM : Val | ||||
| 				Next Val | ||||
| 				Query := @FM | ||||
| 			end | ||||
| 			Btree.Extract(Query, Table, hDict, OrderKeys, Option, Flag) | ||||
| 			If Flag NE 0 then | ||||
| @ -106,6 +109,64 @@ Service GetOrderIds(EntityType=ENTITY_TYPES, EntityID, OrderTypes=ORDER_TYPES, O | ||||
| End Service | ||||
|  | ||||
|  | ||||
| Service GetOrderChecklistIds(NicaOrdersIds, NicaChecklistIds=NICA_CHECKLISTS, IsComplete=BOOLEAN, ChecklistOrderStates=ORDER_CHECKLIST_STATUSES) | ||||
|      | ||||
| 	OrderChecklistIds = '' | ||||
| 	ErrorMsg          = '' | ||||
| 	If ( (NicaOrdersIds NE '') or (IsComplete NE '') or (ChecklistOrderStates NE '') ) then  | ||||
| 		Open 'DICT.NICA_ORDERS_CHECKLISTS' to hDict then | ||||
| 			Query   = '' | ||||
| 			Table   = 'NICA_ORDERS_CHECKLISTS' | ||||
| 			Option  = 'E' | ||||
| 			Flag    = '' | ||||
| 			If (NicaOrdersIds NE '') then | ||||
| 				Query := 'NICA_ORDERS_ID' | ||||
| 				For each NicaOrderId in NicaOrdersIds using @VM | ||||
| 					Query := @VM : NicaOrderId | ||||
| 				Next NicaOrderId | ||||
| 				Query := @FM | ||||
| 			end | ||||
| 			If (NicaChecklistIds NE '') then | ||||
| 			    Query := 'NICA_CHECKLISTS_ID' | ||||
| 			    For each NicaChecklistId in NicaChecklistIds using @VM | ||||
| 			        Query := @VM : NicaChecklistId | ||||
| 			    Next NicaChecklistId | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			If (IsComplete NE '') then | ||||
| 				Query := 'IS_COMPLETE' | ||||
| 				For each Val in IsComplete using @VM | ||||
| 					Query := @VM : Val | ||||
| 				Next Val | ||||
| 				Query := @FM | ||||
| 			end | ||||
| 			If (ChecklistOrderStates NE '') then | ||||
| 			    Query := 'STATE' | ||||
| 			    For each ChecklistOrderState in ChecklistOrderStates using @VM | ||||
| 			        Query := @VM : ChecklistOrderState | ||||
| 			    Next ChecklistOrderState | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			Btree.Extract(Query, Table, hDict, OrderChecklistIds, Option, Flag) | ||||
| 			If Flag NE 0 then | ||||
| 				ErrorMsg = 'Error in ':Service:' service. Btree.Extract call failed.' | ||||
| 			end | ||||
| 		end else | ||||
| 			ErrorMsg = 'Error in ':Service:' service. Failed to open DICT.NICA_ORDERS_CHECKLISTS.' | ||||
| 		end | ||||
| 	end else | ||||
| 		ErrorMsg = 'Error in ':Service:' service. At least one search parameter must be provided.' | ||||
| 	end | ||||
| 	 | ||||
| 	If ErrorMsg EQ '' then | ||||
| 		Response = OrderChecklistIds | ||||
| 	end else | ||||
| 		Error_Services('Add', ErrorMsg) | ||||
| 	end | ||||
|      | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service GetOrderUpdates() | ||||
|  | ||||
| 	hSysLists   = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
| @ -188,13 +249,15 @@ end service | ||||
|  | ||||
|  | ||||
| Service GetActiveOrders(EntityType=ENTITY_TYPES, EntityId, OrderTypes=ORDER_TYPES) | ||||
| 	 | ||||
|  | ||||
| 	Response = Nica_Orders_Services('GetOrderIds', EntityType, EntityID, OrderTypes, '#cancelled', False$:@VM:'')  | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, OrderFlows, OrderResponseLevel, ChecklistIds) | ||||
| Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, OrderFlows, OrderResponseLevel, ChecklistIds, Intrusive=BOOLEAN) | ||||
|  | ||||
|     If Intrusive NE True$ then Intrusive = False$ | ||||
|  | ||||
| 	ErrorMsg     = '' | ||||
| 	EntityTypes  = 'REACTOR,REACTOR_LOG' | ||||
| @ -229,7 +292,39 @@ Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, | ||||
| 			LogData<3> = 'Attempting to create NICA order for entity ':EntityType:' ' :EntityID:' of type ':OrderType | ||||
| 			Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)			 | ||||
| 			 | ||||
| 			CurrActiveOrders       = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderType)  | ||||
| 			Begin Case | ||||
| 			     | ||||
| 			    Case OrderType _EQC 'ABORT_ALARM' | ||||
| 			         | ||||
| 			        OrderTypes            = OrderType:@VM:'INTRUSIVE_MAINT' | ||||
| 			        CurrActiveOrders      = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderTypes) | ||||
| 			        If CurrActiveOrders NE '' then | ||||
| 			            // If any active ABORT_ALARM orders are marked as intrusive (i.e., they were merged  | ||||
| 			            // with an INTRUSIVE_MAINT order then mark the new order as intrusive). | ||||
| 			            ActiveOrdersIntrusive = Sum(Xlate('NICA_ORDERS', CurrActiveOrders, 'INTRUSIVE', 'X')) | ||||
| 			            If ActiveOrdersIntrusive then Intrusive = True$ | ||||
| 			        end | ||||
| 			         | ||||
| 			    Case OrderType _EQC 'INTRUSIVE_MAINT' | ||||
| 			         | ||||
| 			        Intrusive                  = True$ | ||||
| 			        CurrActiveOrders           = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderType) | ||||
| 			        CurrActiveAbortAlarmOrders = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, 'ABORT_ALARM') | ||||
| 			        If CurrActiveAbortAlarmOrders NE '' then | ||||
| 			            CurrActiveOrders<-1> = CurrActiveAbortAlarmOrders | ||||
| 			            // Merge INTRUSIVE_MAINT and ABORT_ALARM orders into one ABORT_ALARM order. | ||||
| 			            // Preserve ABORT_ALARM order flow ids for Reactor mode change logic that relies on these | ||||
| 			            // to determine whether or not to trigger a new ABORT/ALARM order when changing ABORT/ALARM sub modes. | ||||
| 			            OrderType            = 'ABORT_ALARM' | ||||
| 			            OrderFlows           = Xlate('NICA_ORDERS', CurrActiveAbortAlarmOrders, 'ORDER_FLOW_IDS', 'X') | ||||
| 			            OrderFlows           = SRP_Array('Clean', OrderFlows, 'TrimAndMakeUnique', @VM) | ||||
| 			        end | ||||
| 			         | ||||
| 			    Case Otherwise$ | ||||
| 			        CurrActiveOrders = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderType) | ||||
| 			         | ||||
| 			End Case | ||||
| 			 | ||||
| 			OrderTypeAlreadyActive = (CurrActiveOrders NE '') | ||||
| 			 | ||||
| 			If ( (OrderTypeAlreadyActive EQ False$) or (OrderType EQ 'INTRUSIVE_MAINT') or (OrderType EQ 'ABORT_ALARM') ) then | ||||
| @ -300,6 +395,17 @@ Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, | ||||
| 							end | ||||
| 							 | ||||
| 							NewChecklistIds        = SRP_Array('Clean', NewChecklistIds, 'TrimAndMakeUnique', @VM) | ||||
| 							If Intrusive then | ||||
| 							    // Remove checklist ids with REMOVE_IF_INRUSIVE flag set to True$ | ||||
| 							    ChecklistIdsToRemove = Nica_Orders_Services('GetChecklistIds', '', '', '', '', '', '', True$) | ||||
| 							    If ChecklistIdsToRemove NE '' then | ||||
| 							        For each ChecklistIdToRemove in ChecklistIdsToRemove using @VM | ||||
| 							            Locate ChecklistIdToRemove in NewChecklistIds using @VM setting vPos then | ||||
| 							                NewChecklistIds = Delete(NewChecklistIds, 0, vPos, 0) | ||||
| 							            end | ||||
| 							        Next ChecklistIdToRemove | ||||
| 							    end | ||||
| 							end | ||||
| 							NewChecklistPriorities = Xlate('NICA_CHECKLISTS', NewChecklistIds, 'PRIORITY', 'X') | ||||
| 							ChecklistArray         = NewChecklistIds:@FM:NewChecklistPriorities | ||||
| 							ChecklistArray         = SRP_Array('SortRows', ChecklistArray, 'AR2', 'ARRAY', @FM, @VM) | ||||
| @ -369,6 +475,7 @@ Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, | ||||
| 									end | ||||
| 									NicaOrderRec<NICA_ORDERS.ORDER_FLOW_IDS$>       = OrderFlows | ||||
| 									NicaOrderRec<NICA_ORDERS.ORDER_RESPONSE_LEVEL$> = OrderResponseLevel | ||||
| 									NicaOrderRec<NICA_ORDERS.INTRUSIVE$>            = Intrusive | ||||
| 									LogNicaOrderRec                                 = NicaOrderRec | ||||
| 									Swap @FM with ',' in LogNicaOrderRec | ||||
| 									LogData                                         = '' | ||||
| @ -900,6 +1007,119 @@ Service GetAvailableFlowIds(NicaOrderType=ORDER_TYPES) | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service AbortAlarmFromIntrusiveMaintRequired(ReactNo) | ||||
|      | ||||
|     ErrorMsg                             = '' | ||||
|     AbortAlarmFromIntrusiveMaintRequired = '' | ||||
|     If ReactNo NE '' then | ||||
|         If RowExists('REACTOR', ReactNo) then | ||||
|             ActiveIntrusiveMaintOrderIds = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'INTRUSIVE_MAINT') | ||||
|             IntrusiveMaintOrderActive    = (ActiveIntrusiveMaintOrderIds NE '') | ||||
|             If IntrusiveMaintOrderActive then | ||||
|                 // If any FIRST_PRODUCT_RUN_THICK or FIRST_PRODUCT_RUN_HGCV associated with active INTRUSIVE_MAINT | ||||
|                 // orders have been started or completed, then an ABORT/ALARM order should be triggerd. | ||||
|                 ChecklistIdsToSearch                 = 'FIRST_PRODUCT_RUN_THICK':@VM:'FIRST_PRODUCT_RUN_HGCV' | ||||
|                 InProcessOrCompleteOrderChecklistIds = Nica_Orders_Services('GetOrderChecklistIds', ActiveIntrusiveMaintOrderIds, ChecklistIdsToSearch, '', '#not-started') | ||||
|                 AbortAlarmFromIntrusiveMaintRequired = (InProcessOrCompleteOrderChecklistIds NE '') | ||||
|             end else | ||||
|                 AbortAlarmFromIntrusiveMaintRequired = False$ | ||||
|             end | ||||
|         end else | ||||
|             ErrorMsg = 'Error in ':Service:' service. REACTOR ':ReactNo:' does not exist.' | ||||
|         end | ||||
|     end else | ||||
|         ErrorMsg = 'Error in ':Service:' service. Null ReactNo passed into service.' | ||||
|     end | ||||
|      | ||||
|     If ErrorMsg EQ '' then | ||||
|         Response = AbortAlarmFromIntrusiveMaintRequired | ||||
|     end else | ||||
|         Error_Services('Add', ErrorMsg) | ||||
|     end | ||||
|      | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service GetChecklistIds(Priorities, NicaBaseInstructionIds, NicaOrderFlowIds, NicaOrderFlowTypes, ReactorTypes, RemoveIfComplete=BOOLEAN, RemoveIfIntrusive=BOOLEAN) | ||||
|      | ||||
| 	ChecklistIds = '' | ||||
| 	ErrorMsg     = '' | ||||
| 	If ( (Priorities NE '') or (NicaBaseInstructionIds NE '') or (NicaOrderFlowIds NE '') or (NicaOrderFlowTypes NE '') | | ||||
| 	    or (ReactorTypes NE '') or (RemoveIfComplete NE '') or (RemoveIfIntrusive NE '') ) then  | ||||
| 		Open 'DICT.NICA_CHECKLISTS' to hDict then | ||||
| 			Query   = '' | ||||
| 			Table   = 'NICA_CHECKLISTS' | ||||
| 			Option  = 'E' | ||||
| 			Flag    = '' | ||||
| 			If (Priorities NE '') then | ||||
| 				Query := 'PRIORITY' | ||||
| 				For each Priority in Priorities using @VM | ||||
| 					Query := @VM : Priority | ||||
| 				Next Priority | ||||
| 				Query := @FM | ||||
| 			end | ||||
| 			If (NicaBaseInstructionIds NE '') then | ||||
| 			    Query := 'NICA_BASE_INSTRUCTION_ID' | ||||
| 			    For each NicaBaseInstructionId in NicaBaseInstructionIds using @VM | ||||
| 			        Query := @VM : NicaBaseInstructionId | ||||
| 			    Next NicaBaseInstructionId | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			If (NicaOrderFlowIds NE '') then | ||||
| 				Query := 'NICA_ORDER_FLOW_IDS' | ||||
| 				For each NicaOrderFlowId in NicaOrderFlowIds using @VM | ||||
| 					Query := @VM : NicaOrderFlowId | ||||
| 				Next NicaOrderFlowId | ||||
| 				Query := @FM | ||||
| 			end | ||||
| 			If (NicaOrderFlowTypes NE '') then | ||||
| 			    Query := 'NICA_ORDER_FLOW_TYPE' | ||||
| 			    For each NicaOrderFlowType in NicaOrderFlowTypes using @VM | ||||
| 			        Query := @VM : NicaOrderFlowType | ||||
| 			    Next NicaOrderFlowTypes | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			If (ReactorTypes NE '') then | ||||
| 			    Query := 'REACTOR_TYPES' | ||||
| 			    For each NicaOrderFlowType in NicaOrderFlowTypes using @VM | ||||
| 			        Query := @VM : NicaOrderFlowType | ||||
| 			    Next NicaOrderFlowTypes | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			If (RemoveIfComplete NE '') then | ||||
| 			    Query := 'REMOVE_IF_COMPLETE' | ||||
| 			    For each Val in RemoveIfComplete using @VM | ||||
| 			        Query := @VM : Val | ||||
| 			    Next RemoveIfComplete | ||||
| 			    Query := @FM | ||||
| 			end | ||||
| 			If (RemoveIfIntrusive NE '') then | ||||
| 			    Query := 'REMOVE_IF_INTRUSIVE' | ||||
| 			    For each Val in RemoveIfIntrusive using @VM | ||||
| 			        Query := @VM : Val | ||||
| 			    Next Val | ||||
| 			    Query := @FM | ||||
| 			end			 | ||||
| 			Btree.Extract(Query, Table, hDict, ChecklistIds, Option, Flag) | ||||
| 			If Flag NE 0 then | ||||
| 				ErrorMsg = 'Error in ':Service:' service. Btree.Extract call failed.' | ||||
| 			end | ||||
| 		end else | ||||
| 			ErrorMsg = 'Error in ':Service:' service. Failed to open DICT.NICA_CHECKLISTS.' | ||||
| 		end | ||||
| 	end else | ||||
| 		ErrorMsg = 'Error in ':Service:' service. At least one search parameter must be provided.' | ||||
| 	end | ||||
| 	 | ||||
| 	If ErrorMsg EQ '' then | ||||
| 		Response = ChecklistIds | ||||
| 	end else | ||||
| 		Error_Services('Add', ErrorMsg) | ||||
| 	end     | ||||
|      | ||||
| end service | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Internal GoSubs | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| @ -20,7 +20,7 @@ COMPILE FUNCTION obj_Post_Log(Method,Parms) | ||||
|  | ||||
|  | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, Get_Property, obj_RDS, Database_Services, Environment_Services | ||||
| DECLARE FUNCTION Logging_Services, Datetime, SRP_DateTime | ||||
| DECLARE FUNCTION Logging_Services, Datetime, SRP_DateTime, GetTickCount | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, Send_Dyn, RList, obj_WO_Log, Send_Event, obj_RDS | ||||
| DECLARE SUBROUTINE obj_WO_Mat, Send_Info, obj_Notes, ErrMsg, Logging_Services, Mona_Services | ||||
|  | ||||
| @ -42,6 +42,13 @@ Headers     = 'Logging DTM' : @FM : 'WOMatKey' : @FM : ' SAPBatchNo' : @FM : 'Fa | ||||
| objLog      = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJPOSTLOG' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJPOSTLOG' | ||||
| end | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_Post_Log"' | ||||
| ErrorMsg = '' | ||||
|  | ||||
| @ -115,7 +122,10 @@ RETURN | ||||
| * * * * * * * | ||||
| Post: | ||||
| * * * * * * * | ||||
|  | ||||
| 	 | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'Post' | ||||
| 	 | ||||
|     hSysLists       = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
|     ServiceKeyID    = 'Obj_Post_Log*Post' | ||||
|     Lock hSysLists, ServiceKeyID then | ||||
| @ -228,6 +238,10 @@ Post: | ||||
|          | ||||
|         Unlock hSysLists, ServiceKeyID else Null | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -18,8 +18,8 @@ COMPILE FUNCTION obj_Reactor(Method,Parms) | ||||
|  | ||||
|  | ||||
|  | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, ErrMsg | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, ErrMsg, Mona_Services | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, Environment_Services, GetTickCount | ||||
|  | ||||
|  | ||||
| $INSERT REACTOR_EQUATES | ||||
| @ -28,6 +28,14 @@ $INSERT REACT_STATE_EQUATES | ||||
| $INSERT REACT_ITEM_EQUATES | ||||
| $INSERT MSG_EQUATES | ||||
| $insert REACTOR_CHILD_KEY_IDS_EQUATES | ||||
| $Insert LOGICAL | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJREACTOR' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJREACTOR' | ||||
| end | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_Reactor"' | ||||
| ErrorMsg = '' | ||||
| @ -66,6 +74,9 @@ RETURN Result | ||||
| CurrItem: | ||||
| * * * * * * *  | ||||
|  | ||||
| StartTick = GetTickCount() | ||||
| MetricName = 'CurrItem' | ||||
|  | ||||
| ReactNo 	= Parms[1,@RM] | ||||
| ItemType	= Parms[COL2()+1,@RM] | ||||
| ReactRec	= Parms[COL2()+1,@RM] | ||||
| @ -96,6 +107,9 @@ LOCATE ItemType IN CurrInstTypes USING @VM SETTING Pos THEN | ||||
| 	Result = FIELD(CurrInstItems<1,Pos>,'*',2) | ||||
| END | ||||
|  | ||||
| EndTick = GetTickCount() | ||||
| Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
| @ -103,6 +117,9 @@ RETURN | ||||
| CurrGraphite: | ||||
| * * * * * * * | ||||
|  | ||||
| StartTick = GetTickCount() | ||||
| MetricName = 'CurrGraphite' | ||||
|  | ||||
| ReactNo	= Parms[1,@RM] | ||||
| ReactRec	= Parms[COL2()+1,@RM] | ||||
|  | ||||
| @ -135,6 +152,9 @@ FOR I = 1 TO ciCnt | ||||
| 	END | ||||
| NEXT I | ||||
|  | ||||
| EndTick = GetTickCount() | ||||
| Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -15,10 +15,10 @@ COMPILE FUNCTION obj_React_State(Method,Parms) | ||||
| */ | ||||
|  | ||||
|  | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, ErrMsg, Database_Services | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, ErrMsg, Database_Services, Mona_Services | ||||
|  | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, NextKey, Send_Dyn, Database_Services, Error_Services | ||||
|  | ||||
| Declare function Environment_Services, GetTickCount | ||||
|  | ||||
| $INSERT REACT_STATE_EQUATES | ||||
| $INSERT PROD_SPEC_EQUATES | ||||
| @ -28,6 +28,12 @@ $INSERT LOGICAL | ||||
| EQU CRLF$	TO \0D0A\ | ||||
| EQU TAB$	TO \09\ | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJREACTSTATE' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJREACTSTATE' | ||||
| end | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_React_State"' | ||||
| ErrorMsg = '' | ||||
| @ -62,6 +68,9 @@ RETURN Result | ||||
| ReactRunUnload: | ||||
| * * * * * * * | ||||
|  | ||||
| StartTick = GetTickCount() | ||||
| MetricName = 'ReactRunUnload' | ||||
|  | ||||
| * Upadate all parameters set at Reactor Unload signature  * | ||||
|  | ||||
| ReactNo			= Parms[1,@RM] | ||||
| @ -115,6 +124,9 @@ end | ||||
| * otParms = FieldStore(otParms,@RM,4,0,RSRec) | ||||
| * obj_Tables('WriteRec',otParms) | ||||
|  | ||||
| EndTick = GetTickCount() | ||||
| Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -20,9 +20,9 @@ COMPILE FUNCTION obj_React_Status(Method,Parms) | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| DECLARE FUNCTION   Get_Status, Msg, Utility, obj_Tables, Dialog_Box,NextKey, Popup, Get_Property, Database_Services | ||||
| DECLARE FUNCTION   Error_Services, Environment_Services, Logging_Services, Override_Log_Services | ||||
| DECLARE FUNCTION   Error_Services, Environment_Services, Logging_Services, Override_Log_Services, GetTickCount | ||||
| DECLARE SUBROUTINE Set_Status, Msg, obj_Tables, Send_Dyn, Btree.Extract, ErrMsg, Database_Services, Rlist | ||||
| DECLARE SUBROUTINE Logging_Services | ||||
| DECLARE SUBROUTINE Logging_Services, Mona_Services | ||||
|  | ||||
| $INSERT LOGICAL | ||||
| $INSERT MSG_EQUATES | ||||
| @ -43,6 +43,13 @@ LogFilename       = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : | ||||
| Headers           = 'Logging DTM' : @FM : 'User' : @FM : 'CassNo' : @FM : 'RDSNo' : @FM : 'Load DTM' : @FM : 'Service' : @FM : 'Notes' | ||||
| objReactStatusLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJREACTSTATUS' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJREACTSTATUS' | ||||
| end | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_React_Status"' | ||||
| ErrorMsg = '' | ||||
|  | ||||
| @ -125,6 +132,9 @@ RETURN | ||||
| CassLoad: | ||||
| * * * * * * * | ||||
|  | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'CassLoad' | ||||
|      | ||||
|     ReactNo = Parms[1,@RM] | ||||
|     WONo    = Parms[COL2()+1,@RM] | ||||
|     CassNo  = Parms[COL2()+1,@RM] | ||||
| @ -202,6 +212,9 @@ CassLoad: | ||||
|     IdleTime  = OCONV(ICONV(IdleTime*24,'MD2'),'MD2,') | ||||
|  | ||||
|     Result = IdleTime | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
| @ -209,7 +222,9 @@ RETURN | ||||
| * * * * * * * | ||||
| CassUnload: | ||||
| * * * * * * * | ||||
|  | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CassUnload' | ||||
| 	 | ||||
|     ReactNo   = Parms[1,@RM] | ||||
|     WONo      = Parms[COL2()+1,@RM] | ||||
|     CassNo    = Parms[COL2()+1,@RM] | ||||
| @ -270,6 +285,9 @@ CassUnload: | ||||
|     If Error_Services('HasError') then | ||||
|         ErrorMsg = Error_Services('GetMessage') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
| @ -277,7 +295,9 @@ RETURN | ||||
| * * * * * * * | ||||
| ReactorLoad: | ||||
| * * * * * * * | ||||
|  | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'ReactorLoad' | ||||
| 	 | ||||
|     * EpiPro Reactor Load | ||||
|  | ||||
|     ReactNo = Parms[1,@RM] | ||||
| @ -361,13 +381,18 @@ ReactorLoad: | ||||
|     end else | ||||
|         ErrorMsg = 'Unable to read REACT_STATUS record ':ReactNo:' for update (':Method:').' | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
| * * * * * * * | ||||
| ReactorUnload: | ||||
| * * * * * * * | ||||
|  | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'ReactorUnload' | ||||
| 	 | ||||
| * EpiPro Reactor Unload | ||||
|  | ||||
|     ReactNo   = Parms[1,@RM] | ||||
| @ -431,6 +456,9 @@ ReactorUnload: | ||||
|     end else | ||||
|         ErrorMsg = Error_Services('GetMessage') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
| @ -28,11 +28,12 @@ Compile Function obj_WO_Mat(Method,Parms) | ||||
| Declare Function   Get_Status, Msg, Utility, obj_Tables, Dialog_Box,NextKey, Popup, Get_Property, obj_RDS, RetStack | ||||
| Declare Function   Database_Services, GaN_Services, Logging_Services, Environment_Services, Signature_Services | ||||
| Declare Function   obj_WO_Mat, obj_WM_In, obj_WM_Out, obj_Prod_Spec, obj_Clean_Insp, obj_Calendar, obj_Popup | ||||
| Declare Function   Error_Services, Memberof, Datetime | ||||
| Declare Function   Error_Services, Memberof, Datetime, GetTickCount | ||||
| Declare Subroutine Set_Status, Msg, obj_Tables, Send_Dyn, Btree.Extract, ErrMsg, Send_Dyn, RList, obj_WO_Log, Send_Event | ||||
| Declare Subroutine obj_RDS, Extract_SI_Keys, obj_Pend_Ship_Labels, obj_WO_Mat_QA, Work_Order_Services, Service_Services | ||||
| Declare Subroutine obj_notes, obj_Clean_Insp, obj_Post_Log, Send_Info, obj_WO_Mat_Log, obj_SAP, obj_WO_Mat, obj_WO_Wfr | ||||
| Declare Subroutine Logging_Services, Set_Property, Delete, Database_Services, SRP_Stopwatch, Material_Services | ||||
| Declare subroutine Mona_Services | ||||
|  | ||||
| $Insert MSG_EQUATES | ||||
| $Insert WO_MAT_EQUATES | ||||
| @ -120,6 +121,13 @@ SAPFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' SetS | ||||
| SAPHeaders  = 'Logging DTM' : @FM : 'WOMatKey' : @FM : 'SAPBatchNo' | ||||
| objSAPLog   = Logging_Services('NewLog', SAPLogPath, SAPFileName, CRLF$, Comma$, SAPHeaders, '', False$, False$) | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJWOMAT' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJWOMAT' | ||||
| end | ||||
|  | ||||
| IF NOT(ASSIGNED(Method))	THEN ErrorMsg = 'Unassigned parameter "Method" passed to subroutine' | ||||
| IF NOT(ASSIGNED(Parms))		THEN Parms = '' | ||||
|  | ||||
| @ -633,6 +641,9 @@ RETURN | ||||
| * * * * * * * | ||||
| CurrStatus: | ||||
| * * * * * * * | ||||
| 	 | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CurrStatus' | ||||
|  | ||||
| 	IF NOT(ASSIGNED(WOMatKey)) THEN WOMatKey = Parms[1,@RM] | ||||
| 	IF NOT(ASSIGNED(WOMatRec)) THEN WOMatRec = Parms[COL2()+1,@RM] | ||||
| @ -894,6 +905,9 @@ CurrStatus: | ||||
| 	 | ||||
| 	IF Result = 'RTS' AND WOMatRec<WO_MAT_SHIP_HOLD$> = 1	THEN Result = 'SHOLD' | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
| RETURN | ||||
|  | ||||
|  | ||||
| @ -5566,3 +5580,4 @@ ExpCOA: | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -17,9 +17,9 @@ COMPILE FUNCTION obj_WO_Mat_Log(Method,Parms) | ||||
|  | ||||
|  | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, Dialog_Box, NextKey, Popup, Get_Property, obj_RDS, Database_Services | ||||
| Declare function    Logging_Services, Environment_Services, RTI_CreateGUID, Error_Services, Datetime | ||||
| Declare function    Logging_Services, Environment_Services, RTI_CreateGUID, Error_Services, Datetime, GetTickCount | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, Send_Dyn, Btree.Extract, ErrMsg, Send_Dyn, RList, obj_WO_Log, Send_Event, obj_RDS | ||||
| DECLARE SUBROUTINE obj_WO_Mat, Send_Info, obj_Notes, Logging_Services, Database_Services, Lot_Event_Services | ||||
| DECLARE SUBROUTINE obj_WO_Mat, Send_Info, obj_Notes, Logging_Services, Database_Services, Lot_Event_Services, Mona_Services | ||||
|  | ||||
| $INSERT MSG_EQUATES | ||||
| $INSERT WO_MAT_LOG_EQUATES | ||||
| @ -49,6 +49,13 @@ Headers     = 'Logging DTM' | ||||
| objLog      = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJWOMATLOG' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJWOMATLOG' | ||||
| end | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_WO_Mat_Log"' | ||||
| ErrorMsg = '' | ||||
|  | ||||
| @ -77,7 +84,9 @@ RETURN Result | ||||
| * * * * * * * | ||||
| Create: | ||||
| * * * * * * * | ||||
|  | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'Create' | ||||
| 	 | ||||
|     LogFile		= Parms[1,@RM] | ||||
|     TransDTM	= Parms[COL2()+1,@RM] | ||||
|     Action		= Parms[COL2()+1,@RM] | ||||
| @ -233,6 +242,8 @@ Create: | ||||
|     	ErrorMsg = Error_Services('GetMessage') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| RETURN | ||||
|  | ||||
|  | ||||
| @ -364,3 +375,4 @@ Post: | ||||
|      | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -15,8 +15,9 @@ COMPILE FUNCTION obj_WO_React(Method,Parms) | ||||
| */ | ||||
|  | ||||
|  | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, NextKey, obj_Prod_Spec, obj_WO_Mat_QA | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, RList, ErrMsg, Btree.Extract, obj_WO_Mat_QA | ||||
| DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, NextKey, obj_Prod_Spec, obj_WO_Mat_QA, GetTickCount | ||||
| Declare function Environment_Services | ||||
| DECLARE SUBROUTINE  Set_Status, Msg, obj_Tables, RList, ErrMsg, Btree.Extract, obj_WO_Mat_QA, Mona_Services | ||||
|  | ||||
| $INSERT MSG_EQUATES | ||||
| $INSERT WO_REACT_EQUATES | ||||
| @ -24,6 +25,7 @@ $INSERT PRS_STAGE_EQUATES | ||||
| $INSERT WO_MAT_EQUATES | ||||
| $INSERT RDS_EQUATES | ||||
| $INSERT QA_MET_EQUATES			;* Used in GetQAMet data structure return variable | ||||
| $Insert LOGICAL | ||||
|  | ||||
|  | ||||
| ErrTitle = 'Error in Stored Procedure "obj_PRS_Prop"' | ||||
| @ -40,6 +42,13 @@ END | ||||
| Result = '' | ||||
| Log = '' | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_OBJWOREACT' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_OBJWOREACT' | ||||
| end | ||||
|  | ||||
| BEGIN CASE | ||||
| 	CASE Method = 'AddRdsNo'	; GOSUB AddRdsNo | ||||
| 	CASE Method = 'RemRdsNo'	; GOSUB RemRdsNo | ||||
| @ -59,7 +68,10 @@ RETURN Result | ||||
|  | ||||
| * * * * * * * | ||||
| AddRdsNo: | ||||
| * * * * * * *  | ||||
| * * * * * * * | ||||
|  | ||||
| StartTick = GetTickCount() | ||||
| MetricName = 'AddRdsNo' | ||||
|  | ||||
| WONo	= Parms[1,@RM] | ||||
| StepNo	= Parms[COL2()+1,@RM] | ||||
| @ -135,13 +147,19 @@ obj_Tables('WriteOnlyRec',otParms)												;* Done with updates to the WO_REA | ||||
|  | ||||
| Result = Log | ||||
|  | ||||
| EndTick = GetTickCount() | ||||
| Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| * * * * * * * | ||||
| RemRDSNo: | ||||
| * * * * * * *  | ||||
| * * * * * * * | ||||
|  | ||||
| StartTick = GetTickCount() | ||||
| MetricName = 'RemRDSNo' | ||||
|  | ||||
| WONo	= Parms[1,@RM] | ||||
| StepNo	= Parms[COL2()+1,@RM] | ||||
| @ -218,6 +236,9 @@ obj_Tables('WriteOnlyRec',otParms)												;* Done with updates to the WO_REA | ||||
|  | ||||
| Result = Log | ||||
|  | ||||
| EndTick = GetTickCount() | ||||
| Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|  | ||||
| RETURN | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| Compile function Override_Log_Services(@Service, @Params) | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| $insert LOGICAL | ||||
| $Insert SERVICE_SETUP | ||||
| $insert APP_INSERTS | ||||
| $Insert OVERRIDE_LOG_EQUATES | ||||
|  | ||||
| Declare function   Datetime, NextKey, Error_Services, SRP_Datetime | ||||
| @ -22,9 +23,10 @@ Options OVERRIDE_TYPES     = 'ROTR_BLOCK,UNSIGN,CLEAN_INSP,REACTOR_PROVE_IN,REAC | ||||
|  | ||||
| Service Create(Table, Key, OverrideUser, OverrideComment, OverrideType=OVERRIDE_TYPES, OverrideCause='') | ||||
| 	 | ||||
| 	RecKey = '' | ||||
| 	ErrorMsg = '' | ||||
| 	RecKey   = '' | ||||
|     for each TableName in Table using @VM setting TablePos | ||||
|     	RecKey<1,-1> = Nextkey('OVERRIDE_LOG') | ||||
|     	RecKey                        = Nextkey('OVERRIDE_LOG') | ||||
| 		orRec                         = '' | ||||
| 		orRec<OVERRIDE_LOG_TABLE$>    = Table<1, TablePos> | ||||
| 		orRec<OVERRIDE_LOG_KEY$>      = Key<1, TablePos> | ||||
| @ -45,6 +47,7 @@ Service Create(Table, Key, OverrideUser, OverrideComment, OverrideType=OVERRIDE_ | ||||
|      | ||||
| End Service | ||||
|  | ||||
|  | ||||
| Service GetOverrideLogKeys(EntityId, Table, Type, User, DateTimeFrom, DateTimeTo) | ||||
| 	 | ||||
| 	If DateTimeFrom EQ '' OR Not(Num(DateTimeFrom)) Or DateTimeFrom GT DateTimeTo then | ||||
| @ -77,7 +80,6 @@ Service GetOverrideLogKeys(EntityId, Table, Type, User, DateTimeFrom, DateTimeTo | ||||
| 		Error_Services('Add', 'Error in ' : service : ' unable to open OVERRIDE_LOG dictionary.') | ||||
| 	end | ||||
| 	Response = keylist | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -143,7 +143,7 @@ Declare subroutine  RTI_Set_Debugger, Database_Services, Btree.Extract, Extract_ | ||||
| Declare subroutine  Set_Status, Sleepery, Winyield, Yield, SRP_COM, QA_Services, Logging_Services, Obj_RDS | ||||
| Declare subroutine  Validate, obj_WO_Mat, obj_WO_Mat_Log, obj_React_Status, Record_Lock, obj_React_State, obj_Post_Log | ||||
| Declare subroutine  RDS_Services, obj_WO_React, RDS_React_Run, Signature_Services, SQL_Services, SRP_Stopwatch | ||||
| Declare subroutine  Override_Services, Reactor_Services, Lot_Services | ||||
| Declare subroutine  Override_Services, Reactor_Services, Lot_Services, Mona_Services | ||||
| Declare function    SRP_Sort_Array, Metrology_Services, obj_RDS_Test, obj_Test_Point_Map, Database_Services | ||||
| Declare function    Work_Order_Services, SRP_JSON, Logging_Services, Environment_Services, SRP_Trim, Error_Services | ||||
| Declare function    Min, Max, SRPSendMail, Btree.Extract, GetTickCount, HTTPClient_Services, Obj_RDS, SQL_Services | ||||
| @ -177,6 +177,13 @@ LogFilename       = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : | ||||
| Headers           = 'Logging DTM' : @FM : 'User' : @FM : 'CassNo' : @FM : 'RDSNo' : @FM : 'Load DTM' : @FM : 'Service' : @FM : 'Notes' | ||||
| objReactStatusLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_QASERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_QASERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
| 	Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') | ||||
| end | ||||
| @ -229,12 +236,6 @@ Service CalculateHgCVData(Datapoints) | ||||
|             Min    = Min(Min, DataPoint) | ||||
|             Max    = Max(Max, DataPoint) | ||||
|             // Edge Mean Delta | ||||
| *            If Index GE 6 AND Index LE 9 then | ||||
| *                Delta1 = Delta1 + DataPoint | ||||
| *            end | ||||
| *            If Index GE 2 AND Index LE 5 then | ||||
| *                Delta2 = Delta2 + DataPoint | ||||
| *            end | ||||
|         end         | ||||
|         // Range % | ||||
|         Locate Index in RangePoints using ',' setting unusedIndex then | ||||
| @ -256,25 +257,15 @@ Service CalculateHgCVData(Datapoints) | ||||
|     EdgeMean4mm   = Edge4mmSum / 4 | ||||
|     EdgeMean10mm  = Edge10mmSum / 4 | ||||
|     If EdgeMean10mm GT 0 then | ||||
| *        Delta1Avg     = Delta1/4 | ||||
| *        Delta2Avg     = Delta2/4 | ||||
|         EdgeMeanDelta = ( (Edge4mmSum - Edge10mmSum)  / Edge10mmSum) * 100 ; // Changed divisor to Delta2Avg to match SPC - DJS | ||||
|      | ||||
|         // Range % | ||||
|         Range           = RangeMax - RangeMin | ||||
|         NumRangePoints  = DCount(RangePoints, ',') | ||||
|         RangeAvg        = RangeAvg / NumRangePoints | ||||
|         RangePct        = (Range / RangeAvg) * 100 | ||||
|          | ||||
| *        EdgeMeanDelta   = OConv(IConv(EdgeMeanDelta, 'MD3L'), 'MD3L') | ||||
| *        RangePct        = OConv(IConv(RangePct, 'MD3L'), 'MD3L') | ||||
|     end | ||||
|     // Average | ||||
|     Average         = Sum / NumDataPoints | ||||
| *    Average         = OConv(IConv(Average, 'MD3L'), 'MD3L') | ||||
| *    Min             = OConv(IConv(Min, 'MD3L'), 'MD3L') | ||||
| *    Max             = OConv(IConv(Max, 'MD3L'), 'MD3L') | ||||
|      | ||||
|  | ||||
|     Average         = Sum / NumDataPoints    | ||||
|     FullAvg         = '' | ||||
|     TotalDataPoints = DCount(DataPoints, @VM) | ||||
|     If TotalDataPoints GT 0 then FullAvg = Sum(DataPoints)/DCount(DataPoints, @VM) | ||||
| @ -361,25 +352,18 @@ Service PostROTRRequest(RDSNo) | ||||
|             If Flag EQ 0 then | ||||
|                 If RequestKeyID EQ '' then | ||||
|                     WOMatKey     = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') | ||||
|                     FinalSigComp = False$ | ||||
| *                    FinalSigComp = Signature_Services('FinalSigComp', WOMatKey) | ||||
|                     If FinalSigComp NE True$ then  | ||||
|                         // This is a new request | ||||
|                         RequestDate  = Date() | ||||
|                         RequestTime  = Time() | ||||
|                         RequestKeyID = RDSNo:'*':RequestDate :'*':RequestTime | ||||
|                         RequestRow   = '' | ||||
|                         Database_Services('WriteDataRow', 'ROTR_REQUESTS', RequestKeyID, RequestRow, True$, False$, True$) | ||||
|                         If Error_Services('NoError') then | ||||
|                             // Log success | ||||
|                             LogData<3>   = 'Successfully posted ROTR request for ':RDSNo:'.' | ||||
|                             Logging_Services('AppendLog', objErrorLog, LogData, @RM, @FM) | ||||
|                         end else | ||||
|                             ErrorMessage = Error_Services('GetMessage')                        | ||||
|                         end | ||||
|                     end else | ||||
|                         ErrorMessage = 'FQA signed for RDS ':RDSNo:' ignoring ROTR request.'         | ||||
|                     end | ||||
| 					RequestDate  = Date() | ||||
| 					RequestTime  = Time() | ||||
| 					RequestKeyID = RDSNo:'*':RequestDate :'*':RequestTime | ||||
| 					RequestRow   = '' | ||||
| 					Database_Services('WriteDataRow', 'ROTR_REQUESTS', RequestKeyID, RequestRow, True$, False$, True$) | ||||
| 					If Error_Services('NoError') then | ||||
| 						// Log success | ||||
| 						LogData<3>   = 'Successfully posted ROTR request for ':RDSNo:'.' | ||||
| 						Logging_Services('AppendLog', objErrorLog, LogData, @RM, @FM) | ||||
| 					end else | ||||
| 						ErrorMessage = Error_Services('GetMessage')                        | ||||
| 					end | ||||
|                 end else | ||||
|                     ErrorMessage = 'Duplicate request found for RDS ':RDSNo:'. Request ignored.' | ||||
|                 end | ||||
| @ -509,14 +493,7 @@ Service ProcessROTRRequest(RDSNo) | ||||
|                         ResponseCopy                                           = Response | ||||
|                         Swap @FM with ',' in ResponseCopy | ||||
|                         LogData<3>                                             = 'ROTR Status response: ':Response | ||||
|                         Logging_Services('AppendLog', objErrorLog, LogData, @RM, @FM) | ||||
| *                        ROTRRec                                                = '' | ||||
| *                        ROTRRec<ROTR.REACTOR_STATUS$>                          = Response<1> | ||||
| *                        ROTRRec<ROTR.REACTOR_STATUS_REASON$>                   = Response<2> | ||||
| *                        ROTRRec<ROTR.REACTOR_NCR_COUNT$>                       = Response<3> | ||||
| *                        ROTRRec<ROTR.REACTOR_ZERO_NCR_RUN_COUNT$>              = Response<4> | ||||
| *                        ROTRRec<ROTR.REACTOR_UCL_EXCEEDED_RUN_COUNT$>          = Response<5> | ||||
| *                        Database_Services('WriteDataRow', 'ROTR', LWICINo, ROTRRec, True$, False$, True$)                                  | ||||
|                         Logging_Services('AppendLog', objErrorLog, LogData, @RM, @FM)                                 | ||||
|                         CIRec<CLEAN_INSP_ROTR_REACTOR_STATUS$>                 = Response<1> | ||||
|                         CIRec<CLEAN_INSP_ROTR_REACTOR_STATUS_REASON$>          = Response<2> | ||||
|                         CIRec<CLEAN_INSP_ROTR_REACTOR_NCR_COUNT$>              = Response<3> | ||||
| @ -524,7 +501,6 @@ Service ProcessROTRRequest(RDSNo) | ||||
|                         CIRec<CLEAN_INSP_ROTR_REACTOR_UCL_EXCEEDED_RUN_COUNT$> = Response<5> | ||||
|                         // Set ROTR Update Flag to trigger CLEAN_INSP_ACTIONS routine (via BASE_MFS). | ||||
|                         // That routine will recalculate the final ROTR status.  | ||||
| *                        CIRec<CLEAN_INSP_ROTR_UPDATE_FLAG$>                    = True$ | ||||
|                         Database_Services('WriteDataRow', 'CLEAN_INSP', LWICINo, CIRec, True$, False$, True$)        			 | ||||
|                     end else | ||||
|                         ErrorMessage = 'Error in service ':Service:'. Failed to retrieve ROTR status. Error message: ':Error_Services('GetMessage') | ||||
| @ -569,6 +545,7 @@ end service | ||||
| //  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service GetROTRStatus(RDSKey) | ||||
| 	 | ||||
|     RDSRec               = Database_Services('ReadDataRow', 'RDS', RDSKey) | ||||
|     WONo                 = RDSRec<RDS_WO$> | ||||
|     RDSCassNo            = RDSRec<RDS_CASS_NO$> | ||||
| @ -1187,7 +1164,7 @@ return | ||||
|  | ||||
|  | ||||
| Service ProcessWaferImageRequests() | ||||
|      | ||||
|  | ||||
|     hSysLists   = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
|     Lock hSysLists, ServiceKeyID then | ||||
|         hWaferImageRequests = Database_Services('GetTableHandle', 'WAFER_IMAGE_REQUESTS') | ||||
| @ -1218,12 +1195,7 @@ Service ProcessWaferImageRequests() | ||||
|                         Reactor      = Xlate('RDS', RDSNo, 'REACTOR', 'X') | ||||
|                         PSN          = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') | ||||
|                         // Format Wafer Number for SQL Query | ||||
|                         WaferNo      = TrimF(WaferNo) | ||||
|                         If WaferNo < 10 then | ||||
|                             WaferNo  = '*0' : WaferNo | ||||
|                         end else | ||||
|                             WaferNo  = '*' : WaferNo | ||||
|                         end | ||||
|                         WaferNo = Fmt(TrimF(WaferNo), 'R(0)#2') | ||||
|                         Query = "DECLARE @RDS         varchar(10) "                                                     | | ||||
|                               : "DECLARE @RECIPE      varchar(30) "                                                     | | ||||
|                               : "DECLARE @WFRID       varchar(10) "                                                     | | ||||
| @ -1245,7 +1217,7 @@ Service ProcessWaferImageRequests() | ||||
|                         InsertDate   = InsertDTM[1, 'F '] | ||||
|                         Year         = Field(InsertDate, '/', 3, 1)  | ||||
|                         WorkWeek     = 'WW':Date_Services('GetWeekNum', InsertDate) | ||||
|                         PDFPath      = WaferMapRoot:'_\':Year:'\':WorkWeek:'\':AttachmentID:'\image.pdf' | ||||
|                         PDFPath      = WaferMapRoot:'\':Year:'\':WorkWeek:'\':AttachmentID:'\image.pdf' | ||||
|                         Set_Status(0) | ||||
|                         PDFFile      = '' | ||||
|                         OSRead PDFFile from PDFPath then | ||||
| @ -1292,100 +1264,6 @@ Service ProcessWaferImageRequests() | ||||
| end service | ||||
|  | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // ProcessWaferImageRequests | ||||
| // | ||||
| // Service that attempts to process all wafer map image requests. These requests are queued in the | ||||
| // WAFER_IMAGE_REQUESTS table. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ProcessWaferImageRequestsOld() | ||||
|      | ||||
|     hSysLists   = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
|     Lock hSysLists, ServiceKeyID then | ||||
|         hWaferImageRequests = Database_Services('GetTableHandle', 'WAFER_IMAGE_REQUESTS') | ||||
|         If Error_Services('NoError') then | ||||
|             Sentence    = 'SELECT WAFER_IMAGE_REQUESTS WITH RESPONSE_DATE EQ "" BY REQUEST_DATE BY REQUEST_TIME' | ||||
|             Set_Status(0) | ||||
|             RList(Sentence, TARGET_ACTIVELIST$, '', '', '') | ||||
|             EOF         = False$ | ||||
|             Loop | ||||
|                 ReadNext RequestKeyID else EOF = True$ | ||||
|             Until EOF | ||||
|                 RequestDate  = Field(RequestKeyID, '*', 1) | ||||
|                 RequestTime  = Field(RequestKeyID, '*', 2) | ||||
|                 RequestTime  = RequestTime / 86400 | ||||
|                 RequestTime  = RequestTime[3, 5] | ||||
|                 RequestDTM   = RequestDate:'.':RequestTime | ||||
|                 CurrDTM      = Datetime()                | ||||
|                 TimeInQueue = CurrDTM - RequestDTM | ||||
|                 If TimeInQueue LT 1 then | ||||
|                     Lock hWaferImageRequests, RequestKeyID then | ||||
|                         EncodedPDF   = '' | ||||
|                         ResponseBody = '' | ||||
|                         RequestRow   = Database_Services('ReadDataRow', 'WAFER_IMAGE_REQUESTS', RequestKeyID) | ||||
|                         RDSNo        = RequestRow<WAFER_IMAGE_REQUESTS.RDS_NO$> | ||||
|                         WaferNo      = RequestRow<WAFER_IMAGE_REQUESTS.WAFER_NO$> | ||||
|                         TencorRecipe = RequestRow<WAFER_IMAGE_REQUESTS.TENCOR_RECIPE$> | ||||
|                         ReturnPDF    = RequestRow<WAFER_IMAGE_REQUESTS.RETURN_PDF$> | ||||
|                         Reactor      = Xlate('RDS', RDSNo, 'REACTOR', 'X') | ||||
|                         PSN          = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') | ||||
|                         // Format Wafer Number for SQL Query | ||||
|                         WaferNo      = TrimF(WaferNo) | ||||
|                         If WaferNo < 10 then | ||||
|                             WaferNo  = '*0' : WaferNo | ||||
|                         end else | ||||
|                             WaferNo  = '*' : WaferNo | ||||
|                         end | ||||
|                         Query = "DECLARE @RDS         varchar(10) "                                                     | | ||||
|                               : "DECLARE @RECIPE      varchar(30) "                                                     | | ||||
|                               : "DECLARE @WFRID       varchar(10) "                                                     | | ||||
|                               : "SET @RDS      = '":RDSNo:"' "                                                          | | ||||
|                               : "SET @RECIPE   = '":TencorRecipe:"' "                                                   | | ||||
|                               : "SET @WFRID    = '":WaferNo:"' "                                                        | | ||||
|                               : "SELECT child.AttachmentID "                                                            | | ||||
|                               : "FROM Metrology.dbo.TencorRunHeader header "                                            | | ||||
|                               : "INNER JOIN Metrology.dbo.TencorRunData child on header.id = child.headerid "           | | ||||
|                               : "WHERE header.rds = @RDS and header.recipe like @RECIPE + '%' and child.slot = @WFRID " | | ||||
|                               : "ORDER BY header.insertDate DESC, child.slot ASC" | ||||
|                                | ||||
|                         WaferMapDB      = Environment_Services('GetMetrologyProductionPath')      | ||||
|                         AttachmentID    = SQL_Services('GetDataRows', 'SPC', Query) | ||||
|                         AttachmentID    = SRP_Trim(AttachmentID, 'FB', '{}') | ||||
|                         WaferMapRoot    = Environment_Services('GetWaferMapProductionPath') | ||||
|                         PDFPath         = WaferMapRoot:'\':AttachmentID:'\image.pdf' | ||||
|                         Set_Status(0) | ||||
|                         PDFFile         = '' | ||||
|                         OSRead PDFFile from PDFPath then | ||||
|                             // "Cache" PDF on app server | ||||
|                             QA_Services('PostToWaferImageQueue', RDSNo, WaferNo, TencorRecipe, PDFFile) | ||||
|                             If ReturnPDF EQ True$ then | ||||
|                                 ResponseBody                                    = SRP_Encode(PDFFile) | ||||
|                                 RequestRow<WAFER_IMAGE_REQUESTS.RESPONSE_BODY$> = ResponseBody | ||||
|                                 RequestRow<WAFER_IMAGE_REQUESTS.RESPONSE_DATE$> = Date() | ||||
|                                 RequestRow<WAFER_IMAGE_REQUESTS.RESPONSE_TIME$> = Time() | ||||
|                                 Database_Services('WriteDataRow', 'WAFER_IMAGE_REQUESTS', RequestKeyID, RequestRow, True$)     | ||||
|                             end else | ||||
|                                 Database_Services('DeleteDataRow', 'WAFER_IMAGE_REQUESTS', RequestKeyID, True$) | ||||
|                             end | ||||
|                              | ||||
|                         end else                     | ||||
|                             ErrorCode = Status() | ||||
|                             Error_Services('Add', 'Error retrieving wafer map image for AttachmentID ':AttachmentID) | ||||
|                         end | ||||
|                         Unlock hWaferImageRequests, RequestKeyID else Null | ||||
|                     end | ||||
|                 end else | ||||
|                     // Delete request because wafer image may never become available. | ||||
|                     Database_Services('DeleteDataRow', 'WAFER_IMAGE_REQUESTS', RequestKeyID, True$) | ||||
|                 end | ||||
|             Repeat | ||||
|         end | ||||
|         Unlock hSysLists, ServiceKeyID else Null     | ||||
|     end | ||||
|  | ||||
| end service | ||||
|  | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // PostToWaferImageQueue | ||||
| // | ||||
| @ -1753,9 +1631,7 @@ Service ROTRImpactReport() | ||||
|             column = OleGetProperty( xlSht, 'Range' , 'K:K' ) | ||||
|             OlePutProperty( column , 'ColumnWidth' , '15' ) | ||||
|             OlePutProperty( column , 'NumberFormat' , '0.0%' )      | ||||
|              | ||||
|         end | ||||
|          | ||||
|     end | ||||
|      | ||||
| end service | ||||
| @ -1802,6 +1678,8 @@ end service | ||||
| //              False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service PreEpiSignatureReady(RDSNo, Username, WaferQty, Reactor) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'PreEpiSignatureReady' | ||||
|  | ||||
|     If (RDSNo EQ '') or (Username EQ '') or (WaferQty EQ '') or (Reactor EQ '') then | ||||
|         ErrorMessage = 'RDSNo, Username, WaferQty, or Reactor not supplied in the ':Service:' service.' | ||||
| @ -1900,6 +1778,8 @@ Service PreEpiSignatureReady(RDSNo, Username, WaferQty, Reactor) | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)     | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -1916,6 +1796,8 @@ end service | ||||
| //  Reponse   - True$ if PRE stage was successfully signed, False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service SignPreEpiStage(RDSNo, Username, WaferQty, Reactor, ScanEntry) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'SignPreEpiStage' | ||||
|  | ||||
|     Error_Services('Clear') | ||||
|     If (RDSNo EQ '') or (Username EQ '') or (WaferQty EQ '') or (Reactor EQ '') then | ||||
| @ -1967,71 +1849,66 @@ Service SignPreEpiStage(RDSNo, Username, WaferQty, Reactor, ScanEntry) | ||||
|      | ||||
|     PreEpiSig   = RDSRec<RDS_PRE_EPI_SIG$> | ||||
|     ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X') | ||||
|     // Removing OI_SUPERUSER wrappers to alleviate signature issues. 11/18/19 djs | ||||
| *    IF MemberOf(Username, 'OI_SUPERUSER') THEN | ||||
|          | ||||
|         IF ReactorType NE 'EPP' THEN | ||||
|              | ||||
|             WOMatKey        = WONo:'*':CassNo | ||||
|             WOMatRec		= Database_Services('ReadDataRow', 'WO_MAT', WOMatKey) | ||||
|             WOMatSigProfile = WOMatRec<WO_MAT_SIG_PROFILE$> | ||||
|             SigAction		= WOStep:'VER' | ||||
| 	IF ReactorType NE 'EPP' THEN | ||||
| 		 | ||||
| 		WOMatKey        = WONo:'*':CassNo | ||||
| 		WOMatRec		= Database_Services('ReadDataRow', 'WO_MAT', WOMatKey) | ||||
| 		WOMatSigProfile = WOMatRec<WO_MAT_SIG_PROFILE$> | ||||
| 		SigAction		= WOStep:'VER' | ||||
|  | ||||
|             LOCATE SigAction IN WOMatSigProfile USING @VM SETTING Pos THEN | ||||
|                 WOMatSig = WOMatRec<WO_MAT_SIGNATURE$,Pos> | ||||
|                 CurrDTM  = OCONV(WOMatRec<WO_MAT_SIG_DTM$,Pos>,'DT/4^HS') | ||||
|             END ELSE | ||||
|                 WOMatSig = '' | ||||
|             END | ||||
|              | ||||
|             RDSSig = PreEpiSig | ||||
|              | ||||
|             BEGIN CASE | ||||
|                 CASE (WOMatSig EQ '') AND (RDSSig NE '') | ||||
|              | ||||
|                     * Signature missing on WO_MAT                        | ||||
|                     SigDate = RDSRec<RDS_PRE_EPI_SIG_DATE$> | ||||
|                     SigTime = RDSRec<RDS_PRE_EPI_SIG_TIME$> | ||||
|                     owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'VER':@RM:RDSSig:@RM:SigDate:' ':SigTime | ||||
|                     * Sets VER signature | ||||
| *                    obj_WO_Mat('SetSignature',owmParms) | ||||
|                     errCode = '' | ||||
|                     IF Get_Status(errCode) THEN | ||||
|                         ErrorMsg = 'Process Error: Error calling Obj_WO_Mat("SetSignature") within ':Service:'. Error code: ':errCode | ||||
|                         Error_Services('Set', ErrorMsg) | ||||
|                         Response = False$ | ||||
|                     END else | ||||
|                         Response = True$ | ||||
|                     end | ||||
|                     return | ||||
|                                 | ||||
|                 CASE (RDSSig = '') AND (WOMatSig NE '') | ||||
|                  | ||||
|                     * Signature missing on RDS                         | ||||
|                     CurrDate                      = CurrDTM[1,' '] | ||||
|                     CurrTime                      = CurrDTM[COL2()+1,' ']                         | ||||
|                     RDSRec<RDS_PRE_EPI_SIG$>      = WOMatSig | ||||
|                     RDSRec<RDS_PRE_EPI_SIG_DATE$> = IConv(CurrDate, 'D') | ||||
|                     RDSRec<RDS_PRE_EPI_SIG_TIME$> = IConv(CurrTime, 'MT') | ||||
|                     Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, True$) | ||||
|                     Response                      = True$                       | ||||
|                     return | ||||
|                      | ||||
|                 CASE RDSSig NE '' AND WOMatSig NE '' | ||||
|                      | ||||
|                     ErrorMessage = 'Process Error: Pre Epi stage has already been signed.' | ||||
|                     Error_Services('Set', ErrorMessage) | ||||
|                     Response = False$                     | ||||
|                     return | ||||
|                      | ||||
|                 CASE Otherwise$ | ||||
|                     Null | ||||
|                      | ||||
|             END CASE | ||||
|              | ||||
|         END	;* End of check for Reactor Type | ||||
|  | ||||
| *    END            | ||||
| 		LOCATE SigAction IN WOMatSigProfile USING @VM SETTING Pos THEN | ||||
| 			WOMatSig = WOMatRec<WO_MAT_SIGNATURE$,Pos> | ||||
| 			CurrDTM  = OCONV(WOMatRec<WO_MAT_SIG_DTM$,Pos>,'DT/4^HS') | ||||
| 		END ELSE | ||||
| 			WOMatSig = '' | ||||
| 		END | ||||
| 		 | ||||
| 		RDSSig = PreEpiSig | ||||
| 		 | ||||
| 		BEGIN CASE | ||||
| 			CASE (WOMatSig EQ '') AND (RDSSig NE '') | ||||
| 		 | ||||
| 				* Signature missing on WO_MAT                        | ||||
| 				SigDate = RDSRec<RDS_PRE_EPI_SIG_DATE$> | ||||
| 				SigTime = RDSRec<RDS_PRE_EPI_SIG_TIME$> | ||||
| 				owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'VER':@RM:RDSSig:@RM:SigDate:' ':SigTime | ||||
| 				* Sets VER signature | ||||
| 				errCode = '' | ||||
| 				IF Get_Status(errCode) THEN | ||||
| 					ErrorMsg = 'Process Error: Error calling Obj_WO_Mat("SetSignature") within ':Service:'. Error code: ':errCode | ||||
| 					Error_Services('Set', ErrorMsg) | ||||
| 					Response = False$ | ||||
| 				END else | ||||
| 					Response = True$ | ||||
| 				end | ||||
| 				return | ||||
| 						    | ||||
| 			CASE (RDSSig = '') AND (WOMatSig NE '') | ||||
| 			 | ||||
| 				* Signature missing on RDS                         | ||||
| 				CurrDate                      = CurrDTM[1,' '] | ||||
| 				CurrTime                      = CurrDTM[COL2()+1,' ']                         | ||||
| 				RDSRec<RDS_PRE_EPI_SIG$>      = WOMatSig | ||||
| 				RDSRec<RDS_PRE_EPI_SIG_DATE$> = IConv(CurrDate, 'D') | ||||
| 				RDSRec<RDS_PRE_EPI_SIG_TIME$> = IConv(CurrTime, 'MT') | ||||
| 				Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, True$) | ||||
| 				Response                      = True$                       | ||||
| 				return | ||||
| 				 | ||||
| 			CASE RDSSig NE '' AND WOMatSig NE '' | ||||
| 				 | ||||
| 				ErrorMessage = 'Process Error: Pre Epi stage has already been signed.' | ||||
| 				Error_Services('Set', ErrorMessage) | ||||
| 				Response = False$                     | ||||
| 				return | ||||
| 				 | ||||
| 			CASE Otherwise$ | ||||
| 				Null | ||||
| 				 | ||||
| 		END CASE | ||||
| 		 | ||||
| 	END	;* End of check for Reactor Type    | ||||
|  | ||||
|     SigDate = OCONV( Date(), 'D2/' ) | ||||
|     SigTime	= OCONV( Time(), 'MTS' ) | ||||
| @ -2045,7 +1922,6 @@ Service SignPreEpiStage(RDSNo, Username, WaferQty, Reactor, ScanEntry) | ||||
|  | ||||
|         owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'VER':@RM:Username:@RM:SigDate:' ':SigTime	;* Sets VER signature | ||||
|          | ||||
| *        obj_WO_Mat('SetSignature',owmParms) | ||||
|         IF Get_Status(errCode) THEN | ||||
|             ErrorMessage = 'Process Error: Error calling obj_WO_Mat("SetSignature"). Error code: ':errCode | ||||
|             Error_Services('Set', ErrorMessage) | ||||
| @ -2099,6 +1975,8 @@ Service SignPreEpiStage(RDSNo, Username, WaferQty, Reactor, ScanEntry) | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -2118,6 +1996,8 @@ end service | ||||
| //              False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOpt) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'LoadSignatureReady' | ||||
|      | ||||
|     Error_Services('Clear') | ||||
|     If (RDSNo EQ '') or (Username EQ '') or (WaferQty EQ '') then | ||||
| @ -2188,7 +2068,7 @@ Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOp | ||||
|             return | ||||
|         end             | ||||
|     end | ||||
|      | ||||
|  | ||||
|     // Ensure recipe parameters (RDS Layer parameters) have been manually entered or automatically applied. | ||||
|     LSParmsComp = Xlate('RDS', RDSNo, 'LS_PARMS_COMP', 'X') | ||||
|     Buf1        = DCount(LSParmsComp, @VM) | ||||
| @ -2210,16 +2090,8 @@ Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOp | ||||
|         return | ||||
|     end | ||||
|      | ||||
|     //Added 8/18/2021 JRO - checks to make sure recipe limits aren't oos | ||||
| * 	IF ParamOutOfSpec then | ||||
| *        IF Supplement NE True$ then | ||||
| *            ErrorMsg = 'Process Error: Recipe parameters are out of spec and no supplement has been set.' | ||||
| *            Error_Services('Set', ErrorMsg) | ||||
| *            Response = False$ | ||||
| *            return | ||||
| *        end | ||||
| * 	end | ||||
|     Locate True$ in ParamOutOfSpec using @VM setting oPos then | ||||
|     	 | ||||
| 		IF Supplement NE True$ then | ||||
|             ErrorMsg = 'Process Error: Recipe parameters are out of spec and no supplement has been set.' | ||||
|             Error_Services('Set', ErrorMsg) | ||||
| @ -2233,13 +2105,6 @@ Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOp | ||||
|         Response = False$ | ||||
|         return | ||||
|     end | ||||
|                              | ||||
| *    IF (ReactorType = 'ASM+' OR ReactorType = 'HTR') AND (LoadLockVal EQ '') THEN | ||||
| *        ErrorMsg = 'Process Error: Load Lock Side must be set to either Left or Right before signing.' | ||||
| *        Error_Services('Set', ErrorMsg) | ||||
| *        Response = False$ | ||||
| *        return | ||||
| *    END | ||||
|  | ||||
| 	//Added JRO 3/16/2021 | ||||
|     //Load Lock Required Check | ||||
| @ -2313,50 +2178,27 @@ Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOp | ||||
|         Response = False$ | ||||
|         Return | ||||
|     END | ||||
|   | ||||
| 	If PreFlag EQ True$ then | ||||
| 		// PRE and LOAD stages are being signed together. This is usually because the operator is loading a reactor | ||||
| 		// using the barcode scanner, which attempts to sign both stages at once to save time.        | ||||
| 		Stage = 'VER' | ||||
| 	end else | ||||
| 		Stage = 'LOAD' | ||||
| 	end | ||||
|  | ||||
| *    IF ReactorType NE 'EPP' THEN | ||||
|          | ||||
|         If PreFlag EQ True$ then | ||||
|             // PRE and LOAD stages are being signed together. This is usually because the operator is loading a reactor | ||||
|             // using the barcode scanner, which attempts to sign both stages at once to save time.        | ||||
|             Stage = 'VER' | ||||
|         end else | ||||
|             Stage = 'LOAD' | ||||
|         end | ||||
|      | ||||
|       	If ReactorType EQ 'EPP' then | ||||
| 			WOMatKey = '' | ||||
| 		end else | ||||
| 			WOMatKey = WONo:'*':CassNo | ||||
| 		end | ||||
|          | ||||
|         Signature_Services('CheckSigOrder', WOMatKey, Stage, False$, RDSNo) | ||||
|          | ||||
|         If Error_Services('HasError') then | ||||
|             Response = False$ | ||||
|             Return | ||||
|         end | ||||
|              | ||||
| !   Deprecated 11/20/2019 | ||||
| *        Set_Status(0) | ||||
| *        obj_WO_Mat('CheckSigOrder',WONo:'*':CassNo:@RM:WOStep:'LOAD') | ||||
| *        IF Get_Status(errCode) THEN | ||||
| *            ErrorMsg = 'Process Error: Error calling obj_WO_Mat("CheckSigOrder"). Error code: ':errCode | ||||
| *            Error_Services('Set', ErrorMsg) | ||||
| *            Response = False$ | ||||
| *            RETURN | ||||
| *        END | ||||
|  | ||||
| *    END	;* End of check for Epi Pro | ||||
|  | ||||
|      // Deprecated in favor of stage specific supplements | ||||
| *    SupplAckReq = Xlate('RDS', RDSNo, 'SUPPL_ACK_REQ', 'X') | ||||
| *    IF (SupplAckReq EQ True$) then  | ||||
| *        ErrorMsg = 'The RDS Supplement must be acknowledged before the load operation can be signed.' | ||||
| *        Error_Services('Set', ErrorMsg) | ||||
| *        Response = False$ | ||||
| *        Return | ||||
| *    END | ||||
| 	If ReactorType EQ 'EPP' then | ||||
| 		WOMatKey = '' | ||||
| 	end else | ||||
| 		WOMatKey = WONo:'*':CassNo | ||||
| 	end | ||||
| 	 | ||||
| 	Signature_Services('CheckSigOrder', WOMatKey, Stage, False$, RDSNo) | ||||
| 	 | ||||
| 	If Error_Services('HasError') then | ||||
| 		Response = False$ | ||||
| 		Return | ||||
| 	end | ||||
|  | ||||
|     SigDate = RDSRec<RDS_PRE_EPI_SIG_DATE$> | ||||
|     SigTime = RDSrec<RDS_PRE_EPI_SIG_TIME$> | ||||
| @ -2402,9 +2244,13 @@ Service LoadSignatureReady(RDSNo, Username, WaferQty, LLSide, PreFlag, ReactNoOp | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service LoadExtra1stReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2416,9 +2262,12 @@ Service LoadExtra1stReady(RDSNo) | ||||
| 	If StandardLoadSignature NE '' AND UnloadExtra1Signature NE '' AND LoadExtra1Signature EQ '' And LoadExtra2Signature EQ ''AND UnloadExtra2Signature EQ ''  and StandardUnloadSignature EQ '' then | ||||
| 		Response = True$ | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnsignLoadExtra1stReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2435,7 +2284,9 @@ Service UnsignLoadExtra1stReady(RDSNo) | ||||
|  | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service LoadExtra2ndReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2447,9 +2298,12 @@ Service LoadExtra2ndReady(RDSNo) | ||||
| 	If StandardLoadSignature NE '' AND UnloadExtra1Signature NE '' AND LoadExtra1Signature NE '' AND UnloadExtra2Signature NE '' And LoadExtra2Signature EQ '' and StandardUnloadSignature EQ '' then | ||||
| 		Response = True$ | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnsignLoadExtra2ndReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2463,8 +2317,10 @@ Service UnsignLoadExtra2ndReady(RDSNo) | ||||
| 			Response = True$ | ||||
| 		end		 | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // SignLoadStage | ||||
| // | ||||
| @ -2478,6 +2334,8 @@ end service | ||||
| //              False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service SignLoadStage(RDSNo, Username, WaferQty, LLSide, ScanEntry) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'SignLoadStage' | ||||
|      | ||||
|     Error_Services('Clear') | ||||
|     If (RDSNo EQ '') or (Username EQ '') or (WaferQty EQ '') then | ||||
| @ -2685,6 +2543,8 @@ Service SignLoadStage(RDSNo, Username, WaferQty, LLSide, ScanEntry) | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -2700,6 +2560,8 @@ end service | ||||
| //              False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service UnloadSignatureReady(RDSNo, Username, Reactor) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'UnloadSignatureReady' | ||||
|  | ||||
|     If (RDSNo EQ '') or (Username EQ '') or (Reactor EQ '') then | ||||
|         ErrorMsg = 'RDSNo or Username or Reactor not supplied in the ':Service:' service.' | ||||
| @ -2749,39 +2611,17 @@ Service UnloadSignatureReady(RDSNo, Username, Reactor) | ||||
|     end | ||||
|     ReactorType = XLATE('RDS',RDSNo,'REACTOR_TYPE','X') | ||||
|  | ||||
|     | ||||
| *    IF ReactorType NE 'EPP' THEN | ||||
|          | ||||
|          | ||||
|         If ReactorType EQ 'EPP' then | ||||
|         	WOMatKey = '' | ||||
|         end else | ||||
|         	WOMatKey = WONo:'*':CassNo | ||||
|         end | ||||
|          | ||||
|         Signature_Services('CheckSigOrder', WOMatKey, 'UNLOAD', RDSNo) | ||||
|         If Error_Services('HasError') then | ||||
|             Response = False$ | ||||
|             return | ||||
|         end | ||||
|  | ||||
| *    END ELSE | ||||
| *         | ||||
| *        ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')         | ||||
| *        LOCATE 'LWI' IN ReactRunRec<REACT_RUN_CI_STAGE$> USING @VM SETTING Pos THEN | ||||
| *            CINo = ReactRunRec<REACT_RUN_CI_NO$>            | ||||
| *            Actions = obj_Clean_Insp('GetActions',CINo)             | ||||
| *            LOCATE 'Inspection' IN Actions<ACTION$ACTIONS> USING @FM SETTING Pos THEN                 | ||||
| *                IF Actions<ACTION$SIGS,1> = '' THEN | ||||
| *                    ErrorMsg = 'Process Error: A Wafer Inspection is required and has not been completed.' | ||||
| *                    Error_Services('Set', ErrorMsg) | ||||
| *                    Response = False$ | ||||
| *                    return | ||||
| *                END | ||||
| *            END | ||||
| *        END | ||||
| * | ||||
| *    END	;* End of check for EpiPRO (EPP) reactor type | ||||
| 	If ReactorType EQ 'EPP' then | ||||
| 		WOMatKey = '' | ||||
| 	end else | ||||
| 		WOMatKey = WONo:'*':CassNo | ||||
| 	end | ||||
| 	 | ||||
| 	Signature_Services('CheckSigOrder', WOMatKey, 'UNLOAD', RDSNo) | ||||
| 	If Error_Services('HasError') then | ||||
| 		Response = False$ | ||||
| 		return | ||||
| 	end | ||||
|      | ||||
|     LWIInstAckReq = Xlate('RDS', RDSNo, 'LWI_INST_ACK_REQ', 'X') | ||||
|     If LWIInstAckReq EQ True$ then | ||||
| @ -2799,7 +2639,6 @@ Service UnloadSignatureReady(RDSNo, Username, Reactor) | ||||
|         return | ||||
|     end | ||||
|                    | ||||
|     ! Todo: We will have to define special logic for the barcode application to handle extra loads and unloads. | ||||
|     * Check for extra unloads without corresponding extra load                               | ||||
|     IF RDSRec<RDS_OP_OUT_EX1_DATE$> <> '' THEN | ||||
|             IF RDSRec<RDS_OP_IN_EX2_DATE$> = '' THEN | ||||
| @ -2869,9 +2708,13 @@ Service UnloadSignatureReady(RDSNo, Username, Reactor) | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnloadExtra1stReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2883,9 +2726,12 @@ Service UnloadExtra1stReady(RDSNo) | ||||
| 	If StandardLoadSignature NE '' AND UnloadExtra1Signature EQ '' AND LoadExtra1Signature EQ '' AND UnloadExtra2Signature EQ '' And LoadExtra2Signature eq '' and StandardUnloadSignature EQ '' then | ||||
| 		Response = True$ | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnloadExtra2ndReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2897,9 +2743,12 @@ Service UnloadExtra2ndReady(RDSNo) | ||||
| 	If StandardLoadSignature NE '' AND UnloadExtra1Signature NE '' AND LoadExtra1Signature NE '' And LoadExtra2Signature EQ ''AND UnloadExtra2Signature EQ ''  and StandardUnloadSignature EQ '' then | ||||
| 		Response = True$ | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnsignUnloadExtra1stReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2916,7 +2765,9 @@ Service UnsignUnloadExtra1stReady(RDSNo) | ||||
|  | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service UnsignUnloadExtra2ndReady(RDSNo) | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	RDSRec                  = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	StandardLoadSignature   = RDSRec<RDS_OPERATOR_IN$> | ||||
| @ -2930,6 +2781,7 @@ Service UnsignUnloadExtra2ndReady(RDSNo) | ||||
| 			Response = True$ | ||||
| 		end		 | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -2944,6 +2796,9 @@ end service | ||||
| //  Response  - True$ if UNLOAD stage was successfully signed , False$ otherwise. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service SignUnloadStage(RDSNo, Username, ScanEntry) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'SignUnloadStage' | ||||
|      | ||||
|     If (RDSNo EQ '') or (Username EQ '') then | ||||
|         ErrorMsg = 'RDSNo or Username not supplied in the ':Service:' service.' | ||||
|         Error_Services('Add', ErrorMsg) | ||||
| @ -3016,7 +2871,6 @@ Service SignUnloadStage(RDSNo, Username, ScanEntry) | ||||
|  | ||||
|         * 4/30/2013 JCH added parms for merging of two methods			 | ||||
|         owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'UNLOAD':@RM:Username:@RM:SigDt:' ':SigTm:@RM:ReactID:@RM:ReactWH:@RM:ReactLoc:@RM:Tag		 | ||||
| *        obj_WO_Mat('SetSignature',owmParms) | ||||
|                          | ||||
|         IF Get_Status(errCode) THEN | ||||
|             ErrorMsg = 'Process Error: Error calling Obj_WO_Mat("SetSignature") within the ':Service:' service' | ||||
| @ -3050,9 +2904,6 @@ Service SignUnloadStage(RDSNo, Username, ScanEntry) | ||||
|  | ||||
|             obj_React_Status('CassUnload',Reactor:@RM:WONo:@RM:CassNo:@RM:UnloadDTM:@RM:RDSNo) | ||||
|             IF Get_Status(errCode) THEN | ||||
| *                ErrorMsg = 'Process Error: Error calling Obj_React_Status("CassUnload") within the ':Service:' service' | ||||
| *                Error_Services('Add', ErrorMsg) | ||||
| *                Response = False$ | ||||
|                 LogData = '' | ||||
|                 LogData<1> = LoggingDTM | ||||
|                 LogData<2> = @User4 | ||||
| @ -3068,7 +2919,6 @@ Service SignUnloadStage(RDSNo, Username, ScanEntry) | ||||
|         InCassettes = RDSRec<RDS_IN_CASS_NO$> | ||||
|         InCassettes = SRP_Array('Clean', InCassettes, 'TrimAndMakeUnique', @VM) | ||||
|         obj_React_Status('ReactorUnload',Reactor:@RM:WONo:@RM:InCassettes:@RM:UnloadDTM:@RM:RDSNo) | ||||
|         //Reactor_Services('IncrementWfrMetrics', RDSNo) | ||||
|     end | ||||
|                      | ||||
|     RDSRec<RDS_OPERATOR_OUT$> = SigBy | ||||
| @ -3141,6 +2991,8 @@ Service SignUnloadStage(RDSNo, Username, ScanEntry) | ||||
|         Response = False$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -3474,98 +3326,10 @@ Service SignFQAStage(RDSNo, Username) | ||||
|                 END | ||||
|             NEXT Index | ||||
|         END | ||||
|  | ||||
|  | ||||
|         ********************************************** | ||||
|         * Verify the FlatFinder information          * | ||||
|         ********************************************** | ||||
|         EpiPartNo               = {EPI_PART_NO} | ||||
|         WaferSize               = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X') | ||||
|         WaferSizeInch           = Field(WaferSize, ' ', 3, 1) | ||||
|         CustNo                  = {CUST_NO} | ||||
|         CompanyRow              = Xlate('COMPANY', CustNo, '', 'X') | ||||
| 		WafersOut				= {WFRS_OUT}         | ||||
|          | ||||
|         Begin Case | ||||
|         	 | ||||
|         	Case WaferSizeInch = '6' | ||||
|  | ||||
| 				WaferFlatSizeInches     = CompanyRow<COMPANY_WAFER_FLAT_WAFER_SIZE_INCH$> | ||||
| 				WaferFlatLengthMins     = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MIN$>, 'MD1') | ||||
| 				WaferFlatLengthMaxes    = Oconv(CompanyRow<COMPANY_WAFER_FLAT_LENGTH_MAX$>, 'MD1') | ||||
|  | ||||
| 				Locate WaferSizeInch in WaferFlatSizeInches using @VM setting vPos then | ||||
| 					WaferFlatLengthMin  = WaferFlatLengthMins<0, vPos> | ||||
| 					WaferFlatLengthMax  = WaferFlatLengthMaxes<0, vPos> | ||||
| 				end else | ||||
| 					WaferFlatLengthMin  = '' | ||||
| 					WaferFlatLengthMax  = '' | ||||
| 				end | ||||
|  | ||||
| 				// Get FlatFinder Read Value | ||||
| *				FlatFinderWafersQty     = {FLATFINDER_WAFER_CNT} | ||||
| 				FlatFinderWaferLength   = {FLATFINDER_FLAT_LENGTH} | ||||
|  | ||||
| 				*************************************** | ||||
| 				* FlatFinder - Wafers Quatity Section * | ||||
| 				*************************************** | ||||
| *				If (FlatFinderWafersQty NE '') then | ||||
| *					If (FlatFinderWafersQty NE WafersOut) then | ||||
| *						ErrorMsg = 'Unable to sign FQA because Flat Finder and Wafers Out quantities do not match.' | ||||
| *						Error_Services('Add', ErrorMsg) | ||||
| *						return | ||||
| *					end | ||||
| *				end else | ||||
| *					ErrorMsg = 'Unable to sign FQA because the Flat Finder quantity is missing.' | ||||
| *					Error_Services('Add', ErrorMsg) | ||||
| *					return | ||||
| *				end | ||||
| 				************************************ | ||||
| 				* FlatFinder - Flat Length Section * | ||||
| 				************************************ | ||||
| 				If (WaferFlatLengthMin NE '') AND (WaferFlatLengthMax NE '') then | ||||
| 					If (FlatFinderWaferLength NE '') then | ||||
| 						If (FlatFinderWaferLength GE WaferFlatLengthMin) AND (FlatFinderWaferLength LE WaferFlatLengthMax) then | ||||
| 						end else | ||||
| 							ErrorMsg = 'Unable to sign FQA because Flat Finder wafer lengths are out of bounds.' | ||||
| 							Error_Services('Add', ErrorMsg) | ||||
| 							return | ||||
| 						end | ||||
| 					end else | ||||
| 						ErrorMsg = 'Unable to sign FQA because the Flat Finder wafer length is missing.' | ||||
| 						Error_Services('Add', ErrorMsg) | ||||
| 						return | ||||
| 					end | ||||
| 				end | ||||
|         	 | ||||
|         	Case WaferSizeInch = '8' | ||||
|  | ||||
| 				// Get NotchFinder Read Value | ||||
| *				NotchFinderWafersQty     = {FLATFINDER_WAFER_CNT} | ||||
| *  | ||||
| *				*************************************** | ||||
| *				* NotchFinder - Wafers Quatity Section * | ||||
| *				*************************************** | ||||
| *				If (NotchFinderWafersQty NE '') then | ||||
| *					If (NotchFinderWafersQty NE WafersOut) then | ||||
| *						ErrorMsg = 'Unable to sign FQA because Notch Finder and Wafers Out quantities do not match.' | ||||
| *						Error_Services('Add', ErrorMsg) | ||||
| *						return | ||||
| *					end | ||||
| *				end else | ||||
| *					ErrorMsg = 'Unable to sign FQA because the Notch Finder quantity is missing.' | ||||
| *					Error_Services('Add', ErrorMsg) | ||||
| *					return | ||||
| *				end | ||||
|         	 | ||||
|         	Case 1 | ||||
|         End Case | ||||
|          | ||||
|         ************************* | ||||
|         * Verify Wafer Quantity * | ||||
|         ************************* | ||||
|         ! The barcode application will need to inform the user that an override is required. We will return an error for | ||||
|         ! now. Once the user is informed, a LEAD or SUPERVISOR can scan their badge to override and complete the scan. | ||||
|         CassSchedWafers = {CASS_SHIP_QTY} | ||||
|         WafersOut       = {WFRS_OUT} | ||||
|          | ||||
| @ -3585,23 +3349,18 @@ Service SignFQAStage(RDSNo, Username) | ||||
|                      | ||||
|         end | ||||
|          | ||||
|          | ||||
|         ********************************* | ||||
|         * Verify NCR total >= USL Fails * | ||||
|         ********************************* | ||||
|         ! The barcode application will need to inform the user that an override is required. We will return an error for | ||||
|         ! now. Once the user is informed, a LEAD or SUPERVISOR can scan their badge to override and complete the scan. | ||||
|         If Username EQ 'FRANCOIS_R' then | ||||
|             NCRStatus = QA_Services('GetNCRStatus', RDSNo) | ||||
|             If NCRStatus EQ False$ then             | ||||
|                 If NOT( MemberOf(Username, 'LEAD') OR MemberOf(Username, 'SUPERVISOR') ) then | ||||
|                     ErrorMsg = 'Unable to sign FQA because the total quantity of NCR wafers is less than the '| | ||||
|                              : 'number of wafers above the USL threshold. A lead or supervisor must override.' | ||||
|                     Error_Services('Add', ErrorMsg) | ||||
|                     return | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
| 		NCRStatus = QA_Services('GetNCRStatus', RDSNo) | ||||
| 		If NCRStatus EQ False$ then             | ||||
| 			If NOT( MemberOf(Username, 'LEAD') OR MemberOf(Username, 'SUPERVISOR') ) then | ||||
| 				ErrorMsg = 'Unable to sign FQA because the total quantity of NCR wafers is less than the '| | ||||
| 						 : 'number of wafers above the USL threshold. A lead or supervisor must override.' | ||||
| 				Error_Services('Add', ErrorMsg) | ||||
| 				return | ||||
| 			end | ||||
| 		end | ||||
|              | ||||
|         ************************* | ||||
|         * Verify if Shift exist * | ||||
| @ -3663,21 +3422,19 @@ Service SignFQAStage(RDSNo, Username) | ||||
|         Next Test | ||||
|          | ||||
|         ****************************************** | ||||
|         * Verify Unload Stage QA Metrology Tests * On hold until approved for release to production | ||||
|         * Verify Unload Stage QA Metrology Tests *  | ||||
|         ****************************************** | ||||
|         If Username EQ 'FRANCOIS_R' then | ||||
|             WONo        = {WO} | ||||
|             CassNo      = {CASS_NO} | ||||
|             WOMatQAKey  = WONo : '*' : CassNo | ||||
|             WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
|             OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
|             OutOfSpec   = Sum(OutOfSpec) | ||||
|             If OutOfSpec GT 0 then | ||||
|                 ErrorMsg = 'Process Error: One or more Unload QA Metrology results are out of specification.' | ||||
|                 Error_Services('Add', ErrorMsg) | ||||
|                 return | ||||
|             end | ||||
|         end | ||||
| 		WONo        = {WO} | ||||
| 		CassNo      = {CASS_NO} | ||||
| 		WOMatQAKey  = WONo : '*' : CassNo | ||||
| 		WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
| 		OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
| 		OutOfSpec   = Sum(OutOfSpec) | ||||
| 		If OutOfSpec GT 0 then | ||||
| 			ErrorMsg = 'Process Error: One or more Unload QA Metrology results are out of specification.' | ||||
| 			Error_Services('Add', ErrorMsg) | ||||
| 			return | ||||
| 		end | ||||
|  | ||||
|         ******************************************* | ||||
|         * Verify if all steps have been completed * | ||||
| @ -3750,8 +3507,6 @@ Service SignFQAStage(RDSNo, Username) | ||||
|             ;* 4/30/2013 JCH added parms for merging of two methods     | ||||
|             owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'QA':@RM:Username:@RM:SigDt:' ':SigTm:@RM:ToolID:@RM:WHCd:@RM:LocCd:@RM:Tag  | ||||
|              | ||||
| *            obj_WO_Mat('SetSignature',owmParms)        ; * * * * * S I G N A T U R E  * * * * * * | ||||
|              | ||||
|             IF Get_Status(errCode) THEN | ||||
|                 ErrorMsg = 'Error calling Obj_WO_Mat("SetSignature") within ':Service:'. Error code: ':errCode | ||||
|                 Error_Services('Add', ErrorMsg) | ||||
| @ -3888,3 +3643,4 @@ ClearCursors: | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -254,26 +254,23 @@ Event SIGN_BUTTON.CLICK() | ||||
| 	end    | ||||
| 	 | ||||
| 	RDSNo          = Get_Property(@Window : '.RDS_NO','DEFPROP') | ||||
| 	WCCheckEnabled = Xlate('APP_INFO', 'WAFER_COUNTER_CHECK', '', 'X') | ||||
| 	If WCCheckEnabled then | ||||
| 		**************************************** | ||||
| 		* Verify the Wafer Counter information * | ||||
| 		**************************************** | ||||
| 		WafersOut       = Get_Property(@WINDOW:'.WAFERS_OUT','TEXT')         | ||||
| 		WaferCounterQty = Get_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP') | ||||
| 		 | ||||
| 		************************************* | ||||
| 		* Wafer Counter -  Quantity Section * | ||||
| 		************************************* | ||||
| 		If (WaferCounterQty NE '') then | ||||
| 			If (WaferCounterQty NE WafersOut) then | ||||
| 				ErrMsg('Unable to sign FQA because Wafer Counter and Wafers Out quantities do not match.') | ||||
| 				RETURN 0 | ||||
| 			end | ||||
| 		end else | ||||
| 			ErrMsg('Unable to sign FQA because the Wafer Counter quantity is missing.') | ||||
| 	**************************************** | ||||
| 	* Verify the Wafer Counter information * | ||||
| 	**************************************** | ||||
| 	WafersOut       = Get_Property(@WINDOW:'.WAFERS_OUT','TEXT')         | ||||
| 	WaferCounterQty = Get_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP') | ||||
| 	 | ||||
| 	************************************* | ||||
| 	* Wafer Counter -  Quantity Section * | ||||
| 	************************************* | ||||
| 	If (WaferCounterQty NE '') then | ||||
| 		If (WaferCounterQty NE WafersOut) then | ||||
| 			ErrMsg('Unable to sign FQA because Wafer Counter and Wafers Out quantities do not match.') | ||||
| 			RETURN 0 | ||||
| 		end | ||||
| 	end else | ||||
| 		ErrMsg('Unable to sign FQA because the Wafer Counter quantity is missing.') | ||||
| 		RETURN 0 | ||||
| 	end | ||||
| 	 | ||||
| 	*********************************** | ||||
| @ -446,26 +443,21 @@ Event SIGN_BUTTON.CLICK() | ||||
|     ****************************************** | ||||
|     * Verify Unload Stage QA Metrology Tests * | ||||
|     ****************************************** | ||||
|  | ||||
|     DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
|  | ||||
|     If (DevelopmentFlag EQ True$) then | ||||
|         WONo        = Get_Property(@WINDOW:'.WO','DEFPROP') | ||||
|         CassNo      = Get_Property(@WINDOW:'.CASS_NO','DEFPROP') | ||||
|         WOMatQAKey  = WONo : '*' : CassNo | ||||
|         WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
|         OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
|         OutOfSpec   = Sum(OutOfSpec) | ||||
|         If OutOfSpec GT 0 then | ||||
|             FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
|             ErrorMsg = 'Process Error':@SVM | ||||
|             For each FailReason in FailReasons using @VM | ||||
|                 ErrorMsg := FailReason:CRLF$ | ||||
|             Next FailReason | ||||
|             ErrMsg(ErrorMsg) | ||||
|             Return | ||||
|         end | ||||
|     end | ||||
| 	WONo        = Get_Property(@WINDOW:'.WO','DEFPROP') | ||||
| 	CassNo      = Get_Property(@WINDOW:'.CASS_NO','DEFPROP') | ||||
| 	WOMatQAKey  = WONo : '*' : CassNo | ||||
| 	WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
| 	OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
| 	OutOfSpec   = Sum(OutOfSpec) | ||||
| 	If OutOfSpec GT 0 then | ||||
| 		FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
| 		ErrorMsg = 'Process Error':@SVM | ||||
| 		For each FailReason in FailReasons using @VM | ||||
| 			ErrorMsg := FailReason:CRLF$ | ||||
| 		Next FailReason | ||||
| 		ErrMsg(ErrorMsg) | ||||
| 		Return | ||||
| 	end | ||||
|  | ||||
|     ******************************************* | ||||
|     * Verify if all steps have been completed * | ||||
|  | ||||
| @ -115,7 +115,7 @@ AutoDisplayErrors = FALSE$     ; // Set this to True$ when debugging so all erro | ||||
| Declare subroutine  SRP_Stopwatch, Error_Services, obj_Tables, Metrology_Services, obj_RDS_Test, SRP_JSON, Logging_Services | ||||
| Declare subroutine  RTI_Set_Debugger, Database_Services, Btree.Extract, Extract_SI_Keys, Obj_WO_Mat, Obj_WO_Mat_Log | ||||
| Declare subroutine  Dialog_Box, Obj_Notes, RList, Set_Status, Errmsg, Obj_React_Status	, Reactor_Services | ||||
| Declare subroutine  Rds_Services, Obj_Post_Log | ||||
| Declare subroutine  Rds_Services, Obj_Post_Log, Mona_Services | ||||
| Declare function    SRP_Sort_Array, Metrology_Services, obj_RDS_Test, obj_Test_Point_Map, Database_Services | ||||
| Declare function    Work_Order_Services, SRP_JSON, Logging_Services, Environment_Services, SRP_Trim, Error_Services | ||||
| Declare function    Memberof, Obj_WO_Mat, Obj_WO_Mat_Log, SRP_Array, DateTime, Dialog_Box, obj_Prod_Spec | ||||
| @ -131,6 +131,13 @@ Headers       = 'Logging DTM':@FM:'Ctrl':@FM:'Load/Calculate Time' | ||||
| objCtrlLog    = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, COMMA$, Headers, '', False$, False$) | ||||
| LoggingDTM    = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_RDSSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_RDSSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
| 	Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') | ||||
| end | ||||
| @ -226,6 +233,8 @@ End Service | ||||
| // to an RDS record. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service AddComment(RDSNo, Comment, UsernameOpt) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'AddComment' | ||||
| 	 | ||||
| 	RDSRow   = Database_Services('ReadDataRow', 'RDS', RDSNo) | ||||
| 	Username = @USER4 | ||||
| @ -247,7 +256,9 @@ Service AddComment(RDSNo, Comment, UsernameOpt) | ||||
| 	oblParms := Values:@RM | ||||
| 	oblParms := "TOP" :@VM: "TOP" :@VM: "TOP" | ||||
| 	obj_Post_Log('Create',oblParms) | ||||
|  | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| End Service | ||||
|  | ||||
|  | ||||
| @ -750,6 +761,9 @@ Service IsValidSubLot(RDSNo, RDSType, SupplierLot) | ||||
| end service | ||||
|  | ||||
| Service GetRDSRunHistoryByReactorAndWO(ReactorNo, WO) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetRDSRunHistoryByReactorAndWO' | ||||
| 	 | ||||
| 	table = "RDS" | ||||
| 	ErrorMessage = '' | ||||
| 	RDSRecords = '' | ||||
| @ -783,10 +797,16 @@ Service GetRDSRunHistoryByReactorAndWO(ReactorNo, WO) | ||||
|     	end | ||||
|     Next RDS | ||||
|     Response = FinalRDSSortedByAssignmentDTM<1> | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| Service IsTWLoggingReqd(RDSNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'IsTWLoggingReqd' | ||||
| 	 | ||||
|     IsTWReqd            = False$ | ||||
|     ExistingTWRuns      = Test_Run_Services('GetTestRunKeysByRDS', RDSNo) | ||||
|     If ExistingTWRuns EQ '' then | ||||
| @ -809,7 +829,7 @@ Service IsTWLoggingReqd(RDSNo) | ||||
|                 Layer = Field(PRSPropKey, '*', 2) | ||||
|                 MeasureFreq = PRSPropRec<PRS_PROP_FREQ$> | ||||
|                 Start = PRSPropRec<PRS_PROP_MET_START$> | ||||
|                 If WaferType NE 'Product' AND WaferType NE 'Prod' then | ||||
|                 If WaferType NE 'Product' AND WaferType NE 'Prod' AND WaferType NE '' then | ||||
|                     BEGIN CASE | ||||
|                         CASE MeasureFreq = 'F' AND ThisReactorRunOrder = 1	; IsTWReqd = 1 | ||||
|                         CASE ThisReactorRunOrder = Start					; IsTWReqd = 1 | ||||
| @ -847,6 +867,9 @@ Service IsTWLoggingReqd(RDSNo) | ||||
|         IsTWReqd = False$ | ||||
|     end | ||||
|     Response = IsTWReqd | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service TestWaferRanAfterLoad(RDSNo) | ||||
| @ -1099,6 +1122,8 @@ end service | ||||
|  | ||||
|  | ||||
| Service CopyRDSLayerParameters(RDSNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CopyRDSLayerParameters' | ||||
| 	 | ||||
| 	If (RDSNo NE '') then | ||||
| 		RunOrderNo  = Xlate('RDS', RDSNo, 'RUN_ORDER_NUM', 'X') | ||||
| @ -1151,6 +1176,8 @@ Service CopyRDSLayerParameters(RDSNo) | ||||
| 		Error_Services('Add', 'RDSNo not supplied in ':Service:' service.') | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -1828,3 +1855,5 @@ return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -78,7 +78,7 @@ Declare function    SRP_Math, SRP_Hash, SRP_JSON, Epi_Part_Services, Schedule_Se | ||||
| Declare function    Logging_Services, GetCommandLine, NextKey, Reactor_Log_Services, SRP_DateTime, ole_getwebpage | ||||
| Declare function    Datetime, Reactor_Modes_Services, Work_Order_Services, React_Mode_NG_Services, Lsl_Users_Services | ||||
| Declare function    SRP_Time, Rds_Services, SRP_Fastarray, Httpclient_Services, SRP_List, Utility, Memberof, Error_Services | ||||
| Declare function	Nica_Orders_Services, Max, RTI_CreateGUID | ||||
| Declare function	Nica_Orders_Services, Max, RTI_CreateGUID, GetTickCount | ||||
|  | ||||
| // Report paths for various performance report services. | ||||
| TemplatesFolder     = Environment_Services('GetApplicationRootPath') : '\Reports\Scheduler\Templates\' | ||||
| @ -91,6 +91,13 @@ LogDate     = Oconv(Date(), 'D4/') | ||||
| LogTime     = Oconv(Time(), 'MTS') | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_REACTORSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_REACTORSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
|  | ||||
| end | ||||
| @ -116,6 +123,8 @@ Options REACTORMETRIC = 'TUBE_BELL_JAR_THK', 'TUBE_BELL_JAR_WFR_CNT', 'SUSC_THK' | ||||
| //  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service IncrementWfrMetrics(RDSNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'IncrementWfrMetrics' | ||||
| 	 | ||||
| 	// Get Reactor and run count details | ||||
| 	RDSRec          = Xlate('RDS', RDSNo, '', 'X', '') | ||||
| @ -217,6 +226,8 @@ Service IncrementWfrMetrics(RDSNo) | ||||
| 	 | ||||
| 	Database_Services('WriteDataRow', 'REACTOR', ReactorNo, NewReactorRec, 1, 0, 0) | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -2031,16 +2042,35 @@ Service CreateReactModeChange(UserID, ReactNo, Mode, ModeSubCat, ModeText, Force | ||||
| 			If ErrorMsg EQ '' then | ||||
| 			    AbortAlarmFeatureFlag = Xlate('FEATURE_FLAGS', 'NICA_ABORT_ALARM',  FEATURE_FLAGS.ENABLED$, 'X') | ||||
| 			    If AbortAlarmFeatureFlag EQ True$ then | ||||
|                     If IntrMaintFeatureFlag EQ True$ then | ||||
|                         AbortAlarmFromIntrusiveMaintRequired = Nica_Orders_Services('AbortAlarmFromIntrusiveMaintRequired', ReactNo) | ||||
|                         ActiveIntrusiveMaintChecklists       = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'INTRUSIVE_MAINT') | ||||
|                         IntrusiveMaintChecklistActive        = (ActiveIntrusiveMaintChecklists NE '')                         | ||||
|                     end else | ||||
|                         AbortAlarmFromIntrusiveMaintRequired = False$ | ||||
|                         IntrusiveMaintChecklistActive        = False$ | ||||
|                     end | ||||
| 			        ModeSubCatFlowId       = Xlate('REACT_PROB_CAT', ModeSubCatId, REACT_PROB_CAT_ABORT_ALARM_FLOW_ID$, 'X') | ||||
| 			        ModeSubCatRespLvl      = Xlate('REACT_PROB_CAT', ModeSubCatId, REACT_PROB_CAT_ABORT_ALARM_RESPONSE_LEVEL$, 'X') | ||||
| 			        AbortAlarmComp         = Xlate('REACTOR', ReactNo, REACTOR_ABORT_ALARM_COMPLETE$, 'X') | ||||
| 			        ActiveAbortAlarmOrders = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'ABORT_ALARM') | ||||
| 			        AbortAlarmOrderActive  = (ActiveAbortAlarmOrders NE '') | ||||
|                     ReactorType            = Xlate('REACTOR', ReactNo, REACTOR_REACT_TYPE$, 'X') | ||||
|                     ChecklistIds           = Nica_Orders_Services('GetFlowChecklistIds', ModeSubCatFlowId, 'ABORT_ALARM', ReactorType)			         | ||||
| 			        CreateAbortAlarmOrder  = False$ | ||||
| 			        Intrusive              = False$ | ||||
| 			         | ||||
| 			        Begin Case | ||||
| 			            Case ( AbortAlarmOrderActive and (SelE10State _EQC 'Productive') ) | ||||
| 			                ErrorMsg = "An ABORT/ALARM Checklist is active for this reactor and must be completed or overridden in order to change to a productive state." | ||||
| 			                 | ||||
| 			            Case ( AbortAlarmOrderActive and IndexC(ModeSubCat, 'ABORT/ALARM', 1) and (ModeSubCatFlowId NE '') ) | ||||
| 			            Case ( AbortAlarmFromIntrusiveMaintRequired and IndexC(ModeSubCat, 'ABORT/ALARM', 1) and (ModeSubCatFlowId NE '') and (ChecklistIds NE '') ) | ||||
| 			                // INTRUSIVE_MAINT FIRST_PRODUCT_RUN_THICK or FIRST_PRODUCT_RUN_HGCV checklist started and | ||||
| 			                // ABORT/ALARM mode entered, so create an ABORT/ALARM order to contain product in reactor. | ||||
| 			                CreateAbortAlarmOrder = True$ | ||||
| 			                Intrusive             = True$ | ||||
|                              | ||||
| 			            Case ( Not(IntrusiveMaintChecklistActive) and AbortAlarmOrderActive and IndexC(ModeSubCat, 'ABORT/ALARM', 1) and (ModeSubCatFlowId NE '') ) | ||||
|                             // If there is an active ABORT/ALARM NICA order, then we need to check if the new sub mode is different than the sub mode entered when the ABORT/ALARM | ||||
|                             // NICA order was created and is of a higher response level or the new mode is WAITING_FOR_OPERATOR and the sub mode has changed. This means the maintenance | ||||
|                             // team deemed the true ABORT/ALARM root cause was different than the cause the operators selected. | ||||
| @ -2052,26 +2082,26 @@ Service CreateReactModeChange(UserID, ReactNo, Mode, ModeSubCat, ModeText, Force | ||||
|                             Next ActiveAbortAlarmRespLvl | ||||
|                             If ( (Mode _EQC 'WAITING_FOR_OPERATOR') and (ModeSubCatFlowId NE ActiveAbortAlarmFlowIds) ) | | ||||
|                             or ( (ModeSubCatFlowId NE ActiveAbortAlarmFlowIds) and (ModeSubCatRespLvl GT MaxActiveRespLvl) ) then | ||||
| 								ReactorType  = Xlate('REACTOR', ReactNo, REACTOR_REACT_TYPE$, 'X') | ||||
| 								ChecklistIds = Nica_Orders_Services('GetFlowChecklistIds', ModeSubCatFlowId, 'ABORT_ALARM', ReactorType) | ||||
| 								If ChecklistIds NE '' then 			                 | ||||
| 									Nica_Orders_Services('CreateNewOrder', 'REACTOR', ReactNo, 'ABORT_ALARM', ModeSubCatFlowId, ModeSubCatRespLvl, ChecklistIds) | ||||
| 									RlComment = 'ABORT/ALARM initiated for flow ':ModeSubCatFlowId:'.' | ||||
| 									CreateAbortAlarmOrder = True$ | ||||
| 								end                            	 | ||||
|                             end | ||||
|  | ||||
| 			            Case ( Not(AbortAlarmComp) and Not(AbortAlarmOrderActive) and IndexC(ModeSubCat, 'ABORT/ALARM', 1) and (ModeSubCatFlowId NE '') ) | ||||
| 							ReactorType  = Xlate('REACTOR', ReactNo, REACTOR_REACT_TYPE$, 'X') | ||||
| 							ChecklistIds = Nica_Orders_Services('GetFlowChecklistIds', ModeSubCatFlowId, 'ABORT_ALARM', ReactorType) | ||||
| 							If ChecklistIds NE '' then 			                 | ||||
| 								Nica_Orders_Services('CreateNewOrder', 'REACTOR', ReactNo, 'ABORT_ALARM', ModeSubCatFlowId, ModeSubCatRespLvl, ChecklistIds) | ||||
| 								RlComment = 'ABORT/ALARM initiated for flow ':ModeSubCatFlowId:'.' | ||||
| 			                end | ||||
| 			            Case ( Not(IntrusiveMaintChecklistActive) and Not(AbortAlarmComp) and Not(AbortAlarmOrderActive) and IndexC(ModeSubCat, 'ABORT/ALARM', 1) and (ModeSubCatFlowId NE '') and (ChecklistIds NE '') ) | ||||
| 			                // Typical ABORT/ALARM case | ||||
| 			                CreateAbortAlarmOrder = True$ | ||||
| 			                 | ||||
| 			            Case Otherwise$ | ||||
| 			                // Don't create an ABORT/ALARM NICA order | ||||
| 			                Null | ||||
| 			                 | ||||
| 			        End Case | ||||
| 			         | ||||
| 			        If CreateAbortAlarmOrder then | ||||
|                         Nica_Orders_Services('CreateNewOrder', 'REACTOR', ReactNo, 'ABORT_ALARM', ModeSubCatFlowId, ModeSubCatRespLvl, ChecklistIds, Intrusive) | ||||
|                         RlComment = 'ABORT/ALARM initiated for flow ':ModeSubCatFlowId:'.'					             | ||||
| 			        end | ||||
| 			         | ||||
| 			    end | ||||
| 			end | ||||
| 			 | ||||
| @ -3584,6 +3614,8 @@ end service | ||||
|  | ||||
|  | ||||
| Service GetReactorAvailChamberCount(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetReactorAvailChamberCount' | ||||
| 	 | ||||
| 	ErrMsg                = 'Error in ReactorServices -> GetReactorAvailChamberCount: ' | ||||
| 	AvailableChamberCount = 0 | ||||
| @ -3603,6 +3635,8 @@ Service GetReactorAvailChamberCount(ReactNo) | ||||
| 	end | ||||
| 	Response = AvailableChamberCount | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -4321,3 +4355,4 @@ ClearCursors: | ||||
| 	 | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -45,9 +45,9 @@ $insert RDS_EQUATES | ||||
| $insert SCAN_SETUP | ||||
|  | ||||
| Declare Function   Scan_Services, Database_Services, QA_Services, Datetime, RDS_Services, SRP_Array, SRP_Stopwatch | ||||
| Declare function   Logging_Services, Environment_Services | ||||
| Declare function   Logging_Services, Environment_Services, GetTickCount | ||||
| Declare Subroutine Scan_Services, Database_Services, QA_Services, obj_WO_Mat_Log, SRP_Stopwatch | ||||
| Declare Subroutine Logging_Services | ||||
| Declare Subroutine Logging_Services, Mona_Services | ||||
|  | ||||
| LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\ScanAPI\APIResponseTime'; //Define the directory where the log will be saved to. This happens the first time of the day that the log is written to. | ||||
| LogDate      = Oconv(Date(), 'D4/') | ||||
| @ -57,6 +57,13 @@ LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
| LogFileName      = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ScanAPIResponseTimes.csv'; //Define the file name that will get created. | ||||
| Headers          = 'Logging DTM' : @FM : 'API' : @FM : 'ResponseTime' : @FM : 'ScanID' : @FM : 'ScanData' : @VM : 'StatusCode' ; //Define the column names in the log file, delimited by a Field Mark. | ||||
| objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$); //Actually creates the log. | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SCANAPI' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SCANAPI' | ||||
| end | ||||
|   | ||||
| GoToAPI else | ||||
|     // The specific resource endpoint doesn't have a API handler yet. | ||||
| @ -72,16 +79,25 @@ Return Response OR '' | ||||
|  | ||||
|  | ||||
| API scan.POST | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'SCAN_POST' | ||||
| 	 | ||||
|     SRP_Stopwatch('Reset') | ||||
|     SRP_Stopwatch('Start', 'SCAN_POST_RESPONSE_TIME') | ||||
|     ScanID  = Scan_Services('CreateScansRow') | ||||
|     If Error_Services('NoError') then | ||||
|         StatusCode  = 201 | ||||
|         GoSub CreateHALItem | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|     end else | ||||
|         Message = Error_Services('GetMessage') | ||||
|         HTTP_Services('SetResponseStatus', 500, Message) | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'CRITICAL') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_POST_RESPONSE_TIME') | ||||
|     TotalPostResponseTime = SRP_Stopwatch('GetData', 'SCAN_POST_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -100,6 +116,9 @@ end api | ||||
|  | ||||
|  | ||||
| API scan.ID.POST | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'SCAN_ID_POST' | ||||
| 	 | ||||
|     SRP_Stopwatch('Reset') | ||||
|     SRP_Stopwatch('Start', 'SCAN_ID_POST_RESPONSE_TIME') | ||||
|     ScanID      = EndpointSegment | ||||
| @ -112,13 +131,20 @@ API scan.ID.POST | ||||
|         If Error_Services('NoError') then | ||||
|             StatusCode = 200 | ||||
|             GoSub CreateHALItem | ||||
|             Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|         end else | ||||
|             Message    = Error_Services('GetMessage') | ||||
|             HTTP_Services('SetResponseStatus', 400, Message)                                 | ||||
|             HTTP_Services('SetResponseStatus', 400, Message) | ||||
|             Mona_Services('SendStatus', MonaResource, MetricName, 'CRITICAL') | ||||
|         end | ||||
|     end else | ||||
|         HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.') | ||||
|     end    | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_ID_POST_RESPONSE_TIME') | ||||
|     TotalPostResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_POST_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -143,11 +169,19 @@ end api | ||||
|  | ||||
| API scan.ID.HEAD | ||||
| API scan.ID.GET | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'SCAN_ID_GET' | ||||
| 	 | ||||
|     SRP_Stopwatch('Reset') | ||||
|     SRP_Stopwatch('Start', 'SCAN_ID_GET_RESPONSE_TIME') | ||||
|     ScanID     = EndpointSegment | ||||
|     StatusCode = 200 | ||||
|     GoSub CreateHALItem | ||||
|     Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)     | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_ID_POST_RESPONSE_TIME') | ||||
|     TotalGetResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_GET_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -166,6 +200,9 @@ end api | ||||
|  | ||||
|  | ||||
| API scan.ID.DELETE | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'SCAN_ID_DELETE' | ||||
| 	 | ||||
|     SRP_Stopwatch('Reset') | ||||
|     SRP_Stopwatch('Start', 'SCAN_ID_DELETE_RESPONSE_TIME') | ||||
|     ScanID  = EndpointSegment | ||||
| @ -176,17 +213,25 @@ API scan.ID.DELETE | ||||
|             Database_Services('DeleteDataRow', 'SCANS', ScanID, True$, False$) | ||||
|             If Error_Services('NoError') then | ||||
|                 HTTP_Services('SetResponseStatus', 200) | ||||
|                 Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|             end else | ||||
|                 Message = Error_Services('GetMessage') | ||||
|                 HTTP_Services('SetResponseStatus', 500, Message) | ||||
|                 Mona_Services('SendStatus', MonaResource, MetricName, 'CRITICAL') | ||||
|             end | ||||
|         end else | ||||
|             HTTP_Services('SetResponseStatus', 403, 'This scan is already accepted and cannot be deleted.') | ||||
|             Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|         end | ||||
|     end else | ||||
|         Message = Error_Services('GetMessage') | ||||
|         HTTP_Services('SetResponseStatus', 404, Message) | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_ID_DELETE_RESPONSE_TIME') | ||||
|     TotalDeleteResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_DELETE_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -205,7 +250,9 @@ end api | ||||
|  | ||||
|  | ||||
| API scan.ID.PATCH | ||||
|  | ||||
| 	StartTick = GetTickCount() | ||||
| 	MetricName = 'SCAN_ID_PATCH' | ||||
| 	 | ||||
|     // This is where scans are ultimately accepted for final processing. We will need to determine which type | ||||
|     // of scan this is (i.e. Location, Pre-Epi + Load, or Unload). This will be determined by the data coming in and the | ||||
|     // current status of the lot. For example a Location scan would only have an RDS, location code, and username.  | ||||
| @ -232,14 +279,17 @@ API scan.ID.PATCH | ||||
|                     If Error_Services('NoError') then | ||||
|                         StatusCode  = 200 | ||||
|                         GoSub CreateHALItem | ||||
|                         Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|                     end else | ||||
|                         Message = Error_Services('GetMessage') | ||||
|                         HTTP_Services('SetResponseStatus', 500, Message) | ||||
|                         Mona_Services('SendStatus', MonaResource, MetricName, 'CRITICAL') | ||||
|                     end | ||||
|                      | ||||
|                     SRP_JSON(hBody, 'Release')                | ||||
|                 end else | ||||
|                     HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.') | ||||
|                     Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|                 end | ||||
|             end else | ||||
|                 ScanNotAcceptableReason = SRP_JSON(objResource, 'GetValue', 'scan.notAcceptableReason') | ||||
| @ -249,11 +299,17 @@ API scan.ID.PATCH | ||||
|         end else | ||||
|             Message = 'Unable to parse the JSON scan resource.' | ||||
|             HTTP_Services('SetResponseStatus', 400, Message) | ||||
|             Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|         end | ||||
|     end else | ||||
|         Message = Error_Services('GetMessage') | ||||
|         HTTP_Services('SetResponseStatus', 404, Message) | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_ID_PATCH_RESPONSE_TIME') | ||||
|     TotalPatchResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_PATCH_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -272,6 +328,8 @@ end api | ||||
|  | ||||
|  | ||||
| API scan.ID.PUT | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'SCAN_ID_PUT' | ||||
|      | ||||
|     SRP_Stopwatch('Reset') | ||||
|     SRP_Stopwatch('Start', 'SCAN_ID_PUT_RESPONSE_TIME') | ||||
| @ -314,17 +372,25 @@ API scan.ID.PUT | ||||
|             Database_Services('WriteDataRow', 'SCANS', ScanID, ScanRow, True$, False$, True$) | ||||
|             If Error_Services('NoError') then | ||||
|                 GoSub CreateHALItem | ||||
|                 Mona_Services('SendStatus', MonaResource, MetricName, 'OK') | ||||
|             end else | ||||
|                 Message = Error_Services('GetMessage') | ||||
|                 HTTP_Services('SetResponseStatus', 500, Message) | ||||
|                 Mona_Services('SendStatus', MonaResource, MetricName, 'CRITICAL') | ||||
|             end | ||||
|             SRP_JSON(hBody, 'Release') | ||||
|         end else | ||||
|             HTTP_Services('SetResponseStatus', 400, 'Unable to parse the scanData JSON.') | ||||
|             Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|         end | ||||
|     end else | ||||
|         HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.') | ||||
|         Mona_Services('SendStatus', MonaResource, MetricName, 'WARNING') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
|      | ||||
|     SRP_Stopwatch('Stop', 'SCAN_ID_PUT_RESPONSE_TIME') | ||||
|     TotalPutResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_PUT_RESPONSE_TIME') | ||||
|     LogData    = '' | ||||
| @ -339,7 +405,6 @@ API scan.ID.PUT | ||||
|     end | ||||
|     LogData<6> = ResponseStatusCode | ||||
|     Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|      | ||||
| end api | ||||
|  | ||||
|  | ||||
| @ -378,3 +443,4 @@ CreateHALItem: | ||||
|     end | ||||
|  | ||||
| return | ||||
|  | ||||
|  | ||||
| @ -47,9 +47,10 @@ Declare Function    Scan_Services, Memory_Services, Database_Services, SRP_JSON, | ||||
| Declare Function    QA_Services, Error_Services, Security_Services, SRP_Array, obj_WO_Mat, Memberof, Override_Log_Services | ||||
| Declare Function    Keyboard_Sim_Services, Environment_Services, Logging_Services, Reactor_Services, Supplement_Services | ||||
| Declare function    Test_Run_Services, Lot_Services, WO_MAT_Services, Reactor_Log_Services, Schedule_Services | ||||
| Declare function	GetTickCount | ||||
| Declare Subroutine  Scan_Services, Memory_Services, Database_Services, SRP_JSON, QA_Services, Error_Services | ||||
| Declare Subroutine  obj_WO_Mat_Log, Tool_Parms_Services, RDS_Services, Logging_Services, Supplement_Services | ||||
| Declare Subroutine  Test_Run_Services, WO_MAT_Services, Reactor_Log_Services, Schedule_Services | ||||
| Declare Subroutine  Test_Run_Services, WO_MAT_Services, Reactor_Log_Services, Schedule_Services, Mona_Services | ||||
|  | ||||
| Equ CRLF$		to \0D0A\ | ||||
|  | ||||
| @ -61,6 +62,13 @@ Headers     = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'User' : @FM : 'CurrSta | ||||
| objLog      = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SCANSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SCANSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
| 	Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.') | ||||
| end | ||||
| @ -200,6 +208,8 @@ end service | ||||
| // Returns the database row from the SCANS table for the indicated Scan ID. The default format is MultiValue. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service GetScansRow(ScanID, ReturnJSON) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetScansRow' | ||||
| 	 | ||||
| 	ScansRow    = '' | ||||
| 	 | ||||
| @ -214,6 +224,8 @@ Service GetScansRow(ScanID, ReturnJSON) | ||||
| 	 | ||||
| 	Response    = ScansRow | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -223,6 +235,8 @@ end service | ||||
| // Returns the database row from the SCANS table for the indicated Scan ID. The default format is MultiValue. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service SetScansRow(ScanID, ScansRow) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'SetScansRow' | ||||
| 	 | ||||
| 	If (ScanID NE '') AND (ScansRow NE '') then | ||||
| 		Database_Services('WriteDataRow', 'SCANS', ScanID, ScansRow) | ||||
| @ -230,6 +244,8 @@ Service SetScansRow(ScanID, ScansRow) | ||||
| 		Error_Services('Add', 'ScanID or ScansRow argument was missing in the ' : Service : ' service.') | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -242,6 +258,8 @@ end service | ||||
| // evaluated on a case by case basis. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ProcessScanData(ScanID, ScanJSON) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'ProcessScanData' | ||||
| 	 | ||||
| 	If ( (ScanID NE '') AND (ScanJSON NE '') ) then | ||||
| 		hScanJSON     = '' | ||||
| @ -1285,8 +1303,10 @@ Service ProcessScanData(ScanID, ScanJSON) | ||||
| 		SRP_JSON(hScanJSON, 'Release') | ||||
| 	end else | ||||
| 		Error_Services('Add', 'ScanID or ScanJSON argument was missing in the ' : Service : ' service.') | ||||
| 	end     | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -1295,6 +1315,9 @@ end service | ||||
| // | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service AcceptScan(ScanID, ScanJSON) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'AcceptScan' | ||||
| 	 | ||||
| 	If ( (ScanID NE '') and (ScanJSON NE '') ) then | ||||
| 		hBody         = '' | ||||
| 		ParseResponse = SRP_JSON(hBody, 'PARSE', ScanJSON) | ||||
| @ -1649,6 +1672,8 @@ Service AcceptScan(ScanID, ScanJSON) | ||||
| 		Error_Services('Add', 'ScanID or ScanJSON argument was missing in the ' : Service : ' service.') | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)	 | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| @ -1659,6 +1684,8 @@ end service | ||||
| // HAL+JSON properties will be added to the JSON object. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ConvertMVScanToJSON(ScanID, mvScan, itemURL) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'ConvertMVScanToJSON' | ||||
| 	 | ||||
| 	jsonScan    = '' | ||||
| 	 | ||||
| @ -2160,6 +2187,8 @@ Service ConvertMVScanToJSON(ScanID, mvScan, itemURL) | ||||
| 	 | ||||
| 	Response    = jsonScan | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| @ -2396,9 +2425,3 @@ ClearCursors: | ||||
| 	 | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -55,15 +55,23 @@ EQU NOTIFICATION_PERIOD$ TO 12 | ||||
|  | ||||
| Declare subroutine  Error_Services, Schedule_Services, Memory_Services, RList, Database_Services, Logging_Services | ||||
| Declare subroutine  Btree.Extract, Set_Status, Reduce, FSMsg, Messaging_Services, obj_Notes, Make.List | ||||
| Declare subroutine	Mona_Services | ||||
| Declare function    SRP_Array, Schedule_Services, Memory_Services, Database_Services, SRP_Sort_Array, Datetime | ||||
| Declare function    Epi_Part_Services, SRP_Math, SRP_Hash, obj_Prod_Spec, Logging_Services, Environment_Services | ||||
| Declare function    Work_Order_Services, RTI_CreateGUID, Reactor_Services, Schedule_Services, NextKey, SRP_Datetime | ||||
| Declare function	SRP_Time, Lsl_Users_Services | ||||
| Declare function	SRP_Time, Lsl_Users_Services, GetTickCount | ||||
|  | ||||
| Date            = Oconv(Date(), 'D4/') | ||||
| LogFileName     = Date[7, 4] : '-' : Date[1, 2] : '-' : Date[4, 2] : ' Scheduler Log.csv' | ||||
| Headers         = 'Logging DTM' : @FM : 'Service Step' : @FM : 'Service Notes' | ||||
| ColumnWidths    = 20 : @FM : 30 : @FM : 150  | ||||
| ColumnWidths    = 20 : @FM : 30 : @FM : 150 | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SCHEDULESERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SCHEDULESERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
| 	Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') | ||||
| @ -795,6 +803,8 @@ end service | ||||
|  | ||||
|  | ||||
| Service GetCurrentEvent(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetCurrentEvent' | ||||
| 	 | ||||
| 	SchedDetKey = '' | ||||
| 	If ReactNo NE '' then | ||||
| @ -814,9 +824,14 @@ Service GetCurrentEvent(ReactNo) | ||||
| 		GoSub ClearCursors | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service CurrentEventIsBlock(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CurrentEventIsBlock' | ||||
| 	 | ||||
| 	If ReactNo NE '' then | ||||
| 		CurrentSchedDetKey = Schedule_Services('GetCurrentEvent', ReactNo) | ||||
| 				 | ||||
| @ -838,9 +853,15 @@ Service CurrentEventIsBlock(ReactNo) | ||||
| 		ErrorMsg = 'Error in service ':Service:' module. Invalid reactor number.' | ||||
| 		Error_Services('Add', ErrorMsg) | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetNextEvent(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'GetNextEvent' | ||||
| 	 | ||||
| 	SchedDetKey = '' | ||||
| 	If ReactNo NE '' then | ||||
| 		CurrDTM  = Datetime() | ||||
| @ -870,6 +891,9 @@ Service GetNextEvent(ReactNo) | ||||
| 		end | ||||
| 		GoSub ClearCursors | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetEngagedEvent(ReactNo) | ||||
| @ -919,6 +943,9 @@ Service GetLastEngagedEvent(ReactNo) | ||||
| end service | ||||
|  | ||||
| Service NextEventIsSamePsn(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'NextEventIsSamePsn' | ||||
| 	 | ||||
| 	Response = False$ | ||||
| 	If ReactNo NE '' then | ||||
| 		CurrentSchedDetKey = Schedule_Services('GetCurrentEvent', ReactNo) | ||||
| @ -962,9 +989,15 @@ Service NextEventIsSamePsn(ReactNo) | ||||
| 		ErrorMsg = 'Error in service ':Service:' module. Invalid reactor number.' | ||||
| 		Error_Services('Add', ErrorMsg) | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service NextEventIsBlock(ReactNo) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'NextEventIsBlock' | ||||
| 	 | ||||
| 	If ReactNo NE '' then | ||||
| 		NextSchedDetKey = Schedule_Services('GetNextEvent', ReactNo) | ||||
| 				 | ||||
| @ -986,6 +1019,9 @@ Service NextEventIsBlock(ReactNo) | ||||
| 		ErrorMsg = 'Error in service ':Service:' module. Invalid reactor number.' | ||||
| 		Error_Services('Add', ErrorMsg) | ||||
| 	end | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| @ -3561,3 +3597,4 @@ CreateScheduleChangeNotification: | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -27,12 +27,13 @@ Function Service_Services(@Service, @Params) | ||||
|  | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| $insert APP_INSERTS | ||||
| $insert SERVICE_SETUP | ||||
| $insert SERVICES_EQUATES | ||||
| $insert RLIST_EQUATES | ||||
| $insert SQL_REQUESTS_EQUATES | ||||
| $Insert APP_INSERTS | ||||
| $Insert SERVICE_SETUP | ||||
| $Insert SERVICES_EQUATES | ||||
| $Insert RLIST_EQUATES | ||||
| $Insert SQL_REQUESTS_EQUATES | ||||
| $Insert PROC_QUEUE_EQUATES | ||||
| $Insert PROC_QUEUE_FAILED_EQUATES | ||||
|  | ||||
| Equ Comma$ to ',' | ||||
|  | ||||
| @ -175,10 +176,11 @@ Service ProcessProcedureQueue() | ||||
|             ReadNext RequestKeyID else EOF = True$ | ||||
|         Until EOF or Done | ||||
|             Lock hProcQueue, RequestKeyID then | ||||
|             	Server     = Environment_Services('GetServer') | ||||
|             	Done       = True$ | ||||
|             	DeleteRequest = True$ | ||||
|             	Server        = Environment_Services('GetServer') | ||||
|             	Done          = True$ | ||||
|                 Database_Services('GetKeyIDLock', 'PROC_QUEUE', RequestKeyId)           | ||||
|                 RequestRow = Database_Services('ReadDataRow', 'PROC_QUEUE', RequestKeyID) | ||||
|                 RequestRow    = Database_Services('ReadDataRow', 'PROC_QUEUE', RequestKeyID) | ||||
|                 If RequestRow NE '' then                    | ||||
|                     Procedure = RequestRow<PROC_QUEUE.PROC_NAME$> | ||||
|                     Procedure = UCase(Procedure) | ||||
| @ -216,30 +218,48 @@ Service ProcessProcedureQueue() | ||||
|                     LogData<5> = Params | ||||
|                     ErrCode    = '' | ||||
|                     If ( Get_Status(ErrCode) or Error_Services('HasError') ) then | ||||
| 						ErrorMessage = Error_Services('GetMessage') | ||||
| 						Recipients   = '' | ||||
| 						SentFrom     = 'SYSTEM' | ||||
| 						Subject      = 'Background Procedure Queue Error' | ||||
| 						Message      = OConv(Datetime(), 'DT2/^H') | ||||
| 						Message<2>   = 'Error on server ':Server | ||||
| 						Message<3>   = 'Stored Procedure: ':Procedure | ||||
| 						StatCodes    = 'Parameters: ':Params | ||||
| 						Message<4>   = 'Error_Services error message: ':ErrorMessage | ||||
| 						Message<5>   = 'Get_Status error code: ':ErrCode | ||||
| 						Swap @FM with \0D0A\ in Message | ||||
| 						AttachWindow = '' | ||||
| 						AttachKey    = '' | ||||
| 						SendToGroup  = 'OI_SYSADMIN' | ||||
| 						Parms        = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup | ||||
| 						obj_Notes('Create',Parms) | ||||
| 						LogData<6>   = 'Failed' | ||||
| 						LogData<7>   = 'Error_Services error message: ':ErrorMessage:' Get_Status error code: ':ErrCode | ||||
|                     	NumAttempts  = RequestRow<PROC_QUEUE.NUM_ATTEMPTS$> + 1 | ||||
|                     	ErrorMessage = Error_Services('GetMessage') | ||||
|                     	If NumAttempts LT 3 then | ||||
|                     		DeleteRequest                            = False$ | ||||
|                     		RequestRow<PROC_QUEUE.NUM_ATTEMPTS$>     = NumAttempts | ||||
| 							RequestRow<PROC_QUEUE.LAST_ATTEMPT_DTM$> = Datetime() | ||||
| 							RequestRow<PROC_QUEUE.ERROR$>            = 'Error_Services error message: ':ErrorMessage:' Get_Status error code: ':ErrCode | ||||
| 							Database_Services('WriteDataRow', 'PROC_QUEUE', RequestKeyId, RequestRow, True$, False$, False$) | ||||
| 						end else | ||||
| 							// Notify OI_SYSADMIN group | ||||
| 							Recipients                           = '' | ||||
| 							SentFrom                             = 'SYSTEM' | ||||
| 							Subject                              = 'Background Procedure Queue Error' | ||||
| 							Message                              = OConv(Datetime(), 'DT2/^H') | ||||
| 							Message<2>                           = 'Error on server ':Server | ||||
| 							Message<3>                           = 'Stored Procedure: ':Procedure | ||||
| 							StatCodes                            = 'Parameters: ':Params | ||||
| 							Message<4>                           = 'Error_Services error message: ':ErrorMessage | ||||
| 							Message<5>                           = 'Get_Status error code: ':ErrCode | ||||
| 							Swap @FM with \0D0A\ in Message | ||||
| 							AttachWindow                         = '' | ||||
| 							AttachKey                            = '' | ||||
| 							SendToGroup                          = 'OI_SYSADMIN' | ||||
| 							Parms                                = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup | ||||
| 							obj_Notes('Create',Parms) | ||||
| 							 | ||||
| 							// Move request to PROC_QUEUE_FAILED | ||||
|                     		RequestRow<PROC_QUEUE.NUM_ATTEMPTS$>     = NumAttempts | ||||
| 							RequestRow<PROC_QUEUE.LAST_ATTEMPT_DTM$> = Datetime() | ||||
| 							RequestRow<PROC_QUEUE.ERROR$>            = 'Error_Services error message: ':ErrorMessage:'Get_Status error code: ':ErrCode							 | ||||
| 							Database_Services('WriteDataRow', 'PROC_QUEUE_FAILED', RequestKeyId, RequestRow, True$, False$, False$) | ||||
| 						end | ||||
| 						LogData<6> = 'Failed' | ||||
| 						LogData<7> = 'Error_Services error message: ':ErrorMessage:' Get_Status error code: ':ErrCode | ||||
| 					end else | ||||
| 						LogData<6> = 'Success' | ||||
| 					end | ||||
| 					Logging_Services('AppendLog', objLog, LogData, @RM, @FM) | ||||
|                 end | ||||
|                 Database_Services('DeleteDataRow', 'PROC_QUEUE', RequestKeyId, True$, False$) ; // This call should release the lock | ||||
|                 If DeleteRequest then  | ||||
| 					Database_Services('DeleteDataRow', 'PROC_QUEUE', RequestKeyId, True$, False$) | ||||
| 				end | ||||
|                 Unlock hProcQueue, RequestKeyID else Null | ||||
|             end | ||||
|         Repeat | ||||
| @ -253,36 +273,32 @@ Service PostProcedure(ProcedureName, Params, Critical=BOOLEAN) | ||||
|     If Critical EQ '' then Critical = True$ | ||||
|     PostToQueue = True$ | ||||
|     If (ProcedureName NE '') then | ||||
|     	If (Params NE '') then | ||||
|     		If Not(Critical) then | ||||
|     			// Check if there is already a matching request in the queue before posting another one. | ||||
| 				Query = 'PROC_NAME':@VM:ProcedureName:@FM | ||||
| 				Query := 'PARAMS':@VM:Params:@FM | ||||
| 				Open 'DICT.PROC_QUEUE' to hDict then | ||||
| 					Keys   = '' | ||||
| 					Option = 'E' | ||||
| 					Flag   = '' | ||||
| 					Btree.Extract(Query, 'PROC_QUEUE', hDict, Keys, Option, Flag) | ||||
| 					If Flag EQ 0 then | ||||
| 						If Keys NE '' then PostToQueue = False$ | ||||
| 					end else | ||||
| 						Error_Services('Add', 'Error in ':Service:' service. Error calling Btree.Extract.') | ||||
| 					end | ||||
| 		If Not(Critical) then | ||||
| 			// Check if there is already a matching request in the queue before posting another one. | ||||
| 			Query = 'PROC_NAME':@VM:ProcedureName:@FM | ||||
| 			Query := 'PARAMS':@VM:Params:@FM | ||||
| 			Open 'DICT.PROC_QUEUE' to hDict then | ||||
| 				Keys   = '' | ||||
| 				Option = 'E' | ||||
| 				Flag   = '' | ||||
| 				Btree.Extract(Query, 'PROC_QUEUE', hDict, Keys, Option, Flag) | ||||
| 				If Flag EQ 0 then | ||||
| 					If Keys NE '' then PostToQueue = False$ | ||||
| 				end else | ||||
| 					Error_Services('Add', 'Error in ':Service:' service. Error opening DICT.PROC_QUEUE.') | ||||
| 					Error_Services('Add', 'Error in ':Service:' service. Error calling Btree.Extract.') | ||||
| 				end | ||||
| 			end else | ||||
| 				Error_Services('Add', 'Error in ':Service:' service. Error opening DICT.PROC_QUEUE.') | ||||
| 			end | ||||
| 			If PostToQueue then | ||||
| 				RequestKeyID                      = RTI_CreateGUID() | ||||
| 				RequestRow                        = '' | ||||
| 				RequestRow<PROC_QUEUE.PROC_NAME$> = ProcedureName | ||||
| 				RequestRow<PROC_QUEUE.PARAMS$>    = Params | ||||
| 				RequestRow<PROC_QUEUE.ENTRY_DTM$> = Datetime() | ||||
| 				Database_Services('WriteDataRow', 'PROC_QUEUE', RequestKeyID, RequestRow, True$, False$, False$) | ||||
| 			end | ||||
|     	end else | ||||
|     		Error_Services('Add', 'Error in ':Service:' service. Null Params passed in.') | ||||
|     	end | ||||
| 		end | ||||
| 		If PostToQueue then | ||||
| 			RequestKeyID                      = RTI_CreateGUID() | ||||
| 			RequestRow                        = '' | ||||
| 			RequestRow<PROC_QUEUE.PROC_NAME$> = ProcedureName | ||||
| 			RequestRow<PROC_QUEUE.PARAMS$>    = Params | ||||
| 			RequestRow<PROC_QUEUE.ENTRY_DTM$> = Datetime() | ||||
| 			Database_Services('WriteDataRow', 'PROC_QUEUE', RequestKeyID, RequestRow, True$, False$, False$) | ||||
| 		end | ||||
|     end else | ||||
|         Error_Services('Add', 'Error in ':Service:' service. Null ProcedureName passed in.') | ||||
|     end | ||||
| @ -290,6 +306,97 @@ Service PostProcedure(ProcedureName, Params, Critical=BOOLEAN) | ||||
| return | ||||
|  | ||||
|  | ||||
| Service CleanFailedProcQueue(DaysToRetain) | ||||
| 	 | ||||
| 	hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') | ||||
| 	Lock hSysLists, ServiceKeyID then	 | ||||
| 		LogPath                = Environment_Services('GetApplicationRootPath') : '\LogFiles\ProcQueue' | ||||
| 		LogDate                = Oconv(Date(), 'D4/') | ||||
| 		LogTime                = Oconv(Time(), 'MTS') | ||||
| 		LogFileName            = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' CleanFailedProcQueue Log.csv' | ||||
| 		Headers                = 'Logging DTM' : @FM : 'Machine' : @FM : 'RequestKeyId' : @FM : 'Procedure' : @FM : 'Params' | ||||
| 		Headers               := @FM : 'Result' : @FM : 'Error Message' | ||||
| 		objFailedProcQueueLog  = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) | ||||
| 		LoggingDTM             = LogDate : ' ' : LogTime   ; // Logging DTM	 | ||||
| 		Server                 = Environment_Services('GetServer') | ||||
| 		 | ||||
| 		LogData    = '' | ||||
| 		LogData<1> = LoggingDtm | ||||
| 		LogData<2> = Server | ||||
| 		LogData<6> = 'Begin CleanFailedProcQueue' | ||||
| 		Logging_Services('AppendLog', objFailedProcQueueLog, LogData, @RM, @FM) | ||||
| 		 | ||||
| 		ErrorMsg    = '' | ||||
| 		If (DaysToRetain NE '') then | ||||
| 			If Num(DaysToRetain) then | ||||
| 				Open 'PROC_QUEUE_FAILED' to hTable then | ||||
| 					Cutoff = Datetime() - DaysToRetain | ||||
| 					Select hTable | ||||
| 					EOF    = False$ | ||||
| 					Loop | ||||
| 						Readnext Key else EOF = True$ | ||||
| 					Until EOF | ||||
| 						Read Rec from hTable, Key then | ||||
| 							EntryDtm = Rec<PROC_QUEUE_FAILED.ENTRY_DTM$> | ||||
| 							If (EntryDtm LT Cutoff) then | ||||
| 								Delete hTable, Key then | ||||
| 									LogData<1>       = LoggingDtm | ||||
| 									LogData<2>       = Server | ||||
| 									LogData<3>       = Key | ||||
| 									LogData<4>       = Rec<PROC_QUEUE_FAILED.PROC_NAME$> | ||||
| 									ProcFailedParams = Rec<PROC_QUEUE_FAILED.PARAMS$> | ||||
| 									Convert @VM to '|' in ProcFailedParams | ||||
| 									LogData<5>       = ProcFailedParams | ||||
| 									LogData<6>       = 'Removed PROC_QUEUE_FAILED record.' | ||||
| 									LogData<7>       = Rec<PROC_QUEUE_FAILED.ERROR$> | ||||
| 									Logging_Services('AppendLog', objFailedProcQueueLog, LogData, @RM, @FM)								 | ||||
| 								end else | ||||
| 									ErrorMsg = 'Error in ':Service:' service. Error deleting PROC_QUEUE_FAILED record ':Key:'.' | ||||
| 								end | ||||
| 							end else | ||||
| 								LogData<1>       = LoggingDtm | ||||
| 								LogData<2>       = Server | ||||
| 								LogData<3>       = Key | ||||
| 								LogData<4>       = Rec<PROC_QUEUE_FAILED.PROC_NAME$> | ||||
| 								ProcFailedParams = Rec<PROC_QUEUE_FAILED.PARAMS$> | ||||
| 								Convert @VM to '|' in ProcFailedParams | ||||
| 								LogData<5>       = ProcFailedParams | ||||
| 								LogData<6>       = 'Retaining PROC_QUEUE_FAILED record.' | ||||
| 								LogData<7>       = Rec<PROC_QUEUE_FAILED.ERROR$> | ||||
| 								Logging_Services('AppendLog', objFailedProcQueueLog, LogData, @RM, @FM)								 | ||||
| 							end | ||||
| 						end else | ||||
| 							ErrorMsg = 'Error in ':Service:' service. Error reading PROC_QUEUE_FAILED record ':Key:'.' | ||||
| 						end | ||||
| 					Repeat | ||||
| 				end else | ||||
| 					ErrorMsg = 'Error in ':Service:' service. Error opening PROC_QUEUE_FAILED table.' | ||||
| 				end | ||||
| 			end else | ||||
| 				ErrorMsg = 'Error in ':Service:' service. DaysToRetain must be a number.' | ||||
| 			end | ||||
| 		end else | ||||
| 			ErrorMsg = 'Error in ':Service:' service. Null DaysToRetain value passed in.' | ||||
| 		end | ||||
| 		 | ||||
| 		If ErrorMsg NE '' then | ||||
| 			LogData<1> = LoggingDtm | ||||
| 			LogData<2> = Server | ||||
| 			LogData<6> = ErrorMsg | ||||
| 			Logging_Services('AppendLog', objFailedProcQueueLog, LogData, @RM, @FM)			 | ||||
| 		end | ||||
| 		 | ||||
| 		LogData<1> = LoggingDtm | ||||
| 		LogData<2> = Server | ||||
| 		LogData<6> = 'End CleanFailedProcQueue' | ||||
| 		Logging_Services('AppendLog', objFailedProcQueueLog, LogData, @RM, @FM) | ||||
| 		 | ||||
| 		Unlock hSysLists, ServiceKeyID else Null | ||||
| 	end | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| /// Internal GoSubs | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| @ -63,12 +63,20 @@ Equ COL$TOOL_ID         to 10 | ||||
|  | ||||
| Declare function obj_Prod_Spec, RDS_Services, Error_Services, Signature_Services, Memory_Services, obj_RDS_Test | ||||
| Declare function Database_Services, obj_WO_Mat, Dialog_Box, MemberOf, Msg, QA_Services, Datetime, Supplement_Services | ||||
| Declare function Environment_Services, GetTickCount | ||||
| Declare subroutine Error_Services, Popup, Memory_Services, SRP_Stopwatch, Set_Status, Database_Services, obj_WO_Mat | ||||
| Declare subroutine Obj_Notes, Signature_Services, Obj_WO_Mat_Log, ErrMsg | ||||
| Declare subroutine Obj_Notes, Signature_Services, Obj_WO_Mat_Log, ErrMsg, Mona_Services | ||||
|  | ||||
| PSNKey     = ServiceKeyID | ||||
| ReactorKey = ServiceKeyID | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SIGNATURESERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SIGNATURESERVICES' | ||||
| end | ||||
|  | ||||
| GoToService | ||||
|  | ||||
| Return Response or "" | ||||
| @ -114,7 +122,7 @@ end service | ||||
|  | ||||
|  | ||||
| Service CheckQALabelStatus(WOMatKey) | ||||
|      | ||||
|  | ||||
|     rec = Xlate('WO_MAT', WoMatKey,'', '') | ||||
|     locRec = rec<WO_MAT_INV_LOCATION$> | ||||
|     actionRec = rec<WO_MAT_INV_ACTION$> | ||||
| @ -135,6 +143,8 @@ end service | ||||
|  | ||||
|  | ||||
| Service GetSigProfile(WOMatKey, UseCaching, RDSNo) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'GetSigProfile' | ||||
|      | ||||
|     If UseCaching EQ '' then UseCaching = True$ | ||||
|      | ||||
| @ -175,6 +185,8 @@ Service GetSigProfile(WOMatKey, UseCaching, RDSNo) | ||||
|     SigDTMs = OCONV(SigDTMs,'DT4/^S') | ||||
|     Response = SigProfile:@FM:Signatures:@FM:SigDTMs  | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -211,6 +223,9 @@ end service | ||||
|  | ||||
|  | ||||
| Service CheckSigOrder(WOMatKey, CurrStage, UseCaching, RDSNo) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'CheckSigOrder' | ||||
|      | ||||
|     If UseCaching EQ '' then UseCachine = True$ | ||||
|     Response    = False$ | ||||
|     If RDSNo NE '' then | ||||
| @ -264,6 +279,8 @@ Service CheckSigOrder(WOMatKey, CurrStage, UseCaching, RDSNo) | ||||
|         Response = True$ | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| End Service | ||||
|  | ||||
|  | ||||
| @ -282,7 +299,7 @@ end service | ||||
|  | ||||
|  | ||||
| Service GetSigInfo(WOMatKey, Stage, UseCaching, RDSNo) | ||||
|      | ||||
|  | ||||
|     If UseCaching EQ '' then UseCaching = True$ | ||||
|     Signature   = '' | ||||
|     SigDTM      = '' | ||||
| @ -2010,20 +2027,17 @@ Service QASigReady(RDSNo) | ||||
|     * Verify Unload Stage QA Metrology Tests * | ||||
|     ****************************************** | ||||
|     If ErrorMessage EQ '' then | ||||
|         DevelopmentFlag  = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') | ||||
|         If (DevelopmentFlag EQ True$) then | ||||
|             WOMatQAKey = WOMatKey | ||||
|             WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
|             OutOfSpec  = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
|             OutOfSpec  = Sum(OutOfSpec) | ||||
|             If OutOfSpec GT 0 then | ||||
|                 FailReasons  = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
|                 ErrorMessage = 'Error in ':Service:' service. ' | ||||
|                 For each FailReason in FailReasons using @VM | ||||
|                     ErrorMessage := FailReason:' ' | ||||
|                 Next FailReason | ||||
|             end | ||||
|         end | ||||
| 		WOMatQAKey = WOMatKey | ||||
| 		WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) | ||||
| 		OutOfSpec  = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$> | ||||
| 		OutOfSpec  = Sum(OutOfSpec) | ||||
| 		If OutOfSpec GT 0 then | ||||
| 			FailReasons  = WOMatQARec<WO_MAT_QA_FAIL_REASON$> | ||||
| 			ErrorMessage = 'Error in ':Service:' service. ' | ||||
| 			For each FailReason in FailReasons using @VM | ||||
| 				ErrorMessage := FailReason:' ' | ||||
| 			Next FailReason | ||||
| 		end | ||||
|     end | ||||
|      | ||||
|     ************************************************************************ | ||||
| @ -2844,4 +2858,3 @@ GetMostRecentSig: | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -56,9 +56,16 @@ $Insert NOTIFICATION_EQUATES | ||||
| Equ COMMA$ to ',' | ||||
|  | ||||
| Declare function   Database_Services, Supplement_Services, Rti_Createguid, SRP_Array, Datetime, Signature_Services | ||||
| Declare function   Environment_Services, Logging_Services, Select_Into | ||||
| Declare function   Environment_Services, Logging_Services, Select_Into, GetTickCount | ||||
| Declare subroutine Database_Services, Rds_Services, Supplement_Services, Logging_Services, Set_Status, SRP_Stopwatch | ||||
| Declare subroutine Btree.Extract, obj_Notes | ||||
| Declare subroutine Btree.Extract, obj_Notes, Mona_Services | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SUPPLEMENTSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SUPPLEMENTSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
|     Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.') | ||||
| @ -408,6 +415,8 @@ end service | ||||
| // | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service AcknowledgeSupplement(SupplID, EntryUser) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'AcknowledgeSupplement' | ||||
|      | ||||
|     If ( (SupplID NE '') and (EntryUser NE '') ) then | ||||
|         OldRec = Xlate('SUPPLEMENTS', SupplID, '', 'X', '') | ||||
| @ -433,6 +442,8 @@ Service AcknowledgeSupplement(SupplID, EntryUser) | ||||
|         Error_Services('Add', 'SupplID or EntryUser was missing in the ' : Service : ' service.') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -447,6 +458,8 @@ end service | ||||
| // | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service UnacknowledgedSupplementCheck(LotType=LOTTYPES, LotID, Stage=STAGES) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'UnacknowledgedSupplementCheck' | ||||
|      | ||||
|     UnackList = '' | ||||
|     Response  = False$ | ||||
| @ -482,6 +495,8 @@ Service UnacknowledgedSupplementCheck(LotType=LOTTYPES, LotID, Stage=STAGES) | ||||
|      | ||||
|     If UnackList NE '' then Response = UnackList | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -496,6 +511,8 @@ end service | ||||
| // | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service LogSupplementChange(SupplementRec, EditEvent, EntryUser) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'LogSupplementChange' | ||||
|  | ||||
|     If ( (SupplementRec NE '') and (EditEvent NE '') and (EntryUser NE '') ) then | ||||
|         SupplementText = SupplementRec<SUPPLEMENTS_SUPPL_TEXT$> | ||||
| @ -513,6 +530,8 @@ Service LogSupplementChange(SupplementRec, EditEvent, EntryUser) | ||||
|         Error_Services('Add', 'LotType, LotID, or Stage was missing in the ' :  Service : ' service.') | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -613,3 +632,4 @@ Service SendNotifications(RDSList, EditEvent, Instructions, EntryUser) | ||||
| 	 | ||||
| end service | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -10,9 +10,10 @@ $Insert TEST_RUN_OBJ_EQUATES | ||||
| $Insert LOT_EQUATES | ||||
| $Insert LOT_OPERATION_EQUATES | ||||
|  | ||||
| Declare function Nextkey, Error_Services, Environment_Services, OConv, Logging_Services, SRP_Hashtable, Lot_Services | ||||
| Declare function Nextkey, Error_Services, Environment_Services, OConv, Logging_Services, SRP_Hashtable, Lot_Services, GetTickCount | ||||
| Declare function SRP_Datetime, Database_Services, Test_Run_Services, File_Services, Status, delete, Insert, Datetime, SRP_Json, MemberOf | ||||
| Declare subroutine Database_Services, Btree.Extract, Error_Services, Logging_Services, Rlist, Test_Run_Services, Lot_Services, SRP_Json | ||||
| Declare subroutine Mona_Services | ||||
|  | ||||
| LogPath     = Environment_Services('GetApplicationRootPath') : '\LogFiles\TEST_RUN_SERVICES\TestWaferProduct' | ||||
| LogDate     = Oconv(Date(), 'D4/') | ||||
| @ -30,6 +31,13 @@ objLogTR    = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, He | ||||
|  | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_TESTRUNSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_TESTRUNSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService | ||||
|  | ||||
| Return Response or "" | ||||
| @ -280,6 +288,9 @@ Service UpdateTWProdSortOrder(TWProdKey, NewOrder) | ||||
| end service | ||||
|  | ||||
| Service GetAllTestRunTypes() | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'GetAllTestRunTypes' | ||||
|      | ||||
|     keylist = '' | ||||
|     rtList  = '' | ||||
|     RList('SELECT TEST_RUN_TYPE BY RUN_TYPE', 5, '', '', '') | ||||
| @ -297,6 +308,9 @@ Service GetAllTestRunTypes() | ||||
|         end | ||||
|     Next ProdKey | ||||
|     Response = rtList | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetTestWaferLots(ShowOnlyOpenLots) | ||||
| @ -318,6 +332,9 @@ Service GetTestWaferLots(ShowOnlyOpenLots) | ||||
| end service | ||||
|  | ||||
| Service CreateTestRunRecord(RunTypeID, EqpType, EqpID, PSNo, RDSNo, UserID, TWLotIds, TWLotQtys) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'CreateTestRunRecord' | ||||
|      | ||||
|     TWRunKey     = '' | ||||
|     Response     = '' | ||||
|     ErrorMessage = '' | ||||
| @ -490,9 +507,15 @@ Service CreateTestRunRecord(RunTypeID, EqpType, EqpID, PSNo, RDSNo, UserID, TWLo | ||||
|         Error_Services('Add', ErrorMessage) | ||||
|         Response      = '' | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service CreateTestRunWaferRecord(TestRunID, TWPartID, TWUsageTypeID, SourceLotId, Username) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'CreateTestRunWaferRecord' | ||||
|      | ||||
|     ErrorMessage = '' | ||||
|     If TestRunID NE '' AND TWPartID NE '' then | ||||
|         If RowExists('TEST_RUN', TestRunID) then | ||||
| @ -537,6 +560,9 @@ Service CreateTestRunWaferRecord(TestRunID, TWPartID, TWUsageTypeID, SourceLotId | ||||
|         Logging_Services('AppendLog', objLogTR, LogData, @FM, @VM) | ||||
|         Error_Services('Add', 'Error creating new test run record: ' : ErrorMessage) | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service UseTWFromLot(LotId, UsageQty, Username) | ||||
| @ -706,6 +732,9 @@ Service GetTestRunKeysByPSN(PSNo) | ||||
| end service | ||||
|  | ||||
| Service GetTestRunKeysByRDS(RDSNo) | ||||
|     StartTick = GetTickCount() | ||||
|     MetricName = 'GetTestRunKeysByRDS' | ||||
|      | ||||
|     table = "TEST_RUN" | ||||
|     Open "DICT ":table To @DICT Else | ||||
|         Error_Services('Add', 'Error opening TEST_RUN dictionary') | ||||
| @ -718,6 +747,9 @@ Service GetTestRunKeysByRDS(RDSNo) | ||||
|         Btree.Extract(srch_strng, table, @DICT, keylist, option, flag) | ||||
|         Response = keylist | ||||
|     end | ||||
|      | ||||
|     EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service GetTestRunWaferByID(TRWaferID) | ||||
| @ -799,3 +831,4 @@ end service | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										309
									
								
								LSL2/STPROC/WAFERCOUNTER_API.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								LSL2/STPROC/WAFERCOUNTER_API.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,309 @@ | ||||
| Function Wafercounter_API(@API) | ||||
| /*********************************************************************************************************************** | ||||
|  | ||||
|     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        :   Wafercounter_API | ||||
|  | ||||
|     Description :   API logic for the Wafercounter resource. | ||||
|  | ||||
|     Notes       :   All web APIs should include the API_SETUP insert. This will provide several useful variables: | ||||
|  | ||||
|                         HTTPMethod              - The HTTP Method (Verb) submitted by the client (e.g., GET, POST, etc.) | ||||
|                         APIURL                  - The URL for the API entry point (e.g., api.mysite.com/v1). | ||||
|                         FullEndpointURL         - The URL submitted by the client, including query params. | ||||
|                         FullEndpointURLNoQuery  - The URL submitted by the client, excluding query params. | ||||
|                         EndpointSegment         - The URL endpoint segment. | ||||
|                         ParentURL               - The URL path preceeding the current endpoint. | ||||
|                         CurrentAPI              - The name of this stored procedure. | ||||
|  | ||||
|     Parameters  : | ||||
|         API             [in] -- Web API to process. Format is [APIPattern].[HTTPMethod]: | ||||
|                                     - APIPattern must follow this structure Wafercounter[.ID.[<Property>]] | ||||
|                                     - HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc. | ||||
|                                 Examples: | ||||
|                                     - Wafercounter.POST | ||||
|                                     - Wafercounter.ID.PUT | ||||
|                                     - Wafercounter.ID.firstName.GET | ||||
|         Response       [out] -- Response to be sent back to the Controller (HTTP_MCP) or requesting procedure. Web API | ||||
|                                 services do not rely upon anything being returned in the response. This is what the | ||||
|                                 various services like SetResponseBody and SetResponseStatus services are for. A response | ||||
|                                 value is only helpful if the developers want to use it for debug purposes. | ||||
|  | ||||
|     History     :   (Date, Initials, Notes) | ||||
|         06/04/25    xxx     Original programmer. | ||||
|  | ||||
| ***********************************************************************************************************************/ | ||||
|  | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| Declare function OI_Wizard_Services, Wafer_Counter_Services, Database_Services, Datetime, Wo_Mat_Services | ||||
| Declare function Logging_Services, Environment_Services | ||||
| Declare subroutine Logging_Services | ||||
|  | ||||
|  | ||||
| $insert APP_INSERTS | ||||
| $insert API_SETUP | ||||
| $insert HTTP_INSERTS | ||||
| $insert WAFER_COUNTER_EQUATES | ||||
|  | ||||
| LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\API\WaferCounter'; | ||||
| LogDate      = Oconv(Date(), 'D4/') | ||||
| LogTime      = Oconv(Time(), 'MTS') | ||||
| LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| LogFileName      = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WaferCounter.csv' | ||||
| Headers          = 'Logging DTM' : @FM : 'User' : @FM : 'OI Wizard ID' : @FM : 'Message' | ||||
| objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) | ||||
|  | ||||
| GoToAPI else | ||||
|     // The specific resource endpoint doesn't have a API handler yet. | ||||
|     LogData    = '' | ||||
|     LogData<1> = LoggingDTM;//Defined at entry of subroutine | ||||
|     LogData<2> = '' | ||||
|     LogData<3> = '' | ||||
|     LogData<4> = 'Web API not found.' | ||||
|     Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|     HTTP_Services('SetResponseStatus', 204, 'This is a valid endpoint but a web API handler has not yet been created.') | ||||
| end | ||||
|  | ||||
| Return Response OR '' | ||||
|  | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Endpoint Handlers | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| API wafercounter.startnewwafercount.POST | ||||
|      | ||||
|     ErrorMessage = '' | ||||
|     ResponseCode = '' | ||||
|     ResponseMessage = '' | ||||
|     Body = '' | ||||
|     OIWizardID = '' | ||||
|     UserId = '' | ||||
|     CassId = '' | ||||
|     Cookies    = HTTP_Services('GetHTTPCookie') | ||||
|     For each Cookie in Cookies using ';' | ||||
|         Key = Field(Cookie, '=', 1) | ||||
|         If Key EQ 'sessionID' then | ||||
|             OIWizardID = Field(Cookie, '=', 2) | ||||
|         end | ||||
|     Next Cookie | ||||
|      | ||||
|     ValidSession = OI_Wizard_Services('ValidateSession', OIWizardID) | ||||
|     CassBarcodeData = '' | ||||
|     UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X') | ||||
|     StatusCode  = '' | ||||
|     Body        = HTTP_Services('GetHTTPPostString', True$) | ||||
|     DecodedJSON = HTTP_Services('DecodePercentString', Body) | ||||
|      | ||||
|     //Log Entry into API - | ||||
|     LogData    = '' | ||||
|     LogData<1> = LoggingDTM | ||||
|     LogData<2> = UserId | ||||
|     LogData<3> = OIWizardId | ||||
|     LogData<4> = 'New wafer counter transaction started.' | ||||
|     Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|      | ||||
|     If SRP_JSON(objBody, 'Parse', Body) EQ '' then | ||||
|         CassBarcodeData      = SRP_JSON(objBody, 'GetValue', 'CassBarcodeData') | ||||
|         If CassBarcodeData NE '' then | ||||
|             CassData = Wafer_Counter_Services('ProcessCass2DBarcode', CassBarcodeData) | ||||
|             CassId = CassData<1,1> | ||||
|             ExpectedWfrQty = CassData<1,2> | ||||
|             CassType = CassData<1,3> | ||||
|             WoMatKey = '' | ||||
|             Begin Case | ||||
|                 Case CassType EQ 'RDS' | ||||
|                     WONo = XLATE('RDS', CassId, 'WO', 'X') | ||||
|                     CassNo = XLATE('RDS', CassId, 'CASS_NO', 'X') | ||||
|                     WoMatKey = WONo : '*' : CassNo | ||||
|                 Case CassType EQ 'WM_OUT' OR CassType EQ 'WM_IN' | ||||
|                     swap '.' with '*' in CassId | ||||
|                     WONo = Field(CassId, '*', 1) | ||||
|                     CassNo = Field(CassId, '*', 3) | ||||
|                     WoMatKey = WONo : '*' : CassNo | ||||
|             End Case | ||||
|             ExpectedWfrMap = Wo_Mat_Services('GetWaferMap', WoMatKey) | ||||
|             ExpectedCassetteArray = '' | ||||
|             for i = 25 to 1 step -1 | ||||
|                     Slot = i | ||||
|                     WaferPresent = ExpectedWfrMap<1, i> | ||||
|                     ExpectedCassetteArray<-1, 1> = Slot : @VM : WaferPresent | ||||
|             Next i | ||||
|             If Error_Services('NoError') then | ||||
|                 SRP_Json(objBody, 'SetValue', 'CassId', CassId, 'String') | ||||
|                 SRP_Json(objBody, 'SetValue', 'CassType', CassType, 'String') | ||||
|                 SRP_Json(objBody, 'SetValue', 'ExpectedQty', ExpectedWfrQty, 'Number') | ||||
|                 SRP_Json(objBody, 'SetValue', 'ScanDtm', OConv(Datetime(), 'DT4/'), 'String') | ||||
|                 objExpCassArray = '' | ||||
|                 IF SRP_Json(objExpCassArray, 'New', 'Array') then | ||||
|                     for each SlotData in ExpectedCassetteArray using @FM setting sPos | ||||
|                         Slot = SlotData<1, 1> | ||||
|                         WaferPresent = SlotData<1, 2> | ||||
|                         objSlot = '' | ||||
|                         If SRP_Json(objSlot, 'New', 'Object') then | ||||
|                            SRP_Json(objSlot, 'SetValue', 'SlotNo', Slot, 'Number') | ||||
|                            SRP_Json(objSlot, 'SetValue', 'WaferPresent', WaferPresent, 'Boolean') | ||||
|                            SRP_Json(objExpCassArray, 'Add', objSlot) | ||||
|                            SRP_Json(objSlot, 'Release') | ||||
|                         end | ||||
|                     Next SlotData | ||||
|                     SRP_Json(objBody, 'Set', 'ExpectedWaferArray', objExpCassArray) | ||||
|                     SRP_Json(objExpCassArray, 'Release') | ||||
|                 end | ||||
|                 ResponseJson = SRP_Json(objBody, 'Stringify', 'Styled') | ||||
|                 HTTP_Services('SetResponseBody', ResponseJson) | ||||
|                 ResponseCode = 200  | ||||
|             end else | ||||
|                 ErrorMessage =  Error_Services('GetMessage') | ||||
|                 ResponseCode = 500 | ||||
|             end | ||||
|         end else | ||||
|            ErrorMessage = 'Cassette ID Barcode data not detected.' | ||||
|            ResponseCode = 500 | ||||
|         end | ||||
|         SRP_Json(objBody, 'Release') | ||||
|     end | ||||
|      | ||||
|     If ErrorMessage EQ '' then | ||||
|         //Log Success | ||||
|         LogData    = '' | ||||
|         LogData<1> = LoggingDTM | ||||
|         LogData<2> = UserId | ||||
|         LogData<3> = OIWizardId | ||||
|         LogData<4> = 'New wafer counter transaction started successfully. Barcode Data: ' : CassBarcodeData : '. Cass Id: ' : CassId | ||||
|         Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|     end else | ||||
|         //Log Failure | ||||
|         LogData    = '' | ||||
|         LogData<1> = LoggingDTM | ||||
|         LogData<2> = UserId | ||||
|         LogData<3> = OIWizardId | ||||
|         LogData<4> = 'New wafer counter transaction finished with errors. Response Code: ' : ResponseCode : '. Error Message: ' : ErrorMessage : '. Barcode Data: ' : CassBarcodeData : '. Cass Id: ' : CassId | ||||
|         Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|     end | ||||
|     HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) | ||||
|     HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage) | ||||
|  | ||||
| end api | ||||
|  | ||||
|  | ||||
| API wafercounter.completewafercount.POST | ||||
|  | ||||
|     ErrorMessage = '' | ||||
|     ResponseCode = '' | ||||
|     ResponseMessage = '' | ||||
|     WaferCounterId = '' | ||||
|     CassId = '' | ||||
|     Body = '' | ||||
|     OIWizardID = '' | ||||
|     UserId = '' | ||||
|     Cookies    = HTTP_Services('GetHTTPCookie') | ||||
|     For each Cookie in Cookies using ';' | ||||
|         Key = Field(Cookie, '=', 1) | ||||
|         If Key EQ 'sessionID' then | ||||
|             OIWizardID = Field(Cookie, '=', 2) | ||||
|         end | ||||
|     Next Cookie | ||||
|     ValidSession = OI_Wizard_Services('ValidateSession', OIWizardID) | ||||
|     CassBarcodeData = '' | ||||
|     UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X') | ||||
|     StatusCode  = '' | ||||
|     Body        = HTTP_Services('GetHTTPPostString', True$) | ||||
|     DecodedJSON = HTTP_Services('DecodePercentString', Body) | ||||
|      | ||||
|     //Log Entry into API - | ||||
|     LogData    = '' | ||||
|     LogData<1> = LoggingDTM | ||||
|     LogData<2> = UserId | ||||
|     LogData<3> = OIWizardId | ||||
|     LogData<4> = 'Complete wafer counter transaction started.' | ||||
|     Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|      | ||||
|     If SRP_JSON(objBody, 'Parse', Body) EQ '' then | ||||
|         CassId = SRP_JSON(objBody, 'GetValue', 'CassId') | ||||
|         CassType = SRP_Json(objBody, 'GetValue', 'CassType') | ||||
|         ToolBarcodeData      = SRP_JSON(objBody, 'GetValue', 'ToolBarcodeData') | ||||
|         ExpectedQty = SRP_JSON(objBody, 'GetValue', 'ExpectedQty') | ||||
|         If CassId NE '' then | ||||
|             WaferCounterId = Wafer_Counter_Services('ProcessTool2DBarcode', ToolBarcodeData, CassId, CassType, UserId) | ||||
|             If Error_Services('NoError') then | ||||
|                 WaferCounterRec = Database_Services('ReadDataRow', 'WAFER_COUNTER', WaferCounterId, True$, 0, False$) | ||||
|                 ScanDtm = OConv(WaferCounterRec<WAFER_COUNTER.SCAN_DTM$>, 'DT4/') | ||||
|                 ToolId = WaferCounterRec<WAFER_COUNTER.SCAN_TOOL$> | ||||
|                 WaferCount = WaferCounterRec<WAFER_COUNTER.SCAN_QTY$> | ||||
|                 MatchingWfrCount = ExpectedQty EQ WaferCount | ||||
|                 WaferCountData = WaferCounterRec<WAFER_COUNTER.SCAN_WAFER_MAP$> | ||||
|                 swap 1 with 1:@FM in WaferCountData | ||||
|                 swap 0 with 0:@FM in WaferCountData | ||||
|                 WaferCountData[-1, -1] = '' | ||||
|                 CassetteArray = '' | ||||
|                 for i = 25 to 1 step -1 | ||||
|                     Slot = i | ||||
|                     WaferPresent = WaferCountData<i> | ||||
|                     CassetteArray<-1, 1> = Slot : @VM : WaferPresent | ||||
|                 Next i | ||||
|                  | ||||
|                 WaferCountArray = '' | ||||
|                 SRP_Json(objBody, 'SetValue', 'WaferCounterId', WaferCounterId, 'String') | ||||
|                 SRP_Json(objBody, 'SetValue', 'ScanDtm', ScanDtm, 'String') | ||||
|                 SRP_Json(objBody, 'SetValue', 'WaferCount', WaferCount, 'Number') | ||||
|                 SRP_Json(objBody, 'SetValue', 'ToolId', ToolId, 'String') | ||||
|                 SRP_Json(objBody, 'SetValue', 'MatchingWaferCount', MatchingWfrCount, 'Boolean') | ||||
|                 SRP_Json(objBody, 'SetValue', 'WaferCounterId', WaferCounterId, 'String') | ||||
|                 objCassArray = '' | ||||
|                 IF SRP_Json(objCassArray, 'New', 'Array') then | ||||
|                     for each SlotData in CassetteArray using @FM setting sPos | ||||
|                         Slot = SlotData<1, 1> | ||||
|                         WaferPresent = SlotData<1, 2> | ||||
|                         objSlot = '' | ||||
|                         If SRP_Json(objSlot, 'New', 'Object') then | ||||
|                            SRP_Json(objSlot, 'SetValue', 'SlotNo', Slot, 'Number') | ||||
|                            SRP_Json(objSlot, 'SetValue', 'WaferPresent', WaferPresent, 'Boolean') | ||||
|                            SRP_Json(objCassArray, 'Add', objSlot) | ||||
|                            SRP_Json(objSlot, 'Release') | ||||
|                         end | ||||
|                     Next SlotData | ||||
|                     SRP_Json(objBody, 'Set', 'WaferArray', objCassArray) | ||||
|                     SRP_Json(objCassArray, 'Release') | ||||
|                 end | ||||
|                 ResponseJson = SRP_Json(objBody, 'Stringify', 'Styled') | ||||
|                 HTTP_Services('SetResponseBody', ResponseJson) | ||||
|                 ResponseCode = 200  | ||||
|             end else | ||||
|                 ErrorMessage =  Error_Services('GetMessage') | ||||
|                 ResponseCode = 500 | ||||
|             end | ||||
|         end else | ||||
|            ErrorMessage = 'Cassette ID Barcode data not detected.' | ||||
|            ResponseCode = 500 | ||||
|         end | ||||
|         SRP_Json(objBody, 'Release') | ||||
|     end | ||||
|      | ||||
|     If ErrorMessage EQ '' then | ||||
|         //Log Success | ||||
|         LogData    = '' | ||||
|         LogData<1> = LoggingDTM | ||||
|         LogData<2> = UserId | ||||
|         LogData<3> = OIWizardId | ||||
|         LogData<4> = 'Completed wafer counter transaction finished successfully. Barcode Data: ' : CassBarcodeData : '. WAFER_COUNTER Id: ' : WaferCounterId : '. Cass Id: ' : CassId | ||||
|         Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|     end else | ||||
|         //Log Failure | ||||
|         LogData    = '' | ||||
|         LogData<1> = LoggingDTM | ||||
|         LogData<2> = UserId | ||||
|         LogData<3> = OIWizardId | ||||
|         LogData<4> = 'New wafer counter transaction finished with errors. Response Code: ' : ResponseCode : '. Error Message: ' : ErrorMessage : '. Barcode Data: ' : CassBarcodeData : '. Wafer Counter Id: ' : WaferCounterId : '. Cass Id: ' : CassId | ||||
|         Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) | ||||
|     end | ||||
|      | ||||
|     HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) | ||||
|     HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage) | ||||
|  | ||||
| end api | ||||
| @ -32,6 +32,8 @@ $Insert WO_LOG_EQUATES | ||||
| $Insert WM_OUT_EQUATES | ||||
| $Insert RLIST_EQUATES | ||||
| $Insert WAFER_COUNTER_EQUATES | ||||
| $Insert TOOL_EQUATES | ||||
| $Insert TOOL_LOG_EQUATES | ||||
|  | ||||
| Equ Tab$       to \09\ | ||||
| Equ CRLF$      to \0D0A\ | ||||
| @ -43,8 +45,9 @@ Equ next_cur$  To 1 | ||||
| Equ add_exist$ to 2 | ||||
|  | ||||
| Declare subroutine  Error_Services, Database_Services, Logging_Services, Httpclient_Services, Reduce, SRP_JSON | ||||
| Declare function    Database_Services, Environment_Services, Logging_Services, Httpclient_Services | ||||
| Declare function    RTI_CreateGuid, SRP_JSON | ||||
| Declare subroutine Wafer_Counter_Services, Lot_Event_Services | ||||
| Declare function    Database_Services, Environment_Services, Logging_Services, Httpclient_Services, OConv | ||||
| Declare function    RTI_CreateGuid, SRP_JSON, WO_Mat_Services, WM_Out_Services, Wafer_Counter_Services, Datetime | ||||
|  | ||||
| LogPath     = Environment_Services('GetApplicationRootPath') : '\LogFiles\WaferCounter' | ||||
| LogDate     = Oconv(Date(), 'D4/') | ||||
| @ -263,6 +266,8 @@ Service AddScan(LotID, ScanQty, ScanDtm, ScanTool, ScanUser, ScanLocation, Wafer | ||||
|     Record<WAFER_COUNTER.SCAN_WAFER_MAP$> = WaferMap | ||||
|     Database_Services('WriteDataRow', 'WAFER_COUNTER', KeyID, Record) | ||||
|      | ||||
|     Response = KeyId | ||||
|      | ||||
| end service | ||||
|  | ||||
|  | ||||
| @ -393,6 +398,161 @@ Service GetWaferCounterToolID(WaferSize=WAFER_SIZES, Location=LOCATIONS) | ||||
|      | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // ProcessCass2DBarcode | ||||
| // | ||||
| // Takes in the raw barcode data for a 2D Cassette label. Returns a single field array with 3 field delimited by @VM | ||||
| // CassId, Expected Qty, and Cass Type | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ProcessCass2DBarcode(BarcodeText) | ||||
|      | ||||
|     ErrorMessage = '' | ||||
|     ExpectedSlotWaferMap = '' | ||||
|     ExpectedQty = '' | ||||
|     CassId = '' | ||||
|     CassType = '' | ||||
|     If BarcodeText NE '' then | ||||
|         DelimCnt      = DCount(BarcodeText, '|') | ||||
|         If DelimCnt EQ 8 then | ||||
|             CassId = Field(BarcodeText, '|', 3) | ||||
|             If CassId NE '' then | ||||
|                 If CassId[1, 2] EQ '1T' then | ||||
|                     CassId[1, 2] = '' | ||||
|                     Begin Case | ||||
|                         Case CassId[1, 1] EQ 'O' | ||||
|                             CassId[1, 1] = '' | ||||
|                             CassType = 'WM_OUT' | ||||
|                         Case (CassId[1, 1] EQ 'I') | ||||
|                             CassId[1, 1] = '' | ||||
|                             CassType = 'WM_IN' | ||||
|                         Case Otherwise$ | ||||
|                             CassType = 'RDS' | ||||
|                     End Case | ||||
|                     Convert '.' to '*' in CassId | ||||
|                     Begin Case | ||||
|                         Case RowExists('RDS', CassId) | ||||
|                             ExpectedQty = Xlate('RDS', CassId, 'WFRS_OUT', 'X') | ||||
|                         Case RowExists('WM_OUT', CassId) | ||||
|                             ExpectedQty = Xlate('WM_OUT', CassId, 'WAFER_CNT', 'X') | ||||
|                     End Case | ||||
|                 end                     | ||||
|                  | ||||
|             end else | ||||
|                 ErrorMessage = 'Invalid Lot Label Scan. Unable to determine Cass Id' | ||||
|             end | ||||
|         end else | ||||
|             ErrorMessage = 'Invalid Lot Label Scan.' | ||||
|         end | ||||
|     end else | ||||
|         ErrorMessage = 'Scan data was null.' | ||||
|     end | ||||
|      | ||||
|     If ErrorMessage EQ '' then | ||||
|        Response = CassId : @VM: ExpectedQty : @VM : CassType | ||||
|     end else | ||||
|        Error_Services('Add', ErrorMessage)  | ||||
|     end | ||||
|      | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // ProcessTool2DBarcode | ||||
| // | ||||
| // Takes in the raw barcode data for a wafer counter label, Cassette Id, Cassette Type, and UserId(Optional) | ||||
| // Returns a key ID for a completed WAFER_COUNTER record. | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service ProcessTool2DBarcode(BarcodeText, CassId, CassType, UserId) | ||||
|      | ||||
|     ErrorMessage = '' | ||||
|  | ||||
|     If BarcodeText NE '' then | ||||
|         DelimCnt      = DCount(BarcodeText, '|') | ||||
|         If DelimCnt EQ 2 then | ||||
|             WaferSize   = Field(BarcodeText, '|', 1) | ||||
|             Area        = Field(BarcodeText, '|', 2) | ||||
|             If Environment_Services('IsProd') then | ||||
|                WcJson      = Wafer_Counter_Services('GetWaferCounterJSON', WaferSize, Area, CassID)  | ||||
|             end else | ||||
|                WcJson      = Wafer_Counter_Services('GetWaferCounterJSONTestData', WaferSize, Area, CassID)  | ||||
|             end | ||||
|              | ||||
|             If Error_Services('NoError') then | ||||
|                 objJSON = '' | ||||
|                 If SRP_JSON(objJSON, 'Parse', WcJson) EQ '' then | ||||
|                     ScanDtm          = SRP_JSON(objJSON, 'GetValue', 'dateTimeFormatted') | ||||
|                     ToolID           = SRP_JSON(objJSON, 'GetValue', 'equipmentId') | ||||
|                     WaferCount       = SRP_JSON(objJSON, 'GetValue', 'total') | ||||
|                     SlotMap          = SRP_JSON(objJSON, 'GetValue', 'slotMap') | ||||
|                     SRP_JSON(objJSON, 'Release') | ||||
|                     ToolCurrModeKey = Database_Services('ReadDataColumn', 'TOOL', ToolId, TOOL_CURR_MODE_KEY$, True$, 0, False$) | ||||
|                     ToolCurrMode = Database_Services('ReadDataColumn', 'TOOL_LOG', ToolCurrModeKey, TOOL_LOG_TOOL_MODE$, True$, 0, False$) | ||||
|                     If ToolCurrMode EQ 'PROD' OR ToolCurrMode EQ 'LIM' then | ||||
|                         WaferCounterId = Wafer_Counter_Services('AddScan', CassID, WaferCount, ScanDtm, ToolID, UserId, Area, SlotMap) | ||||
|                         If Error_Services('NoError') then | ||||
|                             Lot_Event_Services('CreateLotEvent', CassId, ScanDtm, 'WAFER_COUNTER', 'Wafer counter data received for lot. ' : WaferCount : ' wafers found.', ToolId, UserId, True$, CassType) | ||||
|                         end | ||||
|                     end else | ||||
|                         ErrorMessage = 'Wafer counter is currently down and cannot be used to log wafer counts.' | ||||
|                     end | ||||
|                 end else | ||||
|                     ErrorMessage = 'Error parsing response from wafer counter.' | ||||
|                 end | ||||
|             end else | ||||
|                 ErrorMessage = Error_Services('GetMessage') | ||||
|             end | ||||
|         end else | ||||
|             ErrorMessage = 'Invalid tool scan.'     | ||||
|         end | ||||
|     end else | ||||
|        ErrorMessage = 'Scan data was null.'  | ||||
|     end | ||||
|      | ||||
|     If ErrorMessage EQ '' then | ||||
|         Response = WaferCounterId | ||||
|     end else | ||||
|        Error_Services('Add', ErrorMessage)  | ||||
|     end | ||||
|      | ||||
| end service | ||||
|  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| // GetWaferCounterJSONTestData | ||||
| // | ||||
| // Emulates GetWaferCounterJson service.  | ||||
| //---------------------------------------------------------------------------------------------------------------------- | ||||
| Service GetWaferCounterJSONTestData(WaferSize, ToolLocation, CassID) | ||||
|  | ||||
|     If ( (WaferSize NE '') and (ToolLocation NE '') and (CassID NE '') ) then  | ||||
|         Response = '' | ||||
|         objJson = '' | ||||
|         If SRP_JSON(objJson, 'New', 'Object') then | ||||
|             SRP_JSON(objJson, 'SetValue', 'dateTimeFormatted', Datetime(), 'String') | ||||
|             SRP_JSON(objJson, 'SetValue', 'equipmentId', 'WC8INCH1', 'String') | ||||
|             SRP_JSON(objJson, 'SetValue', 'total', 24, 'Number') | ||||
|             SRP_JSON(objJson, 'SetValue', 'slotMap', '1111111110111111111111111', 'String')  | ||||
|             Response = SRP_Json(objJson, 'Stringify', 'Styled') | ||||
|             SRP_JSON(objJSON, 'Release') | ||||
|         end | ||||
|          | ||||
|         If Error_Services('NoError') then | ||||
|             StatusCode = 200 | ||||
|             If StatusCode NE 200 then | ||||
| 				Begin Case | ||||
| 					Case Response EQ '' | ||||
| 						ErrorMsg = 'Unexpected server error.' | ||||
| 					Case Response EQ 'No files!' | ||||
| 						ErrorMsg = 'No data. Please re-seat cassette and try again.' | ||||
| 					Case Otherwise$ | ||||
| 						// Use message in response body to populate error services | ||||
| 						ErrorMsg = Response | ||||
| 				End Case | ||||
|                 Error_Services('Add', ErrorMsg) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|      | ||||
| end service | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Internal GoSubs | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @ -405,3 +565,4 @@ ClearCursors: | ||||
|      | ||||
| return | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -2,9 +2,9 @@ Compile function WO_MAT_Services(@Service, @Params) | ||||
| #pragma precomp SRP_PreCompiler | ||||
|  | ||||
| Declare function Database_Services, Error_Services, SRP_Json, SRP_Com, Environment_Services, Logging_Services | ||||
| Declare function Datetime | ||||
| Declare function Datetime, GetTickCount | ||||
| Declare subroutine Error_Services, SRP_Json, SRP_Com, Wo_Mat_Services, Database_Services, Logging_Services | ||||
| Declare subroutine obj_wo_mat_log, Set_Status | ||||
| Declare subroutine obj_wo_mat_log, Set_Status, Mona_Services | ||||
|  | ||||
| $insert LOGICAL | ||||
| $Insert APP_INSERTS | ||||
| @ -20,6 +20,13 @@ Headers		= 'Logging DTM' : @FM : 'WOMatKey' : @FM : 'Missing Signature' : @FM : | ||||
| objSyncLog	= Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) | ||||
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM | ||||
|  | ||||
| IsProd = Environment_Services('IsProd') | ||||
| If IsProd EQ True$ then | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_WOMATSERVICES' | ||||
| end else | ||||
| 	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_WOMATSERVICES' | ||||
| end | ||||
|  | ||||
| GoToService else | ||||
| 	Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') | ||||
| end | ||||
| @ -379,6 +386,9 @@ Service SyncWOMatInvActionsAndSigProfile(WOMatKey) | ||||
| end service | ||||
|  | ||||
| Service CassetteIsLastInWo(WoMatKey) | ||||
| 	StartTick = GetTickCount() | ||||
|     MetricName = 'CassetteIsLastInWo' | ||||
| 	 | ||||
| 	IsLastInWo = False$ | ||||
| 	 | ||||
| 	If Unassigned(WoMatKey) or WoMatKey EQ '' or RowExists('WO_MAT', WoMatKey) NE True$ then | ||||
| @ -424,6 +434,9 @@ Service CassetteIsLastInWo(WoMatKey) | ||||
| 	end | ||||
| 	 | ||||
| 	Response = IsLastInWo | ||||
| 	 | ||||
| 	EndTick = GetTickCount() | ||||
|     Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) | ||||
| end service | ||||
|  | ||||
| Service SetWoMatVoidFlag(WoMatKey, Username) | ||||
| @ -473,3 +486,4 @@ Service SetWoMatVoidFlag(WoMatKey, Username) | ||||
| end service | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| compile insert NICA_CHECKLISTS_EQUATES | ||||
| /*---------------------------------------- | ||||
|  Author : Table Create Insert Routine | ||||
|  Written : 05/03/2025 | ||||
|  Written : 03/06/2025 | ||||
|  Description : Insert for Table NICA_CHECKLISTS | ||||
| ----------------------------------------*/ | ||||
| #ifndef __NICA_CHECKLISTS_EQUATES__  | ||||
| @ -13,6 +13,6 @@ compile insert NICA_CHECKLISTS_EQUATES | ||||
|    equ NICA_CHECKLISTS.NICA_ORDER_FLOW_TYPE$     to 4 | ||||
|    equ NICA_CHECKLISTS.REACTOR_TYPES$            to 5 | ||||
|    equ NICA_CHECKLISTS.REMOVE_IF_COMPLETE$       to 6 | ||||
|     | ||||
| #endif | ||||
|    equ NICA_CHECKLISTS.REMOVE_IF_INTRUSIVE$      to 7 | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| compile insert NICA_ORDERS_EQUATES | ||||
| /*---------------------------------------- | ||||
|  Author : Table Create Insert Routine | ||||
|  Written : 05/12/2024 | ||||
|  Written : 28/05/2025 | ||||
|  Description : Insert for Table NICA_ORDERS | ||||
| ----------------------------------------*/ | ||||
| #ifndef __NICA_ORDERS_EQUATES__  | ||||
| @ -16,9 +16,8 @@ compile insert NICA_ORDERS_EQUATES | ||||
|    equ NICA_ORDERS.ORDER_CHECKLIST_IDS$  to 7 | ||||
|    equ NICA_ORDERS.ORDER_FLOW_IDS$       to 8 | ||||
|    equ NICA_ORDERS.ORDER_RESPONSE_LEVEL$ to 9 | ||||
|    equ NICA_ORDERS.CREATED_DTM$			 to 10 | ||||
|    equ NICA_ORDERS.CLOSED_DTM$			 to 11 | ||||
|     | ||||
|    equ NICA_ORDERS.CREATED_DTM$          to 10 | ||||
|    equ NICA_ORDERS.CLOSED_DTM$           to 11 | ||||
|    equ NICA_ORDERS.INTRUSIVE$            to 12 | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -12,6 +12,8 @@ compile insert PROC_QUEUE_EQUATES | ||||
|    equ PROC_QUEUE.LAST_ATTEMPT_DTM$ to 3 | ||||
|    equ PROC_QUEUE.ERROR$            to 4 | ||||
|    equ PROC_QUEUE.ENTRY_DTM$        to 5 | ||||
|    equ PROC_QUEUE.NUM_ATTEMPTS$		to 6 | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										17
									
								
								LSL2/STPROCINS/PROC_QUEUE_FAILED_EQUATES.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								LSL2/STPROCINS/PROC_QUEUE_FAILED_EQUATES.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| compile insert PROC_QUEUE_FAILED_EQUATES | ||||
| /*---------------------------------------- | ||||
|  Author : Table Create Insert Routine | ||||
|  Written : 06/06/2025 | ||||
|  Description : Insert for Table PROC_QUEUE_FAILED | ||||
| ----------------------------------------*/ | ||||
| #ifndef __PROC_QUEUE_FAILED_EQUATES__  | ||||
| #define __PROC_QUEUE_FAILED_EQUATES__  | ||||
|  | ||||
|    equ PROC_QUEUE_FAILED.PROC_NAME$    to 1 | ||||
|    equ PROC_QUEUE_FAILED.PARAMS$       to 2 | ||||
|    equ PROC_QUEUE_FAILED.COMP_DTM$     to 3 | ||||
|    equ PROC_QUEUE_FAILED.ERROR$        to 4 | ||||
|    equ PROC_QUEUE_FAILED.ENTRY_DTM$    to 5 | ||||
|    equ PROC_QUEUE_FAILED.NUM_ATTEMPTS$ to 6 | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user
	