Merged PR 21151: Return To Fab Operations and Processing

This commit is contained in:
Ouellette Jonathan (CSC FI SPS MESLEO)
2025-07-16 21:17:07 +02:00
parent b607432be4
commit aabd4c3a91
56 changed files with 8856 additions and 2508 deletions

File diff suppressed because it is too large Load Diff

View File

@ -149,4 +149,3 @@ end api
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs // Internal GoSubs
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -136,4 +136,3 @@ CreateHALCollection:
end end
return return

258
LSL2/STPROC/CLEAN_API.txt Normal file
View 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

View 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

View File

@ -858,3 +858,4 @@ Result = ReturnData
RETURN RETURN

View File

@ -213,4 +213,3 @@ UpdateHALItem:
end end
return return

View File

@ -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

View File

@ -94,4 +94,3 @@ API engineinfo.ID.GET
end end
end api end api

View File

@ -69,4 +69,3 @@ API healthinfo.GET
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -161,7 +161,3 @@ API Lock.HEAD
end end
end api end api

View 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

View File

@ -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

View File

@ -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

View File

@ -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,48 +114,53 @@ Service RemoveLotOperation(LotOperationId, UserId)
Success = False$ Success = False$
If RowExists('LOT_OPERATION', LotOperationId) then If RowExists('LOT_OPERATION', LotOperationId) then
LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$) If Lot_Services('CanUserModifyLot', UserId) then
LotId = LotOperationRec<LOT_OPERATION_LOT_ID$> LotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationId, True$, 0, False$)
MoveInTime = LotOperationRec<LOT_OPERATION_DATETIME_IN$> LotId = LotOperationRec<LOT_OPERATION_LOT_ID$>
MoveOutTime = LotOperationRec<LOT_OPERATION_DATETIME_OUT$> MoveInTime = LotOperationRec<LOT_OPERATION_DATETIME_IN$>
Sequence = LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> MoveOutTime = LotOperationRec<LOT_OPERATION_DATETIME_OUT$>
OperationId = LotOperationRec<LOT_OPERATION_OPERATION_ID$> Sequence = LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>
OperationClass = XLATE('OPERATION', OperationId, OPERATION_CLASS_ID$, 'X') OperationId = LotOperationRec<LOT_OPERATION_OPERATION_ID$>
If OperationClass NE 'RTF_DEFAULT' AND OperationClass NE 'RTF_DEFAULT_END' then OperationClass = XLATE('OPERATION', OperationId, OPERATION_CLASS_ID$, 'X')
If MoveInTime EQ '' AND MoveOutTime EQ '' then If OperationClass NE 'RTF_DEFAULT' AND OperationClass NE 'RTF_DEFAULT_END' then
LotOperationRec<LOT_OPERATION_LOT_ID$> = '';//Nulling this value out should disassociated the lot operation record from the lot. If MoveInTime EQ '' AND MoveOutTime EQ '' then
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, LotOperationRec) LotOperationRec<LOT_OPERATION_LOT_ID$> = '';//Nulling this value out should disassociated the lot operation record from the lot.
If Error_Services('NoError') then Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationId, LotOperationRec)
Lot_Operation_Services('UpdateLotOperationSequence', LotId, Sequence)
If Error_Services('NoError') then If Error_Services('NoError') then
Success = True$ Lot_Operation_Services('UpdateLotOperationSequence', LotId, Sequence)
If Error_Services('NoError') then
Success = True$
end else
ErrorMessage = Error_Services('GetMessage')
end
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
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REMOVE_LOT_OPERATION', 'Removed operation ' : OperationId : ' from lot.', '', UserId)
end else end else
ErrorMessage = Error_Services('GetMessage') ErrorMessage = 'Lot has already started processing on operation ' : OperationId
end end
end else end else
ErrorMessage = 'Lot has already started processing on operation ' : OperationId ErrorMessage = 'Unable to remove default operations.'
end end
end else end else
ErrorMessage = 'Unable to remove default operations.' ErrorMessage = 'User ' : UserId : ' does not have permission modify lots.'
end 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,9 +205,7 @@ 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
@ -221,30 +213,6 @@ Service GetAvailableSequences(LotId)
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.
@ -436,13 +415,15 @@ Service CompleteLotOperation(LotOperationId, UserId)
ErrorMessage = Error_Services('GetMessage') ErrorMessage = Error_Services('GetMessage')
end end
end else end else
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.'
@ -452,10 +433,10 @@ Service CompleteLotOperation(LotOperationId, UserId)
end end
If ErrorMessage EQ '' then If ErrorMessage EQ '' then
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 end
If CleanRequired then If CleanRequired AND IsValid then
AssociatedCleanIds = LotOperationRec<LOT_OPERATION_CLEAN_ID$>
If AssociatedCleanIds NE '' then
IsValid = True$
end else
IsValid = False$
end
end end
If WaferCountRequired then 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

View File

@ -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,71 +182,112 @@ 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 := 'LEGACY_LOT_ID':@VM:LegacyLotId:@FM
SearchString := 'TYPE':@VM:LegacyLotType:@FM
LotIdKeys = ''
Btree.Extract(SearchString, 'LOT', DictLot, LotIdKeys, '', '')
ErrCode = ''
IF Get_Status(ErrCode) then
ErrorMsg = 'Error in ':Service:' service. Error calling Btree.Extract. Error code ':ErrCode:'.'
end else
Response = LotIdKeys<1,1>
end
end else
ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.'
end
EndTick = GetTickCount() SearchString = ''
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick) SearchString := 'LEGACY_LOT_ID':@VM:LegacyLotId:@FM
SearchString := 'LEGACY_LOT_TYPE':@VM:LegacyLotType:@FM
LotIdKeys = ''
Btree.Extract(SearchString, 'LOT', DictLot, LotIdKeys, '', '')
ErrCode = ''
IF Get_Status(ErrCode) then
ErrorMsg = 'Error in ':Service:' service. Error calling Btree.Extract. Error code ':ErrCode:'.'
end else
Response = LotIdKeys<1,1>
end
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end else
ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
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'
CreatedLotNumber = '' CreatedLotNumber = ''
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'
// Case statement for legacy lot entity types If LegacyLotId NE '' then
NewLotId = Lot_Services('GenerateNewLotId', LotType) LegacyLotType = LotType
If NewLotId NE '' then LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', LegacyLotId, LegacyLotType)
If RowExists('LOT', NewLotId) NE False$ then If LotId EQ '' then
LotRec = '' LotType = 'PROD'
LotRec<LOT_TYPE$> = LotType // Case statement for legacy lot entity types
LotRec<LOT_PROD_ID$> = '' NewLotId = Lot_Services('GenerateNewLotId', LegacyLotType)
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty If NewLotId NE '' then
LotRec<LOT_WAFER_QTY$> = LotQty If RowExists('LOT', NewLotId) NE False$ then
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo WoNo = ''
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo EpiPartNo = ''
LotRec<LOT_VENDOR_CODE$> = VendorCode ProdVerNo = ''
LotRec<LOT_LEGACY_LOT_ID$> = LotId Begin Case
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec) Case LegacyLotType EQ 'RDS'
If Error_Services('HasError') then WoNo = XLATE('RDS', LegacyLotId, RDS_WO$, 'X')
ErrorMessage = 'Error in ':Service:' service. ':Error_Services('GetMessage') Case LegacyLotType EQ 'WM_IN' OR LegacyLotType EQ 'WM_OUT' OR LegacyLotType EQ 'WO_MAT'
end else WoNo = Field(LegacyLotId, '*', 1)
CreatedLotNumber = NewLotId End Case
end
end else ProdVerNo = XLATE('WO_LOG', WoNo, WO_LOG_PROD_VER_NO$, 'X')
ErrorMessage = 'Error in ':Service:' service. LOT record "':NewLotId:'" already exists.' EpiPartNo = XLATE('WO_LOG', WoNo, WO_LOG_EPI_PART_NO$, 'X')
end ProdId = EpiPartNo : '*' : ProdVerNo
end else ProdSpecId = XLATE('WO_LOG', WoNo, WO_LOG_PROD_SPEC_ID$, 'X')
ErrorMessage = 'Error in ':Service:' service. No lot ID passed in.' If ProdSpecId EQ '' then
end Begin Case
Case LotType EQ 'TW' 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<LOT_TYPE$> = 'PROD'
LotRec<LOT_PROD_ID$> = ProdId
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
LotRec<LOT_WAFER_QTY$> = LotQty
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
LotRec<LOT_VENDOR_CODE$> = VendorCode
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)
If Error_Services('NoError') then
CreatedLotNumber = NewLotId
end else
ErrorMessage = 'Error in ':Service:' service. ':Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in ':Service:' service. Failed to generate new LOT id. LOT record "':NewLotId:'" already exists.'
end
end else
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
Case LotType EQ 'TW'
If ProdName NE '' then If ProdName NE '' then
TWProdID = Test_Wafer_Prod_Services('GetTestWaferProdIDsByPartName', ProdName) TWProdID = Test_Wafer_Prod_Services('GetTestWaferProdIDsByPartName', ProdName)
If TWProdID NE '' then If TWProdID NE '' then
@ -536,42 +582,46 @@ end service
Service CreateInitialLotOperationRecords(LotId) Service CreateInitialLotOperationRecords(LotId)
ErrorMessage = ''
If LotId NE '' then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
LotType = LotRec<LOT_TYPE$>
ProdId = LotRec<LOT_PROD_ID$>
ThisInitialProdOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId, LotType)
If Error_Services('NoError') AND ThisInitialProdOperations NE '' then
For each ProdOperation in ThisInitialProdOperations using @VM
ErrorMessage = '' ProdOperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperation)
If LotId NE '' then OperationID = ProdOperationRec<PRODUCT_OPERATION_OPERATION_ID$>
LotRec = Database_Services('ReadDataRow', 'LOT', LotId) OperationSequence = ProdOperationRec<PRODUCT_OPERATION_OPERATION_SEQUENCE$>
LotType = LotRec<LOT_TYPE$>
ProdId = LotRec<LOT_PROD_ID$>
ThisInitialProdOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId, LotType)
If Error_Services('NoError') AND ThisInitialProdOperations NE '' then
For each ProdOperation in ThisInitialProdOperations using @VM
ProdOperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperation)
OperationID = ProdOperationRec<PRODUCT_OPERATION_OPERATION_ID$>
OperationSequence = ProdOperationRec<PRODUCT_OPERATION_OPERATION_SEQUENCE$>
LotOperationRecID = Rti_Createguid()
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
LotOperationRec = ''
LotOperationRec<LOT_OPERATION_LOT_ID$> = LotId
LotOperationRec<LOT_OPERATION_OPERATION_ID$> = OperationID
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = OperationSequence
LotOperationRec<LOT_OPERATION_REWORK$> = False$
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
TestRec = Database_Services('ReadDataRow', 'LOT', LotId)
end else
ErrorMessage = 'Error in ':Service:' service. Lot Operation already existed, cannot overwrite.'
end
Next Operation
end else
ErrorMessage = 'Error in ':Service:' service. Error getting prescribed operations for lot# ' : LotId
end
end else
ErrorMessage = 'Error in ':Service:' service. Null LotID passed into service.'
end
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
LotOperationRecID = Rti_Createguid()
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
LotOperationRec = ''
LotOperationRec<LOT_OPERATION_LOT_ID$> = LotId
LotOperationRec<LOT_OPERATION_OPERATION_ID$> = OperationID
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = OperationSequence
LotOperationRec<LOT_OPERATION_REWORK$> = False$
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
If Error_Services('HasError') then
ErrorMessage = 'Error Writing Lot Operation Record.'
end
end else
ErrorMessage = 'Lot Operation already existed, cannot overwrite'
end
Next Operation
end else
ErrorMessage = 'Error getting prescribed operations for lot# ' : LotId
end
end else
ErrorMessage = 'Lot ID was null'
end
If ErrorMessage NE '' then
Error_Services('Add', ErrorMessage)
end
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)
StartTick = GetTickCount() ErrorMsg = ''
MetricName = 'GetLotCurrOperationId' StartTick = GetTickCount()
ErrorMsg = '' MetricName = 'GetLotCurrOperationId'
CurrOperation = '' CurrOperation = ''
If LotID NE '' then If LotID NE '' then
// Get them in sequence first // Get them in sequence first
@ -1023,124 +1074,143 @@ end service
Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN) Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
ErrorMessage = '' ErrorMessage = ''
JsonString = '' JsonString = ''
If FullObject EQ '' then FullObject = True$ If FullObject EQ '' then
If RowExists('LOT', LotId) then FullObject = True$
objJSON = '' end
If SRP_JSON(objJSON, 'New', 'Object') then If RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId) objJSON = ''
If Error_Services('NoError') then If SRP_JSON(objJSON, 'New', 'Object') then
If SRP_JSON(objLot, 'New', 'Object') then LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
SRP_JSON(objLot, 'SetValue', 'LotId', LotId) If Error_Services('NoError') then
SRP_JSON(objLot, 'SetValue', 'Type', LotRec<LOT_TYPE$>) If SRP_JSON(objLot, 'New', 'Object') then
SRP_JSON(objLot, 'SetValue', 'ProdId', LotRec<LOT_PROD_ID$>)
Begin Case
Case LotRec<LOT_TYPE$> = 'TW'
ProdName = XLATE('TEST_WAFER_PROD', LotRec<LOT_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
Case Otherwise$
ProdName = ''
End Case
SRP_JSON(objLot, 'SetValue', 'ProdName', ProdName)
SRP_JSON(objLot, 'SetValue', 'OrigWaferQty', LotRec<LOT_ORIG_WAFER_QTY$>)
SRP_JSON(objLot, 'SetValue', 'WaferQty', LotRec<LOT_WAFER_QTY$>)
SRP_JSON(objLot, 'SetValue', 'VendorPartNo', LotRec<LOT_VENDOR_PART_NO$>)
SRP_JSON(objLot, 'SetValue', 'VendorLotNo', LotRec<LOT_VENDOR_LOT_NO$>)
SRP_JSON(objLot, 'SetValue', 'Vendor', LotRec<LOT_VENDOR_CODE$>)
CurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
CurrOperation = XLATE('LOT_OPERATION', CurrOperation, LOT_OPERATION_OPERATION_ID$, 'X')
SRP_JSON(objLot, 'SetValue', 'CurrOperation', CurrOperation)
MostRecentEventId = LotRec<LOT_MOST_RECENT_LOT_EVENT_ID$>
MostRecentEventDtmIConv = Xlate('LOT_EVENT', MostRecentEventId, LOT_EVENT_EVENT_DATETIME$, 'X')
MostRecentEventDtmOConv = OConv(MostRecentEventDtmIConv, 'DT')
SRP_JSON(objLot, 'SetValue', 'MostRecentEventDateTime', MostRecentEventDtmOConv)
If FullObject then
// Events Array
EventsArrayJson = ''
If SRP_Json(EventsArrayJson, 'New', 'Array') then
LotEventKeys = Lot_Event_Services('GetLotEventsInSequence', LotId)
for each LotEventKey in LotEventKeys using @FM
objEvent = ''
EventRec = Database_Services('ReadDataRow', 'LOT_EVENT', LotEventKey)
If SRP_Json(objEvent, 'New', 'Object') then
SRP_JSON(objEvent, 'SetValue', 'LotEventId', LotEventKey)
SRP_JSON(objEvent, 'SetValue', 'LotId', EventRec<LOT_EVENT_LOT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'LotEventType', EventRec<LOT_EVENT_LOT_EVENT_TYPE$>)
SRP_JSON(objEvent, 'SetValue', 'EventDatetime', OConv(EventRec<LOT_EVENT_EVENT_DATETIME$>, 'DT'))
SRP_JSON(objEvent, 'SetValue', 'EventNote', EventRec<LOT_EVENT_EVENT_NOTE$>)
SRP_JSON(objEvent, 'SetValue', 'EquipmentId', EventRec<LOT_EVENT_EQUIPMENT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventReduceWaferQty', EventRec<LOT_EVENT_EVENT_REDUCE_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBonusWaferQty', EventRec<LOT_EVENT_EVENT_BONUS_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBeginWaferQty', EventRec<LOT_EVENT_EVENT_BEGIN_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventEndWaferQty', EventRec<LOT_EVENT_EVENT_END_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperationId', EventRec<LOT_EVENT_EVENT_OPERATION_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperatorId', EventRec<LOT_EVENT_EVENT_OPERATOR_ID$>)
SRP_JSON(objEvent, 'SetValue', 'Sequence', EventRec<LOT_EVENT_SEQUENCE$>)
SRP_JSON(EventsArrayJson, 'Add', objEvent)
SRP_JSON(objEvent, 'Release')
end
Next LotEventKey
SRP_JSON(objLot, 'Set', 'LotEvents', EventsArrayJson)
SRP_JSON(EventsArrayJson, 'Release')
end else
ErrorMessage = 'Error Creating Events JSON Array'
end
// Operations Array
OperationsArrayJson = ''
If SRP_Json(OperationsArrayJson, 'New', 'Array') then
LotOperationKeys = Lot_Services('GetLotOperationSequence', LotId)
for each LotOperationKey in LotOperationKeys using @FM
objOperation = ''
OperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationKey)
If SRP_Json(objOperation, 'New', 'Object') then
SRP_JSON(objOperation, 'SetValue', 'LotOperationId', LotOperationKey)
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
Next LotOperationKey SRP_JSON(objLot, 'SetValue', 'LotId', LotId)
SRP_JSON(objLot, 'Set', 'LotOperations', OperationsArrayJson) SRP_JSON(objLot, 'SetValue', 'LegacyLotId', LotRec<LOT_LEGACY_LOT_ID$>, 'String')
SRP_JSON(OperationsArrayJson, 'Release') SRP_JSON(objLot, 'SetValue', 'LegacyLotType', LotRec<LOT_LEGACY_LOT_TYPE$>, 'String')
end else CanUserModifyLot = Lot_Services('CanUserModifyLot', CurrUser)
ErrorMessage = 'Error Creating Operations JSON Array' SRP_JSON(objLot, 'SetValue', 'CanUserModifyLot', CanUserModifyLot, 'Boolean')
end SRP_JSON(objLot, 'SetValue', 'WorkOrderNo', LotRec<LOT_WO_LOG_ID$>, 'String')
end SRP_JSON(objLot, 'SetValue', 'EpiPartNo', LotRec<LOT_EPI_PART_NO$>, 'String')
SRP_JSON(objLot, 'SetValue', 'Type', LotRec<LOT_TYPE$>)
SRP_JSON(objJSON, 'Set', 'Lot', objLot) SRP_JSON(objLot, 'SetValue', 'ProdId', LotRec<LOT_PROD_ID$>)
SRP_JSON(objLot, 'Release') ProdSpecNo = LotRec<LOT_PROD_SPEC_ID$>
end else SRP_JSON(objLot, 'SetValue', 'ProdSpecNo', ProdSpecNo, 'String')
ErrorMessage = 'Error creating new Lot Json Object' Begin Case
end Case LotRec<LOT_TYPE$> = 'TW'
end else ProdName = XLATE('TEST_WAFER_PROD', LotRec<LOT_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
ErrorMessage = 'Error reading ':LotId:' from lot table.' Case Otherwise$
end ProdName = ''
JsonString = SRP_JSON(objJSON, 'Stringify', 'Styled') End Case
SRP_JSON(objJSON, 'Release') SRP_JSON(objLot, 'SetValue', 'ProdName', ProdName)
end else SRP_JSON(objLot, 'SetValue', 'OrigWaferQty', LotRec<LOT_ORIG_WAFER_QTY$>)
ErrorMessage = 'Error creating new Json Object' SRP_JSON(objLot, 'SetValue', 'WaferQty', LotRec<LOT_WAFER_QTY$>)
end SRP_JSON(objLot, 'SetValue', 'VendorPartNo', LotRec<LOT_VENDOR_PART_NO$>)
end else SRP_JSON(objLot, 'SetValue', 'VendorLotNo', LotRec<LOT_VENDOR_LOT_NO$>)
ErrorMessage = 'Invalid or null lot number passed to routine.' SRP_JSON(objLot, 'SetValue', 'Vendor', LotRec<LOT_VENDOR_CODE$>)
end CurrLotOperationId = Lot_Services('GetLotCurrOperationId', LotId)
CurrOperation = XLATE('LOT_OPERATION', CurrLotOperationId, LOT_OPERATION_OPERATION_ID$, 'X')
If ErrorMessage EQ '' then CurrOperationDesc = XLATE('OPERATION', CurrOperation, OPERATION_OPERATION_DESCRIPTION$, 'X')
Response = JsonString SRP_JSON(objLot, 'SetValue', 'CurrLotOperationId', CurrLotOperationId)
end else SRP_JSON(objLot, 'SetValue', 'CurrOperation', CurrOperation)
Error_Services('Add', ErrorMessage) SRP_JSON(objLot, 'SetValue', 'CurrOperationDesc', CurrOperationDesc, 'String')
end MostRecentEventId = LotRec<LOT_MOST_RECENT_LOT_EVENT_ID$>
MostRecentEventDtmIConv = Xlate('LOT_EVENT', MostRecentEventId, LOT_EVENT_EVENT_DATETIME$, 'X')
MostRecentEventDtmOConv = OConv(MostRecentEventDtmIConv, 'DT')
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
//Events Array
EventsArrayJson = ''
If SRP_Json(EventsArrayJson, 'New', 'Array') then
LotEventKeys = Lot_Event_Services('GetLotEventsInSequence', LotId)
for each LotEventKey in LotEventKeys using @FM
objEvent = ''
EventRec = Database_Services('ReadDataRow', 'LOT_EVENT', LotEventKey)
If SRP_Json(objEvent, 'New', 'Object') then
SRP_JSON(objEvent, 'SetValue', 'LotEventId', LotEventKey)
SRP_JSON(objEvent, 'SetValue', 'LotId', EventRec<LOT_EVENT_LOT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'LotEventType', EventRec<LOT_EVENT_LOT_EVENT_TYPE$>)
SRP_JSON(objEvent, 'SetValue', 'EventDatetime', OConv(EventRec<LOT_EVENT_EVENT_DATETIME$>, 'DT'))
SRP_JSON(objEvent, 'SetValue', 'EventNote', EventRec<LOT_EVENT_EVENT_NOTE$>)
SRP_JSON(objEvent, 'SetValue', 'EquipmentId', EventRec<LOT_EVENT_EQUIPMENT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventReduceWaferQty', EventRec<LOT_EVENT_EVENT_REDUCE_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBonusWaferQty', EventRec<LOT_EVENT_EVENT_BONUS_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBeginWaferQty', EventRec<LOT_EVENT_EVENT_BEGIN_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventEndWaferQty', EventRec<LOT_EVENT_EVENT_END_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperationId', EventRec<LOT_EVENT_EVENT_OPERATION_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperatorId', EventRec<LOT_EVENT_EVENT_OPERATOR_ID$>)
SRP_JSON(objEvent, 'SetValue', 'Sequence', EventRec<LOT_EVENT_SEQUENCE$>)
SRP_JSON(EventsArrayJson, 'Add', objEvent)
SRP_JSON(objEvent, 'Release')
end
Next LotEventKey
SRP_JSON(objLot, 'Set', 'LotEvents', EventsArrayJson)
SRP_JSON(EventsArrayJson, 'Release')
end else
ErrorMessage = 'Error Creating Events JSON Array'
end
OperationsArrayJson = ''
If SRP_Json(OperationsArrayJson, 'New', 'Array') then
LotOperationKeys = Lot_Services('GetLotOperationSequence', LotId)
for each LotOperationKey in LotOperationKeys using @FM
ThisLotOperationJsonString = Lot_Operation_Services('ConvertRecordToJson', LotOperationKey)
If SRP_Json(objLotOperation, 'PARSE', ThisLotOperationJsonString) EQ '' then
SRP_Json(OperationsArrayJson, 'Add', objLotOperation)
SRP_Json(objLotOperation, 'Release')
end
Next LotOperationKey
SRP_JSON(objLot, 'Set', 'LotOperations', OperationsArrayJson)
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
ErrorMessage = 'Error Creating Operations JSON Array'
end
end
SRP_JSON(objJSON, 'Set', 'Lot', objLot)
SRP_JSON(objLot, 'Release')
end else
ErrorMessage = 'Error creating new Lot Json Object'
end
end else
ErrorMessage = 'Error reading ':LotId:' from lot table.'
end
JsonString = SRP_JSON(objJSON, 'Stringify', 'Styled')
SRP_JSON(objJSON, 'Release')
end else
ErrorMessage = 'Error creating new Json Object'
end
end else
ErrorMessage = 'Invalid or null lot number passed to routine.'
end
If ErrorMessage NE '' then
Error_Services('Add', ErrorMessage)
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
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------

View File

@ -132,4 +132,3 @@ CreateHALItem:
end end
return return

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View File

@ -135,4 +135,3 @@ API monaengines.ID.GET
end end
end api end api

View File

@ -61,4 +61,3 @@ API mona.GET
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -190,9 +190,3 @@ return

View File

@ -300,3 +300,5 @@ SetDelay:
return return

View 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

View 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

View 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

View File

@ -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

View File

@ -76,4 +76,3 @@ API pm.ID.POST
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -61,4 +61,3 @@ API pm_spec.GET
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -102,5 +102,3 @@ CreateHALItem:
end end
return return

View File

@ -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

View File

@ -103,4 +103,3 @@ API reactorloadings.POST
end end
end api end api

View File

@ -260,5 +260,3 @@ API reactorlogs.ID.nicaoverride.PUT
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -259,5 +259,3 @@ CreateHALCollection:
end end
return return

View File

@ -61,4 +61,3 @@ API remotehealthcheck.GET
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -233,5 +233,3 @@ API reports.GET
HTTP_Resource_Services('LoremIpsum') HTTP_Resource_Services('LoremIpsum')
end api end api

View File

@ -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,28 +258,18 @@ 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') RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', True$)
RTFId = EndpointSegment If RTFJson NE '' then
If Error_Services('NoError') AND RTFId NE '' then HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
RTFJson = Return_To_Fab_Services('CreateReturnToFabReportJson', True$) HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
If Error_Services('NoError') then If Assigned(Message) then
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) HTTP_Services('SetResponseStatus', 201, Message)
HTTP_Services('SetResponseBody', RTFJson, False$, 'application/hal+json')
If Assigned(Message) then
HTTP_Services('SetResponseStatus', 201, Message)
end else
HTTP_Services('SetResponseStatus', 201)
end
end else
end
end else end else
HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage')) HTTP_Services('SetResponseStatus', 201)
end end
end else end else
HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.') ErrorMessage = 'Error getting report data.'
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

View File

@ -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

View File

@ -830,8 +830,3 @@ end service

View File

@ -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

View File

@ -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

View File

@ -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\
@ -226,15 +228,15 @@ Service GetWaferCounterJSON(WaferSize, ToolLocation, CassID)
If Error_Services('NoError') then If Error_Services('NoError') then
StatusCode = Httpclient_Services('GetResponseStatusCode') StatusCode = Httpclient_Services('GetResponseStatusCode')
If StatusCode NE 200 then If StatusCode NE 200 then
Begin Case Begin Case
Case Response EQ '' Case Response EQ ''
ErrorMsg = 'Unexpected server error.' ErrorMsg = 'Unexpected server error.'
Case Response EQ 'No files!' Case Response EQ 'No files!'
ErrorMsg = 'No data. Please re-seat cassette and try again.' ErrorMsg = 'No data. Please re-seat cassette and try again.'
Case Otherwise$ Case Otherwise$
// Use message in response body to populate error services // Use message in response body to populate error services
ErrorMsg = Response ErrorMsg = Response
End Case End Case
Error_Services('Add', ErrorMsg) Error_Services('Add', ErrorMsg)
end end
end end
@ -448,9 +450,9 @@ Service ProcessCass2DBarcode(BarcodeText)
end end
If ErrorMessage EQ '' then If ErrorMessage EQ '' then
Response = CassId : @VM: ExpectedQty : @VM : CassType Response = CassId : @VM: ExpectedQty : @VM : CassType
end else end else
Error_Services('Add', ErrorMessage) Error_Services('Add', ErrorMessage)
end end
end service end service
@ -471,9 +473,9 @@ Service ProcessTool2DBarcode(BarcodeText, CassId, CassType, UserId)
WaferSize = Field(BarcodeText, '|', 1) WaferSize = Field(BarcodeText, '|', 1)
Area = Field(BarcodeText, '|', 2) Area = Field(BarcodeText, '|', 2)
If Environment_Services('IsProd') then If Environment_Services('IsProd') then
WcJson = Wafer_Counter_Services('GetWaferCounterJSON', WaferSize, Area, CassID) WcJson = Wafer_Counter_Services('GetWaferCounterJSON', WaferSize, Area, CassID)
end else end else
WcJson = Wafer_Counter_Services('GetWaferCounterJSONTestData', WaferSize, Area, CassID) WcJson = Wafer_Counter_Services('GetWaferCounterJSONTestData', WaferSize, Area, CassID)
end end
If Error_Services('NoError') then If Error_Services('NoError') then
@ -504,13 +506,13 @@ Service ProcessTool2DBarcode(BarcodeText, CassId, CassType, UserId)
ErrorMessage = 'Invalid tool scan.' ErrorMessage = 'Invalid tool scan.'
end end
end else end else
ErrorMessage = 'Scan data was null.' ErrorMessage = 'Scan data was null.'
end end
If ErrorMessage EQ '' then If ErrorMessage EQ '' then
Response = WaferCounterId Response = WaferCounterId
end else end else
Error_Services('Add', ErrorMessage) Error_Services('Add', ErrorMessage)
end end
end service end service
@ -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
@ -537,15 +539,15 @@ Service GetWaferCounterJSONTestData(WaferSize, ToolLocation, CassID)
If Error_Services('NoError') then If Error_Services('NoError') then
StatusCode = 200 StatusCode = 200
If StatusCode NE 200 then If StatusCode NE 200 then
Begin Case Begin Case
Case Response EQ '' Case Response EQ ''
ErrorMsg = 'Unexpected server error.' ErrorMsg = 'Unexpected server error.'
Case Response EQ 'No files!' Case Response EQ 'No files!'
ErrorMsg = 'No data. Please re-seat cassette and try again.' ErrorMsg = 'No data. Please re-seat cassette and try again.'
Case Otherwise$ Case Otherwise$
// Use message in response body to populate error services // Use message in response body to populate error services
ErrorMsg = Response ErrorMsg = Response
End Case End Case
Error_Services('Add', ErrorMsg) Error_Services('Add', ErrorMsg)
end end
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

View File

@ -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

View File

@ -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

View 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

View File

@ -28,6 +28,6 @@ compile insert LOT_EQUATES
equ LOT_PROD_SPEC_ID$ to 19 equ LOT_PROD_SPEC_ID$ to 19
equ LOT_EPI_PART_NO$ to 20 equ LOT_EPI_PART_NO$ to 20
equ LOT_PROD_VER_NO$ to 21 equ LOT_PROD_VER_NO$ to 21
equ LOT_MET_TEST_IDS$ to 22 equ LOT_MET_TEST_IDS$ to 22
#endif #endif

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View 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

View File

@ -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__