Merged PR 21151: Return To Fab Operations and Processing
This commit is contained in:
parent
b607432be4
commit
aabd4c3a91
File diff suppressed because it is too large
Load Diff
@ -149,4 +149,3 @@ end api
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Internal GoSubs
|
// Internal GoSubs
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -136,4 +136,3 @@ CreateHALCollection:
|
|||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
258
LSL2/STPROC/CLEAN_API.txt
Normal file
258
LSL2/STPROC/CLEAN_API.txt
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
Function Clean_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 : Clean_API
|
||||||
|
|
||||||
|
Description : API logic for the Clean 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 Clean[.ID.[<Property>]]
|
||||||
|
- HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
|
||||||
|
Examples:
|
||||||
|
- Clean.POST
|
||||||
|
- Clean.ID.PUT
|
||||||
|
- Clean.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/18/25 xxx Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare function OI_Wizard_Services, Lot_Operation_Services, Database_Services, Lot_Services, Clean_Services
|
||||||
|
Declare subroutine Clean_Services, Lot_Services
|
||||||
|
|
||||||
|
$insert APP_INSERTS
|
||||||
|
$insert API_SETUP
|
||||||
|
$insert HTTP_INSERTS
|
||||||
|
$insert OI_WIZARD_EQUATES
|
||||||
|
$insert LOT_OPERATION_EQUATES
|
||||||
|
|
||||||
|
GoToAPI else
|
||||||
|
// The specific resource endpoint doesn't have a API handler yet.
|
||||||
|
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 clean.ID.HEAD
|
||||||
|
API clean.ID.GET
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
CleanRecId = EndpointSegment
|
||||||
|
CleanRecJson = Clean_Services('ConvertCleanRecToJson', CleanRecId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Http_Services('SetResponseBody', CleanRecJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API clean.ID.markcleanrecordcomplete.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
CleanRecId = ParentSegment
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationId')
|
||||||
|
CleanTool = SRP_JSON(objBody, 'GetValue', 'CleanTool')
|
||||||
|
CleanRecipe = SRP_JSON(objBody, 'GetValue', 'CleanRecipe')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
Clean_Services('MarkCleanRecComplete', CleanRecId, CleanRecipe, CleanTool, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
CleanRecJson = Clean_Services('ConvertCleanRecToJson', CleanRecId)
|
||||||
|
HTTP_Services('SetResponseBody', CleanRecJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API clean.createcleanrecord.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotId = SRP_JSON(objBody, 'GetValue', 'LotId')
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
CleanRecId = Clean_Services('CreateNewCleanRecord', LotId, LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
CleanRecJson = Clean_Services('ConvertCleanRecToJson', CleanRecId)
|
||||||
|
HTTP_Services('SetResponseBody', CleanRecJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API clean.getnewcleanoperationparams.HEAD
|
||||||
|
API clean.getnewcleanoperationparams.GET
|
||||||
|
|
||||||
|
JSONCollection = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
If ValidSession then
|
||||||
|
Body = HTTP_Services('GetHTTPGetString')
|
||||||
|
If Body NE '' then
|
||||||
|
RequestJson = HTTP_Services('DecodePercentString', Body)
|
||||||
|
LotId = Http_Services('GetQueryField', 'LotId')
|
||||||
|
objJSONResponse = ''
|
||||||
|
If SRP_Json(objJSONResponse, 'New', 'Object') then
|
||||||
|
//Available Tools
|
||||||
|
If SRP_Json(objCleanTools, 'New', 'Array') then
|
||||||
|
CleanTools = Clean_Services('GetCleanToolOptions')
|
||||||
|
for each CleanTool in CleanTools using @FM
|
||||||
|
SRP_Json(objCleanTools, 'AddValue', CleanTool, 'String')
|
||||||
|
Next CleanTool
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'CleanToolOptions', objCleanTools)
|
||||||
|
SRP_Json(objCleanTools, 'Release')
|
||||||
|
end
|
||||||
|
//Available Recipes
|
||||||
|
If SRP_Json(objCleanRecipes, 'New', 'Array') then
|
||||||
|
CleanRecipes = Clean_Services('GetCleanRecipeOptions')
|
||||||
|
for each Recipe in CleanRecipes using @VM
|
||||||
|
SRP_Json(objCleanRecipes, 'AddValue', Recipe, 'String')
|
||||||
|
Next Recipe
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'CleanRecipeOptions', objCleanRecipes)
|
||||||
|
SRP_Json(objCleanRecipes, 'Release')
|
||||||
|
end
|
||||||
|
JsonResponse = SRP_Json(objJsonResponse, 'Stringify', 'Styled')
|
||||||
|
SRP_Json(objJsonResponse, 'Release')
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error when creating JSON response.')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'No body was sent with the request.')
|
||||||
|
end
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseStatus', 201, 'Success')
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseBody', JsonResponse, False$, 'application/hal+json')
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end api
|
217
LSL2/STPROC/CLEAN_SERVICES.txt
Normal file
217
LSL2/STPROC/CLEAN_SERVICES.txt
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
Compile function Clean_Services(@Service, @Params)
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare Function Database_Services, Error_Services, Logging_Services, Datetime
|
||||||
|
Declare Function RTI_CreateGUID, Tool_Services, SRP_Json, Date_Services
|
||||||
|
Declare Subroutine Database_Services, Error_Services, Logging_Services, SRP_Json, Lot_Event_Services
|
||||||
|
|
||||||
|
$insert LOGICAL
|
||||||
|
$Insert CLEAN_EQUATES
|
||||||
|
$Insert LOT_EQUATES
|
||||||
|
$Insert LOT_OPERATION_EQUATES
|
||||||
|
$Insert TOOL_EQUATES
|
||||||
|
$Insert TOOL_CLASS_EQUATES
|
||||||
|
|
||||||
|
Options Stage = 'LWI',
|
||||||
|
|
||||||
|
GoToService
|
||||||
|
|
||||||
|
Return Response or ""
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// SERVICES
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Service CreateNewCleanRecord(LotId, LotOperationId, UserId)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
CleanRecId = ''
|
||||||
|
If RowExists('LOT', LotId) then
|
||||||
|
//ToDo check Lot Operation Exists
|
||||||
|
//Checks complete, create the CLEAN record
|
||||||
|
TransDtm = Datetime()
|
||||||
|
CleanRecId = RTI_CreateGUID()
|
||||||
|
CleanRec = ''
|
||||||
|
CleanRec<CLEAN_LOT_ID$> = LotId
|
||||||
|
CleanRec<CLEAN_LOT_OPERATION_ID$> = LotOperationId
|
||||||
|
CleanRec<CLEAN_CLEAN_START_DTM$> = TransDtm
|
||||||
|
CleanRec<CLEAN_CLEAN_START_USER_ID$> = UserId
|
||||||
|
Database_Services('WriteDataRow', 'CLEAN', CleanRecId, CleanRec)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If LotOperationId NE '' then
|
||||||
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
||||||
|
LotOperationRec<LOT_OPERATION_CLEAN_ID$> = CleanRecId
|
||||||
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, LotOperationRec)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, TransDtm, 'CLEAN_START', 'Created clean record.', '', UserId)
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
//Todo add error message
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage EQ '' then
|
||||||
|
Response = CleanRecId
|
||||||
|
end else
|
||||||
|
// Todo: Add logging
|
||||||
|
ErrorMessage = 'Error Creating a new clean record: ' : ErrorMessage
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
End Service
|
||||||
|
|
||||||
|
Service ConvertCleanRecToJson(CleanRecId)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
CleanRecJson = ''
|
||||||
|
|
||||||
|
If RowExists('CLEAN', CleanRecId) then
|
||||||
|
CleanRec = Database_Services('ReadDataRow', 'CLEAN', CleanRecId, True$, 0, False$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
objJson = ''
|
||||||
|
If SRP_Json(objJson, 'New', 'Object') then
|
||||||
|
SRP_Json(objJson, 'SetValue', 'CleanId', CleanRecId, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'LotId', CleanRec<CLEAN_LOT_ID$>, 'String')
|
||||||
|
LegacyLotId = Database_Services('ReadDataColumn', 'LOT', CleanRec<CLEAN_LOT_ID$>, LOT_LEGACY_LOT_ID$)
|
||||||
|
SRP_Json(objJson, 'SetValue', 'LegacyLotId', LegacyLotId, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'Recipe', CleanRec<CLEAN_RECIPE$>, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'Tool', CleanRec<CLEAN_TOOL$>, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'StartUser', CleanRec<CLEAN_CLEAN_START_USER_ID$>, 'String')
|
||||||
|
StartDtm = Date_Services('ConvertDateTimeToISO8601', CleanRec<CLEAN_CLEAN_START_DTM$>)
|
||||||
|
if StartDtm NE '' then
|
||||||
|
SRP_Json(objJson, 'SetValue', 'StartDtm', StartDtm)
|
||||||
|
end
|
||||||
|
SRP_Json(objJson, 'SetValue', 'StopUser', CleanRec<CLEAN_CLEAN_STOP_USER_ID$>, 'String')
|
||||||
|
StopDtm = Date_Services('ConvertDateTimeToISO8601', CleanRec<CLEAN_CLEAN_STOP_DTM$>)
|
||||||
|
if StopDtm NE '' then
|
||||||
|
SRP_Json(objJson, 'SetValue', 'StopDtm', StopDtm, 'String')
|
||||||
|
end
|
||||||
|
SRP_Json(objJson, 'SetValue', 'LotOperationId', CleanRec<CLEAN_LOT_OPERATION_ID$>, 'String')
|
||||||
|
CleanRecJson = SRP_Json(objJson, 'Stringify', 'Styled')
|
||||||
|
SRP_Json(objJson, 'Release')
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error creating clean record json'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean record not found.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage EQ '' then
|
||||||
|
Response = CleanRecJson
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error getting clean record : ' : ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service MarkCleanRecComplete(CleanRecId, CleanRecipe, CleanTool, CleanUser)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
TransDtm = Datetime()
|
||||||
|
|
||||||
|
If RowExists('CLEAN', CleanRecId) then
|
||||||
|
CleanRec = Database_Services('ReadDataRow', 'CLEAN', CleanRecId, True$, 0, False$)
|
||||||
|
If CleanRec<CLEAN_CLEAN_START_DTM$> NE '' then
|
||||||
|
If CleanRec<CLEAN_TOOL$> EQ '' AND CleanRec<CLEAN_RECIPE$> EQ '' then
|
||||||
|
if RowExists('LSL_USERS', CleanUser) then
|
||||||
|
If CleanRec<CLEAN_COMPLETE_DTM$> EQ '' then
|
||||||
|
CleanRec<CLEAN_TOOL$> = CleanTool
|
||||||
|
CleanRec<CLEAN_RECIPE$> = CleanRecipe
|
||||||
|
CleanRec<CLEAN_CLEAN_STOP_USER_ID$> = CleanUser
|
||||||
|
CleanRec<CLEAN_CLEAN_STOP_DTM$> = TransDtm
|
||||||
|
Database_Services('WriteDataRow', 'CLEAN', CleanRecId, CleanRec)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotId = CleanRec<CLEAN_LOT_ID$>
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, TransDtm, 'CLEAN', 'Clean completed', CleanTool, CleanUser)
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean is already signed off.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean tool or clean recipe is missing.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean has already been logged.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean has not been started.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Clean record not found.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service ValidateCleanRecord(CleanRecId)
|
||||||
|
|
||||||
|
//ErrorMessage = ''
|
||||||
|
CleanRecValid = False$
|
||||||
|
|
||||||
|
* If CleanRecId NE '' then
|
||||||
|
* If RowExists('CLEAN', CleanRecId) then
|
||||||
|
* CleanRec = Database_Services('ReadDataRow', 'CLEAN', CleanRecId, True$, 0, False$)
|
||||||
|
* SpecTool = CleanRec<CLEAN_TOOL$>
|
||||||
|
* ToolUsed = CleanRec<CLEAN_RECIPE$>
|
||||||
|
* If ToolUsed EQ SpecTool AND ToolUsed NE '' then
|
||||||
|
* SpecRecipe = CleanRec<CLEAN_SPEC_RECIPE$>
|
||||||
|
* RecipeUsed = CleanRec<CLEAN_RECIPE$>
|
||||||
|
* If RecipeUsed EQ SpecRecipe AND RecipeUsed NE '' then
|
||||||
|
* CleanRecValid = True$
|
||||||
|
* end
|
||||||
|
* end
|
||||||
|
* end else
|
||||||
|
* ErrorMessage = 'Clean record not found in CLEAN database.'
|
||||||
|
* end
|
||||||
|
* end else
|
||||||
|
* ErrorMessage = 'Clean ID was null.'
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* If ErrorMessage EQ '' then
|
||||||
|
* Response = CleanRecValid
|
||||||
|
* end else
|
||||||
|
* // Todo: Add logging
|
||||||
|
* ErrorMessage = 'Error validating clean record: ' : ErrorMessage
|
||||||
|
* Error_Services('Add', ErrorMessage)
|
||||||
|
* end
|
||||||
|
|
||||||
|
Response = CleanRecValid
|
||||||
|
End Service
|
||||||
|
|
||||||
|
Service GetCleanToolOptions(CleanRecId)
|
||||||
|
|
||||||
|
If RowExists('CLEAN', CleanRecId) then
|
||||||
|
CleanTools = Database_Services('ReadDataColumn', 'CLEAN', CleanRecId, CLEAN_SPEC_CLEAN_TOOL$, True$, 0, False$)
|
||||||
|
end else
|
||||||
|
CleanTools = Tool_Services('GetTools', 'AKRION')
|
||||||
|
end
|
||||||
|
|
||||||
|
Response = CleanTools
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetCleanRecipeOptions(CleanRecId)
|
||||||
|
|
||||||
|
If RowExists('CLEAN', CleanRecId) then
|
||||||
|
Recipes = Database_Services('ReadDataColumn', 'CLEAN', CleanRecId, CLEAN_SPEC_CLEAN_RECIPE$, True$, 0, False$)
|
||||||
|
end else
|
||||||
|
//Todo: Make this smarter, so as to block out pre-epi recipes
|
||||||
|
Recipes = XLATE('TOOL_CLASS','AKRION',TOOL_CLASS_RECIPES$,'X')
|
||||||
|
end
|
||||||
|
|
||||||
|
Response = Recipes
|
||||||
|
|
||||||
|
end service
|
@ -858,3 +858,4 @@ Result = ReturnData
|
|||||||
RETURN
|
RETURN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,4 +213,3 @@ UpdateHALItem:
|
|||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -220,6 +220,13 @@ Service GetWeekNum(InputDate)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
Service ConvertDateTimeToISO8601(DatetimeToConv)
|
||||||
|
|
||||||
|
Response = OConv(DatetimeToConv, "[SRP_DATETIME,()YYYY-MM-DD hh:mm:ss.000Z]")
|
||||||
|
swap ' ' with 'T' in Response
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Internal GoSubs
|
// Internal GoSubs
|
||||||
|
@ -94,4 +94,3 @@ API engineinfo.ID.GET
|
|||||||
end
|
end
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -69,4 +69,3 @@ API healthinfo.GET
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -161,7 +161,3 @@ API Lock.HEAD
|
|||||||
end
|
end
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
460
LSL2/STPROC/LOTOPERATION_API.txt
Normal file
460
LSL2/STPROC/LOTOPERATION_API.txt
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
Function Lotoperation_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 : Lotoperation_API
|
||||||
|
|
||||||
|
Description : API logic for the Lotoperation 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 Lotoperation[.ID.[<Property>]]
|
||||||
|
- HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
|
||||||
|
Examples:
|
||||||
|
- Lotoperation.POST
|
||||||
|
- Lotoperation.ID.PUT
|
||||||
|
- Lotoperation.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)
|
||||||
|
05/20/25 xxx Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare function OI_Wizard_Services, Lot_Operation_Services, Database_Services, Lot_Services, Clean_Services
|
||||||
|
Declare function Met_Test_Services
|
||||||
|
Declare subroutine Lot_Services, Met_Test_Services, Wafer_Counter_Services
|
||||||
|
|
||||||
|
$insert APP_INSERTS
|
||||||
|
$insert API_SETUP
|
||||||
|
$insert HTTP_INSERTS
|
||||||
|
$insert OI_WIZARD_EQUATES
|
||||||
|
$insert LOT_OPERATION_EQUATES
|
||||||
|
|
||||||
|
GoToAPI else
|
||||||
|
// The specific resource endpoint doesn't have a API handler yet.
|
||||||
|
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 lotoperation.HEAD
|
||||||
|
API lotoperation.GET
|
||||||
|
|
||||||
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.addoperation.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotId = SRP_JSON(objBody, 'GetValue', 'NewLotOperationData.LotId')
|
||||||
|
OperationId = SRP_JSON(objBody, 'GetValue', 'NewLotOperationData.OperationId')
|
||||||
|
Sequence = SRP_JSON(objBody, 'GetValue', 'NewLotOperationData.Sequence')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
If RowExists('LOT', LotId) then
|
||||||
|
If RowExists('OPERATION', OperationId) then
|
||||||
|
If Sequence NE '' then
|
||||||
|
NewOperationId = Lot_Operation_Services('AddOperationToLot', LotId, OperationId, Sequence, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotJsonString = Lot_Services('ConvertLotRecordToJson', LotId, '', UserId)
|
||||||
|
HTTP_Services('SetResponseBody', LotJsonString, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid Sequence.'
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid Operation.'
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid Lot.'
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
API lotoperation.removeoperation.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationIdToRemove')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
|
LotId = Database_Services('ReadDataColumn', 'LOT_OPERATION', LotOperationId, LOT_OPERATION_LOT_ID$, True$, 0, False$)
|
||||||
|
Removed = Lot_Operation_Services('RemoveLotOperation', LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotJsonString = Lot_Services('ConvertLotRecordToJson', LotId, '', UserId)
|
||||||
|
HTTP_Services('SetResponseBody', LotJsonString, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid Operation.'
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
API lotoperation.startlotoperation.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'lotOperationId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
LotProcessStarted = Lot_Operation_Services('StartLotOperation', LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotOperationJson = Lot_Operation_Services('ConvertRecordToJson', LotOperationId)
|
||||||
|
HTTP_Services('SetResponseBody', LotOperationJson,False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error while moving lot in. ' : Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.completelotoperation.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'lotOperationId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
LotProcessCompleted = Lot_Operation_Services('CompleteLotOperation', LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotOperationJson = Lot_Operation_Services('ConvertRecordToJson', LotOperationId)
|
||||||
|
HTTP_Services('SetResponseBody', LotOperationJson)
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.ID.HEAD
|
||||||
|
API lotoperation.ID.GET
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
LotOperationId = EndpointSegment
|
||||||
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
|
LotOperationJson = Lot_Operation_Services('ConvertRecordToJson', LotOperationId)
|
||||||
|
HTTP_Services('SetResponseBody', LotOperationJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Lot Operation not found in database.'
|
||||||
|
end
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.associatemettest.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationId')
|
||||||
|
MetTestId = SRP_JSON(objBody, 'GetValue', 'MetTestId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
Met_Test_Services('AttachMetTestToLotOperation', MetTestId, LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.removemettest.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationId')
|
||||||
|
MetTestId = SRP_JSON(objBody, 'GetValue', 'MetTestId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
Met_Test_Services('RemoveMetTestFromLotOperation', MetTestId, LotOperationId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseBody', LotJsonString, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lotoperation.associatewafercounter.POST
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPPostString', True$)
|
||||||
|
// The POST string will have been encoded so use percent (URL) decoding.
|
||||||
|
DecodedJSON = HTTP_Services('DecodePercentString', Body)
|
||||||
|
If SRP_JSON(objBody, 'Parse', Body) EQ '' then
|
||||||
|
LotOperationId = SRP_JSON(objBody, 'GetValue', 'LotOperationId')
|
||||||
|
WaferCounterId = SRP_JSON(objBody, 'GetValue', 'WaferCounterId')
|
||||||
|
SRP_JSON(objBody, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
Wafer_Counter_Services('AssociateWaferCounter', LotOperationId, WaferCounterId, UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
@ -38,9 +38,12 @@ Function Lot_API(@API)
|
|||||||
|
|
||||||
#pragma precomp SRP_PreCompiler
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare function OI_Wizard_Services, Lot_Services, Database_Services, PSN_Services, Clean_Services
|
||||||
|
|
||||||
$insert APP_INSERTS
|
$insert APP_INSERTS
|
||||||
$insert API_SETUP
|
$insert API_SETUP
|
||||||
$insert HTTP_INSERTS
|
$insert HTTP_INSERTS
|
||||||
|
$Insert OI_WIZARD_EQUATES
|
||||||
|
|
||||||
GoToAPI else
|
GoToAPI else
|
||||||
// The specific resource endpoint doesn't have a API handler yet.
|
// The specific resource endpoint doesn't have a API handler yet.
|
||||||
@ -55,3 +58,159 @@ Return Response OR ''
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
API lot.ID.HEAD
|
||||||
|
API lot.ID.GET
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
LotId = EndpointSegment
|
||||||
|
If RowExists('LOT', LotId) then
|
||||||
|
LotJson = Lot_Services('ConvertLotRecordToJson', LotId, '', UserId)
|
||||||
|
HTTP_Services('SetResponseBody', LotJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ResponseCode = 500
|
||||||
|
ErrorMessage = 'Lot not found in database.'
|
||||||
|
end
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lot.getlotbylegacylotid.HEAD
|
||||||
|
API lot.getlotbylegacylotid.GET
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
ResponseMessage = ''
|
||||||
|
Body = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
If ValidSession then
|
||||||
|
UserId = Xlate('OI_WIZARD', OIWizardID, OI_WIZARD.EMPLOYEE_ID$, 'X')
|
||||||
|
StatusCode = ''
|
||||||
|
Body = HTTP_Services('GetHTTPGetString')
|
||||||
|
|
||||||
|
LegacyLotId = Http_Services('GetQueryField', 'LegacyLotId')
|
||||||
|
LegacyLotType = Http_Services('GetQueryField', 'LegacyLotType')
|
||||||
|
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', LegacyLotId, LegacyLotType)
|
||||||
|
LotJson = Lot_Services('ConvertLotRecordToJson', LotId, '', UserId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseBody', LotJson, False$, 'application/hal+json')
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Invalid session. Reauthentication required.'
|
||||||
|
ResponseCode = 401
|
||||||
|
end
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API lot.ID.getrecipeoptions.HEAD
|
||||||
|
API lot.ID.getrecipeoptions.GET
|
||||||
|
|
||||||
|
JSONCollection = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
If ValidSession then
|
||||||
|
LotId = EndpointSegment
|
||||||
|
PSN = Database_Services('ReadDataColumn', 'LOT', LotId, LOT_PROD_SPEC_ID$, True$, 0, False$)
|
||||||
|
RecipeParameters = PSN_Services('GetAllMetrologyRecipes', PSN, True$, True$, True$, True$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If Body NE '' then
|
||||||
|
RequestJson = HTTP_Services('DecodePercentString', Body)
|
||||||
|
objJSONResponse = ''
|
||||||
|
If SRP_Json(objJSONResponse, 'New', 'Object') then
|
||||||
|
//Available Tools
|
||||||
|
If SRP_Json(objCleanTools, 'New', 'Array') then
|
||||||
|
CleanTools = Clean_Services('GetCleanToolOptions')
|
||||||
|
for each CleanTool in CleanTools using @FM
|
||||||
|
SRP_Json(objCleanTools, 'AddValue', CleanTool, 'String')
|
||||||
|
Next CleanTool
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'CleanToolOptions', objCleanTools)
|
||||||
|
SRP_Json(objCleanTools, 'Release')
|
||||||
|
end
|
||||||
|
//Available Recipes
|
||||||
|
If SRP_Json(objCleanRecipes, 'New', 'Array') then
|
||||||
|
CleanRecipes = Clean_Services('GetCleanRecipeOptions')
|
||||||
|
for each Recipe in CleanRecipes using @VM
|
||||||
|
SRP_Json(objCleanRecipes, 'AddValue', Recipe, 'String')
|
||||||
|
Next Recipe
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'CleanRecipeOptions', objCleanRecipes)
|
||||||
|
SRP_Json(objCleanRecipes, 'Release')
|
||||||
|
end
|
||||||
|
JsonResponse = SRP_Json(objJsonResponse, 'Stringify', 'Styled')
|
||||||
|
SRP_Json(objJsonResponse, 'Release')
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error when creating JSON response.')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'No body was sent with the request.')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseStatus', 201, 'Success')
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseBody', JsonResponse, False$, 'application/hal+json')
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ Declare function Lot_Event_Services, Lot_Services
|
|||||||
Declare subroutine Error_Services, Logging_Services, Database_Services, Lot_Services, Service_Services
|
Declare subroutine Error_Services, Logging_Services, Database_Services, Lot_Services, Service_Services
|
||||||
Declare subroutine Transaction_Services
|
Declare subroutine Transaction_Services
|
||||||
|
|
||||||
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', 'SIGN_FQA', 'UNSIGN_FQA'
|
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', 'SIGN_FQA', 'UNSIGN_FQA', 'ADD_LOT_OPERATION', 'REMOVE_LOT_OPERATION', 'MET_TEST', 'LOG_WAFER_COUNT', 'PACKAGING'
|
||||||
Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT'
|
Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT'
|
||||||
Options LEGACY_LOT_TYPES = 'RDS', 'WM_OUT', 'WM_IN'
|
Options LEGACY_LOT_TYPES = 'RDS', 'WM_OUT', 'WM_IN'
|
||||||
Options BOOLEAN = 'True', 'False'
|
Options BOOLEAN = 'True', 'False'
|
||||||
@ -230,3 +230,6 @@ InitEventLog:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@ Compile function Lot_Operation_Services(@Service, @Params)
|
|||||||
|
|
||||||
Declare function Lot_Services, Database_Services, Error_Services, Srp_Sort_Array, Lot_Operation_Services
|
Declare function Lot_Services, Database_Services, Error_Services, Srp_Sort_Array, Lot_Operation_Services
|
||||||
Declare function RTI_CreateGUID, MemberOf, SRP_JSON, Operation_Services, Datetime, Met_Test_Services, PSN_Services
|
Declare function RTI_CreateGUID, MemberOf, SRP_JSON, Operation_Services, Datetime, Met_Test_Services, PSN_Services
|
||||||
|
Declare function Date_Services
|
||||||
Declare subroutine Database_Services, Error_Services, SRP_JSON, Lot_Services, Lot_Event_Services, Lot_Operation_Services
|
Declare subroutine Database_Services, Error_Services, SRP_JSON, Lot_Services, Lot_Event_Services, Lot_Operation_Services
|
||||||
|
|
||||||
$insert LOGICAL
|
$insert LOGICAL
|
||||||
$insert LOT_EQUATES
|
$insert LOT_EQUATES
|
||||||
$Insert LOT_OPERATION_EQUATES
|
$Insert LOT_OPERATION_EQUATES
|
||||||
$Insert METROLOGY_DATA_EXAMPLE_EQUATES
|
|
||||||
$Insert OPERATION_EQUATES
|
$Insert OPERATION_EQUATES
|
||||||
$Insert MET_TEST_EQUATES
|
$Insert MET_TEST_EQUATES
|
||||||
$Insert WAFER_COUNTER_EQUATES
|
$Insert WAFER_COUNTER_EQUATES
|
||||||
@ -30,7 +30,7 @@ Service AddOperationToLot(LotId, OperationId, PrescribedSequence, UserId)
|
|||||||
If RowExists('LOT', LotId) then
|
If RowExists('LOT', LotId) then
|
||||||
If RowExists('OPERATION', OperationId) then
|
If RowExists('OPERATION', OperationId) then
|
||||||
If PrescribedSequence AND Num(PrescribedSequence) then
|
If PrescribedSequence AND Num(PrescribedSequence) then
|
||||||
If Lot_Operation_Services('CanUserAddLotOperation', UserId) then
|
If Lot_Services('CanUserModifyLot', UserId) then
|
||||||
LotCurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
|
LotCurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
|
||||||
CurrOperationSequence = Xlate('LOT_OPERATION', LotCurrOperation, LOT_OPERATION_OPERATION_SEQUENCE$, 'X')
|
CurrOperationSequence = Xlate('LOT_OPERATION', LotCurrOperation, LOT_OPERATION_OPERATION_SEQUENCE$, 'X')
|
||||||
If CurrOperationSequence LT PrescribedSequence then
|
If CurrOperationSequence LT PrescribedSequence then
|
||||||
@ -74,7 +74,8 @@ Service AddOperationToLot(LotId, OperationId, PrescribedSequence, UserId)
|
|||||||
IsOperationRework = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_REWORK$)
|
IsOperationRework = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_REWORK$)
|
||||||
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'ADD_LOT_OPERATION', 'Added operation ' : Operation : ' to lot.', '', UserId)
|
OperationDesc = XLATE('OPERATION', OperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'ADD_LOT_OPERATION', 'Added operation ' : Quote(OperationDesc) : ' to lot.', '', UserId)
|
||||||
end else
|
end else
|
||||||
ErrorMessage = Error_Services('GetMessage')
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
end
|
end
|
||||||
@ -86,7 +87,7 @@ Service AddOperationToLot(LotId, OperationId, PrescribedSequence, UserId)
|
|||||||
ErrorMessage = 'Not allowed to add new operations prior to current operation'
|
ErrorMessage = 'Not allowed to add new operations prior to current operation'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'User ' : UserId : ' does not have permission to add operations to lots.'
|
ErrorMessage = 'User ' : UserId : ' does not have permission to modify lots.'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Invalid operation sequence entered.'
|
ErrorMessage = 'Invalid operation sequence entered.'
|
||||||
@ -102,7 +103,6 @@ Service AddOperationToLot(LotId, OperationId, PrescribedSequence, UserId)
|
|||||||
Response = Operation
|
Response = Operation
|
||||||
end else
|
end else
|
||||||
Error_Services('Add', 'Error in ' : Service : '.' : ErrorMessage)
|
Error_Services('Add', 'Error in ' : Service : '.' : ErrorMessage)
|
||||||
// todo: add logging
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end service
|
end service
|
||||||
@ -114,6 +114,7 @@ Service RemoveLotOperation(LotOperationId, UserId)
|
|||||||
Success = False$
|
Success = False$
|
||||||
|
|
||||||
If RowExists('LOT_OPERATION', LotOperationId) then
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
|
If Lot_Services('CanUserModifyLot', UserId) then
|
||||||
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
||||||
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
||||||
MoveInTime = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
MoveInTime = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
||||||
@ -132,7 +133,8 @@ Service RemoveLotOperation(LotOperationId, UserId)
|
|||||||
end else
|
end else
|
||||||
ErrorMessage = Error_Services('GetMessage')
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
end
|
end
|
||||||
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REMOVE_LOT_OPERATION', 'Removed operation ' : OperationId : ' from lot.', '', UserId)
|
OperationDesc = XLATE('OPERATION', OperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REMOVE_LOT_OPERATION', 'Removed operation ' : Quote(OperationDesc) : ' from lot.', '', UserId)
|
||||||
end else
|
end else
|
||||||
ErrorMessage = Error_Services('GetMessage')
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
end
|
end
|
||||||
@ -142,20 +144,23 @@ Service RemoveLotOperation(LotOperationId, UserId)
|
|||||||
end else
|
end else
|
||||||
ErrorMessage = 'Unable to remove default operations.'
|
ErrorMessage = 'Unable to remove default operations.'
|
||||||
end
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'User ' : UserId : ' does not have permission modify lots.'
|
||||||
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Lot Operation record not found'
|
ErrorMessage = 'Lot Operation record not found'
|
||||||
end
|
end
|
||||||
|
|
||||||
If ErrorMessage NE '' then
|
If ErrorMessage NE '' then
|
||||||
Error_Services('Add', 'Error in service ': Service : ' : ' : ErrorMessage)
|
Error_Services('Add', ErrorMessage)
|
||||||
end
|
end
|
||||||
|
|
||||||
Response = Success
|
Response = Success
|
||||||
|
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
Service UpdateLotOperationSequence(LotId, StartSequence)
|
Service UpdateLotOperationSequence(LotId, StartSequence)
|
||||||
|
|
||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
If StartSequence EQ '' then
|
If StartSequence EQ '' then
|
||||||
StartSequence = 1
|
StartSequence = 1
|
||||||
@ -189,17 +194,6 @@ Service UpdateLotOperationSequence(LotId, StartSequence)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
Service ModifyLotOperationSequence(LotOperationId, NewSequence, UserId)
|
|
||||||
|
|
||||||
ErrorMessage = ''
|
|
||||||
|
|
||||||
If ErrorMessage NE '' then
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
Service GetAvailableSequences(LotId)
|
Service GetAvailableSequences(LotId)
|
||||||
AvailableSequences = ''
|
AvailableSequences = ''
|
||||||
|
|
||||||
@ -211,40 +205,14 @@ Service GetAvailableSequences(LotId)
|
|||||||
OperationClass = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_CLASS_ID$)
|
OperationClass = Database_Services('ReadDataColumn', 'OPERATION', OperationId, OPERATION_CLASS_ID$)
|
||||||
StartDtm = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
StartDtm = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
||||||
If StartDTM EQ '' then
|
If StartDTM EQ '' then
|
||||||
If OperationClass NE 'RTF_DEFAULT' then
|
|
||||||
AvailableSequences<1, -1> = Sequence + 1
|
AvailableSequences<1, -1> = Sequence + 1
|
||||||
end
|
end
|
||||||
end
|
|
||||||
Next LotOperationId
|
Next LotOperationId
|
||||||
end
|
end
|
||||||
|
|
||||||
Response = AvailableSequences
|
Response = AvailableSequences
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
Service AddSpecsToLotOperation(LotOperationId)
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
Service CanUserAddLotOperation(UserId)
|
|
||||||
|
|
||||||
If UserId NE '' then
|
|
||||||
Begin Case
|
|
||||||
Case MemberOf(UserId, 'LEAD')
|
|
||||||
Response = True$
|
|
||||||
Case MemberOf(UserId, 'SUPERVISOR')
|
|
||||||
Response = True$
|
|
||||||
Case MemberOf(UserId, 'ENGINEER')
|
|
||||||
Response = True$
|
|
||||||
Case MemberOf(UserId, 'ENG_TECH')
|
|
||||||
Response = True$
|
|
||||||
Case Otherwise$
|
|
||||||
Response = False$
|
|
||||||
End Case
|
|
||||||
end
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
Service ConvertRecordToJson(LotOperationId)
|
Service ConvertRecordToJson(LotOperationId)
|
||||||
|
|
||||||
JsonString = ''
|
JsonString = ''
|
||||||
@ -258,8 +226,14 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
SRP_JSON(objJSON, 'SetValue', 'LotId', LotId, 'String')
|
SRP_JSON(objJSON, 'SetValue', 'LotId', LotId, 'String')
|
||||||
SRP_JSON(objJSON, 'SetValue', 'LegacyLotId', LegacyLotId, 'String')
|
SRP_JSON(objJSON, 'SetValue', 'LegacyLotId', LegacyLotId, 'String')
|
||||||
SRP_JSON(objJSON, 'SetValue', 'OperationId', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, 'String')
|
SRP_JSON(objJSON, 'SetValue', 'OperationId', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, 'String')
|
||||||
SRP_JSON(objJSON, 'SetValue', 'DateTimeIn', OConv(LotOperationRec<LOT_OPERATION_DATETIME_IN$>, 'DT'), 'String')
|
OperationDesc = XLATE('OPERATION', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
||||||
SRP_JSON(objJSON, 'SetValue', 'DateTimeOut', OConv(LotOperationRec<LOT_OPERATION_DATETIME_OUT$>, 'DT'), 'String')
|
SRP_JSON(objJSON, 'SetValue', 'Description', OperationDesc, 'String')
|
||||||
|
OperationClass = XLATE('OPERATION', LotOperationRec<LOT_OPERATION_OPERATION_ID$>, OPERATION_CLASS_ID$, 'X')
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'OperationClass', OperationClass)
|
||||||
|
DatetimeIn = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_IN$>)
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeIn', DatetimeIn)
|
||||||
|
DatetimeOut = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_OUT$>)
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeOut', DatetimeOut)
|
||||||
EquipmentId = LotOperationRec<LOT_OPERATION_EQUIPMENT_ID$>
|
EquipmentId = LotOperationRec<LOT_OPERATION_EQUIPMENT_ID$>
|
||||||
SRP_JSON(objJSON, 'SetValue', 'EquipmentId', EquipmentId)
|
SRP_JSON(objJSON, 'SetValue', 'EquipmentId', EquipmentId)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'WaferInQty', LotOperationRec<LOT_OPERATION_WAFER_IN_QTY$>, 'Number')
|
SRP_JSON(objJSON, 'SetValue', 'WaferInQty', LotOperationRec<LOT_OPERATION_WAFER_IN_QTY$>, 'Number')
|
||||||
@ -267,8 +241,10 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
SRP_JSON(objJSON, 'SetValue', 'OperatorInId', LotOperationRec<LOT_OPERATION_OPERATOR_IN_ID$>)
|
SRP_JSON(objJSON, 'SetValue', 'OperatorInId', LotOperationRec<LOT_OPERATION_OPERATOR_IN_ID$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'OperatorOutId', LotOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$>)
|
SRP_JSON(objJSON, 'SetValue', 'OperatorOutId', LotOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'OperationSequence', LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>)
|
SRP_JSON(objJSON, 'SetValue', 'OperationSequence', LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'DateTimeStart', OConv(LotOperationRec<LOT_OPERATION_DATETIME_START$>, 'DT'), 'String')
|
DatetimeStart = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_START$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'DateTimeStop', OConv(LotOperationRec<LOT_OPERATION_DATETIME_STOP$>, 'DT'), 'String')
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeStart', DatetimeStart)
|
||||||
|
DatetimeStop = Date_Services('ConvertDateTimeToISO8601', LotOperationRec<LOT_OPERATION_DATETIME_STOP$>)
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'DateTimeStop', DatetimeStop)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'MetTestId', LotOperationRec<LOT_OPERATION_MET_TEST_ID$>)
|
SRP_JSON(objJSON, 'SetValue', 'MetTestId', LotOperationRec<LOT_OPERATION_MET_TEST_ID$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'CleanId', LotOperationRec<LOT_OPERATION_CLEAN_ID$>)
|
SRP_JSON(objJSON, 'SetValue', 'CleanId', LotOperationRec<LOT_OPERATION_CLEAN_ID$>)
|
||||||
SRP_JSON(objJSON, 'SetValue', 'PackagingId', LotOperationRec<LOT_OPERATION_PACKAGING_ID$>)
|
SRP_JSON(objJSON, 'SetValue', 'PackagingId', LotOperationRec<LOT_OPERATION_PACKAGING_ID$>)
|
||||||
@ -278,7 +254,22 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
SRP_JSON(objJson, 'SetValue', 'PackagingRequired', LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>, 'Boolean')
|
SRP_JSON(objJson, 'SetValue', 'PackagingRequired', LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>, 'Boolean')
|
||||||
SRP_JSON(objJson, 'SetValue', 'CleanRequired', LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>, 'Boolean')
|
SRP_JSON(objJson, 'SetValue', 'CleanRequired', LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>, 'Boolean')
|
||||||
SRP_JSON(objJson, 'SetValue', 'WaferCounterRequired', LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>, 'Boolean')
|
SRP_JSON(objJson, 'SetValue', 'WaferCounterRequired', LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>, 'Boolean')
|
||||||
|
PSNo = Xlate('LOT', LotId, LOT_PROD_SPEC_ID$, 'X')
|
||||||
|
RecipeToolInfo = PSN_Services('GetAllMetrologyRecipes', PSNo, True$, True$, True$, True$)
|
||||||
|
objRecipeInfo = ''
|
||||||
|
If SRP_Json(objRecipeInfo, 'New', 'Array') then
|
||||||
|
for each RecipeLine in RecipeToolInfo using @FM
|
||||||
|
If SRP_Json(objRecipeLine, 'New', 'Object') then
|
||||||
|
SRP_Json(objRecipeLine, 'SetValue', 'ToolClass', RecipeLine<1,1>, 'String')
|
||||||
|
SRP_Json(objRecipeLine, 'SetValue', 'Recipe', RecipeLine<1,2>, 'String')
|
||||||
|
SRP_Json(objRecipeLine, 'SetValue', 'Stage', RecipeLine<1,3>, 'String')
|
||||||
|
SRP_Json(objRecipeInfo, 'Add', objRecipeLine)
|
||||||
|
SRP_Json(objRecipeLine, 'Release')
|
||||||
|
end
|
||||||
|
Next RecipeLine
|
||||||
|
SRP_Json(objJSON, 'Set', 'RecipeInfo', objRecipeInfo)
|
||||||
|
SRP_Json(objRecipeInfo, 'Release')
|
||||||
|
end
|
||||||
SRP_JSON(objJSON, 'SetValue', 'OperationType', LotOperationRec<LOT_OPERATION_OPERATION_TYPE$>)
|
SRP_JSON(objJSON, 'SetValue', 'OperationType', LotOperationRec<LOT_OPERATION_OPERATION_TYPE$>)
|
||||||
//Add OPERATION Object
|
//Add OPERATION Object
|
||||||
OperationJson = Operation_Services('ConvertRecordToJSON', LotOperationRec<LOT_OPERATION_OPERATION_ID$>)
|
OperationJson = Operation_Services('ConvertRecordToJSON', LotOperationRec<LOT_OPERATION_OPERATION_ID$>)
|
||||||
@ -302,7 +293,7 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
end
|
end
|
||||||
|
|
||||||
//Add Available Met Test Record
|
//Add Available Met Test Record
|
||||||
AvailMetTestIds = Met_Test_Services('GetMetTests', LotId, LegacyLotId, '', EquipmentId, True$)
|
AvailMetTestIds = Met_Test_Services('GetMetTests', LotId, LegacyLotId, '', '', True$)
|
||||||
objAvailMetTest = ''
|
objAvailMetTest = ''
|
||||||
If SRP_Json(objAvailMetTest, 'New', 'Array') then
|
If SRP_Json(objAvailMetTest, 'New', 'Array') then
|
||||||
for each MetTestId in AvailMetTestIds using @VM
|
for each MetTestId in AvailMetTestIds using @VM
|
||||||
@ -316,8 +307,6 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
SRP_Json(objAvailMetTest, 'Release')
|
SRP_Json(objAvailMetTest, 'Release')
|
||||||
end
|
end
|
||||||
//Add in relevant recipes
|
//Add in relevant recipes
|
||||||
//OperationType = LotOperationRec<LOT_OPERATION_OPERATION_TYPE$>
|
|
||||||
//MetTestTypeRequired = LotOperationRec<LOT_OPERATION_MET_TEST_TYPE_REQUIRED$>
|
|
||||||
Recipes = ''
|
Recipes = ''
|
||||||
ShowThickRecipes = False$
|
ShowThickRecipes = False$
|
||||||
ShowResRecipes = False$
|
ShowResRecipes = False$
|
||||||
@ -340,7 +329,7 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
ShowCleanRecipes = True$
|
ShowCleanRecipes = True$
|
||||||
end
|
end
|
||||||
ProdSpecNo = XLATE('LOT', LotId, LOT_PROD_SPEC_ID$, 'X')
|
ProdSpecNo = XLATE('LOT', LotId, LOT_PROD_SPEC_ID$, 'X')
|
||||||
Recipes = PSN_Services('GetAllMetrologoyRecipes', ProdSpecNo, ShowSurfscanRecipes, ShowCleanRecipes, ShowResRecipes, ShowThickRecipes)
|
Recipes = PSN_Services('GetAllMetrologyRecipes', ProdSpecNo, ShowSurfscanRecipes, ShowCleanRecipes, ShowResRecipes, ShowThickRecipes)
|
||||||
If SRP_JSON(objRecipes, 'New', 'Array') then
|
If SRP_JSON(objRecipes, 'New', 'Array') then
|
||||||
for each Recipe in Recipes using @FM
|
for each Recipe in Recipes using @FM
|
||||||
//ToolClass : @VM : Recipe : @VM : Stage
|
//ToolClass : @VM : Recipe : @VM : Stage
|
||||||
@ -358,9 +347,8 @@ Service ConvertRecordToJson(LotOperationId)
|
|||||||
SRP_JSON(objJSON, 'Set', 'RecipeParams', objRecipes)
|
SRP_JSON(objJSON, 'Set', 'RecipeParams', objRecipes)
|
||||||
SRP_JSON(objRecipes, 'Release')
|
SRP_JSON(objRecipes, 'Release')
|
||||||
end
|
end
|
||||||
JsonString = SRP_JSON(objJSON, 'Stringify', 'Styled')
|
JsonString = SRP_JSON(objJSON, 'Stringify', 'Fast')
|
||||||
SRP_JSON(objJSON, 'Release')
|
SRP_JSON(objJSON, 'Release')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Response = JsonString
|
Response = JsonString
|
||||||
@ -370,12 +358,6 @@ end service
|
|||||||
|
|
||||||
Service StartLotOperation(LotOperationId, UserId)
|
Service StartLotOperation(LotOperationId, UserId)
|
||||||
|
|
||||||
//1. Validate that it can be moved into the operation passed in.
|
|
||||||
|
|
||||||
//2. Move in the lot
|
|
||||||
//3. Return true is move in successfully
|
|
||||||
//4. Return false if error moving in
|
|
||||||
|
|
||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
|
|
||||||
If RowExists('LOT_OPERATION', LotOperationId) then
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
@ -415,10 +397,7 @@ end service
|
|||||||
|
|
||||||
Service CompleteLotOperation(LotOperationId, UserId)
|
Service CompleteLotOperation(LotOperationId, UserId)
|
||||||
|
|
||||||
//1. Validate that the lot is moved into the operation
|
|
||||||
//2. Validate that the lot
|
|
||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
|
|
||||||
If RowExists('LOT_OPERATION', LotOperationId) then
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
If RowExists('LSL_USERS', UserId) then
|
If RowExists('LSL_USERS', UserId) then
|
||||||
//We can also add additional checks like security checks, training checks, etc here if needed.
|
//We can also add additional checks like security checks, training checks, etc here if needed.
|
||||||
@ -439,10 +418,12 @@ Service CompleteLotOperation(LotOperationId, UserId)
|
|||||||
ErrorMessage = 'Lot Operation has not finished processing and cannot be moved out.'
|
ErrorMessage = 'Lot Operation has not finished processing and cannot be moved out.'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Lot is already moved into this operation.'
|
ErrorMessage = 'Cannot complete operation because lot is not currently moved in.'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
CurrOperationId = Xlate('LOT_OPERATION', LotCurrentLotOpId, LOT_OPERATION_OPERATION_ID$, 'X')
|
||||||
|
CurrOperationDesc = Xlate('OPERATION', CurrOperationId, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
||||||
|
ErrorMessage = 'Cannot complete operation. Lot is currently at ' : CurrOperationDesc
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Invalid user passed to routine.'
|
ErrorMessage = 'Invalid user passed to routine.'
|
||||||
@ -455,7 +436,7 @@ Service CompleteLotOperation(LotOperationId, UserId)
|
|||||||
Response = True$
|
Response = True$
|
||||||
end else
|
end else
|
||||||
Response = False$
|
Response = False$
|
||||||
Error_Services('Add', 'Error in ' : Service : '. ' : ErrorMessage)
|
Error_Services('Add', ErrorMessage)
|
||||||
end
|
end
|
||||||
|
|
||||||
end service
|
end service
|
||||||
@ -472,14 +453,14 @@ Service ValidateLotOperation(LotOperationId)
|
|||||||
PackagingRequired = LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>
|
PackagingRequired = LotOperationRec<LOT_OPERATION_PACKAGING_REQUIRED$>
|
||||||
CleanRequired = LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>
|
CleanRequired = LotOperationRec<LOT_OPERATION_CLEAN_REQUIRED$>
|
||||||
WaferCountRequired = LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>
|
WaferCountRequired = LotOperationRec<LOT_OPERATION_WAFER_COUNTER_REQUIRED$>
|
||||||
|
OperationClass = XLATE('OPERATION', OperationId, OPERATION_CLASS_ID$, 'X')
|
||||||
If MetTestRequired then
|
If MetTestRequired then
|
||||||
MetTestsInSpec = True$
|
MetTestsInSpec = True$
|
||||||
AssociatedMetTestIds = LotOperationRec<LOT_OPERATION_MET_TEST_ID$>
|
AssociatedMetTestIds = LotOperationRec<LOT_OPERATION_MET_TEST_ID$>
|
||||||
If AssociatedMetTestIds NE '' then
|
If AssociatedMetTestIds NE '' then
|
||||||
for each MetTestId in AssociatedMetTestIds using @VM
|
for each MetTestId in AssociatedMetTestIds using @VM
|
||||||
MetTestOoS = Database_Services('ReadDataColumn', 'MET_TEST', MetTestId, MET_TEST.OUT_OF_SPEC$, True$, 0, False)
|
MetTestOoS = Database_Services('ReadDataColumn', 'MET_TEST', MetTestId, MET_TEST.OUT_OF_SPEC$, True$, 0, False)
|
||||||
If MetTestOoS then
|
If MetTestOoS AND OperationClass NE 'RTF' AND OperationClass NE 'RTF_DEFAULT' then
|
||||||
//ToDo Check that the met tests meet the requirements.
|
|
||||||
MetTestsInSpec = False$
|
MetTestsInSpec = False$
|
||||||
ErrorMessage = 'An associated Met test record is out of spec.'
|
ErrorMessage = 'An associated Met test record is out of spec.'
|
||||||
end
|
end
|
||||||
@ -490,14 +471,29 @@ Service ValidateLotOperation(LotOperationId)
|
|||||||
ErrorMessage = 'Met tests are required and none are assigned.'
|
ErrorMessage = 'Met tests are required and none are assigned.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
If PackagingRequired then
|
If PackagingRequired AND IsValid then
|
||||||
|
AssociatedPackagingIds = LotOperationRec<LOT_OPERATION_PACKAGING_ID$>
|
||||||
|
If AssociatedPackagingIds NE '' then
|
||||||
|
|
||||||
|
end else
|
||||||
|
IsValid = False$
|
||||||
end
|
end
|
||||||
If CleanRequired then
|
|
||||||
|
|
||||||
end
|
end
|
||||||
If WaferCountRequired then
|
If CleanRequired AND IsValid then
|
||||||
|
AssociatedCleanIds = LotOperationRec<LOT_OPERATION_CLEAN_ID$>
|
||||||
|
If AssociatedCleanIds NE '' then
|
||||||
|
IsValid = True$
|
||||||
|
end else
|
||||||
|
IsValid = False$
|
||||||
|
end
|
||||||
|
end
|
||||||
|
If WaferCountRequired AND IsValid then
|
||||||
|
AssociatedWaferCountIds = LotOperationRec<LOT_OPERATION_WAFER_COUNTER_ID$>
|
||||||
|
If AssociatedWaferCountIds NE '' then
|
||||||
|
IsValid = True$
|
||||||
|
end else
|
||||||
|
IsValid = False$
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Lot Operation not found'
|
ErrorMessage = 'Lot Operation not found'
|
||||||
@ -509,27 +505,3 @@ Service ValidateLotOperation(LotOperationId)
|
|||||||
Response = IsValid
|
Response = IsValid
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
Service ValidateFQA(LotOperationId)
|
|
||||||
|
|
||||||
Response = False$
|
|
||||||
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
|
||||||
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
|
||||||
OperationStartDtm = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
|
|
||||||
RelevantMetTests = ''
|
|
||||||
MetTests = Met_Test_Services('GetMetTestsByLotId', LotId)
|
|
||||||
For each MetTestId in MetTests using @VM
|
|
||||||
ThisMetTestRec = Database_Services('ReadDataRow', 'MET_TEST', MetTestId, True$, 0, False$)
|
|
||||||
|
|
||||||
Next MetTestId
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
Service AssociateClean(LotOperationId, CleanId, UserId)
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
Service GetFinalQAOperationJson(LotId, Stage)
|
|
||||||
|
|
||||||
end service
|
|
||||||
|
|
||||||
|
@ -46,21 +46,25 @@ Compile function Lot_Services(@Service, @Params)
|
|||||||
|
|
||||||
***********************************************************************************************************************/
|
***********************************************************************************************************************/
|
||||||
#pragma precomp SRP_PreCompiler
|
#pragma precomp SRP_PreCompiler
|
||||||
$Insert SERVICE_SETUP
|
|
||||||
$Insert APP_INSERTS
|
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, GetTickCount, Lot_Operation_Services
|
||||||
|
Declare function PSN_Services, Return_To_Fab_Services
|
||||||
|
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, Mona_Services
|
||||||
|
|
||||||
|
$insert APP_INSERTS
|
||||||
$Insert LOT_EQUATES
|
$Insert LOT_EQUATES
|
||||||
$Insert TEST_WAFER_PROD_EQUATES
|
$Insert TEST_WAFER_PROD_EQUATES
|
||||||
$Insert LOT_OPERATION_EQUATES
|
$Insert Lot_Operation_Equates
|
||||||
$Insert PRODUCT_OPERATION_EQUATES
|
$Insert PRODUCT_OPERATION_EQUATES
|
||||||
$Insert LOT_EVENT_EQUATES
|
$Insert LOT_EVENT_EQUATES
|
||||||
$Insert NOTIFICATION_EQUATES
|
$Insert NOTIFICATION_EQUATES
|
||||||
$Insert VOIDED_LOT_EQUATES
|
$Insert VOIDED_LOT_EQUATES
|
||||||
$Insert IFX_EQUATES
|
$Insert RDS_EQUATES
|
||||||
|
$Insert WO_LOG_EQUATES
|
||||||
Declare function TEST_WAFER_PROD_SERVICES, SRP_Datetime, Datetime, Database_Services, Lot_Services, Error_Services, RTI_CREATEGUID
|
$Insert PROD_VER_EQUATES
|
||||||
Declare function SRP_Array, SRP_Json, Environment_Services, Logging_Services, MemberOf, Lot_Event_Services, GetTickCount
|
$Insert OPERATION_EQUATES
|
||||||
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, Mona_Services
|
|
||||||
|
|
||||||
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Lot'
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Lot'
|
||||||
LogDate = Oconv(Date(), 'D4/')
|
LogDate = Oconv(Date(), 'D4/')
|
||||||
@ -77,7 +81,7 @@ objLotStartLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', He
|
|||||||
|
|
||||||
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotRun.csv'
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotRun.csv'
|
||||||
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Tool Id' : @FM : 'Message'
|
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Tool Id' : @FM : 'Message'
|
||||||
objLotRunLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
objRunLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
||||||
|
|
||||||
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotMove.csv'
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotMove.csv'
|
||||||
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Message'
|
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Message'
|
||||||
@ -91,8 +95,9 @@ LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' T
|
|||||||
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Operator' : @FM : 'Message'
|
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Operator' : @FM : 'Message'
|
||||||
objLotClosureLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
objLotClosureLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
||||||
|
|
||||||
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', 'SIGN_FQA', 'UNSIGN_FQA'
|
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', 'SIGN_FQA', 'UNSIGN_FQA', 'SYSTEM_COMMENT'
|
||||||
Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT'
|
Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT'
|
||||||
|
Options LEGACY_LOT_TYPES = 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT'
|
||||||
|
|
||||||
IsProd = Environment_Services('IsProd')
|
IsProd = Environment_Services('IsProd')
|
||||||
If IsProd EQ True$ then
|
If IsProd EQ True$ then
|
||||||
@ -177,16 +182,16 @@ Service GenerateNewLotId(LotType)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType=LEGACY_LOT_TYPES)
|
||||||
Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType)
|
|
||||||
|
|
||||||
StartTick = GetTickCount()
|
StartTick = GetTickCount()
|
||||||
MetricName = 'GetLotIdByLegacyLotIdAndType'
|
MetricName = 'GetLotIdByLegacyLotIdAndType'
|
||||||
|
|
||||||
ErrorMsg = ''
|
ErrorMsg = ''
|
||||||
Open 'DICT.LOT' to DictLot then
|
Open 'DICT.LOT' to DictLot then
|
||||||
|
|
||||||
SearchString = ''
|
SearchString = ''
|
||||||
SearchString := 'LEGACY_LOT_ID':@VM:LegacyLotId:@FM
|
SearchString := 'LEGACY_LOT_ID':@VM:LegacyLotId:@FM
|
||||||
SearchString := 'TYPE':@VM:LegacyLotType:@FM
|
SearchString := 'LEGACY_LOT_TYPE':@VM:LegacyLotType:@FM
|
||||||
LotIdKeys = ''
|
LotIdKeys = ''
|
||||||
Btree.Extract(SearchString, 'LOT', DictLot, LotIdKeys, '', '')
|
Btree.Extract(SearchString, 'LOT', DictLot, LotIdKeys, '', '')
|
||||||
ErrCode = ''
|
ErrCode = ''
|
||||||
@ -195,6 +200,7 @@ Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType)
|
|||||||
end else
|
end else
|
||||||
Response = LotIdKeys<1,1>
|
Response = LotIdKeys<1,1>
|
||||||
end
|
end
|
||||||
|
|
||||||
end else
|
end else
|
||||||
ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.'
|
ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.'
|
||||||
end
|
end
|
||||||
@ -202,13 +208,14 @@ Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType)
|
|||||||
EndTick = GetTickCount()
|
EndTick = GetTickCount()
|
||||||
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
||||||
|
|
||||||
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
|
If ErrorMsg NE '' then
|
||||||
|
Error_Services('Add', ErrorMsg)
|
||||||
|
end
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, VendorCode, Username, PrinterID, LotId)
|
Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, VendorCode, Username, PrinterID, LegacyLotId)
|
||||||
|
|
||||||
StartTick = GetTickCount()
|
StartTick = GetTickCount()
|
||||||
MetricName = 'CreateNewLot'
|
MetricName = 'CreateNewLot'
|
||||||
|
|
||||||
@ -216,30 +223,69 @@ Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, Vendo
|
|||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
Begin Case
|
Begin Case
|
||||||
Case LotType EQ 'RDS' OR LotType EQ 'WM_IN' OR LotType EQ 'WM_OUT' OR LotType EQ 'WO_MAT'
|
Case LotType EQ 'RDS' OR LotType EQ 'WM_IN' OR LotType EQ 'WM_OUT' OR LotType EQ 'WO_MAT'
|
||||||
|
If LegacyLotId NE '' then
|
||||||
|
LegacyLotType = LotType
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', LegacyLotId, LegacyLotType)
|
||||||
|
If LotId EQ '' then
|
||||||
|
LotType = 'PROD'
|
||||||
// Case statement for legacy lot entity types
|
// Case statement for legacy lot entity types
|
||||||
NewLotId = Lot_Services('GenerateNewLotId', LotType)
|
NewLotId = Lot_Services('GenerateNewLotId', LegacyLotType)
|
||||||
If NewLotId NE '' then
|
If NewLotId NE '' then
|
||||||
If RowExists('LOT', NewLotId) NE False$ then
|
If RowExists('LOT', NewLotId) NE False$ then
|
||||||
|
WoNo = ''
|
||||||
|
EpiPartNo = ''
|
||||||
|
ProdVerNo = ''
|
||||||
|
Begin Case
|
||||||
|
Case LegacyLotType EQ 'RDS'
|
||||||
|
WoNo = XLATE('RDS', LegacyLotId, RDS_WO$, 'X')
|
||||||
|
Case LegacyLotType EQ 'WM_IN' OR LegacyLotType EQ 'WM_OUT' OR LegacyLotType EQ 'WO_MAT'
|
||||||
|
WoNo = Field(LegacyLotId, '*', 1)
|
||||||
|
End Case
|
||||||
|
|
||||||
|
ProdVerNo = XLATE('WO_LOG', WoNo, WO_LOG_PROD_VER_NO$, 'X')
|
||||||
|
EpiPartNo = XLATE('WO_LOG', WoNo, WO_LOG_EPI_PART_NO$, 'X')
|
||||||
|
ProdId = EpiPartNo : '*' : ProdVerNo
|
||||||
|
ProdSpecId = XLATE('WO_LOG', WoNo, WO_LOG_PROD_SPEC_ID$, 'X')
|
||||||
|
If ProdSpecId EQ '' then
|
||||||
|
Begin Case
|
||||||
|
Case LegacyLotType EQ 'RDS'
|
||||||
|
ProdSpecId = XLATE('RDS', LegacyLotId, RDS_PROD_SPEC_ID$, 'X')
|
||||||
|
Case Otherwise$
|
||||||
|
ProdSpecId = XLATE('PROD_VER', ProdVerNo, PROD_VER_PROC_STEP_PSN$, 'X')
|
||||||
|
End Case
|
||||||
|
end
|
||||||
|
If Not(RowExists('PRODUCT', ProdId)) then ProdId = ''
|
||||||
LotRec = ''
|
LotRec = ''
|
||||||
LotRec<LOT_TYPE$> = LotType
|
LotRec<LOT_TYPE$> = 'PROD'
|
||||||
LotRec<LOT_PROD_ID$> = ''
|
LotRec<LOT_PROD_ID$> = ProdId
|
||||||
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
|
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
|
||||||
LotRec<LOT_WAFER_QTY$> = LotQty
|
LotRec<LOT_WAFER_QTY$> = LotQty
|
||||||
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
|
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
|
||||||
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
|
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
|
||||||
LotRec<LOT_VENDOR_CODE$> = VendorCode
|
LotRec<LOT_VENDOR_CODE$> = VendorCode
|
||||||
LotRec<LOT_LEGACY_LOT_ID$> = LotId
|
LotRec<LOT_LEGACY_LOT_ID$> = LegacyLotId
|
||||||
|
LotRec<LOT_LEGACY_LOT_TYPE$> = LegacyLotType
|
||||||
|
LotRec<LOT_WO_LOG_ID$> = WONo
|
||||||
|
LotRec<LOT_PROD_SPEC_ID$> = ProdSpecId
|
||||||
|
LotRec<LOT_EPI_PART_NO$> = EpiPartNo
|
||||||
|
LotRec<LOT_PROD_VER_NO$> = ProdVerNo
|
||||||
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec)
|
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec)
|
||||||
If Error_Services('HasError') then
|
If Error_Services('NoError') then
|
||||||
ErrorMessage = 'Error in ':Service:' service. ':Error_Services('GetMessage')
|
|
||||||
end else
|
|
||||||
CreatedLotNumber = NewLotId
|
CreatedLotNumber = NewLotId
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error in ':Service:' service. ':Error_Services('GetMessage')
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error in ':Service:' service. LOT record "':NewLotId:'" already exists.'
|
ErrorMessage = 'Error in ':Service:' service. Failed to generate new LOT id. LOT record "':NewLotId:'" already exists.'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error in ':Service:' service. No lot ID passed in.'
|
ErrorMessage = 'Error in ':Service:' service. Failed to generate new LOT id.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error in ':Service:' service. Lot Id ':LotId:' already exists for LegacyLotId ':LegacyLotId:'.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error in ':Service:' service. Null LegacyLotId passed in.'
|
||||||
end
|
end
|
||||||
Case LotType EQ 'TW'
|
Case LotType EQ 'TW'
|
||||||
If ProdName NE '' then
|
If ProdName NE '' then
|
||||||
@ -536,7 +582,6 @@ end service
|
|||||||
|
|
||||||
|
|
||||||
Service CreateInitialLotOperationRecords(LotId)
|
Service CreateInitialLotOperationRecords(LotId)
|
||||||
|
|
||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
If LotId NE '' then
|
If LotId NE '' then
|
||||||
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
|
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
|
||||||
@ -545,9 +590,11 @@ Service CreateInitialLotOperationRecords(LotId)
|
|||||||
ThisInitialProdOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId, LotType)
|
ThisInitialProdOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId, LotType)
|
||||||
If Error_Services('NoError') AND ThisInitialProdOperations NE '' then
|
If Error_Services('NoError') AND ThisInitialProdOperations NE '' then
|
||||||
For each ProdOperation in ThisInitialProdOperations using @VM
|
For each ProdOperation in ThisInitialProdOperations using @VM
|
||||||
|
|
||||||
ProdOperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperation)
|
ProdOperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperation)
|
||||||
OperationID = ProdOperationRec<PRODUCT_OPERATION_OPERATION_ID$>
|
OperationID = ProdOperationRec<PRODUCT_OPERATION_OPERATION_ID$>
|
||||||
OperationSequence = ProdOperationRec<PRODUCT_OPERATION_OPERATION_SEQUENCE$>
|
OperationSequence = ProdOperationRec<PRODUCT_OPERATION_OPERATION_SEQUENCE$>
|
||||||
|
|
||||||
LotOperationRecID = Rti_Createguid()
|
LotOperationRecID = Rti_Createguid()
|
||||||
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
|
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
|
||||||
LotOperationRec = ''
|
LotOperationRec = ''
|
||||||
@ -556,22 +603,25 @@ Service CreateInitialLotOperationRecords(LotId)
|
|||||||
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = OperationSequence
|
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = OperationSequence
|
||||||
LotOperationRec<LOT_OPERATION_REWORK$> = False$
|
LotOperationRec<LOT_OPERATION_REWORK$> = False$
|
||||||
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
|
||||||
TestRec = Database_Services('ReadDataRow', 'LOT', LotId)
|
If Error_Services('HasError') then
|
||||||
|
ErrorMessage = 'Error Writing Lot Operation Record.'
|
||||||
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error in ':Service:' service. Lot Operation already existed, cannot overwrite.'
|
ErrorMessage = 'Lot Operation already existed, cannot overwrite'
|
||||||
end
|
end
|
||||||
Next Operation
|
Next Operation
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error in ':Service:' service. Error getting prescribed operations for lot# ' : LotId
|
ErrorMessage = 'Error getting prescribed operations for lot# ' : LotId
|
||||||
end
|
end
|
||||||
|
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error in ':Service:' service. Null LotID passed into service.'
|
ErrorMessage = 'Lot ID was null'
|
||||||
|
end
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
end
|
end
|
||||||
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
// Returns a @FM delimited list of operations in sequence
|
// Returns a @FM delimited list of operations in sequence
|
||||||
Service GetLotOperationSequence(LotId)
|
Service GetLotOperationSequence(LotId)
|
||||||
|
|
||||||
@ -604,9 +654,10 @@ end service
|
|||||||
|
|
||||||
Service GetLotCurrOperationId(LotId)
|
Service GetLotCurrOperationId(LotId)
|
||||||
|
|
||||||
|
ErrorMsg = ''
|
||||||
StartTick = GetTickCount()
|
StartTick = GetTickCount()
|
||||||
MetricName = 'GetLotCurrOperationId'
|
MetricName = 'GetLotCurrOperationId'
|
||||||
ErrorMsg = ''
|
|
||||||
CurrOperation = ''
|
CurrOperation = ''
|
||||||
If LotID NE '' then
|
If LotID NE '' then
|
||||||
// Get them in sequence first
|
// Get them in sequence first
|
||||||
@ -1025,16 +1076,27 @@ Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
|
|||||||
|
|
||||||
ErrorMessage = ''
|
ErrorMessage = ''
|
||||||
JsonString = ''
|
JsonString = ''
|
||||||
If FullObject EQ '' then FullObject = True$
|
If FullObject EQ '' then
|
||||||
|
FullObject = True$
|
||||||
|
end
|
||||||
If RowExists('LOT', LotId) then
|
If RowExists('LOT', LotId) then
|
||||||
objJSON = ''
|
objJSON = ''
|
||||||
If SRP_JSON(objJSON, 'New', 'Object') then
|
If SRP_JSON(objJSON, 'New', 'Object') then
|
||||||
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
|
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
If SRP_JSON(objLot, 'New', 'Object') then
|
If SRP_JSON(objLot, 'New', 'Object') then
|
||||||
|
|
||||||
SRP_JSON(objLot, 'SetValue', 'LotId', LotId)
|
SRP_JSON(objLot, 'SetValue', 'LotId', LotId)
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'LegacyLotId', LotRec<LOT_LEGACY_LOT_ID$>, 'String')
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'LegacyLotType', LotRec<LOT_LEGACY_LOT_TYPE$>, 'String')
|
||||||
|
CanUserModifyLot = Lot_Services('CanUserModifyLot', CurrUser)
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'CanUserModifyLot', CanUserModifyLot, 'Boolean')
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'WorkOrderNo', LotRec<LOT_WO_LOG_ID$>, 'String')
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'EpiPartNo', LotRec<LOT_EPI_PART_NO$>, 'String')
|
||||||
SRP_JSON(objLot, 'SetValue', 'Type', LotRec<LOT_TYPE$>)
|
SRP_JSON(objLot, 'SetValue', 'Type', LotRec<LOT_TYPE$>)
|
||||||
SRP_JSON(objLot, 'SetValue', 'ProdId', LotRec<LOT_PROD_ID$>)
|
SRP_JSON(objLot, 'SetValue', 'ProdId', LotRec<LOT_PROD_ID$>)
|
||||||
|
ProdSpecNo = LotRec<LOT_PROD_SPEC_ID$>
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'ProdSpecNo', ProdSpecNo, 'String')
|
||||||
Begin Case
|
Begin Case
|
||||||
Case LotRec<LOT_TYPE$> = 'TW'
|
Case LotRec<LOT_TYPE$> = 'TW'
|
||||||
ProdName = XLATE('TEST_WAFER_PROD', LotRec<LOT_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
|
ProdName = XLATE('TEST_WAFER_PROD', LotRec<LOT_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
|
||||||
@ -1047,13 +1109,22 @@ Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
|
|||||||
SRP_JSON(objLot, 'SetValue', 'VendorPartNo', LotRec<LOT_VENDOR_PART_NO$>)
|
SRP_JSON(objLot, 'SetValue', 'VendorPartNo', LotRec<LOT_VENDOR_PART_NO$>)
|
||||||
SRP_JSON(objLot, 'SetValue', 'VendorLotNo', LotRec<LOT_VENDOR_LOT_NO$>)
|
SRP_JSON(objLot, 'SetValue', 'VendorLotNo', LotRec<LOT_VENDOR_LOT_NO$>)
|
||||||
SRP_JSON(objLot, 'SetValue', 'Vendor', LotRec<LOT_VENDOR_CODE$>)
|
SRP_JSON(objLot, 'SetValue', 'Vendor', LotRec<LOT_VENDOR_CODE$>)
|
||||||
CurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
|
CurrLotOperationId = Lot_Services('GetLotCurrOperationId', LotId)
|
||||||
CurrOperation = XLATE('LOT_OPERATION', CurrOperation, LOT_OPERATION_OPERATION_ID$, 'X')
|
CurrOperation = XLATE('LOT_OPERATION', CurrLotOperationId, LOT_OPERATION_OPERATION_ID$, 'X')
|
||||||
|
CurrOperationDesc = XLATE('OPERATION', CurrOperation, OPERATION_OPERATION_DESCRIPTION$, 'X')
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'CurrLotOperationId', CurrLotOperationId)
|
||||||
SRP_JSON(objLot, 'SetValue', 'CurrOperation', CurrOperation)
|
SRP_JSON(objLot, 'SetValue', 'CurrOperation', CurrOperation)
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'CurrOperationDesc', CurrOperationDesc, 'String')
|
||||||
MostRecentEventId = LotRec<LOT_MOST_RECENT_LOT_EVENT_ID$>
|
MostRecentEventId = LotRec<LOT_MOST_RECENT_LOT_EVENT_ID$>
|
||||||
MostRecentEventDtmIConv = Xlate('LOT_EVENT', MostRecentEventId, LOT_EVENT_EVENT_DATETIME$, 'X')
|
MostRecentEventDtmIConv = Xlate('LOT_EVENT', MostRecentEventId, LOT_EVENT_EVENT_DATETIME$, 'X')
|
||||||
MostRecentEventDtmOConv = OConv(MostRecentEventDtmIConv, 'DT')
|
MostRecentEventDtmOConv = OConv(MostRecentEventDtmIConv, 'DT')
|
||||||
SRP_JSON(objLot, 'SetValue', 'MostRecentEventDateTime', MostRecentEventDtmOConv)
|
SRP_JSON(objLot, 'SetValue', 'MostRecentEventDateTime', MostRecentEventDtmOConv)
|
||||||
|
if LotRec<LOT_LEGACY_LOT_ID$> NE '' then
|
||||||
|
ActiveRTFId = Return_To_Fab_Services('GetOpenReturnToFabRecordIdByCassId', LotRec<LOT_LEGACY_LOT_ID$>)
|
||||||
|
end else
|
||||||
|
ActiveRTFId = Return_To_Fab_Services('GetOpenReturnToFabRecordIdByCassId', LotId)
|
||||||
|
end
|
||||||
|
SRP_JSON(objLot, 'SetValue', 'ActiveRTFId', ActiveRTFId, 'String')
|
||||||
If FullObject then
|
If FullObject then
|
||||||
//Events Array
|
//Events Array
|
||||||
EventsArrayJson = ''
|
EventsArrayJson = ''
|
||||||
@ -1085,40 +1156,41 @@ Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
|
|||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error Creating Events JSON Array'
|
ErrorMessage = 'Error Creating Events JSON Array'
|
||||||
end
|
end
|
||||||
// Operations Array
|
|
||||||
OperationsArrayJson = ''
|
OperationsArrayJson = ''
|
||||||
If SRP_Json(OperationsArrayJson, 'New', 'Array') then
|
If SRP_Json(OperationsArrayJson, 'New', 'Array') then
|
||||||
LotOperationKeys = Lot_Services('GetLotOperationSequence', LotId)
|
LotOperationKeys = Lot_Services('GetLotOperationSequence', LotId)
|
||||||
for each LotOperationKey in LotOperationKeys using @FM
|
for each LotOperationKey in LotOperationKeys using @FM
|
||||||
objOperation = ''
|
ThisLotOperationJsonString = Lot_Operation_Services('ConvertRecordToJson', LotOperationKey)
|
||||||
OperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationKey)
|
If SRP_Json(objLotOperation, 'PARSE', ThisLotOperationJsonString) EQ '' then
|
||||||
If SRP_Json(objOperation, 'New', 'Object') then
|
SRP_Json(OperationsArrayJson, 'Add', objLotOperation)
|
||||||
SRP_JSON(objOperation, 'SetValue', 'LotOperationId', LotOperationKey)
|
SRP_Json(objLotOperation, 'Release')
|
||||||
SRP_JSON(objOperation, 'SetValue', 'LotId', OperationRec<LOT_OPERATION_LOT_ID$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'OperationId', OperationRec<LOT_OPERATION_OPERATION_ID$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'DatetimeIn', OConv(OperationRec<LOT_OPERATION_DATETIME_IN$>, 'DT'))
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'DatetimeOut', Oconv(OperationRec<LOT_OPERATION_DATETIME_OUT$>, 'DT'))
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'EquipmentId', OperationRec<LOT_OPERATION_EQUIPMENT_ID$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'WaferInQty', OperationRec<LOT_OPERATION_WAFER_IN_QTY$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'WaferOutQty', OperationRec<LOT_OPERATION_WAFER_OUT_QTY$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'OperatorInId', OperationRec<LOT_OPERATION_OPERATOR_IN_ID$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'OperatorOutId', OperationRec<LOT_OPERATION_OPERATOR_OUT_ID$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'OperationSequence', OperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'Rework', OperationRec<LOT_OPERATION_REWORK$>)
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'DatetimeStart', OConv(OperationRec<LOT_OPERATION_DATETIME_START$>, 'DT'))
|
|
||||||
SRP_JSON(objOperation, 'SetValue', 'DatetimeStop', OConv(OperationRec<LOT_OPERATION_DATETIME_STOP$>, 'DT'))
|
|
||||||
SRP_JSON(OperationsArrayJson, 'Add', objOperation)
|
|
||||||
SRP_JSON(objOperation, 'Release')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Next LotOperationKey
|
Next LotOperationKey
|
||||||
SRP_JSON(objLot, 'Set', 'LotOperations', OperationsArrayJson)
|
SRP_JSON(objLot, 'Set', 'LotOperations', OperationsArrayJson)
|
||||||
SRP_JSON(OperationsArrayJson, 'Release')
|
SRP_JSON(OperationsArrayJson, 'Release')
|
||||||
|
Recipes = PSN_Services('GetAllMetrologyRecipes', ProdSpecNo, True$, True$, True$, True$)
|
||||||
|
//Add in all lot recipe parameters
|
||||||
|
If SRP_JSON(objRecipes, 'New', 'Array') then
|
||||||
|
for each Recipe in Recipes using @FM
|
||||||
|
//ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
ToolClass = Recipe<1,1>
|
||||||
|
RecipeName = Recipe<1,2>
|
||||||
|
Stage = Recipe<1,3>
|
||||||
|
If SRP_JSON(objRecipe, 'New', 'Object') then
|
||||||
|
SRP_JSON(objRecipe, 'SetValue', 'ToolClass', ToolClass, 'String')
|
||||||
|
SRP_JSON(objRecipe, 'SetValue', 'RecipeName', RecipeName, 'String')
|
||||||
|
SRP_JSON(objRecipe, 'SetValue', 'StageName', Stage, 'String')
|
||||||
|
SRP_JSON(objRecipes, 'Add', objRecipe)
|
||||||
|
SRP_JSON(objRecipe, 'Release')
|
||||||
|
end
|
||||||
|
Next Recipe
|
||||||
|
SRP_JSON(objLot, 'Set', 'AllRecipes', objRecipes)
|
||||||
|
SRP_JSON(objRecipes, 'Release')
|
||||||
|
end
|
||||||
end else
|
end else
|
||||||
ErrorMessage = 'Error Creating Operations JSON Array'
|
ErrorMessage = 'Error Creating Operations JSON Array'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SRP_JSON(objJSON, 'Set', 'Lot', objLot)
|
SRP_JSON(objJSON, 'Set', 'Lot', objLot)
|
||||||
SRP_JSON(objLot, 'Release')
|
SRP_JSON(objLot, 'Release')
|
||||||
end else
|
end else
|
||||||
@ -1135,12 +1207,10 @@ Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
|
|||||||
end else
|
end else
|
||||||
ErrorMessage = 'Invalid or null lot number passed to routine.'
|
ErrorMessage = 'Invalid or null lot number passed to routine.'
|
||||||
end
|
end
|
||||||
|
If ErrorMessage NE '' then
|
||||||
If ErrorMessage EQ '' then
|
|
||||||
Response = JsonString
|
|
||||||
end else
|
|
||||||
Error_Services('Add', ErrorMessage)
|
Error_Services('Add', ErrorMessage)
|
||||||
end
|
end
|
||||||
|
Response = JsonString
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
@ -1339,7 +1409,7 @@ Service ReduceLotWaferCount(LotId, ReductionQty, OperatorId)
|
|||||||
// Write Lot Event
|
// Write Lot Event
|
||||||
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REDUCE_WAFER_QTY', 'Reduced wafer count by ' : ReductionQty, '', OperatorId, False$, '')
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REDUCE_WAFER_QTY', 'Reduced wafer count by ' : ReductionQty, '', OperatorId, False$, '')
|
||||||
if LotNewWfrQty EQ 0 AND LotType EQ 'TW' then
|
if LotNewWfrQty EQ 0 AND LotType EQ 'TW' then
|
||||||
ServiceParms = 'AutoCloseTestWaferLot' : SD$ : LotId : SD$ : 'SYSTEM'
|
ServiceParms = 'AutoCloseTestWaferLot' : @VM : LotId : @VM : 'SYSTEM'
|
||||||
Service_Services('PostProcedure', 'LOT_SERVICES', ServiceParms)
|
Service_Services('PostProcedure', 'LOT_SERVICES', ServiceParms)
|
||||||
If Error_Services('HasError') then
|
If Error_Services('HasError') then
|
||||||
Recipients = Xlate('NOTIFICATION', 'FI_SUPPORT', NOTIFICATION_USER_ID$, 'X')
|
Recipients = Xlate('NOTIFICATION', 'FI_SUPPORT', NOTIFICATION_USER_ID$, 'X')
|
||||||
@ -1510,11 +1580,37 @@ Service CreateNewVoidedLotRecord(LotId, LegacyLotId, LotType=LOT_TYPES, Username
|
|||||||
EndTick = GetTickCount()
|
EndTick = GetTickCount()
|
||||||
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
||||||
|
|
||||||
|
|
||||||
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
|
||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
Service CanUserModifyLot(UserId)
|
||||||
|
|
||||||
|
Begin Case
|
||||||
|
|
||||||
|
Case MemberOf(UserId, 'OI_ADMIN')
|
||||||
|
Response = true$
|
||||||
|
Case MemberOf(UserId, 'ENGINEERING')
|
||||||
|
Response = true$
|
||||||
|
Case MemberOf(UserId, 'ENG_TECH')
|
||||||
|
Response = true$
|
||||||
|
Case MemberOf(UserId, 'SUPERVISOR')
|
||||||
|
Response = true$
|
||||||
|
Case MemberOf(UserId, 'LEAD')
|
||||||
|
Response = true$
|
||||||
|
Case UserId EQ 'SYSTEM'
|
||||||
|
Response = true$
|
||||||
|
Case Otherwise$
|
||||||
|
Response = false$
|
||||||
|
|
||||||
|
End Case
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// Internal GoSubs
|
// Internal GoSubs
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,4 +132,3 @@ CreateHALItem:
|
|||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -11,6 +11,19 @@ Function Metrology_Services(@Service, @Params)
|
|||||||
Notes : The generic parameters should contain all the necessary information to process the services. Often
|
Notes : The generic parameters should contain all the necessary information to process the services. Often
|
||||||
this will be information like the data Record and Key ID.
|
this will be information like the data Record and Key ID.
|
||||||
|
|
||||||
|
Surface Scan Tool Types:
|
||||||
|
Tencor
|
||||||
|
SP1
|
||||||
|
|
||||||
|
Thickness tool types:
|
||||||
|
Biorad
|
||||||
|
Stratus
|
||||||
|
|
||||||
|
Resistivity (HgCV) Tool Types:
|
||||||
|
CDE
|
||||||
|
4PP
|
||||||
|
SRP
|
||||||
|
|
||||||
Parameters :
|
Parameters :
|
||||||
Service [in] -- Name of the service being requested
|
Service [in] -- Name of the service being requested
|
||||||
Param1-10 [in/out] -- Additional request parameter holders
|
Param1-10 [in/out] -- Additional request parameter holders
|
||||||
@ -70,7 +83,7 @@ $Insert RLIST_EQUATES
|
|||||||
$Insert WM_OUT_EQUATES
|
$Insert WM_OUT_EQUATES
|
||||||
$Insert IQS_VIOL_DATA_EQUATES
|
$Insert IQS_VIOL_DATA_EQUATES
|
||||||
|
|
||||||
Common /MetrologyServices/ MachineType@, RDSNo@
|
Common /MetrologyServices/ MachineType@, LegacyLotId@
|
||||||
|
|
||||||
Equ RETRY_ATTEMPTS$ TO 3
|
Equ RETRY_ATTEMPTS$ TO 3
|
||||||
Equ MINUTES_UNTIL_RETRY$ TO 3
|
Equ MINUTES_UNTIL_RETRY$ TO 3
|
||||||
@ -93,12 +106,12 @@ Equ Comma$ to ','
|
|||||||
Declare subroutine SRP_Stopwatch, Error_Services, obj_Tables, Metrology_Services, obj_RDS_Test, SRP_JSON
|
Declare subroutine SRP_Stopwatch, Error_Services, obj_Tables, Metrology_Services, obj_RDS_Test, SRP_JSON
|
||||||
Declare subroutine RTI_Set_Debugger, Database_Services, Btree.Extract, Set_Status, QA_Services, obj_Notes
|
Declare subroutine RTI_Set_Debugger, Database_Services, Btree.Extract, Set_Status, QA_Services, obj_Notes
|
||||||
Declare subroutine Logging_Services, SRP_Send_Mail, SRP_Run_Command, PM_Services, Httpclient_Services
|
Declare subroutine Logging_Services, SRP_Send_Mail, SRP_Run_Command, PM_Services, Httpclient_Services
|
||||||
Declare subroutine Tool_Services, Mona_Services, Reactor_Services
|
Declare subroutine Tool_Services, Mona_Services, Reactor_Services, Met_Test_Services, Met_Test_Services
|
||||||
Declare function SRP_Sort_Array, Metrology_Services, obj_RDS_Test, obj_Test_Point_Map, Database_Services, UCase
|
Declare function SRP_Sort_Array, Metrology_Services, obj_RDS_Test, obj_Test_Point_Map, Database_Services, UCase
|
||||||
Declare function Work_Order_Services, SRP_JSON, Logging_Services, Environment_Services, SRP_Trim, Min, Max
|
Declare function Work_Order_Services, SRP_JSON, Logging_Services, Environment_Services, SRP_Trim, Min, Max
|
||||||
Declare function QA_Services, SRP_Join_Arrays, Get_Status, Obj_Clean_Insp, Datetime, SRP_Datetime
|
Declare function QA_Services, SRP_Join_Arrays, Get_Status, Obj_Clean_Insp, Datetime, SRP_Datetime
|
||||||
Declare function Httpclient_Services, PM_Services, Signature_Services, SRP_Array, Math_Services
|
Declare function Httpclient_Services, PM_Services, Signature_Services, SRP_Array, Math_Services
|
||||||
Declare function Tool_Class_Services, obj_wo_mat
|
Declare function Tool_Class_Services, obj_Wo_Mat, Met_Test_Services, Lot_Services
|
||||||
Declare function SRP_String
|
Declare function SRP_String
|
||||||
|
|
||||||
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Metrology'
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Metrology'
|
||||||
@ -163,6 +176,12 @@ end
|
|||||||
Return Response else ''
|
Return Response else ''
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Service Parameter Options
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
Options MACHINE_TYPES = 'Tencor', 'HgCV', 'CDE', 'Biorad', 'Stratus', 'SP1', 'SPV', 'SRP'
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Services
|
// Services
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -387,7 +406,7 @@ end service
|
|||||||
//
|
//
|
||||||
// Looks for available Metrology files that are ready to be imported into the MES system.
|
// Looks for available Metrology files that are ready to be imported into the MES system.
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
Service ImportMetrologyFiles(Machine)
|
Service ImportMetrologyFiles(Machine=MACHINE_TYPES)
|
||||||
|
|
||||||
If Machine NE '' then
|
If Machine NE '' then
|
||||||
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
|
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
|
||||||
@ -743,7 +762,7 @@ Service ImportStratusData(RunData, ResourceID, PSN)
|
|||||||
ThickAvg = RunData<12>
|
ThickAvg = RunData<12>
|
||||||
Positions = ''
|
Positions = ''
|
||||||
DataPoints = ''
|
DataPoints = ''
|
||||||
|
ToolClass = Xlate('TOOL', Tool, 'CLASS', 'X')
|
||||||
Loop
|
Loop
|
||||||
Position = Trim(RunData<FieldPos>)
|
Position = Trim(RunData<FieldPos>)
|
||||||
DataPoint = Trim(RunData<FieldPos + Offset>)
|
DataPoint = Trim(RunData<FieldPos + Offset>)
|
||||||
@ -767,17 +786,69 @@ Service ImportStratusData(RunData, ResourceID, PSN)
|
|||||||
Case RowExists('WM_OUT', Cassette)
|
Case RowExists('WM_OUT', Cassette)
|
||||||
WorkOrderNo = Field(Cassette, '*', 1)
|
WorkOrderNo = Field(Cassette, '*', 1)
|
||||||
CassNo = Field(Cassette, '*', 3)
|
CassNo = Field(Cassette, '*', 3)
|
||||||
RDSNo@ = Cassette ; // This is used for logging purposes.
|
LegacyLotId@ = Cassette
|
||||||
IsEpiPro = true$
|
IsEpiPro = True$
|
||||||
|
LegacyLotType = 'WM_OUT'
|
||||||
Case RowExists('RDS', RDSNo)
|
Case RowExists('RDS', RDSNo)
|
||||||
WorkOrderNo = Xlate('RDS', RDSNo, 'WO', 'X')
|
WorkOrderNo = Xlate('RDS', RDSNo, 'WO', 'X')
|
||||||
CassNo = Xlate('RDS', RDSNo, 'CASS_NO', 'X')
|
CassNo = Xlate('RDS', RDSNo, 'CASS_NO', 'X')
|
||||||
RDSNo@ = RDSNo ; // This is used for logging purposes.
|
LegacyLotId@ = RDSNo
|
||||||
|
LegacyLotType = 'RDS'
|
||||||
Case Otherwise$
|
Case Otherwise$
|
||||||
Error_Services('Add', 'Unrecognized cassette ID ':Cassette:'.')
|
Error_Services('Add', 'Unrecognized cassette ID ':Cassette:'.')
|
||||||
End Case
|
End Case
|
||||||
|
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', LegacyLotId@, LegacyLotType)
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
If Datapoints NE '' then
|
||||||
|
Done = False$
|
||||||
|
For each DataPoint in DataPoints using @VM setting vPos
|
||||||
|
Slot = Positions<0, vPos>
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, LegacyLotId@, ToolClass, Recipe)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, Tool)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestSlot', MetTestId, Slot)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, '', DataPoint)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Done = True$
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
Next DataPoint
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. No DataPoints to import.'
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// Update WO_MAT record
|
// Update WO_MAT record
|
||||||
StdDev = ''
|
StdDev = ''
|
||||||
@ -804,15 +875,15 @@ Service ImportStratusData(RunData, ResourceID, PSN)
|
|||||||
end
|
end
|
||||||
Database_Services('WriteDataRow', 'WO_MAT', WOMatKey, WOMatRec, True$, False$, True$)
|
Database_Services('WriteDataRow', 'WO_MAT', WOMatKey, WOMatRec, True$, False$, True$)
|
||||||
If Error_Services('HasError') then
|
If Error_Services('HasError') then
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
// Update the WM_OUT record for EpiPro
|
// Update the WM_OUT record for EpiPro
|
||||||
If IsEpiPro then
|
If IsEpiPro then
|
||||||
NumVals = 0
|
NumVals = 0
|
||||||
WMORec = Database_Services('ReadDataRow', 'WM_OUT', RDSNo@)
|
WMORec = Database_Services('ReadDataRow', 'WM_OUT', LegacyLotId@)
|
||||||
For each Wafer in Positions using @VM setting dPos
|
For each Wafer in Positions using @VM setting dPos
|
||||||
If Wafer NE '' then
|
If Wafer NE '' then
|
||||||
WMORec<WM_OUT_MU_WAFER_THK_RESULT$, Wafer> = DataPoints<0, dPos>
|
WMORec<WM_OUT_MU_WAFER_THK_RESULT$, Wafer> = DataPoints<0, dPos>
|
||||||
@ -830,7 +901,7 @@ Service ImportStratusData(RunData, ResourceID, PSN)
|
|||||||
StdDev = Math_Services('GetStdDev', Vals, StdDevType)
|
StdDev = Math_Services('GetStdDev', Vals, StdDevType)
|
||||||
StdDev = OConv(IConv(StdDev, 'MD3'), 'MD3')
|
StdDev = OConv(IConv(StdDev, 'MD3'), 'MD3')
|
||||||
end
|
end
|
||||||
Database_Services('WriteDataRow', 'WM_OUT', RDSNo@, WMORec, True$, False$, True$)
|
Database_Services('WriteDataRow', 'WM_OUT', LegacyLotId@, WMORec, True$, False$, True$)
|
||||||
end
|
end
|
||||||
|
|
||||||
// Update WO_MAT_QA record
|
// Update WO_MAT_QA record
|
||||||
@ -882,15 +953,15 @@ Service ImportStratusData(RunData, ResourceID, PSN)
|
|||||||
Next Profile
|
Next Profile
|
||||||
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAID, WOMatQARec, True$, False$, True$)
|
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAID, WOMatQARec, True$, False$, True$)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID000', Service : ' : Success.')
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID000', Service : ' : Success.')
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
|
|
||||||
end service
|
end service
|
||||||
@ -1037,6 +1108,56 @@ Service ImportBioRadData(RunData, ResourceID, IsViewerFile, PSN, FileName)
|
|||||||
Swap ' AM' with 'AM' in Timestamp
|
Swap ' AM' with 'AM' in Timestamp
|
||||||
Swap ' PM' with 'PM' in Timestamp
|
Swap ' PM' with 'PM' in Timestamp
|
||||||
Timestamp = IConv(Timestamp,'DT')
|
Timestamp = IConv(Timestamp,'DT')
|
||||||
|
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS')
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
ToolId = Field(Filename, ' ', 2, 1)
|
||||||
|
ToolClass = Xlate('TOOL', ToolId, 'CLASS', 'X')
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, ToolClass, ScanRecipe, '', RunDataLayer, RunDataZone, '')
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ToolId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If RawDataPoints NE '' then
|
||||||
|
Done = False$
|
||||||
|
For each DataPoint in RawDataPoints using @VM setting vPos
|
||||||
|
Position = Positions<0, vPos>
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, Position, DataPoint)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Done = True$
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
Until Done
|
||||||
|
Next DataPoint
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. No DataPoints to import.'
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
||||||
NumDataPoints = DCount(DataPoints, @VM)
|
NumDataPoints = DCount(DataPoints, @VM)
|
||||||
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
||||||
@ -1255,7 +1376,6 @@ Service ImportBioRadData(RunData, ResourceID, IsViewerFile, PSN, FileName)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
Service ImportCDEQualData(RunData, ResourceID, PSN)
|
Service ImportCDEQualData(RunData, ResourceID, PSN)
|
||||||
|
|
||||||
Machine = 'CDE'
|
Machine = 'CDE'
|
||||||
@ -1288,7 +1408,6 @@ Service ImportCDEQualData(RunData, ResourceID, PSN)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
Service ImportCDEData(RunData, ResourceID, IsViewerFile, PSN)
|
Service ImportCDEData(RunData, ResourceID, IsViewerFile, PSN)
|
||||||
|
|
||||||
Machine = 'CDE'
|
Machine = 'CDE'
|
||||||
@ -1381,6 +1500,57 @@ Service ImportCDEData(RunData, ResourceID, IsViewerFile, PSN)
|
|||||||
Swap ' PM' with 'PM' in Timestamp
|
Swap ' PM' with 'PM' in Timestamp
|
||||||
Timestamp = IConv(Timestamp,'DT')
|
Timestamp = IConv(Timestamp,'DT')
|
||||||
|
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS')
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
ToolRecipe = Trim(Field(ScanRecipe, '\', 1, 1))
|
||||||
|
ToolPattern = Trim(Field(ScanRecipe, '\', 2, 1))
|
||||||
|
ToolClass = Xlate('TOOL', ToolId, 'CLASS', 'X')
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, ToolClass, ToolRecipe, ToolPattern, RunDataLayer, RunDataZone)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ToolId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If RawDatapoints NE '' then
|
||||||
|
Done = False$
|
||||||
|
TempDataPoints = OConv(IConv(RawDatapoints, 'MD':Decimals), 'MD':Decimals)
|
||||||
|
For each DataPoint in TempDataPoints using @VM setting vPos
|
||||||
|
Position = Positions<0, vPos>
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, Position, DataPoint)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Done = True$
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
Until Done
|
||||||
|
Next DataPoint
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. No DataPoints to import.'
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
||||||
NumDataPoints = DCount(DataPoints, @VM)
|
NumDataPoints = DCount(DataPoints, @VM)
|
||||||
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
||||||
@ -1549,7 +1719,7 @@ Service ImportHgCVData(RunData, ResourceID, IsViewerFile, PSN)
|
|||||||
DataIndex = RDS_TEST_READ_HGCV1_RES$
|
DataIndex = RDS_TEST_READ_HGCV1_RES$
|
||||||
DTMIndex = RDS_TEST_TEST_RUN_HGCV_DTM$
|
DTMIndex = RDS_TEST_TEST_RUN_HGCV_DTM$
|
||||||
Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : ' : 'Beginning ImportHgCVData')
|
Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : ' : 'Beginning ImportHgCVData')
|
||||||
RDSNo@ = RDSKeyID
|
LegacyLotId@ = RDSKeyID
|
||||||
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID)
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
WorkOrderNo = RDSRec<RDS_WO$>
|
WorkOrderNo = RDSRec<RDS_WO$>
|
||||||
@ -1606,23 +1776,83 @@ Service ImportHgCVData(RunData, ResourceID, IsViewerFile, PSN)
|
|||||||
Positions = ''
|
Positions = ''
|
||||||
DataPoints = ''
|
DataPoints = ''
|
||||||
HgCVDataPoints = ''
|
HgCVDataPoints = ''
|
||||||
|
PhaseDataPoints = ''
|
||||||
Loop
|
Loop
|
||||||
Position = Trim(RunData<FieldPos>)
|
Position = Trim(RunData<FieldPos>)
|
||||||
HgCVDataPoint = Trim(RunData<FieldPos + Offset>)
|
HgCVDataPoint = Trim(RunData<FieldPos + Offset>)
|
||||||
|
PhaseDataPoint = Trim(RunData<FieldPos + PhaseOffset>)
|
||||||
Until Position EQ ''
|
Until Position EQ ''
|
||||||
Positions := Position : @VM
|
Positions := Position : @VM
|
||||||
HgCVDataPoints := HgCVDataPoint : @VM
|
HgCVDataPoints := HgCVDataPoint : @VM
|
||||||
|
PhaseDataPoints := PhaseDataPoint : @VM
|
||||||
FieldPos += FieldPosIncrement
|
FieldPos += FieldPosIncrement
|
||||||
Repeat
|
Repeat
|
||||||
Positions[-1, 1] = '' ; // Strip final @VM
|
Positions[-1, 1] = '' ; // Strip final @VM
|
||||||
HgCVDataPoints[-1, 1] = '' ; // Strip final @VM
|
HgCVDataPoints[-1, 1] = '' ; // Strip final @VM
|
||||||
|
PhaseDataPoints[-1, 1] = '' ; // Strip final @VM
|
||||||
|
RawDataPoints = HgCVDataPoints
|
||||||
|
RawPhaseDataPoints = PhaseDataPoints
|
||||||
HgCVDataPoints = Iconv(HgCVDataPoints, 'MD' : Decimals)
|
HgCVDataPoints = Iconv(HgCVDataPoints, 'MD' : Decimals)
|
||||||
|
PhaseDataPoints = Iconv(PhaseDataPoints, 'MD' : Decimals)
|
||||||
|
|
||||||
Swap ' AM' with 'AM' in Timestamp
|
Swap ' AM' with 'AM' in Timestamp
|
||||||
Swap ' PM' with 'PM' in Timestamp
|
Swap ' PM' with 'PM' in Timestamp
|
||||||
Timestamp = IConv(Timestamp,'DT')
|
Timestamp = IConv(Timestamp,'DT')
|
||||||
|
|
||||||
|
// Recipe field 21
|
||||||
|
// Pattern field 24
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS')
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
ToolId = RunData<2>
|
||||||
|
ToolRecipe = RunData<21>
|
||||||
|
ToolPattern = RunData<24>
|
||||||
|
ToolClass = Xlate('TOOL', ToolId, 'CLASS', 'X')
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, ToolClass, ToolRecipe, ToolPattern, RunDataLayer, RunDataZone)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ToolId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If RawDataPoints NE '' then
|
||||||
|
Done = False$
|
||||||
|
For each DataPoint in RawDataPoints using @VM setting vPos
|
||||||
|
Position = Positions<0, vPos>
|
||||||
|
PhaseDataPoint = RawPhaseDataPoints<0, vPos>
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, Position, DataPoint, PhaseDataPoint)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Done = True$
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
Until Done
|
||||||
|
Next DataPoint
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. No DataPoints to import.'
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer
|
||||||
NumDataPoints = DCount(HgCVDataPoints, @VM)
|
NumDataPoints = DCount(HgCVDataPoints, @VM)
|
||||||
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID)
|
||||||
@ -1673,7 +1903,6 @@ Service ImportHgCVData(RunData, ResourceID, IsViewerFile, PSN)
|
|||||||
PhaseDataPoints[-1, 1] = '' ; // Strip final @VM
|
PhaseDataPoints[-1, 1] = '' ; // Strip final @VM
|
||||||
PhaseDataPoints = Iconv(PhaseDataPoints, 'MD' : Decimals)
|
PhaseDataPoints = Iconv(PhaseDataPoints, 'MD' : Decimals)
|
||||||
DataPoints = HgCVDataPoints
|
DataPoints = HgCVDataPoints
|
||||||
* GoSub CalculateQAData
|
|
||||||
Response = QA_Services('CalculateHgCVData', Datapoints)
|
Response = QA_Services('CalculateHgCVData', Datapoints)
|
||||||
HgCVMin = Response<0, 2>
|
HgCVMin = Response<0, 2>
|
||||||
HgCVMax = Response<0, 3>
|
HgCVMax = Response<0, 3>
|
||||||
@ -1687,23 +1916,12 @@ Service ImportHgCVData(RunData, ResourceID, IsViewerFile, PSN)
|
|||||||
|
|
||||||
DataPoints = PhaseDataPoints
|
DataPoints = PhaseDataPoints
|
||||||
Response = QA_Services('CalculateHgCVData', Datapoints)
|
Response = QA_Services('CalculateHgCVData', Datapoints)
|
||||||
* GoSub CalculateQAData
|
|
||||||
PhaseMin = Response<0, 2>
|
PhaseMin = Response<0, 2>
|
||||||
PhaseMax = Response<0, 3>
|
PhaseMax = Response<0, 3>
|
||||||
PhaseAvg = Response<0, 1>
|
PhaseAvg = Response<0, 1>
|
||||||
PhaseEdgeMean = Response<0, 4>
|
PhaseEdgeMean = Response<0, 4>
|
||||||
PhaseRangePct = Response<0, 5>
|
PhaseRangePct = Response<0, 5>
|
||||||
// Format data. Round to significant digits.
|
// Format data. Round to significant digits.
|
||||||
* HgCVAvg = Oconv(Iconv(Oconv(HgCVAvg, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* PhaseAvg = Oconv(Iconv(Oconv(PhaseAvg, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* HgCVMin = Oconv(Iconv(Oconv(HgCVMin, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* HgCVMax = Oconv(Iconv(Oconv(HgCVMax, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* PhaseMin = Oconv(Iconv(Oconv(PhaseMin, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* PhaseMax = Oconv(Iconv(Oconv(PhaseMax, 'MD3L'), 'MD3L'), 'MD3L')
|
|
||||||
* HgCVEdgeMean = OConv(IConv(HgCVEdgeMean, 'MD3L'), 'MD3L')
|
|
||||||
* PhaseEdgeMean = Oconv(IConv(PhaseEdgeMean, 'MD3L'), 'MD3L')
|
|
||||||
* HgCVRangePct = Oconv(Iconv(HgCVRangePct, 'MD3L'), 'MD3L')
|
|
||||||
* PhaseRangePct = Oconv(Iconv(PhaseRangePct, 'MD3L'), 'MD3L')
|
|
||||||
WOMatQARec<WO_MAT_QA_RESULT$, vPos> = HgCVAvg : @SVM : PhaseAvg
|
WOMatQARec<WO_MAT_QA_RESULT$, vPos> = HgCVAvg : @SVM : PhaseAvg
|
||||||
WOMatQARec<WO_MAT_QA_MIN_RESULT$, vPos> = HgCVMin : @SVM : PhaseMin
|
WOMatQARec<WO_MAT_QA_MIN_RESULT$, vPos> = HgCVMin : @SVM : PhaseMin
|
||||||
WOMatQARec<WO_MAT_QA_MAX_RESULT$, vPos> = HgCVMax : @SVM : PhaseMax
|
WOMatQARec<WO_MAT_QA_MAX_RESULT$, vPos> = HgCVMax : @SVM : PhaseMax
|
||||||
@ -1853,13 +2071,98 @@ Service ImportTencorData(RunData)
|
|||||||
SoDMin = RunData<41>
|
SoDMin = RunData<41>
|
||||||
ScanTool = RunData<43>
|
ScanTool = RunData<43>
|
||||||
Swap '%' with ' ' in ScanTool
|
Swap '%' with ' ' in ScanTool
|
||||||
RDSNo@ = RDSKeyID
|
LegacyLotId@ = RDSKeyID
|
||||||
Convert @Lower_Case to @Upper_Case in ScanTool
|
Convert @Lower_Case to @Upper_Case in ScanTool
|
||||||
|
|
||||||
Swap ' AM' with 'AM' in Timestamp
|
Swap ' AM' with 'AM' in Timestamp
|
||||||
Swap ' PM' with 'PM' in Timestamp
|
Swap ' PM' with 'PM' in Timestamp
|
||||||
Timestamp = IConv(Timestamp,'DT')
|
Timestamp = IConv(Timestamp,'DT')
|
||||||
|
|
||||||
|
SODWaferArray = ''
|
||||||
|
WaferNos = ''
|
||||||
|
SODVals = ''
|
||||||
|
SortVals = ''
|
||||||
|
SODStartTime = Time()
|
||||||
|
SODWaferArray = QA_Services('GetSODPerWafer', RDSKeyID, ScanRecipe, Timestamp)
|
||||||
|
SODStopTime = Time()
|
||||||
|
TimeTaken = SODStopTime - SODStartTime
|
||||||
|
LogData = ''
|
||||||
|
LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS')
|
||||||
|
LogData<2> = MachineType@
|
||||||
|
LogData<3> = LegacyLotId@
|
||||||
|
LogData<4> = 'Time taken to import SOD data: ':TimeTaken:' seconds.'
|
||||||
|
Logging_Services('AppendLog', objSODPerfLog, LogData, @RM, @FM)
|
||||||
|
If SODWaferArray NE '' then
|
||||||
|
WaferNos = SODWaferArray<1>
|
||||||
|
SODVals = SODWaferArray<2>
|
||||||
|
SortVals = SODWaferArray<3>
|
||||||
|
For each WaferNo in WaferNos using @VM
|
||||||
|
If WaferNo NE '' then QA_Services('PostWaferImageRequest', RDSKeyID, WaferNo, ScanRecipe)
|
||||||
|
Next Wafer
|
||||||
|
end
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS')
|
||||||
|
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, '', ScanRecipe)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ScanTool)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
// Add SORT property to Tencor surfscan MET_TEST - 'PASS' or 'FAIL' - no min or max
|
||||||
|
//Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SORT')
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
// Prop 1: SURFACE_SCAN_SUM_OF_DEFECTS_MIN
|
||||||
|
// Prop 2: SURFACE_SCAN_SUM_OF_DEFECTS_MAX
|
||||||
|
// Prop 3: SURFACE_SCAN_SUM_OF_DEFECTS_AVG
|
||||||
|
// Prop 4: SURFACE_SCAN_SUM_OF_DEFECTS (per wafer)
|
||||||
|
// Prop 5: SURFACE_SCAN_HAZE_AVG
|
||||||
|
// Prop 6: SURFACE_SCAN_SORT (per wafer)
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SUM_OF_DEFECTS_MIN')
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SUM_OF_DEFECTS_MAX')
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SUM_OF_DEFECTS_AVG')
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SUM_OF_DEFECTS')
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_HAZE_AVG')
|
||||||
|
Met_Test_Services('AddProperty', MetTestId, 'SURFACE_SCAN_SORT')
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, '', SoDMin, SoDMax, SoDAvg, '', HazeAvg)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
For each WaferNo in WaferNos using @VM setting vPos
|
||||||
|
If WaferNo NE '' then
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, WaferNo, '', '', '', SODVals<0, vPos>, '', SortVals<0, vPos>)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Next WaferNo
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
If RowExists('RDS', RDSKeyID) then
|
If RowExists('RDS', RDSKeyID) then
|
||||||
// Try to read the CleanInsp datarow. Use this to identify the RDSKeyID.
|
// Try to read the CleanInsp datarow. Use this to identify the RDSKeyID.
|
||||||
ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSKeyID)
|
ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSKeyID)
|
||||||
@ -1893,30 +2196,11 @@ Service ImportTencorData(RunData)
|
|||||||
NumWfrs = 0
|
NumWfrs = 0
|
||||||
Locate ScanRecipe In SpecRecipeList Using @VM Setting RecipeIndex then
|
Locate ScanRecipe In SpecRecipeList Using @VM Setting RecipeIndex then
|
||||||
// Recipe found in spec list
|
// Recipe found in spec list
|
||||||
SpecSampleQty = CleanInspRec<CLEAN_INSP_SPEC_SS_SAMP_QTY$, RecipeIndex>
|
|
||||||
SODWaferArray = ''
|
|
||||||
SODStartTime = Time()
|
|
||||||
SODWaferArray = QA_Services('GetSODPerWafer', RDSKeyID, ScanRecipe, Timestamp)
|
|
||||||
SODStopTime = Time()
|
|
||||||
TimeTaken = SODStopTime - SODStartTime
|
|
||||||
LogData = ''
|
|
||||||
LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS')
|
|
||||||
LogData<2> = MachineType@
|
|
||||||
LogData<3> = RDSNo@
|
|
||||||
LogData<4> = 'Time taken to import SOD data: ':TimeTaken:' seconds.'
|
|
||||||
Logging_Services('AppendLog', objSODPerfLog, LogData, @RM, @FM)
|
|
||||||
If SODWaferArray NE '' then
|
If SODWaferArray NE '' then
|
||||||
WaferNos = SODWaferArray<1>
|
|
||||||
SODVals = SODWaferArray<2>
|
|
||||||
SortVals = SODWaferArray<3>
|
|
||||||
For each Wfr in SODVals using @VM setting vPos
|
|
||||||
NumWfrs += (Wfr NE '')
|
|
||||||
Next Wfr
|
|
||||||
For each WaferNo in WaferNos using @VM
|
For each WaferNo in WaferNos using @VM
|
||||||
If WaferNo NE '' then
|
If WaferNo NE '' then
|
||||||
CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex, WaferNo> = SODVals<1,WaferNo>
|
CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex, WaferNo> = SODVals<1,WaferNo>
|
||||||
CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, ScanIndex, WaferNo> = SortVals<1,WaferNo>
|
CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, ScanIndex, WaferNo> = SortVals<1,WaferNo>
|
||||||
QA_Services('PostWaferImageRequest', RDSKeyID, WaferNo, ScanRecipe)
|
|
||||||
end
|
end
|
||||||
Next Wafer
|
Next Wafer
|
||||||
end
|
end
|
||||||
@ -2019,28 +2303,18 @@ Service ImportTencorData(RunData)
|
|||||||
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, -1, 0, Timestamp)
|
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, -1, 0, Timestamp)
|
||||||
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURFSCAN_RECIPE$, -1, 0, ScanRecipe)
|
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURFSCAN_RECIPE$, -1, 0, ScanRecipe)
|
||||||
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURF_DEFECTS$, -1, 0, DefectSpec)
|
CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURF_DEFECTS$, -1, 0, DefectSpec)
|
||||||
//Here I am attempting to create the scan details.
|
|
||||||
SODWaferArray = ''
|
|
||||||
SODWaferArray = QA_Services('GetSODPerWafer', RDSKeyID, ScanRecipe, Timestamp)
|
|
||||||
|
|
||||||
|
// Here I am attempting to create the scan details.
|
||||||
If SODWaferArray NE '' then
|
If SODWaferArray NE '' then
|
||||||
WaferNos = SODWaferArray<1>
|
|
||||||
SODVals = SODWaferArray<2>
|
|
||||||
SortVals = SODWaferArray<3>
|
|
||||||
NumRecipes = DCount(CleanInspRec<CLEAN_INSP_SCAN_RECIPE$>, @VM)
|
NumRecipes = DCount(CleanInspRec<CLEAN_INSP_SCAN_RECIPE$>, @VM)
|
||||||
NumWfrs = ''
|
|
||||||
For each Wfr in SODVals using @VM setting vPos
|
|
||||||
NumWfrs += (Wfr NE '')
|
|
||||||
Next Wfr
|
|
||||||
For each WaferNo in WaferNos using @VM
|
For each WaferNo in WaferNos using @VM
|
||||||
If WaferNo NE '' then
|
If WaferNo NE '' then
|
||||||
CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, NumRecipes, WaferNo> = SODVals<1,WaferNo>
|
CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, NumRecipes, WaferNo> = SODVals<1,WaferNo>
|
||||||
CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, NumRecipes, WaferNo> = SortVals<1,WaferNo>
|
CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, NumRecipes, WaferNo> = SortVals<1,WaferNo>
|
||||||
QA_Services('PostWaferImageRequest', RDSKeyID, WaferNo, ScanRecipe)
|
|
||||||
end
|
end
|
||||||
Next Wafer
|
Next Wafer
|
||||||
end
|
end
|
||||||
if exists Eq False$ then
|
If exists EQ False$ then
|
||||||
oCIParms := CleanInspRec ;
|
oCIParms := CleanInspRec ;
|
||||||
CINo = obj_Clean_Insp('Create',oCIParms)
|
CINo = obj_Clean_Insp('Create',oCIParms)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
@ -2053,7 +2327,7 @@ Service ImportTencorData(RunData)
|
|||||||
LogData = ''
|
LogData = ''
|
||||||
LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS')
|
LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS')
|
||||||
LogData<2> = MachineType@
|
LogData<2> = MachineType@
|
||||||
LogData<3> = RDSNo@
|
LogData<3> = LegacyLotId@
|
||||||
LogData<4> = 'Time taken to import POST data: ':TimeTaken:' seconds.'
|
LogData<4> = 'Time taken to import POST data: ':TimeTaken:' seconds.'
|
||||||
Logging_Services('AppendLog', objPOSTPerfLog, LogData, @RM, @FM)
|
Logging_Services('AppendLog', objPOSTPerfLog, LogData, @RM, @FM)
|
||||||
end else
|
end else
|
||||||
@ -2062,7 +2336,7 @@ Service ImportTencorData(RunData)
|
|||||||
ErrorMessage = 'Failed to create CLEAN_INSP record. Error UID002.'
|
ErrorMessage = 'Failed to create CLEAN_INSP record. Error UID002.'
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
//write to existing CI rec.
|
// Write to existing CI rec.
|
||||||
obj_Tables('WriteRec','CLEAN_INSP':@RM:CINo:@RM:@RM:CleanInspRec)
|
obj_Tables('WriteRec','CLEAN_INSP':@RM:CINo:@RM:@RM:CleanInspRec)
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
@ -2117,17 +2391,64 @@ Service ImportSP1Data(RunData)
|
|||||||
end
|
end
|
||||||
ScanTool = RunData<43>
|
ScanTool = RunData<43>
|
||||||
DCNMM2 = RunData<44>
|
DCNMM2 = RunData<44>
|
||||||
* Swap '%' with ' ' in ScanTool
|
|
||||||
// The 4th character can be 0 or %, but needs to be ' ' in OpenInsight
|
// The 4th character can be 0 or %, but needs to be ' ' in OpenInsight
|
||||||
ScanTool[4,1] = ' '
|
ScanTool[4,1] = ' '
|
||||||
Convert @Lower_Case to @Upper_Case in ScanTool
|
Convert @Lower_Case to @Upper_Case in ScanTool
|
||||||
Convert @Lower_Case to @Upper_Case in CompareScanRecipe
|
Convert @Lower_Case to @Upper_Case in CompareScanRecipe
|
||||||
* Convert ' ' to '' in CompareScanRecipe
|
|
||||||
|
|
||||||
Swap ' AM' with 'AM' in Timestamp
|
Swap ' AM' with 'AM' in Timestamp
|
||||||
Swap ' PM' with 'PM' in Timestamp
|
Swap ' PM' with 'PM' in Timestamp
|
||||||
Timestamp = IConv(Timestamp,'DT')
|
Timestamp = IConv(Timestamp,'DT')
|
||||||
RDSNo@ = RDSKeyID
|
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS')
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, '', ScanRecipe)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ScanTool)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
// Prop 1: SURFACE_SCAN_SUM_OF_DEFECTS_MIN
|
||||||
|
// Prop 2: SURFACE_SCAN_SUM_OF_DEFECTS_MAX
|
||||||
|
// Prop 3: SURFACE_SCAN_SUM_OF_DEFECTS_AVG
|
||||||
|
// Prop 4: SURFACE_SCAN_SUM_OF_DEFECTS (per wafer) - Currently not captured for SP1
|
||||||
|
// Prop 5: SURFACE_SCAN_HAZE_AVG
|
||||||
|
Met_Test_Services('RemoveProperty', MetTestId, 'SURFACE_SCAN_SUM_OF_DEFECTS')
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
// Set SOD min, SOD max, SOD avg, and Haze Avg
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, '', SoDMin, SoDMax, SoDAvg, '', HazeAvg)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LegacyLotId@ = RDSKeyID
|
||||||
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID)
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
WorkOrderNo = RDSRec<RDS_WO$>
|
WorkOrderNo = RDSRec<RDS_WO$>
|
||||||
@ -2519,7 +2840,7 @@ The service does the following actions:
|
|||||||
5. Determines the spec slot by reading the WO_MAT_QA record -> SLOT field
|
5. Determines the spec slot by reading the WO_MAT_QA record -> SLOT field
|
||||||
6. If the detected RunDataSlot matches the spec slot, writes the datapoint to the WO_MAT_QA record - > RESULT field in the same @VM that the iterator is currently set to.
|
6. If the detected RunDataSlot matches the spec slot, writes the datapoint to the WO_MAT_QA record - > RESULT field in the same @VM that the iterator is currently set to.
|
||||||
*/
|
*/
|
||||||
Service ImportBioRadEPPFQAData(RunData, FileName)
|
Service ImportBioRadEPPFQAData(RunData, Filename)
|
||||||
|
|
||||||
Timestamp = RunData<2>
|
Timestamp = RunData<2>
|
||||||
WMOKeyID = RunData<6>
|
WMOKeyID = RunData<6>
|
||||||
@ -2552,20 +2873,66 @@ Service ImportBioRadEPPFQAData(RunData, FileName)
|
|||||||
Positions[-1, 1] = '' ; // Strip final @VM
|
Positions[-1, 1] = '' ; // Strip final @VM
|
||||||
DataPoints[-1, 1] = '' ; // Strip final @VM
|
DataPoints[-1, 1] = '' ; // Strip final @VM
|
||||||
|
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', WMOKeyID, 'WM_OUT')
|
||||||
|
If LotId NE '' then
|
||||||
|
If DCount(LotId, @VM) EQ 1 then
|
||||||
|
// Import into new metrology data structures
|
||||||
|
ToolId = Field(Filename, ' ', 2, 1)
|
||||||
|
ToolClass = Xlate('TOOL', ToolId, 'CLASS', 'X')
|
||||||
|
If DataPoints NE '' then
|
||||||
|
For each DataPoint in DataPoints using @VM setting vPos
|
||||||
|
Slot = Positions<0, vPos>
|
||||||
|
MetTestId = Met_Test_Services('CreateMetTest', LotId, WMOKeyID, ToolClass, ScanRecipe, '', RunDataLayer)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
If DataSlotId NE '' then
|
Met_Test_Services('SetPropsAndLimits', MetTestId)
|
||||||
If Num(DataSlotId) then
|
If Error_Services('HasError') then
|
||||||
|
// Failed to set property names and limits based on input data from metrology file. Log this and continue importing data.
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
Met_Test_Services('SetMetTestTool', MetTestId, ToolId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestDtm', MetTestId, TimeStamp)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('SetMetTestSlot', MetTestId, Slot)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Met_Test_Services('AddMetTestData', MetTestId, '', DataPoint)
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
Next DataPoint
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. No DataPoints to import.'
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Swap @VM with ',' in LotId
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
//Update the WM_OUT record for EpiPro
|
//Update the WM_OUT record for EpiPro
|
||||||
WMORec<WM_OUT_MU_WAFER_THK_RESULT$, Int(DataSlotId)> = DataPoints
|
WMORec<WM_OUT_MU_WAFER_THK_RESULT$, DataSlotId> = DataPoints
|
||||||
Database_Services('WriteDataRow', 'WM_OUT', WMOKeyID, WMORec, True$, False$, True$)
|
Database_Services('WriteDataRow', 'WM_OUT', WMOKeyID, WMORec, True$, False$, True$)
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : DataSlotId ':Quote(DataSlotId):' is not a number!')
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
|
||||||
end else
|
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : DataSlotId is null!')
|
|
||||||
end
|
|
||||||
end else
|
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
|
||||||
end
|
end
|
||||||
// Update WO_MAT_QA record
|
// Update WO_MAT_QA record
|
||||||
WOMatQAID = Field(WMOKeyID, '*', 1) : '*' : Field(WMOKeyID, '*', 3)
|
WOMatQAID = Field(WMOKeyID, '*', 1) : '*' : Field(WMOKeyID, '*', 3)
|
||||||
@ -2608,12 +2975,12 @@ Service ImportBioRadEPPFQAData(RunData, FileName)
|
|||||||
Next Profile
|
Next Profile
|
||||||
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAID, WOMatQARec, True$, False$, True$)
|
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAID, WOMatQARec, True$, False$, True$)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID000', Service : ' : Success.')
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID000', Service : ' : Success.')
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage'))
|
||||||
end
|
end
|
||||||
|
|
||||||
end service
|
end service
|
||||||
@ -3277,3 +3644,6 @@ LoadRunDataToDatabase:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
98
LSL2/STPROC/METTESTS_API.txt
Normal file
98
LSL2/STPROC/METTESTS_API.txt
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
Function Mettests_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 : Mettests_API
|
||||||
|
|
||||||
|
Description : API logic for the Mettests 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 Mettests[.ID.[<Property>]]
|
||||||
|
- HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
|
||||||
|
Examples:
|
||||||
|
- Mettests.POST
|
||||||
|
- Mettests.ID.PUT
|
||||||
|
- Mettests.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)
|
||||||
|
05/20/25 xxx Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
$insert APP_INSERTS
|
||||||
|
$insert API_SETUP
|
||||||
|
$insert HTTP_INSERTS
|
||||||
|
|
||||||
|
Declare function Met_Test_Services
|
||||||
|
|
||||||
|
GoToAPI else
|
||||||
|
// The specific resource endpoint doesn't have a API handler yet.
|
||||||
|
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 mettests.ID.HEAD
|
||||||
|
API mettests.ID.GET
|
||||||
|
|
||||||
|
// Return JSON payload containing RDS record details
|
||||||
|
StatusCode = 200
|
||||||
|
GoSub CreateHALItem
|
||||||
|
|
||||||
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal GoSubs
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// CreateHALItem
|
||||||
|
//
|
||||||
|
// Creates a HAL+JSON object based on the OpenInsight data row representation of the scan.
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
CreateHALItem:
|
||||||
|
|
||||||
|
MetTestId = EndpointSegment
|
||||||
|
MetTestJSON = Met_Test_Services('ConvertRecordToJSON', MetTestId, '', FullEndpointURL)
|
||||||
|
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseBody', MetTestJSON, False$, 'application/hal+json')
|
||||||
|
If Assigned(Message) then
|
||||||
|
HTTP_Services('SetResponseStatus', StatusCode, Message)
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', StatusCode)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Message = Error_Services('GetMessage')
|
||||||
|
HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
257
LSL2/STPROC/MET_TEST_ACTIONS.txt
Normal file
257
LSL2/STPROC/MET_TEST_ACTIONS.txt
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
Function MET_TEST_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)
|
||||||
|
/***********************************************************************************************************************
|
||||||
|
|
||||||
|
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 Infineon.
|
||||||
|
|
||||||
|
Name : Met_Test_Actions
|
||||||
|
|
||||||
|
Description : Handles calculated columns and MFS calls for the current table.
|
||||||
|
|
||||||
|
Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly.
|
||||||
|
If called from outside of a calculated column these will need to be set and restored.
|
||||||
|
|
||||||
|
Parameters :
|
||||||
|
Action [in] -- Name of the action to be taken
|
||||||
|
CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be
|
||||||
|
populated when the CalcField action is being used.
|
||||||
|
FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM
|
||||||
|
delimited array, with the current MFS name as the first value in the array, and the BFS
|
||||||
|
name as the last value. Normally set by a calling MFS.
|
||||||
|
Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the
|
||||||
|
entire handle structure that the Basic+ Open statement would provide. Normally set by a
|
||||||
|
calling MFS.
|
||||||
|
Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS.
|
||||||
|
FMC [in] -- Various functions. Normally set by a calling MFS.
|
||||||
|
Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for
|
||||||
|
"get handle" functions). Normally set by a calling MFS.
|
||||||
|
Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but
|
||||||
|
for some actions can be set by the action handler to indicate failure.
|
||||||
|
OrigRecord [in] -- Original content of the record being processed by the current action. This is
|
||||||
|
automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within
|
||||||
|
BASE_MFS.
|
||||||
|
Param1-10 [in/out] -- Additional request parameter holders
|
||||||
|
ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.)
|
||||||
|
Can also be used to return a special value, such as the results of the CalcField
|
||||||
|
method.
|
||||||
|
|
||||||
|
History : (Date, Initials, Notes)
|
||||||
|
05/14/25 djs Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
$Insert FILE.SYSTEM.EQUATES
|
||||||
|
$Insert ACTION_SETUP
|
||||||
|
$Insert APP_INSERTS
|
||||||
|
$Insert MET_TEST_EQUATES
|
||||||
|
$Insert MET_TEST_DATA_EQUATES
|
||||||
|
$Insert MET_TEST_INSERTS
|
||||||
|
$Insert DICT_EQUATES
|
||||||
|
|
||||||
|
Declare function Database_Services, SRP_Array, Read_Column
|
||||||
|
Declare subroutine Database_Services, RTI_Xlate_Controller
|
||||||
|
|
||||||
|
If KeyID then GoSub Initialize_System_Variables
|
||||||
|
|
||||||
|
Begin Case
|
||||||
|
|
||||||
|
Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn
|
||||||
|
Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE
|
||||||
|
Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD
|
||||||
|
Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE
|
||||||
|
Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD
|
||||||
|
Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE
|
||||||
|
Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD
|
||||||
|
Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE
|
||||||
|
Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD
|
||||||
|
Case Otherwise$ ; Status = 'Invalid Action'
|
||||||
|
|
||||||
|
End Case
|
||||||
|
|
||||||
|
If KeyID then GoSub Restore_System_Variables
|
||||||
|
|
||||||
|
If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$
|
||||||
|
|
||||||
|
Return ActionFlow
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Calculated Columns
|
||||||
|
//
|
||||||
|
// The typical structure of a calculated column will look like this:
|
||||||
|
//
|
||||||
|
// Declare function Database_Services
|
||||||
|
//
|
||||||
|
// @ANS = Database_Services('CalculateColumn')
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CalculateColumn:
|
||||||
|
|
||||||
|
// Make sure the ActionFlow return variable is cleared in case nothing is calculated.
|
||||||
|
ActionFlow = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
// ----- MFS calls -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
READ_RECORD_PRE:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
// ActionFlow = ACTION_STOP$
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READ_RECORD:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READONLY_RECORD_PRE:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
// ActionFlow = ACTION_STOP$
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READONLY_RECORD:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
WRITE_RECORD_PRE:
|
||||||
|
|
||||||
|
MetTestDataIds = {MET_TEST_DATA_IDS}
|
||||||
|
If MetTestDataIds NE '' then
|
||||||
|
// Evaluate if MET_TEST is out of spec
|
||||||
|
RTI_Xlate_Controller('DisableCache')
|
||||||
|
For PropertyIndex = 1 to NUM_PROPERTIES$
|
||||||
|
MetTestOutofSpec = (Sum(Xlate('MET_TEST_DATA', MetTestDataIds, "PROPERTY_":PropertyIndex:'_OUT_OF_SPEC', 'X')) GT 0)
|
||||||
|
Until MetTestOutofSpec
|
||||||
|
Next PropertyIndex
|
||||||
|
Record<MET_TEST.OUT_OF_SPEC$> = MetTestOutofSpec
|
||||||
|
// Evaluate if MET_TEST is complete (all required data has been recorded)
|
||||||
|
// If Sample Size set, then each defined property should have that number of related data points (MET_TEST_DATA) records.
|
||||||
|
// If Sample Size is not set, then each defined property should have at least one related data point (MET_TEST_DATA) record.
|
||||||
|
MetComplete = True$
|
||||||
|
SampleSize = {SAMPLE_SIZE}
|
||||||
|
If SampleSize EQ '' then SampleSize = 1
|
||||||
|
For PropertyIndex = 1 to NUM_PROPERTIES$
|
||||||
|
PropColNo = Xlate('DICT.MET_TEST', 'PROPERTY_':PropertyIndex, DICT_COLUMN_NO$, 'X')
|
||||||
|
If (Record<PropColNo> NE '') then
|
||||||
|
// Property is defined, check if number of data points matches SAMPLE_SIZE
|
||||||
|
PropVals = Xlate('MET_TEST_DATA', MetTestDataIds, 'PROPERTY_':PropertyIndex:'_VALUE', 'X')
|
||||||
|
PropVals = SRP_Array('Clean', PropVals, 'Trim')
|
||||||
|
MetComplete = (DCount(PropVals, @VM) GE SampleSize)
|
||||||
|
end
|
||||||
|
Until Not(MetComplete)
|
||||||
|
Next PropertyIndex
|
||||||
|
Record<MET_TEST.COMPLETE$> = MetComplete
|
||||||
|
RTI_Xlate_Controller('EnableCache')
|
||||||
|
end else
|
||||||
|
Record<MET_TEST.OUT_OF_SPEC$> = False$
|
||||||
|
Record<MET_TEST.COMPLETE$> = False$
|
||||||
|
end
|
||||||
|
SaveRecord = Record
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
WRITE_RECORD:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DELETE_RECORD_PRE:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DELETE_RECORD:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal GoSubs
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ClearCursors:
|
||||||
|
|
||||||
|
For counter = 0 to 8
|
||||||
|
ClearSelect counter
|
||||||
|
Next counter
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Initialize_System_Variables:
|
||||||
|
|
||||||
|
// Save these for restoration later
|
||||||
|
SaveDict = @DICT
|
||||||
|
SaveID = @ID
|
||||||
|
SaveRecord = @RECORD
|
||||||
|
OrigFileError = @FILE.ERROR
|
||||||
|
|
||||||
|
// Now make sure @DICT, ID, and @RECORD are populated
|
||||||
|
CurrentDictName = ''
|
||||||
|
If @DICT then
|
||||||
|
DictHandle = @DICT<1, 2>
|
||||||
|
Locate DictHandle in @TABLES(5) Using @FM Setting fPos then
|
||||||
|
CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
If CurrentDictName NE DictName then
|
||||||
|
Open DictName to @DICT else Status = 'Unable to initialize @DICT'
|
||||||
|
end
|
||||||
|
|
||||||
|
@ID = KeyID
|
||||||
|
If Record else
|
||||||
|
// Record might not have been passed in. Read the record from the database table just to make sure.
|
||||||
|
@FILE.ERROR = ''
|
||||||
|
Open TableName to hTable then
|
||||||
|
FullFSList = hTable[1, 'F' : @VM]
|
||||||
|
BFS = FullFSList[-1, 'B' : @SVM]
|
||||||
|
LastHandle = hTable[-1, 'B' : \0D\]
|
||||||
|
FileHandle = \0D\ : LastHandle[1, @VM]
|
||||||
|
|
||||||
|
Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@RECORD = Record
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Restore_System_Variables:
|
||||||
|
|
||||||
|
Transfer SaveDict to @DICT
|
||||||
|
Transfer SaveID to @ID
|
||||||
|
Transfer SaveRecord to @RECORD
|
||||||
|
@FILE.ERROR = OrigFileError
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
276
LSL2/STPROC/MET_TEST_DATA_ACTIONS.txt
Normal file
276
LSL2/STPROC/MET_TEST_DATA_ACTIONS.txt
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
Function MET_TEST_DATA_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)
|
||||||
|
/***********************************************************************************************************************
|
||||||
|
|
||||||
|
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 Infineon.
|
||||||
|
|
||||||
|
Name : Met_Test_Data_Actions
|
||||||
|
|
||||||
|
Description : Handles calculated columns and MFS calls for the current table.
|
||||||
|
|
||||||
|
Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly.
|
||||||
|
If called from outside of a calculated column these will need to be set and restored.
|
||||||
|
|
||||||
|
Parameters :
|
||||||
|
Action [in] -- Name of the action to be taken
|
||||||
|
CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be
|
||||||
|
populated when the CalcField action is being used.
|
||||||
|
FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM
|
||||||
|
delimited array, with the current MFS name as the first value in the array, and the BFS
|
||||||
|
name as the last value. Normally set by a calling MFS.
|
||||||
|
Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the
|
||||||
|
entire handle structure that the Basic+ Open statement would provide. Normally set by a
|
||||||
|
calling MFS.
|
||||||
|
Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS.
|
||||||
|
FMC [in] -- Various functions. Normally set by a calling MFS.
|
||||||
|
Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for
|
||||||
|
"get handle" functions). Normally set by a calling MFS.
|
||||||
|
Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but
|
||||||
|
for some actions can be set by the action handler to indicate failure.
|
||||||
|
OrigRecord [in] -- Original content of the record being processed by the current action. This is
|
||||||
|
automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within
|
||||||
|
BASE_MFS.
|
||||||
|
Param1-10 [in/out] -- Additional request parameter holders
|
||||||
|
ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.)
|
||||||
|
Can also be used to return a special value, such as the results of the CalcField
|
||||||
|
method.
|
||||||
|
|
||||||
|
History : (Date, Initials, Notes)
|
||||||
|
05/14/25 djs Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
$Insert FILE.SYSTEM.EQUATES
|
||||||
|
$Insert ACTION_SETUP
|
||||||
|
$Insert APP_INSERTS
|
||||||
|
$Insert MET_TEST_EQUATES
|
||||||
|
$Insert MET_TEST_DATA_EQUATES
|
||||||
|
$Insert MET_TEST_INSERTS
|
||||||
|
$Insert DICT_EQUATES
|
||||||
|
|
||||||
|
Declare function Database_Services
|
||||||
|
Declare subroutine Database_Services
|
||||||
|
|
||||||
|
If KeyID then GoSub Initialize_System_Variables
|
||||||
|
|
||||||
|
Begin Case
|
||||||
|
|
||||||
|
Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn
|
||||||
|
Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE
|
||||||
|
Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD
|
||||||
|
Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE
|
||||||
|
Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD
|
||||||
|
Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE
|
||||||
|
Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD
|
||||||
|
Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE
|
||||||
|
Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD
|
||||||
|
Case Otherwise$ ; Status = 'Invalid Action'
|
||||||
|
|
||||||
|
End Case
|
||||||
|
|
||||||
|
If KeyID then GoSub Restore_System_Variables
|
||||||
|
|
||||||
|
If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$
|
||||||
|
|
||||||
|
Return ActionFlow
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Calculated Columns
|
||||||
|
//
|
||||||
|
// The typical structure of a calculated column will look like this:
|
||||||
|
//
|
||||||
|
// Declare function Database_Services
|
||||||
|
//
|
||||||
|
// @ANS = Database_Services('CalculateColumn')
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CalculateColumn:
|
||||||
|
|
||||||
|
// Make sure the ActionFlow return variable is cleared in case nothing is calculated.
|
||||||
|
ActionFlow = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
// ----- MFS calls -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
READ_RECORD_PRE:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
// ActionFlow = ACTION_STOP$
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READ_RECORD:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READONLY_RECORD_PRE:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
// ActionFlow = ACTION_STOP$
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
READONLY_RECORD:
|
||||||
|
|
||||||
|
// In order to stop a record from being read in this action these lines of code must be used:
|
||||||
|
//
|
||||||
|
// OrigFileError = 100 : @FM : KeyID
|
||||||
|
// Status = 0
|
||||||
|
// Record = ''
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
WRITE_RECORD_PRE:
|
||||||
|
|
||||||
|
// Validate Property Values against specs defined in MET_TEST parent record
|
||||||
|
MetTestId = {MET_TEST_ID}
|
||||||
|
If MetTestId NE '' then
|
||||||
|
MetTestRec = Database_Services('ReadDataRow', 'MET_TEST', MetTestId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
MetTestOutofSpecOrig = MetTestRec<MET_TEST.OUT_OF_SPEC$>
|
||||||
|
MetTestOutofSpec = False$
|
||||||
|
For PropertyIndex = 1 to NUM_PROPERTIES$
|
||||||
|
PropOutofSpec = False$
|
||||||
|
Prop = Xlate('MET_TEST', MetTestId, 'PROPERTY_':PropertyIndex, 'X')
|
||||||
|
If Prop NE '' then
|
||||||
|
PropMin = Xlate('MET_TEST', MetTestId, 'PROPERTY_':PropertyIndex:'_SPEC_MIN', 'X')
|
||||||
|
PropMax = Xlate('MET_TEST', MetTestId, 'PROPERTY_':PropertyIndex:'_SPEC_MAX', 'X')
|
||||||
|
PropValColNo = Xlate('DICT.MET_TEST_DATA', 'PROPERTY_':PropertyIndex:'_VALUE', DICT_COLUMN_NO$, 'X')
|
||||||
|
PropVal = Record<PropValColNo>
|
||||||
|
Begin Case
|
||||||
|
|
||||||
|
Case (PropVal EQ '')
|
||||||
|
PropOutofSpec = False$
|
||||||
|
|
||||||
|
Case ( (PropMin NE '') and (PropMax NE '') )
|
||||||
|
|
||||||
|
PropOutofSpec = ( (PropVal LT PropMin) or (PropVal GT PropMax) )
|
||||||
|
|
||||||
|
Case (PropMin NE '')
|
||||||
|
|
||||||
|
PropOutofSpec = (PropVal LT PropMin)
|
||||||
|
|
||||||
|
Case (PropMax NE '')
|
||||||
|
|
||||||
|
PropOutofSpec = (PropVal GT PropMax)
|
||||||
|
|
||||||
|
Case (Prop EQ 'SURFACE_SCAN_SORT')
|
||||||
|
PropOutofSpec = Not((PropVal _EQC 'PASS'))
|
||||||
|
|
||||||
|
Case Otherwise$
|
||||||
|
Null
|
||||||
|
|
||||||
|
End Case
|
||||||
|
PropOOSColNo = Xlate('DICT.MET_TEST_DATA', 'PROPERTY_':PropertyIndex:'_OUT_OF_SPEC', DICT_COLUMN_NO$, 'X')
|
||||||
|
Record<PropOOSColNo> = PropOutofSpec
|
||||||
|
end
|
||||||
|
If PropOutofSpec then MetTestOutofSpec = True$
|
||||||
|
Next PropertyIndex
|
||||||
|
SaveRecord = Record
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
WRITE_RECORD:
|
||||||
|
|
||||||
|
// Trigger MET_TEST_ACTIONS to re-evaluate if the entire MET_TEST record is in spec and comlete
|
||||||
|
MetTestRec = Database_Services('ReadDataRow', 'MET_TEST', {MET_TEST_ID})
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Database_Services('WriteDataRow', 'MET_TEST', {MET_TEST_ID}, MetTestRec, True$, False$, False$)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DELETE_RECORD_PRE:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DELETE_RECORD:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal GoSubs
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ClearCursors:
|
||||||
|
For counter = 0 to 8
|
||||||
|
ClearSelect counter
|
||||||
|
Next counter
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Initialize_System_Variables:
|
||||||
|
|
||||||
|
// Save these for restoration later
|
||||||
|
SaveDict = @DICT
|
||||||
|
SaveID = @ID
|
||||||
|
SaveRecord = @RECORD
|
||||||
|
OrigFileError = @FILE.ERROR
|
||||||
|
|
||||||
|
// Now make sure @DICT, ID, and @RECORD are populated
|
||||||
|
CurrentDictName = ''
|
||||||
|
If @DICT then
|
||||||
|
DictHandle = @DICT<1, 2>
|
||||||
|
Locate DictHandle in @TABLES(5) Using @FM Setting fPos then
|
||||||
|
CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
If CurrentDictName NE DictName then
|
||||||
|
Open DictName to @DICT else Status = 'Unable to initialize @DICT'
|
||||||
|
end
|
||||||
|
|
||||||
|
@ID = KeyID
|
||||||
|
If Record else
|
||||||
|
// Record might not have been passed in. Read the record from the database table just to make sure.
|
||||||
|
@FILE.ERROR = ''
|
||||||
|
Open TableName to hTable then
|
||||||
|
FullFSList = hTable[1, 'F' : @VM]
|
||||||
|
BFS = FullFSList[-1, 'B' : @SVM]
|
||||||
|
LastHandle = hTable[-1, 'B' : \0D\]
|
||||||
|
FileHandle = \0D\ : LastHandle[1, @VM]
|
||||||
|
|
||||||
|
Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@RECORD = Record
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Restore_System_Variables:
|
||||||
|
|
||||||
|
Transfer SaveDict to @DICT
|
||||||
|
Transfer SaveID to @ID
|
||||||
|
Transfer SaveRecord to @RECORD
|
||||||
|
@FILE.ERROR = OrigFileError
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
1254
LSL2/STPROC/MET_TEST_SERVICES.txt
Normal file
1254
LSL2/STPROC/MET_TEST_SERVICES.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -135,4 +135,3 @@ API monaengines.ID.GET
|
|||||||
end
|
end
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -61,4 +61,3 @@ API mona.GET
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -190,9 +190,3 @@ return
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,3 +300,5 @@ SetDelay:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
130
LSL2/STPROC/OPERATION_API.txt
Normal file
130
LSL2/STPROC/OPERATION_API.txt
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
Function Operation_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 : Operation_API
|
||||||
|
|
||||||
|
Description : API logic for the Operation 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 Operation[.ID.[<Property>]]
|
||||||
|
- HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
|
||||||
|
Examples:
|
||||||
|
- Operation.POST
|
||||||
|
- Operation.ID.PUT
|
||||||
|
- Operation.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)
|
||||||
|
05/19/25 xxx Original programmer.
|
||||||
|
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare function OI_Wizard_Services, Operation_Services, Clean_Services, Lot_Operation_Services
|
||||||
|
|
||||||
|
$insert APP_INSERTS
|
||||||
|
$insert API_SETUP
|
||||||
|
$insert HTTP_INSERTS
|
||||||
|
|
||||||
|
GoToAPI else
|
||||||
|
// The specific resource endpoint doesn't have a API handler yet.
|
||||||
|
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 operation.HEAD
|
||||||
|
API operation.GET
|
||||||
|
|
||||||
|
JSONCollection = ''
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
If ValidSession then
|
||||||
|
Body = HTTP_Services('GetHTTPGetString')
|
||||||
|
If Body NE '' then
|
||||||
|
RequestJson = HTTP_Services('DecodePercentString', Body)
|
||||||
|
ClassFilter = Http_Services('GetQueryField', 'Class')
|
||||||
|
ActiveFilter = Http_Services('GetQueryField', 'Active')
|
||||||
|
LotId = Http_Services('GetQueryField', 'LotId')
|
||||||
|
Operations = Operation_Services('GetOperations', ClassFilter, ActiveFilter)
|
||||||
|
|
||||||
|
objJSONResponse = ''
|
||||||
|
If SRP_Json(objJSONResponse, 'New', 'Object') then
|
||||||
|
//Available Operations
|
||||||
|
If SRP_Json(objOperations, 'New', 'Array') then
|
||||||
|
for each Operation in Operations using @VM
|
||||||
|
OperationJSONString = Operation_Services('ConvertRecordToJSON', Operation)
|
||||||
|
objOperation = ''
|
||||||
|
If SRP_Json(objOperation, 'Parse', OperationJSONString) EQ '' then
|
||||||
|
SRP_Json(objOperations, 'Add', objOperation)
|
||||||
|
SRP_Json(objOperation, 'Release')
|
||||||
|
end
|
||||||
|
Next Operation
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'Operations', objOperations)
|
||||||
|
SRP_Json(objOperations, 'Release')
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error when creating Operation array in JSON response.')
|
||||||
|
end
|
||||||
|
//Available Sequences
|
||||||
|
Sequences = Lot_Operation_Services('GetAvailableSequences', LotId)
|
||||||
|
If SRP_Json(objSequences, 'New', 'Array') then
|
||||||
|
for each Sequence in Sequences using @VM
|
||||||
|
SRP_Json(objSequences, 'AddValue', Sequence, 'Number')
|
||||||
|
Next Sequence
|
||||||
|
SRP_Json(objJsonResponse, 'Set', 'AvailableSequences', objSequences)
|
||||||
|
SRP_Json(objSequences, 'Release')
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error when creating Operation array in JSON response.')
|
||||||
|
end
|
||||||
|
JsonResponse = SRP_Json(objJsonResponse, 'Stringify', 'Styled')
|
||||||
|
SRP_Json(objJsonResponse, 'Release')
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'Error when creating JSON response.')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Error_Services('Add', 'No body was sent with the request.')
|
||||||
|
end
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseStatus', 201, 'Success')
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseBody', JsonResponse, False$, 'application/hal+json')
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end api
|
21
LSL2/STPROC/OPERATION_EQUATES.txt
Normal file
21
LSL2/STPROC/OPERATION_EQUATES.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
compile insert OPERATION_EQUATES
|
||||||
|
/*----------------------------------------
|
||||||
|
Author : Table Create Insert Routine
|
||||||
|
Written : 29/05/2025
|
||||||
|
Description : Insert for Table OPERATION
|
||||||
|
----------------------------------------*/
|
||||||
|
#ifndef __OPERATION_EQUATES__
|
||||||
|
#define __OPERATION_EQUATES__
|
||||||
|
|
||||||
|
equ OPERATION_ACTIVE$ to 1
|
||||||
|
equ OPERATION_CLASS_ID$ to 2
|
||||||
|
equ OPERATION_OPERATION_DESCRIPTION$ to 3
|
||||||
|
equ OPERATION_TYPE$ to 4
|
||||||
|
equ OPERATION_REWORK$ to 5
|
||||||
|
equ OPERATION_MET_TEST_TYPE_REQUIRED$ to 6
|
||||||
|
equ OPERATION_MET_TEST_REQUIRED$ to 7
|
||||||
|
equ OPERATION_PACKAGING_REQUIRED$ to 8
|
||||||
|
equ OPERATION_CLEAN_REQUIRED$ to 9
|
||||||
|
equ OPERATION_WAFER_COUNTER_REQUIRED$ to 10
|
||||||
|
|
||||||
|
#endif
|
57
LSL2/STPROC/OPERATION_SERVICES.txt
Normal file
57
LSL2/STPROC/OPERATION_SERVICES.txt
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
Compile function Operation_Services(@Service, @Params)
|
||||||
|
#pragma precomp SRP_PreCompiler
|
||||||
|
|
||||||
|
Declare function Database_Services, SRP_Json
|
||||||
|
Declare subroutine Database_Services, SRP_Json, Btree.Extract
|
||||||
|
|
||||||
|
$insert LOGICAL
|
||||||
|
$Insert OPERATION_EQUATES
|
||||||
|
|
||||||
|
Options OPERATION_TYPE = 'CLEAN', 'THICK_METROLOGY', 'RES_METROLOGY', 'SURFACE_METROLOGY', 'VISUAL_INSPECTION', 'PACKAGING'
|
||||||
|
|
||||||
|
GoToService
|
||||||
|
|
||||||
|
Return Response or ""
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// SERVICES
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Service ConvertRecordToJson(OperationId)
|
||||||
|
|
||||||
|
JsonString = ''
|
||||||
|
objJSON = ''
|
||||||
|
OperationRec = Database_Services('ReadDataRow', 'OPERATION', OperationId, True$, 0, False$)
|
||||||
|
If SRP_JSON(objJSON, 'New', 'Object') then
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'OperationId', OperationId)
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'Active', OperationRec<OPERATION_ACTIVE$>, 'Boolean')
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'ClassId', OperationRec<OPERATION_CLASS_ID$>, 'String')
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'Description', OperationRec<OPERATION_OPERATION_DESCRIPTION$>, 'String')
|
||||||
|
SRP_JSON(objJSON, 'SetValue', 'Type', OperationRec<OPERATION_TYPE$>, 'String')
|
||||||
|
JsonString = SRP_JSON(objJSON, 'Stringify', 'Styled')
|
||||||
|
SRP_JSON(objJSON, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
Response = JsonString
|
||||||
|
|
||||||
|
End Service
|
||||||
|
|
||||||
|
Service GetOperations(Class, ActiveFlag)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
RTFOperationKeys = ''
|
||||||
|
|
||||||
|
Open 'DICT.OPERATION' to DICT then
|
||||||
|
SearchString = 'CLASS_ID':@VM:Class:@FM
|
||||||
|
SearchString := 'ACTIVE':@VM:True$:@FM
|
||||||
|
Option = ''
|
||||||
|
Flag = ''
|
||||||
|
Btree.Extract(SearchString, 'OPERATION', DICT, RTFOperationKeys, Option, Flag)
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error opening OPERATION table dictionary.'
|
||||||
|
end
|
||||||
|
|
||||||
|
Response = RTFOperationKeys
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
@ -32,11 +32,24 @@ $insert SCANS_EQUATES
|
|||||||
$insert APP_INSERTS
|
$insert APP_INSERTS
|
||||||
$insert WO_MAT_EQUATES
|
$insert WO_MAT_EQUATES
|
||||||
$insert NOTIFICATION_EQU
|
$insert NOTIFICATION_EQU
|
||||||
|
$insert PACKAGING_EQUATES
|
||||||
|
$insert LOT_OPERATION_EQUATES
|
||||||
|
$Insert LOT_EQUATES
|
||||||
|
|
||||||
Declare function Scan_Services, Memory_Services, Database_Services, SRP_JSON, RTI_CreateGUID, Memberof
|
Declare function Scan_Services, Memory_Services, Database_Services, SRP_JSON, RTI_CreateGUID, Memberof
|
||||||
Declare function Get_Property, RDS_Services, EpiPro_Services, DateTime, Signature_Services
|
Declare function Get_Property, RDS_Services, EpiPro_Services, DateTime, Signature_Services, Packaging_Services
|
||||||
|
Declare function Lot_Services, Environment_Services, Logging_Services
|
||||||
Declare subroutine Scan_Services, Memory_Services, Database_Services, SRP_JSON, Security_Services, obj_Notes
|
Declare subroutine Scan_Services, Memory_Services, Database_Services, SRP_JSON, Security_Services, obj_Notes
|
||||||
Declare subroutine obj_WO_Mat_Log, obj_WO_Mat, Set_Status, SAP_Services, Rds_Services, Wm_Out_Services, Hold_Services
|
Declare subroutine obj_WO_Mat_Log, obj_WO_Mat, Set_Status, SAP_Services, Rds_Services, Wm_Out_Services, Hold_Services
|
||||||
|
Declare subroutine Lot_Event_Services, Lot_Services, Packaging_Services, Logging_Services
|
||||||
|
|
||||||
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Packaging'
|
||||||
|
LogDate = Oconv(Date(), 'D4/')
|
||||||
|
LogTime = Oconv(Time(), 'MTS')
|
||||||
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
||||||
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Packaging Log.csv'
|
||||||
|
Headers = 'Logging DTM' : @FM : 'Message'
|
||||||
|
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
||||||
|
|
||||||
GoToService else
|
GoToService else
|
||||||
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.')
|
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.')
|
||||||
@ -62,6 +75,7 @@ Service CompletePackaging(CassetteID, OperatorID, BaggerIdentifier)
|
|||||||
|
|
||||||
RDSKey = CassetteID
|
RDSKey = CassetteID
|
||||||
WMOKey = CassetteID
|
WMOKey = CassetteID
|
||||||
|
LotId = ''
|
||||||
Convert '.' to '*' in WMOKey
|
Convert '.' to '*' in WMOKey
|
||||||
CommentEntity = ''
|
CommentEntity = ''
|
||||||
Begin Case
|
Begin Case
|
||||||
@ -70,11 +84,13 @@ Service CompletePackaging(CassetteID, OperatorID, BaggerIdentifier)
|
|||||||
WOMatKey = Xlate('RDS', RDSKey, 'WO', 'X')
|
WOMatKey = Xlate('RDS', RDSKey, 'WO', 'X')
|
||||||
WOMatKey = WoMatKey:'*':Xlate('RDS', RDSKey, 'CASS_NO', 'X')
|
WOMatKey = WoMatKey:'*':Xlate('RDS', RDSKey, 'CASS_NO', 'X')
|
||||||
CommentEntity = 'RDS'
|
CommentEntity = 'RDS'
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKey, 'RDS')
|
||||||
|
|
||||||
Case RowExists('WM_OUT', WMOKey) EQ True$
|
Case RowExists('WM_OUT', WMOKey) EQ True$
|
||||||
// WM_OUT key
|
// WM_OUT key
|
||||||
WOMatKey = Xlate('WM_OUT', WMOKey, 'WO_MAT_KEY', 'X')
|
WOMatKey = Xlate('WM_OUT', WMOKey, 'WO_MAT_KEY', 'X')
|
||||||
CommentEntity = 'WM_OUT'
|
CommentEntity = 'WM_OUT'
|
||||||
|
LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', WMOKey, 'WM_OUT')
|
||||||
|
|
||||||
Case RowExists('WO_MAT', CassetteID) EQ True$
|
Case RowExists('WO_MAT', CassetteID) EQ True$
|
||||||
// WO_MAT key
|
// WO_MAT key
|
||||||
@ -138,6 +154,24 @@ Service CompletePackaging(CassetteID, OperatorID, BaggerIdentifier)
|
|||||||
// Add CassComp transaction to SAP queue
|
// Add CassComp transaction to SAP queue
|
||||||
SAPBatchNo = Xlate('WO_MAT', WOMatKey, 'SAP_BATCH_NO', 'X')
|
SAPBatchNo = Xlate('WO_MAT', WOMatKey, 'SAP_BATCH_NO', 'X')
|
||||||
If SAPBatchNo EQ '' then SAP_Services('AddCassCompTransaction', WOMatKey)
|
If SAPBatchNo EQ '' then SAP_Services('AddCassCompTransaction', WOMatKey)
|
||||||
|
|
||||||
|
//Handle NG lot functions.
|
||||||
|
If LotId NE '' then
|
||||||
|
NewPackRecId = Packaging_Services('CreatePackagingRecord', LotId, UserID, ToolID)
|
||||||
|
CurrOperationId = Lot_Services('GetLotCurrOperationId', LotId)
|
||||||
|
If CurrOperationId NE '' then
|
||||||
|
Packaging_Services('AddPackToLotOperation', CurrOperationId, NewPackRecId, UserID)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Lot_Services('MoveOutLot', LotId, UserId)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
If Error_Services('HasError') then
|
||||||
|
//Remove any error messages as a result of NG Lot functions. At the moment we don't want them interrupting production when they occur.
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -664,3 +698,72 @@ Service ProcessScanData(ScanData, ScanType = SCAN_TYPES, Param1, Param2, Param3)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
Service CreatePackagingRecord(LotId, UserId, EqpId)
|
||||||
|
|
||||||
|
NewRecId = ''
|
||||||
|
ErrorMessage = ''
|
||||||
|
|
||||||
|
If RowExists('LOT', LotId) then
|
||||||
|
NewRecId = RTI_CreateGuid()
|
||||||
|
TransDtm = Datetime()
|
||||||
|
NewPackagingRec = ''
|
||||||
|
NewPackagingRec<PACKAGING_LOT_ID$> = LotId
|
||||||
|
NewPackagingRec<PACKAGING_COMPLETE$> = True$
|
||||||
|
NewPackagingRec<PACKAGING_COMPLETE_DTM$> = TransDtm
|
||||||
|
Database_Services('WriteDataRow', 'PACKAGING', NewRecId, NewPackagingRec, True$, 0, False$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, TransDtm, 'PACKAGING', 'Lot Packaged.', EqpId, UserId)
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'LOT: ' LotId : ' not found'
|
||||||
|
end
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
LogData = ''
|
||||||
|
LogData<1> = LoggingDTM
|
||||||
|
LogData<2> = Error_Services('GetMessage')
|
||||||
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
||||||
|
Error_Services('Clear')
|
||||||
|
end
|
||||||
|
|
||||||
|
Response = NewRecId
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service AddPackToLotOperation(LotOperationId, PackagingId, UserId)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
|
||||||
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
|
If RowExists('LSL_USERS', UserId) then
|
||||||
|
//Can add user group check here.
|
||||||
|
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
||||||
|
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
|
||||||
|
ExistingPackId = LotOperationRec<LOT_OPERATION_PACKAGING_ID$>
|
||||||
|
If ExistingPackId EQ '' then
|
||||||
|
LotOperationRec<LOT_OPERATION_PACKAGING_ID$> = PackagingId
|
||||||
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, LotOperationRec)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
TransDtm = Datetime()
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, TransDtm, 'COMMENT', 'PACKAGING record added to operation.', '', UserId)
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'A pack scan already exists for the lot operation. Please remove the pack before adding a new one.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'USER ID: ' UserId : ' not found.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'LOT_OPERATION: ' LotOperationId : ' not found.'
|
||||||
|
end
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,4 +76,3 @@ API pm.ID.POST
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -61,4 +61,3 @@ API pm_spec.GET
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -102,5 +102,3 @@ CreateHALItem:
|
|||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,9 +35,11 @@ $Insert RDS_TEST_EQUATES
|
|||||||
$Insert RDS_TEST_PROP_EQUATES
|
$Insert RDS_TEST_PROP_EQUATES
|
||||||
$Insert PRS_LAYER_EQU
|
$Insert PRS_LAYER_EQU
|
||||||
|
|
||||||
|
Options SpecTypes = 'CLEAN', 'SURFSCAN', 'THICK', 'THICKA', 'RES', 'SRES', 'CRES', 'CONC'
|
||||||
|
|
||||||
Declare function Database_Services, Psn_Services, obj_Prod_Spec, Error_Services, SRP_JSON, Cust_Epi_Part_Services
|
Declare function Database_Services, Psn_Services, obj_Prod_Spec, Error_Services, SRP_JSON, Cust_Epi_Part_Services
|
||||||
Declare function Prod_Ver_Services, PRS_Stage_Services
|
Declare function Prod_Ver_Services, PRS_Stage_Services, SRP_Array
|
||||||
Declare subroutine Database_Services, Psn_Services, Error_Services, SRP_JSON
|
Declare subroutine Database_Services, Psn_Services, Error_Services, SRP_JSON, Extract_Si_Keys
|
||||||
|
|
||||||
GoToService else
|
GoToService else
|
||||||
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
|
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
|
||||||
@ -72,6 +74,216 @@ Service InitializeCritParams(PSNo)
|
|||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
|
Service GetRecipes(PSNo)
|
||||||
|
|
||||||
|
ErrorMsg = ''
|
||||||
|
Recipes = ''
|
||||||
|
If PSNo NE '' then
|
||||||
|
If RowExists('PROD_SPEC', PSNo) then
|
||||||
|
PropKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_PROP', 'PS_NO', PSNo, PropKeys)
|
||||||
|
Recipes = Xlate('PRS_PROP', PropKeys, 'MET_RECIPE', 'X')
|
||||||
|
PRSStageKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_STAGE', 'PS_NO', PSNo, PRSStageKeys)
|
||||||
|
Recipes<0, -1> = Xlate('PRS_STAGE', PRSStageKeys, 'MET_RECIPE', 'X')
|
||||||
|
Recipes<0, -1> = Xlate('PRS_STAGE', PRSStageKeys, 'SURFSCAN_RECIPE', 'X')
|
||||||
|
Recipes<0, -1> = @VM : Xlate('PRS_STAGE', PRSStageKeys, 'CLEAN_RECIPE', 'X')
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @VM)
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. PROD_SPEC record "':PSNo:'" does not exist.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Null PSNo passed into service.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMsg EQ '' then
|
||||||
|
Response = Recipes
|
||||||
|
end else
|
||||||
|
Error_Services('Add', ErrorMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetAllMetrologyRecipes(PSNo, GetSurfscan, GetClean, GetRes, GetThick)
|
||||||
|
|
||||||
|
Recipes = ''
|
||||||
|
If GetSurfscan EQ '' then GetSurfscan = True$
|
||||||
|
If GetClean EQ '' then GetClean = True$
|
||||||
|
If GetRes EQ '' then GetRes = True$
|
||||||
|
If GetThick EQ '' then GetThick = True$
|
||||||
|
|
||||||
|
If GetSurfscan then Recipes := PSN_Services('GetSurfscanRecipes', PSNo) : @FM
|
||||||
|
If GetClean then Recipes := PSN_Services('GetCleanRecipes', PSNo) :@FM
|
||||||
|
If GetRes then Recipes := PSN_Services('GetResRecipes', PSNo) :@FM
|
||||||
|
If GetThick then Recipes := PSN_Services('GetThicknessRecipes', PSNo)
|
||||||
|
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @FM)
|
||||||
|
Response = Recipes
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetSurfscanRecipes(PSNo)
|
||||||
|
|
||||||
|
Recipes = ''
|
||||||
|
If PSNo NE '' then
|
||||||
|
If RowExists('PROD_SPEC', PSNo) then
|
||||||
|
PropKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_PROP', 'PS_NO', PSNo, PropKeys)
|
||||||
|
PRSStageKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_STAGE', 'PS_NO', PSNo, PRSStageKeys)
|
||||||
|
for each PRSStageKey in PRSStageKeys using @VM setting pPos
|
||||||
|
Stage = Xlate('PRS_STAGE', PRSStageKey, 'STAGE', 'X')
|
||||||
|
TencorRecipes = Xlate('PRS_STAGE', PRSStageKey, 'SURFSCAN_RECIPE', 'X')
|
||||||
|
for each Recipe in TencorRecipes using @VM
|
||||||
|
ToolClass = 'TENCOR'
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
Next TencorRecipe
|
||||||
|
Next PRSStageKey
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @FM)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Response = Recipes
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetCleanRecipes(PSNo)
|
||||||
|
|
||||||
|
Recipes = ''
|
||||||
|
If PSNo NE '' then
|
||||||
|
If RowExists('PROD_SPEC', PSNo) then
|
||||||
|
PropKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_PROP', 'PS_NO', PSNo, PropKeys)
|
||||||
|
PRSStageKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_STAGE', 'PS_NO', PSNo, PRSStageKeys)
|
||||||
|
for each PRSStageKey in PRSStageKeys using @VM setting pPos
|
||||||
|
Stage = Xlate('PRS_STAGE', PRSStageKey, 'STAGE', 'X')
|
||||||
|
CleanRecipes = Xlate('PRS_STAGE', PRSStageKey, 'CLEAN_RECIPE', 'X')
|
||||||
|
for each Recipe in CleanRecipes using @VM
|
||||||
|
ToolClass = 'CLEAN'
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
Next TencorRecipe
|
||||||
|
Next PRSStageKey
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @FM)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Response = Recipes
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetThicknessRecipes(PSNo)
|
||||||
|
|
||||||
|
ErrorMsg = ''
|
||||||
|
Recipes = ''
|
||||||
|
If PSNo NE '' then
|
||||||
|
If RowExists('PROD_SPEC', PSNo) then
|
||||||
|
//First get QA Recipes
|
||||||
|
PropKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_PROP', 'PS_NO', PSNo, PropKeys)
|
||||||
|
Recipes = ''
|
||||||
|
PRSStageKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_STAGE', 'PS_NO', PSNo, PRSStageKeys)
|
||||||
|
for each PRSStageKey in PRSStageKeys using @VM setting pPos
|
||||||
|
Stage = Xlate('PRS_STAGE', PRSStageKey, 'STAGE', 'X')
|
||||||
|
PRSStageRecipes = Xlate('PRS_STAGE', PRSStageKey, 'MET_RECIPE', 'X')
|
||||||
|
for each PRSStageRecipe in PRSStageRecipes using @VM setting rPos
|
||||||
|
PropType = Xlate('PRS_STAGE', PRSStageKey, 'MET_PROP', 'X')<1, rPos>
|
||||||
|
If PropType EQ 'THICK' OR PropType EQ 'THICKA' then
|
||||||
|
Recipe = PRSStageRecipe
|
||||||
|
ToolClass = 'FTIR'
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
end
|
||||||
|
Next PRSStageRecipe
|
||||||
|
Next PRSStageKey
|
||||||
|
//Next get Rathole recipes
|
||||||
|
SpecEpiData = XLATE('PROD_SPEC', PSNo, 'SPEC_EPI', 'X')
|
||||||
|
swap @VM with @FM in SpecEpiData
|
||||||
|
swap '~' with @VM in SpecEpiData
|
||||||
|
ThicknessData = SpecEpiData<13>
|
||||||
|
ToolClass = ThicknessData<1, 1>
|
||||||
|
Recipe = ThicknessData<1, 3>
|
||||||
|
Stage = 'RDS_TEST'
|
||||||
|
If ToolClass EQ 'FTIR' OR ToolClass EQ 'ADE' then
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
end
|
||||||
|
// Remove any duplicate entries
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @FM)
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. PROD_SPEC record "':PSNo:'" does not exist.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Null PSNo passed into service.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMsg EQ '' then
|
||||||
|
Response = Recipes
|
||||||
|
end else
|
||||||
|
Error_Services('Add', ErrorMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service GetResRecipes(PSNo)
|
||||||
|
|
||||||
|
ErrorMsg = ''
|
||||||
|
Recipes = ''
|
||||||
|
If PSNo NE '' then
|
||||||
|
If RowExists('PROD_SPEC', PSNo) then
|
||||||
|
//First get QA Recipes
|
||||||
|
PropKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_PROP', 'PS_NO', PSNo, PropKeys)
|
||||||
|
Recipes = ''
|
||||||
|
PRSStageKeys = ''
|
||||||
|
Extract_Si_Keys('PRS_STAGE', 'PS_NO', PSNo, PRSStageKeys)
|
||||||
|
for each PRSStageKey in PRSStageKeys using @VM setting pPos
|
||||||
|
Stage = Xlate('PRS_STAGE', PRSStageKey, 'STAGE', 'X')
|
||||||
|
PRSStageRecipes = Xlate('PRS_STAGE', PRSStageKey, 'MET_RECIPE', 'X')
|
||||||
|
for each PRSStageRecipe in PRSStageRecipes using @VM setting rPos
|
||||||
|
PropType = Xlate('PRS_STAGE', PRSStageKey, 'MET_PROP', 'X')<1, rPos>
|
||||||
|
ToolClass = Xlate('PRS_STAGE', PRSStageKey, 'MET_TOOL_CLASS', 'X')<1, rPos>
|
||||||
|
If PropType EQ 'RES' OR PropType EQ 'SRES' OR PropType EQ 'CRES' OR PropType EQ 'CONC' then
|
||||||
|
Recipe = PRSStageRecipe
|
||||||
|
ToolClass = ToolClass
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
end
|
||||||
|
Next PRSStageRecipe
|
||||||
|
Next PRSStageKey
|
||||||
|
//Next get Rathole recipes
|
||||||
|
Stage = 'RDS_TEST'
|
||||||
|
SpecEpiData = XLATE('PROD_SPEC', PSNo, 'SPEC_EPI', 'X')
|
||||||
|
swap @VM with @FM in SpecEpiData
|
||||||
|
swap '~' with @VM in SpecEpiData
|
||||||
|
ResData1 = SpecEpiData<19>
|
||||||
|
|
||||||
|
If ResData1 NE '' then
|
||||||
|
ToolClass = ResData1<1, 1>
|
||||||
|
Recipe = ResData1<1, 3>
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
end
|
||||||
|
|
||||||
|
ResData2 = SpecEpiData<14>
|
||||||
|
If ResData2 NE '' then
|
||||||
|
ToolClass = ResData2<1, 1>
|
||||||
|
Recipe = ResData2<1, 3>
|
||||||
|
Recipes<-1> = ToolClass : @VM : Recipe : @VM : Stage
|
||||||
|
end
|
||||||
|
|
||||||
|
// Remove any duplicate entries
|
||||||
|
Recipes = SRP_Array('Clean', Recipes, 'TrimAndMakeUnique', @FM)
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. PROD_SPEC record "':PSNo:'" does not exist.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Null PSNo passed into service.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMsg EQ '' then
|
||||||
|
Response = Recipes
|
||||||
|
end else
|
||||||
|
Error_Services('Add', ErrorMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
Service CheckPSNStages(PSNo, Stage)
|
Service CheckPSNStages(PSNo, Stage)
|
||||||
|
|
||||||
Begin Case
|
Begin Case
|
||||||
@ -950,3 +1162,8 @@ CheckAdHoc:
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,4 +103,3 @@ API reactorloadings.POST
|
|||||||
end
|
end
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -260,5 +260,3 @@ API reactorlogs.ID.nicaoverride.PUT
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,5 +259,3 @@ CreateHALCollection:
|
|||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,4 +61,3 @@ API remotehealthcheck.GET
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
@ -233,5 +233,3 @@ API reports.GET
|
|||||||
HTTP_Resource_Services('LoremIpsum')
|
HTTP_Resource_Services('LoremIpsum')
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ API returntofab.ID.GET
|
|||||||
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
||||||
RTFId = EndpointSegment
|
RTFId = EndpointSegment
|
||||||
If Error_Services('NoError') AND RTFId NE '' then
|
If Error_Services('NoError') AND RTFId NE '' then
|
||||||
RTFJson = Return_To_Fab_Services('ConvertReturnToFabRecordToJSON', RTFId)
|
RTFJson = Return_To_Fab_Services('ConvertReturnToFabRecordToJSON', RTFId, UserId)
|
||||||
If Error_Services('NoError') then
|
If Error_Services('NoError') then
|
||||||
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
||||||
@ -247,7 +247,6 @@ end api
|
|||||||
|
|
||||||
API returntofab.reportopenforms.HEAD
|
API returntofab.reportopenforms.HEAD
|
||||||
API returntofab.reportopenforms.GET
|
API returntofab.reportopenforms.GET
|
||||||
|
|
||||||
OIWizardID = ''
|
OIWizardID = ''
|
||||||
Cookies = HTTP_Services('GetHTTPCookie')
|
Cookies = HTTP_Services('GetHTTPCookie')
|
||||||
For each Cookie in Cookies using ';'
|
For each Cookie in Cookies using ';'
|
||||||
@ -259,12 +258,9 @@ API returntofab.reportopenforms.GET
|
|||||||
|
|
||||||
ValidSession = OI_Wizard_Services('ValidateSession', OIWizardID)
|
ValidSession = OI_Wizard_Services('ValidateSession', OIWizardID)
|
||||||
|
|
||||||
If ValidSession then
|
|
||||||
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
||||||
RTFId = EndpointSegment
|
|
||||||
If Error_Services('NoError') AND RTFId NE '' then
|
|
||||||
RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', True$)
|
RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', True$)
|
||||||
If Error_Services('NoError') then
|
If RTFJson NE '' then
|
||||||
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
||||||
If Assigned(Message) then
|
If Assigned(Message) then
|
||||||
@ -273,14 +269,7 @@ API returntofab.reportopenforms.GET
|
|||||||
HTTP_Services('SetResponseStatus', 201)
|
HTTP_Services('SetResponseStatus', 201)
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
ErrorMessage = 'Error getting report data.'
|
||||||
end
|
|
||||||
|
|
||||||
end else
|
|
||||||
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
|
|
||||||
end
|
|
||||||
end else
|
|
||||||
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end api
|
end api
|
||||||
@ -288,7 +277,6 @@ end api
|
|||||||
|
|
||||||
API returntofab.reportallforms.HEAD
|
API returntofab.reportallforms.HEAD
|
||||||
API returntofab.reportallforms.GET
|
API returntofab.reportallforms.GET
|
||||||
|
|
||||||
OIWizardID = ''
|
OIWizardID = ''
|
||||||
Cookies = HTTP_Services('GetHTTPCookie')
|
Cookies = HTTP_Services('GetHTTPCookie')
|
||||||
For each Cookie in Cookies using ';'
|
For each Cookie in Cookies using ';'
|
||||||
@ -303,9 +291,9 @@ API returntofab.reportallforms.GET
|
|||||||
If ValidSession then
|
If ValidSession then
|
||||||
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
UserId = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
|
||||||
RTFId = EndpointSegment
|
RTFId = EndpointSegment
|
||||||
If Error_Services('NoError') AND RTFId NE '' then
|
If RTFId NE '' then
|
||||||
RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', False$)
|
RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', False$)
|
||||||
If Error_Services('NoError') then
|
If RTFJson NE '' then
|
||||||
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
|
||||||
If Assigned(Message) then
|
If Assigned(Message) then
|
||||||
@ -314,11 +302,10 @@ API returntofab.reportallforms.GET
|
|||||||
HTTP_Services('SetResponseStatus', 201)
|
HTTP_Services('SetResponseStatus', 201)
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
ErrorMessage = 'Error getting report data.'
|
||||||
end
|
end
|
||||||
|
|
||||||
end else
|
end else
|
||||||
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
|
HTTP_Services('SetResponseStatus', 400, 'Return To Fab ID was null')
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
@ -370,6 +357,37 @@ CreateResultOptionCollection:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
CreateOperationOptionCollection:
|
||||||
|
JSONCollection = ''
|
||||||
|
Abort = False$
|
||||||
|
OperationOptions = Return_To_Fab_Services('GetRTFOperationIDs')
|
||||||
|
hJSONCollection = ''
|
||||||
|
If SRP_JSON(hJSONCollection, 'New', 'Object') then
|
||||||
|
hOperationOptionCollection = ''
|
||||||
|
If SRP_JSON(hOperationOptionCollection, 'New', 'Array') then
|
||||||
|
For each OperationOptionId in OperationOptions using @VM setting fPos
|
||||||
|
SRP_Json(hOperationOptionCollection, 'AddValue', OperationOptionId, 'String')
|
||||||
|
Next OperationOptionId
|
||||||
|
SRP_JSON(hJSONCollection, 'Set', 'OperationOptions', hOperationOptionCollection)
|
||||||
|
SRP_JSON(hOperationOptionCollection, 'Release')
|
||||||
|
end
|
||||||
|
JSONCollection = SRP_JSON(hJSONCollection, 'Stringify', 'Fast')
|
||||||
|
SRP_JSON(hJSONCollection, 'Release')
|
||||||
|
end
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseBody', JSONCollection, False$, 'application/hal+json')
|
||||||
|
If Assigned(Message) then
|
||||||
|
HTTP_Services('SetResponseStatus', 201, Message)
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 201)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
Message = Error_Services('GetMessage')
|
||||||
|
HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
API returntofab.getreturntofablabelzpl.HEAD
|
API returntofab.getreturntofablabelzpl.HEAD
|
||||||
API returntofab.getreturntofablabelzpl.GET
|
API returntofab.getreturntofablabelzpl.GET
|
||||||
@ -404,3 +422,26 @@ API returntofab.getreturntofablabelzpl.GET
|
|||||||
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
end
|
end
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API returntofab.rtfoperations.HEAD
|
||||||
|
API returntofab.rtfoperations.GET
|
||||||
|
|
||||||
|
OIWizardID = ''
|
||||||
|
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)
|
||||||
|
|
||||||
|
If ValidSession then
|
||||||
|
GoSub CreateOperationOptionCollection
|
||||||
|
end else
|
||||||
|
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end api
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -127,5 +127,3 @@ API scrubber_pm.ID.GET
|
|||||||
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
|
||||||
end
|
end
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
@ -830,8 +830,3 @@ end service
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ Service GetTools(ToolClass)
|
|||||||
|
|
||||||
Query = 'SELECT TOOL '
|
Query = 'SELECT TOOL '
|
||||||
If ToolClass NE '' then
|
If ToolClass NE '' then
|
||||||
Query := 'WITH CLASS EQ ':ToolClass:' '
|
Query := 'WITH CLASS EQ ': Quote(ToolClass)
|
||||||
end
|
end
|
||||||
Query := 'BY CLASS BY TOOL_ID'
|
Query := 'BY CLASS BY TOOL_ID'
|
||||||
Set_Status(0)
|
Set_Status(0)
|
||||||
@ -238,6 +238,33 @@ Service ChangeToolMode(ToolID, NewMode, NewReason, CurrUser, ForceModeChange)
|
|||||||
end service
|
end service
|
||||||
|
|
||||||
|
|
||||||
|
Service GetNumPoints(ToolClass, ToolPattern)
|
||||||
|
|
||||||
|
ErrorMsg = ''
|
||||||
|
NumPoints = ''
|
||||||
|
If ( (ToolClass NE '') and (ToolPattern NE '') ) then
|
||||||
|
If RowExists('TOOL_CLASS', ToolClass) then
|
||||||
|
ToolPatterns = Xlate('TOOL_CLASS', ToolClass, 'PATTERN', 'X')
|
||||||
|
Locate ToolPattern in ToolPatterns using @VM setting PatternPos then
|
||||||
|
NumPoints = Xlate('TOOL_CLASS', ToolClass, 'PATTERN_SIZE', 'X')<0, PatternPos>
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. ToolPattern "':ToolPattern:'" not found in TOOL_CLASS "':ToolClass:'".'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. ToolClass "':ToolClass:'" does not exist.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMsg = 'Error in ':Service:' service. Null ToolClass or ToolPattern passed into service.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMsg EQ '' then
|
||||||
|
Response = NumPoints
|
||||||
|
end else
|
||||||
|
Error_Services('Add', ErrorMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Internal GoSubs
|
// Internal GoSubs
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -329,3 +356,4 @@ return
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,3 +307,72 @@ API wafercounter.completewafercount.POST
|
|||||||
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
end api
|
end api
|
||||||
|
|
||||||
|
|
||||||
|
API wafercounter.ID.HEAD
|
||||||
|
API wafercounter.ID.GET
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
ResponseCode = ''
|
||||||
|
WaferCounterId = EndPointSegment
|
||||||
|
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> = 'Getting Wafer counter record. Record Id: ' : WaferCounterId
|
||||||
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
||||||
|
|
||||||
|
If WaferCounterId NE '' then
|
||||||
|
WaferCounterJson = Wafer_Counter_Services('ConvertWaferCounterRecToJson', WaferCounterId)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
HTTP_Services('SetResponseBody', WaferCounterJson)
|
||||||
|
ResponseCode = 200
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
ResponseCode = 500
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Null wafer counter passed to endpoint.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage EQ '' then
|
||||||
|
//Log Success
|
||||||
|
LogData = ''
|
||||||
|
LogData<1> = LoggingDTM
|
||||||
|
LogData<2> = UserId
|
||||||
|
LogData<3> = OIWizardId
|
||||||
|
LogData<4> = 'Wafer Counter record successfully returned. Wafer Counter Id: ' : WaferCounterId
|
||||||
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
||||||
|
end else
|
||||||
|
//Log Failure
|
||||||
|
LogData = ''
|
||||||
|
LogData<1> = LoggingDTM
|
||||||
|
LogData<2> = UserId
|
||||||
|
LogData<3> = OIWizardId
|
||||||
|
LogData<4> = 'Error returning wafer counter record. Wafer Counter Id: ' : WaferCounterId : ' . Error Message: ' : ErrorMessage
|
||||||
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
||||||
|
end
|
||||||
|
|
||||||
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
||||||
|
HTTP_Services('SetResponseStatus', ResponseCode, ErrorMessage)
|
||||||
|
|
||||||
|
end api
|
||||||
|
@ -34,6 +34,8 @@ $Insert RLIST_EQUATES
|
|||||||
$Insert WAFER_COUNTER_EQUATES
|
$Insert WAFER_COUNTER_EQUATES
|
||||||
$Insert TOOL_EQUATES
|
$Insert TOOL_EQUATES
|
||||||
$Insert TOOL_LOG_EQUATES
|
$Insert TOOL_LOG_EQUATES
|
||||||
|
$Insert LOT_OPERATION_EQUATES
|
||||||
|
$Insert LOT_EQUATES
|
||||||
|
|
||||||
Equ Tab$ to \09\
|
Equ Tab$ to \09\
|
||||||
Equ CRLF$ to \0D0A\
|
Equ CRLF$ to \0D0A\
|
||||||
@ -528,8 +530,8 @@ Service GetWaferCounterJSONTestData(WaferSize, ToolLocation, CassID)
|
|||||||
If SRP_JSON(objJson, 'New', 'Object') then
|
If SRP_JSON(objJson, 'New', 'Object') then
|
||||||
SRP_JSON(objJson, 'SetValue', 'dateTimeFormatted', Datetime(), 'String')
|
SRP_JSON(objJson, 'SetValue', 'dateTimeFormatted', Datetime(), 'String')
|
||||||
SRP_JSON(objJson, 'SetValue', 'equipmentId', 'WC8INCH1', 'String')
|
SRP_JSON(objJson, 'SetValue', 'equipmentId', 'WC8INCH1', 'String')
|
||||||
SRP_JSON(objJson, 'SetValue', 'total', 24, 'Number')
|
SRP_JSON(objJson, 'SetValue', 'total', 25, 'Number')
|
||||||
SRP_JSON(objJson, 'SetValue', 'slotMap', '1111111110111111111111111', 'String')
|
SRP_JSON(objJson, 'SetValue', 'slotMap', '1111111111111111111111111', 'String')
|
||||||
Response = SRP_Json(objJson, 'Stringify', 'Styled')
|
Response = SRP_Json(objJson, 'Stringify', 'Styled')
|
||||||
SRP_JSON(objJSON, 'Release')
|
SRP_JSON(objJSON, 'Release')
|
||||||
end
|
end
|
||||||
@ -553,6 +555,181 @@ Service GetWaferCounterJSONTestData(WaferSize, ToolLocation, CassID)
|
|||||||
|
|
||||||
end service
|
end service
|
||||||
|
|
||||||
|
Service ConvertWaferCounterRecToJson(WaferCounterId)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
If WaferCounterId NE '' then
|
||||||
|
WaferCounterRec = Database_Services('ReadDataRow', 'WAFER_COUNTER', WaferCounterId, True$, 0, False$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
//Fields within wafer counter rec
|
||||||
|
CassId = WaferCounterRec<WAFER_COUNTER.LOT_ID$>
|
||||||
|
swap '.' with '*' in CassId
|
||||||
|
WaferCount = WaferCounterRec<WAFER_COUNTER.SCAN_QTY$>
|
||||||
|
ScanDtm = WaferCounterRec<WAFER_COUNTER.SCAN_DTM$>
|
||||||
|
ToolID = WaferCounterRec<WAFER_COUNTER.SCAN_TOOL$>
|
||||||
|
WaferMapData = WaferCounterRec<WAFER_COUNTER.SCAN_WAFER_MAP$>
|
||||||
|
swap 1 with 1:@FM in WaferMapData
|
||||||
|
swap 0 with 0:@FM in WaferMapData
|
||||||
|
|
||||||
|
ActualWaferArray = ''
|
||||||
|
for i = 25 to 1 step -1
|
||||||
|
Slot = i
|
||||||
|
WaferPresent = WaferMapData<i>
|
||||||
|
ActualWaferArray<-1, 1> = Slot : @VM : WaferPresent
|
||||||
|
Next i
|
||||||
|
//Fields calculated at runtime.
|
||||||
|
CassType = ''
|
||||||
|
WONo = ''
|
||||||
|
CassNo = ''
|
||||||
|
ExpectedQty = ''
|
||||||
|
Begin Case
|
||||||
|
Case RowExists('RDS', CassId)
|
||||||
|
CassType = 'RDS'
|
||||||
|
WONo = XLATE('RDS', CassId, 'WO', 'X')
|
||||||
|
CassNo = XLATE('RDS', CassId, 'CASS_NO', 'X')
|
||||||
|
ExpectedQty = Xlate('RDS', CassId, 'WFRS_OUT', 'X')
|
||||||
|
Case RowExists('WM_OUT', CassId) OR RowExists('WM_IN', CassId)
|
||||||
|
CassType = 'WM_OUT'
|
||||||
|
WONo = Field(CassId, '*', 1)
|
||||||
|
CassNo = Field(CassId, '*', 3)
|
||||||
|
ExpectedQty = Xlate('WM_OUT', CassId, 'WAFER_CNT', 'X')
|
||||||
|
End Case
|
||||||
|
WoMatKey = WONo : '*' : CassNo
|
||||||
|
|
||||||
|
ExpectedWaferData = Wo_Mat_Services('GetWaferMap', WoMatKey)
|
||||||
|
ExpectedWaferArray = ''
|
||||||
|
for i = 25 to 1 step -1
|
||||||
|
Slot = i
|
||||||
|
WaferPresent = ExpectedWaferData<1, i>
|
||||||
|
ExpectedWaferArray<-1, 1> = Slot : @VM : WaferPresent
|
||||||
|
Next i
|
||||||
|
|
||||||
|
//Constructing the JSON Object
|
||||||
|
objJson = ''
|
||||||
|
If SRP_Json(objJson, 'New', 'Object') then
|
||||||
|
SRP_Json(objJson, 'SetValue', 'WaferCounterId', WaferCounterId, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'CassId', CassId, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'CassType', CassType, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'ExpectedQty', ExpectedQty, 'Number')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'ScanDtm', OConv(ScanDtm, 'DT4/'), 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'ToolId', ToolId, 'String')
|
||||||
|
SRP_Json(objJson, 'SetValue', 'WaferCount', WaferCount, 'Number')
|
||||||
|
|
||||||
|
//Wafer Counter Slot Array
|
||||||
|
objWaferCounterSlotArray = ''
|
||||||
|
IF SRP_Json(objWaferCounterSlotArray, 'New', 'Array') then
|
||||||
|
For each Slot in ActualWaferArray using @FM
|
||||||
|
SlotNo = Slot<1, 1>
|
||||||
|
WaferPresent = Slot<1, 2>
|
||||||
|
//Create the individiual slot object
|
||||||
|
objSlot = ''
|
||||||
|
If SRP_Json(objSlot, 'New', 'Object') then
|
||||||
|
SRP_Json(objSlot, 'SetValue', 'SlotNo', SlotNo, 'Number')
|
||||||
|
SRP_Json(objSlot, 'SetValue', 'WaferPresent', WaferPresent, 'Boolean')
|
||||||
|
SRP_Json(objWaferCounterSlotArray, 'Add', objSlot)
|
||||||
|
SRP_Json(objSlot, 'Release')
|
||||||
|
end
|
||||||
|
Next Slot
|
||||||
|
SRP_Json(objJson, 'Set', 'WaferArray', objWaferCounterSlotArray)
|
||||||
|
SRP_Json(objWaferCounterSlotArray, 'Release')
|
||||||
|
end
|
||||||
|
|
||||||
|
//OpenInsight Expected Slot Array
|
||||||
|
objOISlotArray = ''
|
||||||
|
IF SRP_Json(objOISlotArray, 'New', 'Array') then
|
||||||
|
For each Slot in ExpectedWaferArray using @FM
|
||||||
|
SlotNo = Slot<1, 1>
|
||||||
|
WaferPresent = Slot<1, 2>
|
||||||
|
//Create the individiual slot object
|
||||||
|
objSlot = ''
|
||||||
|
If SRP_Json(objSlot, 'New', 'Object') then
|
||||||
|
SRP_Json(objSlot, 'SetValue', 'SlotNo', SlotNo, 'Number')
|
||||||
|
SRP_Json(objSlot, 'SetValue', 'WaferPresent', WaferPresent, 'Boolean')
|
||||||
|
SRP_Json(objOISlotArray, 'Add', objSlot)
|
||||||
|
SRP_Json(objSlot, 'Release')
|
||||||
|
end
|
||||||
|
Next slot
|
||||||
|
SRP_Json(objJson, 'Set', 'ExpectedWaferArray', objOISlotArray)
|
||||||
|
SRP_Json(objWaferCounterSlotArray, 'Release')
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
Response = SRP_Json(objJson, 'Stringify', 'Styled')
|
||||||
|
SRP_Json(objJson, 'Release')
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error initializing JSON object'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Error reading wafer counter record. ' : Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Wafer counter id was null.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
|
Service AssociateWaferCounter(LotOperationId, WaferCounterId, UserId)
|
||||||
|
|
||||||
|
ErrorMessage = ''
|
||||||
|
|
||||||
|
If RowExists('LSL_USERS', UserId) then
|
||||||
|
If RowExists('LOT_OPERATION', LotOperationId) then
|
||||||
|
If RowExists('WAFER_COUNTER', WaferCounterId) then
|
||||||
|
WaferCounterRec = Database_Services('ReadDataRow', 'WAFER_COUNTER', WaferCounterId, True$, 0, False$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
WaferCounterToolId = WaferCounterRec<WAFER_COUNTER.SCAN_TOOL$>
|
||||||
|
ThisLotOpRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
LotId = ThisLotOpRec<LOT_OPERATION_LOT_ID$>
|
||||||
|
If RowExists('LOT', LotId) then
|
||||||
|
ThisWaferCountCassId = WaferCounterRec<WAFER_COUNTER.LOT_ID$>
|
||||||
|
ThisLotId = ThisLotOpRec<LOT_OPERATION_LOT_ID$>
|
||||||
|
LegacyLotType = Xlate('LOT', ThisLotId, LOT_LEGACY_LOT_TYPE$, 'X')
|
||||||
|
LotIdToCompare = ''
|
||||||
|
If LegacyLotType NE '' then
|
||||||
|
LotIdToCompare = Xlate('LOT', ThisLotId, LOT_LEGACY_LOT_ID$, 'X')
|
||||||
|
end else
|
||||||
|
LotIdToCompare = ThisLotId
|
||||||
|
end
|
||||||
|
|
||||||
|
If ThisWaferCountCassId EQ LotIdToCompare then
|
||||||
|
ThisLotOpRec<LOT_OPERATION_WAFER_COUNTER_ID$> = WaferCounterId
|
||||||
|
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, ThisLotOpRec)
|
||||||
|
If Error_Services('NoError') then
|
||||||
|
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'LOG_WAFER_COUNT', 'Wafer Count logged.', WaferCounterToolId, UserId)
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Lot IDs do not match!'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Lot not found.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = Error_Services('GetMessage')
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Wafer counter record not found.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'Lot Operation record not found.'
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
ErrorMessage = 'User ID not found.'
|
||||||
|
end
|
||||||
|
|
||||||
|
If ErrorMessage NE '' then
|
||||||
|
Error_Services('Add', ErrorMessage)
|
||||||
|
end
|
||||||
|
|
||||||
|
end service
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Internal GoSubs
|
// Internal GoSubs
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -566,3 +743,5 @@ ClearCursors:
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,4 +149,3 @@ CreateHALItem:
|
|||||||
HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
|
HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -120,4 +120,3 @@ CreateHalItem:
|
|||||||
LogData<5> = ResponseMessage
|
LogData<5> = ResponseMessage
|
||||||
Logging_Services('AppendLog', ObjLog, LogData, @RM, @FM)
|
Logging_Services('AppendLog', ObjLog, LogData, @RM, @FM)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
20
LSL2/STPROCINS/CLEAN_EQUATES.txt
Normal file
20
LSL2/STPROCINS/CLEAN_EQUATES.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
compile insert CLEAN_EQUATES
|
||||||
|
/*----------------------------------------
|
||||||
|
Author : Table Create Insert Routine
|
||||||
|
Written : 17/06/2025
|
||||||
|
Description : Insert for Table CLEAN
|
||||||
|
----------------------------------------*/
|
||||||
|
#ifndef __CLEAN_EQUATES__
|
||||||
|
#define __CLEAN_EQUATES__
|
||||||
|
|
||||||
|
equ CLEAN_LOT_ID$ to 1
|
||||||
|
equ CLEAN_TOOL$ to 2
|
||||||
|
equ CLEAN_RECIPE$ to 3
|
||||||
|
equ CLEAN_COMPLETE_DTM$ to 4
|
||||||
|
equ CLEAN_LOT_OPERATION_ID$ to 5
|
||||||
|
equ CLEAN_CLEAN_START_DTM$ to 6
|
||||||
|
equ CLEAN_CLEAN_START_USER_ID$ to 7
|
||||||
|
equ CLEAN_CLEAN_STOP_DTM$ to 8
|
||||||
|
equ CLEAN_CLEAN_STOP_USER_ID$ to 9
|
||||||
|
|
||||||
|
#endif
|
@ -23,13 +23,13 @@ compile insert LOT_OPERATION_EQUATES
|
|||||||
equ LOT_OPERATION_MET_TEST_ID$ to 14
|
equ LOT_OPERATION_MET_TEST_ID$ to 14
|
||||||
equ LOT_OPERATION_CLEAN_ID$ to 15
|
equ LOT_OPERATION_CLEAN_ID$ to 15
|
||||||
equ LOT_OPERATION_PACKAGING_ID$ to 16
|
equ LOT_OPERATION_PACKAGING_ID$ to 16
|
||||||
equ LOT_OPERATION_WAFER_COUNTER_ID$ to 17
|
equ LOT_OPERATION_WAFER_COUNTER_ID$ to 18
|
||||||
equ LOT_OPERATION_OPERATION_TYPE$ to 18
|
equ LOT_OPERATION_OPERATION_TYPE$ to 19
|
||||||
equ LOT_OPERATION_OPERATION_CLASS$ to 19
|
equ LOT_OPERATION_OPERATION_CLASS$ to 20
|
||||||
equ LOT_OPERATION_MET_TEST_TYPE_REQUIRED$ to 20
|
equ LOT_OPERATION_MET_TEST_TYPE_REQUIRED$ to 21
|
||||||
equ LOT_OPERATION_MET_TEST_REQUIRED$ to 21
|
equ LOT_OPERATION_MET_TEST_REQUIRED$ to 22
|
||||||
equ LOT_OPERATION_PACKAGING_REQUIRED$ to 22
|
equ LOT_OPERATION_PACKAGING_REQUIRED$ to 23
|
||||||
equ LOT_OPERATION_CLEAN_REQUIRED$ to 23
|
equ LOT_OPERATION_CLEAN_REQUIRED$ to 24
|
||||||
equ LOT_OPERATION_WAFER_COUNTER_REQUIRED$ to 24
|
equ LOT_OPERATION_WAFER_COUNTER_REQUIRED$ to 25
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
compile insert METROLOGY_DATA_EXAMPLE_EQUATES
|
|
||||||
/*----------------------------------------
|
|
||||||
Author : Table Create Insert Routine
|
|
||||||
Written : 07/04/2025
|
|
||||||
Description : Insert for Table METROLOGY_DATA_EXAMPLE
|
|
||||||
----------------------------------------*/
|
|
||||||
#ifndef __METROLOGY_DATA_EXAMPLE_EQUATES__
|
|
||||||
#define __METROLOGY_DATA_EXAMPLE_EQUATES__
|
|
||||||
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_INSPECTION_TYPE$ to 1
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_TOOL_ID$ to 2
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_DATA_ENTRY_DTM$ to 3
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_DATA_ENTRY_USER$ to 4
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_RAW_DATA_POINTS$ to 5
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_DATA_AVERAGE$ to 6
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_SPEC_LIMIT_UPPER$ to 7
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_IN_SPEC$ to 8
|
|
||||||
equ METROLOGY_DATA_EXAMPLE_SPEC_LIMIT_LOWER$ to 9
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
|||||||
compile insert MET_TEST_DATA_EQUATES
|
compile insert MET_TEST_DATA_EQUATES
|
||||||
/*----------------------------------------
|
/*----------------------------------------
|
||||||
Author : Table Create Insert Routine
|
Author : Table Create Insert Routine
|
||||||
Written : 16/06/2025
|
|
||||||
Description : Insert for Table MET_TEST_DATA
|
Description : Insert for Table MET_TEST_DATA
|
||||||
----------------------------------------*/
|
----------------------------------------*/
|
||||||
#ifndef __MET_TEST_DATA_EQUATES__
|
#ifndef __MET_TEST_DATA_EQUATES__
|
||||||
@ -41,3 +40,4 @@ compile insert MET_TEST_DATA_EQUATES
|
|||||||
equ MET_TEST_DATA.PROPERTY_15_OUT_OF_SPEC$ to 32
|
equ MET_TEST_DATA.PROPERTY_15_OUT_OF_SPEC$ to 32
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
16
LSL2/STPROCINS/MET_TEST_INSERTS.txt
Normal file
16
LSL2/STPROCINS/MET_TEST_INSERTS.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
compile insert MET_TEST_INSERTS
|
||||||
|
/*----------------------------------------
|
||||||
|
Author : Daniel Stieber
|
||||||
|
Written : 20/05/2025
|
||||||
|
Description : Metadata Insert for
|
||||||
|
MET_TEST system.
|
||||||
|
----------------------------------------*/
|
||||||
|
#ifndef __MET_TEST_INSERTS__
|
||||||
|
#define __MET_TEST_INSERTS__
|
||||||
|
|
||||||
|
Declare subroutine Met_Test_Services
|
||||||
|
Declare function Met_Test_Services
|
||||||
|
|
||||||
|
Equ NUM_PROPERTIES$ to 15
|
||||||
|
|
||||||
|
#endif
|
14
LSL2/STPROCINS/PACKAGING_EQUATES.txt
Normal file
14
LSL2/STPROCINS/PACKAGING_EQUATES.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
compile insert PACKAGING_EQUATES
|
||||||
|
/*----------------------------------------
|
||||||
|
Author : Table Create Insert Routine
|
||||||
|
Written : 16/05/2025
|
||||||
|
Description : Insert for Table PACKAGING
|
||||||
|
----------------------------------------*/
|
||||||
|
#ifndef __PACKAGING_EQUATES__
|
||||||
|
#define __PACKAGING_EQUATES__
|
||||||
|
|
||||||
|
equ PACKAGING_LOT_ID$ to 1
|
||||||
|
equ PACKAGING_COMPLETE$ to 2
|
||||||
|
equ PACKAGING_COMPLETE_DTM$ to 3
|
||||||
|
|
||||||
|
#endif
|
@ -1,7 +1,7 @@
|
|||||||
compile insert PRODUCT_OPERATION_EQUATES
|
compile insert PRODUCT_OPERATION_EQUATES
|
||||||
/*----------------------------------------
|
/*----------------------------------------
|
||||||
Author : Table Create Insert Routine
|
Author : Table Create Insert Routine
|
||||||
Written : 11/10/2024
|
Written : 13/05/2025
|
||||||
Description : Insert for Table PRODUCT_OPERATION
|
Description : Insert for Table PRODUCT_OPERATION
|
||||||
----------------------------------------*/
|
----------------------------------------*/
|
||||||
#ifndef __PRODUCT_OPERATION_EQUATES__
|
#ifndef __PRODUCT_OPERATION_EQUATES__
|
||||||
|
Reference in New Issue
Block a user