401 lines
20 KiB
Plaintext
401 lines
20 KiB
Plaintext
Compile function WM_Out_Services(@Service, @Params)
|
|
/***********************************************************************************************************************
|
|
|
|
Name : WM_Out_Services
|
|
|
|
Description : Handler program for all WM_OUT services.
|
|
|
|
Notes : Application errors should be logged using the Error Services module. There are a few methodological
|
|
assumptions built into way errors are managed which are important to understand in order to properly
|
|
work with Error Services:
|
|
|
|
- The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
|
|
the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
|
|
this will appear backwards since the originating procedure always appears at the bottom of the
|
|
list and the current routine appears at the top of the list. We are using this orientation because
|
|
it is common to refer to the process of calling other procedures as 'drilling down'.
|
|
|
|
- The reason for defining the orientation of the call stack is because Error_Services allows for
|
|
multiple error conditions to be appended to an original error. In most cases this will happen when
|
|
a procedure at the bottom of the stack generates an error condition and then returns to its
|
|
calling procedure. This higher level procedure can optionally add more information relevant to
|
|
itself. This continues as the call stack 'bubbles' its way back to the top to where the
|
|
originating procedure is waiting.
|
|
|
|
- Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
|
|
preserve their error state until explicitly cleared. This can hinder the normal execution of code
|
|
since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
|
|
Our philosophy is that error conditions should automatically be cleared before a new procedure
|
|
is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
|
|
automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
|
|
philosophy then it should include a call into the 'Clear' service request at the top of the
|
|
program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)
|
|
|
|
- Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
|
|
error conditions that were set before.
|
|
|
|
Parameters :
|
|
Service [in] -- Name of the service being requested
|
|
Param1-10 [in/out] -- Additional request parameter holders
|
|
Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure
|
|
|
|
Metadata :
|
|
|
|
History : (Date, Initials, Notes)
|
|
11/16/22 djs Original programmer.
|
|
08/31/23 djm Added view/add comment functions.
|
|
|
|
***********************************************************************************************************************/
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$Insert SERVICE_SETUP
|
|
$Insert LOGICAL
|
|
$Insert MSG_EQUATES
|
|
$Insert DICT_EQUATES
|
|
$Insert WM_OUT_EQUATES
|
|
$Insert WO_MAT_EQUATES
|
|
$Insert WO_LOG_EQUATES
|
|
$Insert COMPANY_EQUATES
|
|
$Insert RETURN_TO_FAB_LOTS_EQUATES
|
|
|
|
Declare function Database_Services, SRP_JSON, Error_Services, Clean_Insp_Services, WO_Mat_QA_Services
|
|
Declare function PSN_Services, SRP_Rotate_Array, Datetime, Return_To_Fab_Services
|
|
Declare subroutine Database_Services, SRP_JSON, Error_Services, Extract_Si_Keys
|
|
|
|
GoToService
|
|
|
|
Return Response or ""
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SERVICES
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetComments
|
|
//
|
|
// WMOutNo - [Required]
|
|
//
|
|
// Returns a delimited array of all EPP_COMMENT_NOTE, EPP_COMMENT_USER, and EPP_COMMENT_DATE
|
|
// associated with a WM_OUT record. Note: Dates are returned Oconv'd.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetComments(WMOutNo)
|
|
|
|
CommentArray = ''
|
|
WMOutRow = Database_Services('ReadDataRow', 'WM_OUT', WMOutNo)
|
|
|
|
CommentDates = Oconv(WMOutRow<WM_OUT_EPP_COMMENT_DATE$>, 'DT')
|
|
CommentUsers = WMOutRow<WM_OUT_EPP_COMMENT_USER$>
|
|
Comments = WMOutRow<WM_OUT_EPP_COMMENT_NOTE$>
|
|
|
|
CommentList = CommentDates :@FM: CommentUsers :@FM: Comments
|
|
CommentArray = SRP_Rotate_Array(CommentList)
|
|
Response = CommentArray
|
|
|
|
End Service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// AddComment
|
|
//
|
|
// WMOutNo - [Required]
|
|
// Comment - [Required]
|
|
//
|
|
// Adds an EPP_COMMENT_NOTE, EPP_COMMENT_USER, and EPP_COMMENT_DATE
|
|
// to a WM_OUT record.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service AddComment(WMOutNo, Comment, UsernameOpt)
|
|
|
|
WMOutRow = Database_Services('ReadDataRow', 'WM_OUT', WMOutNo)
|
|
UserName = @USER4
|
|
If Assigned(UsernameOpt) then
|
|
If UsernameOpt NE '' then
|
|
Username = UsernameOpt
|
|
end
|
|
end
|
|
CommentTime = Datetime()
|
|
|
|
OldDates = WMOutRow<WM_OUT_EPP_COMMENT_DATE$>
|
|
OldUsers = WMOutRow<WM_OUT_EPP_COMMENT_USER$>
|
|
OldComments = WMOutRow<WM_OUT_EPP_COMMENT_NOTE$>
|
|
If (OldDates EQ '' AND OldUsers EQ '' AND OldComments EQ '') then
|
|
WMOutRow<WM_OUT_EPP_COMMENT_DATE$> = CommentTime
|
|
WMOutRow<WM_OUT_EPP_COMMENT_USER$> = UserName
|
|
WMOutRow<WM_OUT_EPP_COMMENT_NOTE$> = Comment
|
|
end else
|
|
WMOutRow<WM_OUT_EPP_COMMENT_DATE$> = CommentTime :@VM: OldDates
|
|
WMOutRow<WM_OUT_EPP_COMMENT_USER$> = UserName :@VM: OldUsers
|
|
WMOutRow<WM_OUT_EPP_COMMENT_NOTE$> = Comment :@VM: OldComments
|
|
end
|
|
Database_Services('WriteDataRow', 'WM_OUT', WMOutNo, WMOutRow, 1, 0, 0)
|
|
|
|
End Service
|
|
|
|
|
|
Service ConvertRecordToJSON(KeyID, Record, ItemURL)
|
|
|
|
jsonRecord = ''
|
|
|
|
If KeyID NE '' then
|
|
|
|
If Record EQ '' then Record = Database_Services('ReadDataRow', 'WM_OUT', KeyID)
|
|
If Error_Services('NoError') then
|
|
@DICT = Database_Services('GetTableHandle', 'DICT.WM_OUT')
|
|
@ID = KeyID
|
|
@RECORD = Record
|
|
objJSON = ''
|
|
If SRP_JSON(objJSON, 'New', 'Object') then
|
|
objWMOut = ''
|
|
If SRP_JSON(objWMOut, 'New', 'Object') then
|
|
SRP_JSON(objWMOut, 'SetValue', 'keyId', @ID)
|
|
SRP_JSON(objWMOut, 'SetValue', 'workOrder', {WO_NO})
|
|
SRP_JSON(objWMOut, 'SetValue', 'outCassNo', {OUT_CASS_NO})
|
|
WoMatKey = {WO_NO} : '*' : {OUT_CASS_NO}
|
|
SAPBatchNo = Database_Services('ReadDataColumn', 'WO_MAT', WoMatKey, WO_MAT_SAP_BATCH_NO$, True$, 0, False$)
|
|
SRP_JSON(objWMOut, 'SetValue', 'SapBatchNo', SAPBatchNo, 'String')
|
|
CurrWfrQty = XLATE('WO_MAT', WoMatKey, 'CURR_WFR_CNT', 'X')
|
|
SRP_JSON(objWMOut, 'SetValue', 'CURR_WFR_CNT', CurrWfrQty)
|
|
CustNo = Database_Services('ReadDataColumn', 'WO_LOG', {WO_NO}, WO_LOG_CUST_NO$, True$, 0, False$)
|
|
CustReshipNo = Database_Services('ReadDataColumn', 'WO_MAT', WoMatKey, WO_MAT_RESHIP_CUST_NO$, True$, 0, False$)
|
|
If CustReshipNo NE '' then
|
|
CustNo = CustReshipNo
|
|
end
|
|
CustName = Database_Services('ReadDataColumn', 'COMPANY', CustNo, COMPANY_CO_NAME$, True$, 0, False$)
|
|
CustAbbrev = Database_Services('ReadDataColumn', 'COMPANY', CustNo, COMPANY_ABBREV$, True$, 0, False$)
|
|
SRP_JSON(objWMOut, 'SetValue', 'CustNo', CustNo)
|
|
SRP_JSON(objWMOut, 'SetValue', 'CustName', CustName)
|
|
SRP_JSON(objWMOut, 'SetValue', 'CustAbbrev', CustAbbrev)
|
|
SRP_JSON(objWMOut, 'SetValue', 'PSN', {PS_NO})
|
|
SRP_JSON(objWMOut, 'SetValue', 'partNo', {PART_NO})
|
|
SRP_JSON(objWMOut, 'SetValue', 'postEpiSig', {POST_EPI_SIG})
|
|
SRP_JSON(objWMOut, 'SetValue', 'postEpiSigDtm', OConv({POST_EPI_SIG_DTM}, 'DT/^1HS'))
|
|
SRP_JSON(objWMOut, 'SetValue', 'supVerSig', {SUP_VER_SIG})
|
|
SRP_JSON(objWMOut, 'SetValue', 'supVerSigDtm', OConv({SUP_VER_SIG_DTM}, 'DT/^1HS'))
|
|
CINos = {EPO_CI_NO}
|
|
// Add a PSN object
|
|
ProdSpecJSON = PSN_Services('ConvertRecordToJSON', {PS_NO})
|
|
objProdSpecResponse = ''
|
|
If SRP_JSON(objProdSpecResponse, 'Parse', ProdSpecJSON) EQ '' then
|
|
objProdSpec = SRP_JSON(objProdSpecResponse, 'Get', 'prodSpec')
|
|
SRP_JSON(objWMOut, 'Set', 'prodSpec', objProdSpec)
|
|
SRP_JSON(objProdSpec, 'Release')
|
|
SRP_JSON(objProdSpecResponse, 'Release')
|
|
end
|
|
// Add CLEAN_INSP object(s)
|
|
If CINos NE '' then
|
|
objCleanInspArray = ''
|
|
If SRP_JSON(objCleanInspArray, 'New', 'Array') then
|
|
For each CINo in CINos using @VM setting vPos
|
|
If CINo NE '' then
|
|
CleanInspJSON = Clean_Insp_Services('ConvertRecordToJSON', CINo)
|
|
objCleanInsp = ''
|
|
If SRP_JSON(objCleanInsp, 'Parse', CleanInspJSON) EQ '' then
|
|
objTemp = SRP_JSON(objCleanInsp, 'Get', 'cleanInsp')
|
|
SRP_JSON(objCleanInspArray, 'Add', objTemp)
|
|
SRP_JSON(objTemp, 'Release')
|
|
SRP_JSON(objCleanInsp, 'Release')
|
|
end
|
|
end
|
|
Next CINo
|
|
SRP_JSON(objWMOut, 'Set', 'cleanInsp', objCleanInspArray)
|
|
SRP_JSON(objCleanInspArray, 'Release')
|
|
end
|
|
end
|
|
|
|
// Add WO_MAT_QA object
|
|
WOMatQAKey = Field(KeyID, '*', 1):'*':Field(KeyID, '*', 3)
|
|
WOMatQAJSON = WO_Mat_QA_Services('ConvertRecordToJSON', WOMatQAKey)
|
|
objWOMatQA = ''
|
|
If SRP_JSON(objWOMatQA, 'Parse', WOMatQAJSON) EQ '' then
|
|
objTemp = SRP_JSON(objWOMatQA, 'Get', 'woMatQa')
|
|
SRP_JSON(objWMOut, 'Set', 'woMatQA', objTemp)
|
|
SRP_JSON(objTemp, 'Release')
|
|
SRP_JSON(objWOMatQA, 'Release')
|
|
end
|
|
AllRTFRecords = Return_To_Fab_Services('GetReturnToFabRecordIdByCassId', KeyID)
|
|
If AllRTFRecords NE '' then
|
|
objRTFRecords = ''
|
|
If SRP_JSON(objRTFRecords, 'New', 'Array') then
|
|
For each RTFRecordId in AllRTFRecords using @VM setting vPos
|
|
objRTF = ''
|
|
If SRP_JSON(objRTF, 'New', 'Object') then
|
|
RTFRecord = Database_Services('ReadDataRow', 'RETURN_TO_FAB_LOTS', RTFRecordId, True$, 0, False$)
|
|
SRP_JSON(objRTF, 'SetValue', 'ReturnToFabLotsId', RTFRecordId)
|
|
SRP_JSON(objRTF, 'SetValue', 'StartDtm', OConv(RTFRecord<RETURN_TO_FAB_LOTS_MH_INIT_DTM$>, 'DT'))
|
|
SRP_JSON(objRTF, 'SetValue', 'Completed', RTFRecord<RETURN_TO_FAB_LOTS_COMPLETED$>, 'Boolean')
|
|
SRP_JSON(objRTFRecords, 'Set', 'ReturnToFabRecord', objRTF)
|
|
SRP_JSON(objRTFRecords, 'Add', objRTF)
|
|
SRP_JSON(objRTF, 'Release')
|
|
end
|
|
Next RTFRecordId
|
|
|
|
SRP_JSON(objWMOut, 'Set', 'ReturnToFabRecords', objRTFRecords)
|
|
SRP_JSON(objRTFRecords, 'Release')
|
|
end
|
|
end else
|
|
SRP_JSON(objWMOut, 'SetValue', 'ReturnToFabRecords', '')
|
|
end
|
|
SRP_JSON(objJSON, 'Set', 'wmOut', objWMOut)
|
|
SRP_JSON(objWMOut, 'Release')
|
|
end
|
|
|
|
If itemURL NE '' then
|
|
// The itemURL was passed in so add HAL+JSON properties.
|
|
// Create the _links property and then all link objects needed for this resource.
|
|
objLinks = ''
|
|
If SRP_JSON(objLinks, 'New', 'Object') then
|
|
// Create a self link.
|
|
objLink = ''
|
|
If SRP_JSON(objLink, 'New', 'Object') then
|
|
SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String')
|
|
SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String')
|
|
SRP_JSON(objLinks, 'Set', 'self', objLink)
|
|
SRP_JSON(objLink, 'Release')
|
|
end
|
|
SRP_JSON(objJSON, 'Set', '_links', objLinks)
|
|
SRP_JSON(objLinks, 'Release')
|
|
end
|
|
// Create the _class property for this resource.
|
|
SRP_JSON(objJSON, 'SetValue', '_class', 'resource')
|
|
end
|
|
jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled')
|
|
SRP_JSON(objJSON, 'Release')
|
|
end else
|
|
Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.')
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.')
|
|
end
|
|
|
|
Response = jsonRecord
|
|
|
|
End Service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetWMOData
|
|
//
|
|
// WorkOrderNo. - [Required]
|
|
// KeysOnly. - [Optional]
|
|
//
|
|
// Returns a list of WMO records within a supplied Work Order.
|
|
// Rows are @FM delimted while columns are @VM delimited.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetWMOData(WorkOrderNo, Columns, ShowGasGauge, WMOOverrideList)
|
|
|
|
WMOList = ''
|
|
|
|
If ( (WorkOrderNo NE '') or (WMOOverrideList NE '') ) then
|
|
If ShowGasGauge NE True$ then ShowGasGauge = False$
|
|
rv = Set_Status(0)
|
|
WMOKeys = ''
|
|
|
|
If WorkOrderNo NE '' then
|
|
Extract_Si_Keys('WM_OUT', 'WO_NO', WorkOrderNo, WMOKeys)
|
|
end else
|
|
Swap @FM with @VM in WMOOverrideList
|
|
WMOKeys = WMOOverrideList
|
|
end
|
|
StatusCode = ''
|
|
If Get_Status(StatusCode) then
|
|
Error_Services('Add', 'Error calling Extract_SI_Keys in the ' : Service : ' service. StatusCode: ' : StatusCode)
|
|
end else
|
|
NumWMO = DCount(WMOKeys, @VM)
|
|
|
|
If ShowGasGauge then
|
|
Def = ""
|
|
Def<MCAPTION$> = "Loading Outbound Cassettes..."
|
|
Def<MTYPE$> = "G"
|
|
Def<MEXTENT$> = NumWMO
|
|
Def<MTEXTWIDTH$> = 400
|
|
Def<MCOL$> = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent)
|
|
Def<MROW$> = -2 ;* message v-pos in pixels
|
|
MsgUp = Msg(@Window, Def)
|
|
end
|
|
|
|
@DICT = Database_Services('GetTableHandle', 'DICT.' : 'WM_OUT')
|
|
If Error_Services('NoError') then
|
|
For each @ID in WMOKeys using @VM setting fPos
|
|
@RECORD = Database_Services('ReadDataRow', 'WM_OUT', @ID)
|
|
If Error_Services('NoError') then
|
|
For each Column in Columns using @VM setting vPos
|
|
Begin Case
|
|
Case Column EQ 'HOLD'
|
|
HoldStatus = Calculate(Column)
|
|
If HoldStatus EQ True$ then
|
|
HoldStatus = 'On Hold'
|
|
end else
|
|
HoldStatus = 'Off Hold'
|
|
end
|
|
WMOList<fPos, vPos> = HoldStatus
|
|
Case Otherwise$
|
|
Val = Calculate(Column)
|
|
Conv = Xlate('DICT.WM_OUT', Column, DICT_CONV$, 'X')
|
|
If Conv NE '' then
|
|
Val = OConv(Val, Conv)
|
|
end
|
|
WMOList<fPos, vPos> = Val
|
|
End Case
|
|
Next Column
|
|
end else
|
|
Error_Services('Add', 'Error reading WM_OUT Record ' : @ID : ' in the ' : Service : ' service.')
|
|
end
|
|
* update the gauge
|
|
If ShowGasGauge then Msg(@Window, MsgUp, fPos, MSGINSTUPDATE$)
|
|
Next @ID
|
|
end else
|
|
Error_Services('Add', 'Error opening WM_OUT dictionary in the ' : Service : ' service.')
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'WorkOrderNo or WMOOverrideList argument was missing from the ' : Service : ' service.')
|
|
end
|
|
If ShowGasGauge then Msg(@Window, MsgUp) ;* take down the gauge
|
|
Response = WMOList
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetWaferMap
|
|
//
|
|
// Returns a @VM delimited array of boolean values, which represents which slots are filled.
|
|
// Note: The response is in the slot order 25, 24, ..., 2, 1.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetWaferMap(WMOKey)
|
|
|
|
WaferMap = ''
|
|
ErrorMsg = ''
|
|
If WMOKey NE '' then
|
|
If RowExists('WM_OUT', WMOKey) then
|
|
WOMatKey = Xlate('WM_OUT', WMOKey, 'WO_MAT_KEY', 'X')
|
|
ReactType = Xlate('WO_MAT', WOMatKey, 'REACTOR_TYPE', 'X')
|
|
If ReactType EQ 'EPP' then
|
|
RDSNos = Xlate('WM_OUT', WMOKey, 'RDS', 'X')
|
|
WaferMap = ''
|
|
For SlotIndex = 1 to 25
|
|
RDSNo = RDSNos<0, SlotIndex>
|
|
WaferMap = Insert(WaferMap, 0, 1, 0, (RDSNo NE '') )
|
|
Next SlotIndex
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Non-EpiPro is not supported by this service. Use WO_MAT_SERVICES instead.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. WM_OUT record ':WMOKey:' does not exist.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Null WMOKey passed in.'
|
|
end
|
|
|
|
If ErrorMsg EQ '' then
|
|
Response = WaferMap
|
|
end else
|
|
Error_Services('Add', ErrorMsg)
|
|
Response = False$
|
|
end
|
|
|
|
end service
|
|
|
|
|