Function Tool_Parms_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        :   Tool_Parms_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)
        10/04/18    djs     Original programmer.
        10/04/18    djs     Added a trigger within the WRITE_RECORD event, which automatically updates all RDS_LAYER
                            records associated with an RDS that does not contain an UNLOAD signature.

***********************************************************************************************************************/

#pragma precomp SRP_PreCompiler

$Insert LOGICAL
$Insert FILE.SYSTEM.EQUATES
$Insert ACTION_SETUP
$Insert RDS_EQUATES
$Insert CLEAN_INSP_EQUATES
$Insert COMPANY_EQUATES
$Insert RDS_LAYER_EQUATES
$Insert TOOL_PARMS_EQUATES
$Insert RLIST_EQUATES

Declare function    Error_Services, Database_Services, obj_RDS_Test, Logging_Services, Environment_Services
Declare function    Tool_Parms_Services
Declare subroutine  Error_Services, Database_Services, Logging_Services, Set_Status, RList

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 = ''

    Begin Case
        Case Otherwise$ ; NULL
    End Case

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:
    
return

WRITE_RECORD:

*    // Updates all RDS records in the current run without an unload signature.
*    PSN     = Field(@ID, '*', 1)
*    Reactor = Field(@ID, '*', 2)
*    LastRDSNo = Xlate('REACT_STATE', Reactor, 'LAST_RDS_NO', 'X')
*    If LastRDSNo NE '' then
*        WorkOrderNo = Xlate('RDS', LastRDSNo, 'WO', 'X')
*        Query  = 'SELECT RDS WITH WO EQ ':WorkOrderNo        
*        GoSub ClearCursors
*        Set_Status(0)
*        RList(Query, TARGET_ACTIVELIST$, '', '' '')
*        If Get_Status(ErrorCode) then
*            ErrorMsg = 'Error calling RList(): error code ':ErrorCode
*            Error_Services('Add', ErrorMsg)
*            return
*        end
*        Done = False$
*        Loop
*            Readnext RDSKey Else Done = True$
*            // Ensure the current TOOL_PARMS record being saved matches the current run on the reactor.
*            // If they do not match, then do not update the RDS_LAYER records in the current run.
*            RdsPSN     = Xlate('RDS', RDSKey, 'PROD_SPEC_ID', 'X')
*            RDSReactor = Xlate('RDS', RDSKey, 'REACTOR', 'X')
*            If (RdsPSN NE PSN) or (RDSReactor NE Reactor) then Done = True$
*        Until Done
*            // Need to check if unload stage has been signed
*            UnloadSig = Xlate('RDS', RDSKey, 'OPERATOR_OUT', 'X')
*            If UnloadSig EQ '' then                
*                // Get RDSLayer keys -> copy tool parameters to each layer
*                RDSLayerIDs = Xlate('RDS', RDSKey, 'RDS_LAYER_KEYS', 'X')
*                If RDSLayerIDs NE '' then
*                    ToolParmLayers = Record<TOOL_PARMS.LS_ID$>
*                    For each RDSLayerKey in RDSLayerIDs
*                        // Copy tool paramters
*                        LayerID = Field(RDSLayerKey, '*', 2)
*                        RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)
*                        Locate LayerID in ToolParmLayers using @VM setting LayerPos then
*                            RDSLayerRec<RDS_LAYER_DOPANT$>            = Record<TOOL_PARMS.DOPANT$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_EPI_DILUENT$>       = Record<TOOL_PARMS.EPI_DILUENT$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_EPI_TIME$>          = Record<TOOL_PARMS.EPI_TIME$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$> = Record<TOOL_PARMS.DILUENT_ADJ_PARAM$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>       = Record<TOOL_PARMS.DOPANT_FLOW$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_HCL_FLOW$>          = Record<TOOL_PARMS.HCL_FLOW$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_BAKE_TIME$>         = Record<TOOL_PARMS.BAKE_TIME$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>       = Record<TOOL_PARMS.EPI_H2_FLOW$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_TCS_FLOW$>          = Record<TOOL_PARMS.TCS_FLOW$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_DCS_FLOW$>          = Record<TOOL_PARMS.DCS_FLOW$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_AUX1$>              = Record<TOOL_PARMS.AUX1$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_AUX2$>              = Record<TOOL_PARMS.AUX2$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_F_OFFSET$>          = Record<TOOL_PARMS.F_OFFSET$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_S_OFFSET$>          = Record<TOOL_PARMS.S_OFFSET$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_R_OFFSET$>          = Record<TOOL_PARMS.R_OFFSET$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_ETCH1$>             = Record<TOOL_PARMS.ETCH1$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_ETCH2$>             = Record<TOOL_PARMS.ETCH2$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>      = Record<TOOL_PARMS.OVERGROW_REQ$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_SUSC_ETCH$>         = Record<TOOL_PARMS.SUSC_ETCH$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_UL_TEMP$>           = Record<TOOL_PARMS.UNLOAD_TEMP$, LayerPos>
*                            RDSLayerRec<RDS_LAYER_MODIFY_USER$>       = Record<TOOL_PARMS.ENTRY_USERNAME$>
*                            RDSLayerRec<RDS_LAYER_MODIFY_DTM$>        = Field(@ID, '*', 3)
*                        end
*                        Database_Services('WriteDataRow', 'RDS_LAYER', RDSLayerKey, RDSLayerRec, True$, False$, True$)
*                    Next RDSLayerKey
*                end
*            end
*        Repeat
*        GoSub ClearCursors       
*    end
    
return

DELETE_RECORD_PRE:
return

DELETE_RECORD:
return


// ----- Internal Methods ----------------------------------------------------------------------------------------------

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


ClearCursors:
    
    For counter = 0 to 8
        ClearSelect counter
    Next counter
    
return
