From 05e0fb3eda011f6483af2baa14ea3c2a69c7b7b5 Mon Sep 17 00:00:00 2001 From: "Ouellette Jonathan (CSC FI SPS MESLEO)" Date: Thu, 16 Oct 2025 23:55:23 +0000 Subject: [PATCH] Merged PR 28607: Archive Services Initial Pull This is the initial pull for Archiving data. --- LSL2/STPROC/ARCHIVE_ACTIONS.txt | 240 +++ LSL2/STPROC/ARCHIVE_API.txt | 238 +++ LSL2/STPROC/ARCHIVE_SERVICES.txt | 1727 +++++++++++++++-- LSL2/STPROC/DEARCHIVE_API.txt | 105 + LSL2/STPROC/ENVIRONMENT_SERVICES.txt | 313 +-- LSL2/STPROC/REARCHIVE_API.txt | 105 + LSL2/STPROC/TW_USE_SERVICES.txt | 70 + LSL2/STPROC/WM_OUT_SERVICES.txt | 300 ++- LSL2/STPROC/WORK_ORDER_SERVICES.txt | 768 +++++--- LSL2/STPROCINS/ARCHIVE_EQUATES.txt | 23 +- LSL2/STPROCINS/ARCHIVE_QUEUE_EQUATES.txt | 13 + .../STPROCINS/ARCHIVE_QUEUE_ERROR_EQUATES.txt | 13 + LSL2/STPROCINS/DELETE_QUEUE_EQUATES.txt | 13 + LSL2/STPROCINS/DELETE_QUEUE_ERROR_EQUATES.txt | 13 + LSL2/STPROCINS/MESSAGING_EQUATES.txt | 1 + 15 files changed, 3246 insertions(+), 696 deletions(-) create mode 100644 LSL2/STPROC/ARCHIVE_ACTIONS.txt create mode 100644 LSL2/STPROC/ARCHIVE_API.txt create mode 100644 LSL2/STPROC/DEARCHIVE_API.txt create mode 100644 LSL2/STPROC/REARCHIVE_API.txt create mode 100644 LSL2/STPROC/TW_USE_SERVICES.txt create mode 100644 LSL2/STPROCINS/ARCHIVE_QUEUE_EQUATES.txt create mode 100644 LSL2/STPROCINS/ARCHIVE_QUEUE_ERROR_EQUATES.txt create mode 100644 LSL2/STPROCINS/DELETE_QUEUE_EQUATES.txt create mode 100644 LSL2/STPROCINS/DELETE_QUEUE_ERROR_EQUATES.txt diff --git a/LSL2/STPROC/ARCHIVE_ACTIONS.txt b/LSL2/STPROC/ARCHIVE_ACTIONS.txt new file mode 100644 index 0000000..a03bffc --- /dev/null +++ b/LSL2/STPROC/ARCHIVE_ACTIONS.txt @@ -0,0 +1,240 @@ +Function ARCHIVE_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 : RDS_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) + 04/10/18 dmb Original programmer. + 10/04/18 djs Added a trigger within the WRITE_RECORD event, which fires when the reactor number has + changed. When this occurs the related RDS_LAYER records for this RDS record are populated + with the most recent associated TOOL_PARMS record. (related by PSN and Reactor) + +***********************************************************************************************************************/ + +#pragma precomp SRP_PreCompiler + +$Insert FILE.SYSTEM.EQUATES +$Insert ACTION_SETUP +$Insert RLIST_EQUATES +$Insert APP_INSERTS +$Insert IFX_EQUATES +$Insert ARCHIVE_EQUATES + +Equ COMMA$ to ',' + +Declare function Error_Services, Database_Services, obj_RDS_Test, Logging_Services, Environment_Services +Declare function Tool_Parms_Services, Signature_Services, obj_WO_Mat_QA, Datetime, Override_Services +Declare function Rds_Services, SRP_DateTime, SRP_Math, obj_WO_Mat, Lot_Services, SRP_Array +Declare function Lot_Event_Services, GetTickCount, Work_Order_Services, Archive_Services +Declare subroutine Error_Services, Database_Services, Logging_Services, Service_Services, obj_WO_React +Declare Subroutine Mona_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$ + + * This code prevents an anomaly where an @SVM appears when the value is read + * and causes an error when copying the record to SQL. + +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: + +return + + +DELETE_RECORD_PRE: + + ActionFlow = ACTION_STOP$ + +return + + +DELETE_RECORD: + + ActionFlow = ACTION_STOP$ + +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 + + + + + + + + diff --git a/LSL2/STPROC/ARCHIVE_API.txt b/LSL2/STPROC/ARCHIVE_API.txt new file mode 100644 index 0000000..8cf9eca --- /dev/null +++ b/LSL2/STPROC/ARCHIVE_API.txt @@ -0,0 +1,238 @@ +Function Archive_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 : Archive_API + + Description : API logic for the Archive 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 Archive[.ID.[]] + - HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc. + Examples: + - Archive.POST + - Archive.ID.PUT + - Archive.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) + 10/10/25 xxx Original programmer. + +***********************************************************************************************************************/ + +#pragma precomp SRP_PreCompiler + +$insert APP_INSERTS +$insert API_SETUP +$insert HTTP_INSERTS +$insert SRPJSONX + +Declare Function OI_WIZARD_SERVICES, ARCHIVE_SERVICES, Date_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 archive.HEAD +API archive.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 + ArchiveIds = Archive_Services('GetAllArchiveIDs') + ArchiveListJson = '' + GoSub GenerateArchiveListJson + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + HTTP_Services('SetResponseBody', ArchiveListJson, False$, 'application/hal+json') + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end else + HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.') + end + +end api + + +API archive.getarchive.HEAD +API archive.getarchive.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 + ArchiveId = Http_Services('GetQueryField', 'ArchiveId') + ArchiveJson = Archive_Services('ConvertArchiveRecordToJson', ArchiveId) + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + HTTP_Services('SetResponseBody', ArchiveJson, False$, 'application/hal+json') + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end else + HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.') + end + + +end api + + +API archive.findarchivebyrecord.HEAD +API archive.findarchivebyrecord.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 + + Table = Http_Services('GetQueryField', 'Table') + RecordId = Http_Services('GetQueryField', 'RecordId') + ArchiveIds = Archive_Services('GetArchiveIDsByRecord', RecordId, Table) + + SRP_JsonX_Begin('JSON', '{') + SRP_JsonX('ArchiveRecords','[') + for each ArchiveId in ArchiveIds using @FM + ThisArchiveJson = Archive_Services('ConvertArchiveRecordToJson', ArchiveId) + SRP_JsonX(ThisArchiveJson) + Next ArchiveId + SRP_JsonX(']') + ArchiveJson = SRP_JsonX_End('Pretty') + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + HTTP_Services('SetResponseBody', ArchiveJson, False$, 'application/hal+json') + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end else + HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.') + end + +end api + + +API archive.findarchivebymetadata.HEAD +API archive.findarchivebymetadata.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 + MetaDataType = Http_Services('GetQueryField', 'MetaDataType') + SearchValues = Http_Services('GetQueryField', 'SearchValue') + ArchiveIds = Archive_Services('GetArchiveIDsByMetaData', MetaDataType, SearchValues) + + SRP_JsonX_Begin('JSON', '{') + SRP_JsonX('ArchiveRecords','[') + for each ArchiveId in ArchiveIds using @FM + ThisArchiveJson = Archive_Services('ConvertArchiveRecordToJson', ArchiveId) + SRP_JsonX(ThisArchiveJson) + Next ArchiveId + SRP_JsonX(']') + ArchiveJson = SRP_JsonX_End('Pretty') + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + HTTP_Services('SetResponseBody', ArchiveJson, False$, 'application/hal+json') + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end else + HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.') + end + +end api + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Internal GoSubs +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +GenerateArchiveListJson: + + If Assigned(ArchiveListJson) AND Assigned(ArchiveIds) then + SRP_JsonX_Begin('JSON', '{') + SRP_JsonX('Archives', '[') + for each ArchiveId in ArchiveIds using @FM + ArchiveType = Field(ArchiveId, '*', 1) + ArchiveParent = Field(ArchiveId, '*', 2) + CreationDtm = Date_Services('ConvertDateTimeToISO8601', XLATE('ARCHIVE', ArchiveId, ARCHIVE_ARCHIVE_CREATION_DTM$, 'X')) + RecordCount = DCOUNT(XLATE('ARCHIVE', ArchiveId, ARCHIVE_CHILD_RECORD$, 'X'), @VM) + SRP_JsonX('{') + SRP_JsonX('ArchiveId', ArchiveId, 'String') + SRP_JsonX('ArchiveType', ArchiveType, 'String') + SRP_JsonX('ArchiveParent', ArchiveParent, 'String') + SRP_JsonX('CreationDtm', CreationDtm, 'String') + SRP_JsonX('RecordCount', RecordCount) + SRP_JsonX('}') + Next ArchiveId + SRP_JsonX(']') + ArchiveListJson = SRP_JsonX_End('Pretty') + end + + +return + + + diff --git a/LSL2/STPROC/ARCHIVE_SERVICES.txt b/LSL2/STPROC/ARCHIVE_SERVICES.txt index 34833c4..f32cd08 100644 --- a/LSL2/STPROC/ARCHIVE_SERVICES.txt +++ b/LSL2/STPROC/ARCHIVE_SERVICES.txt @@ -1,20 +1,31 @@ Compile function Archive_Services(@Service, @Params) #pragma precomp SRP_PreCompiler + +$Insert SERVICE_SETUP $insert LOGICAL $insert APP_INSERTS $Insert WO_LOG_EQUATES +$Insert WO_STEP_EQUATES $Insert RDS_EQUATES $Insert REACT_RUN_EQUATES $Insert RDS_LAYER_EQUATES $Insert RDS_TEST_EQUATES $Insert ARCHIVE_EQUATES +$Insert RLIST_EQUATES +$Insert ARCHIVE_QUEUE_EQUATES +$Insert DELETE_QUEUE_EQUATES +$Insert DELETE_QUEUE_ERROR_EQUATES +$Insert ARCHIVE_QUEUE_ERROR_EQUATES +$insert SRPJSONX EQU COMMA$ To ',' Declare subroutine Change_Log_Services, Logging_Services, Error_Services, Database_Services -Declare function SRP_Datetime, Logging_Services, Environment_Services, Datetime -Declare function Database_Services, Wo_Mat_Services, Error_Services, RDS_Services -Declare function WM_In_Services, WM_Out_Services +Declare subroutine Set_Status, Set_MFS, Btree.Extract, Archive_Services, Delay +Declare function SRP_Datetime, Logging_Services, Environment_Services, Datetime, RTI_CreateGUID +Declare function Database_Services, Wo_Mat_Services, Error_Services, RDS_Services, RTI_OS_Directory +Declare function WM_In_Services, WM_Out_Services, DirExists, Archive_Services, Work_Order_Services +Declare function email_Services, UCase, Date_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive' LogDate = Oconv(Date(), 'D4/') @@ -24,6 +35,8 @@ Headers = 'Logging DTM' : @FM : 'Message' : @FM : 'Cutoff Date' objLogArchiveService = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM +OPTIONS ARCHIVE_TYPES = 'WO_LOG' + GoToService Return Response or "" @@ -32,180 +45,442 @@ Return Response or "" // SERVICES //----------------------------------------------------------------------------- -Service ArchiveRecords() - Errors = '' - StatusMessage = 'Starting Archive Script.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) +/* +RunArchive +Step 1.1 of data archiving procedures. + Responsible for initiating the Archive Process by creating ARCHIVE records of a specified type. + No return type. +Parameters- + ArchiveType - Determines what method will be run to generate the ARCHIVE record. +*/ +Service RunArchive(ArchiveType=ARCHIVE_TYPES) - //Archive Change Log Records - GoSub ChangeLogArchive - - //Finish - Locate True$ in Errors using @FM setting ePos then - StatusMessage = 'Archive script complete. Errors detected. Check individual archive logs for more info.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') + Lock hSysLists, ServiceKeyID then + ErrorMsg = '' + If ArchiveType NE '' then + ArchiveSettings = Database_Services('ReadDataRow', 'APP_INFO', 'ARCHIVE_CONFIG') + Locate ArchiveType in ArchiveSettings<1> using @VM setting ArchConfPos then + YearsBackSetting = ArchiveSettings<2, ArchConfPos> + CreatedArchiveRecId = '' + KeysToArchive = '' + Begin Case + + Case ArchiveType EQ 'WO_LOG' + //Get WO_LOG Keys + KeysToArchive = Work_Order_Services('GetClosedWOsToArchive', YearsBackSetting) + if Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + + Case Otherwise$ + ErrorMsg = 'Invalid archive type.' + + End Case + end else + ErrorMsg = 'Archive settings not found in APP_INFO -> ARCHIVE_CONFIG.' + end + + If ErrorMsg EQ '' then + ArchiveRecordsIds = '' + If KeysToArchive NE '' then + ArchiveCountLimit = 30000 + ArchiveCount = 0 + for each Key in KeysToArchive using @VM + Until ArchiveCount EQ ArchiveCountLimit + CreatedArchiveRecId = Archive_Services('CreateArchiveRecord', Key, ArchiveType, False$, True$) + If Error_Services('NoError') then + If CreatedArchiveRecId NE '' then + ArchiveRecordsIds<1, -1> = CreatedArchiveRecId + ArchiveCount += 1 + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Next Key + end + Archive_Services('GenerateArchiveCreationReport', ArchiveRecordsIds) + end end else - StatusMessage = 'Archive script complete. No errors detected.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) + ErrorMsg = 'Archive type was null.' end -End Service + If ErrorMsg NE '' then + Error_Services('Add', ErrorMsg) + end + Unlock hSysLists, ServiceKeyID else Null + end + + +end service -Service GetWORelatedRecord(WOLogId) +/* +CreateArchiveRecord +Step 1.2 of data archiving procedures. + Responsible for creating an ARCHIVE record for WO_LOG hierarchies. + Returns the key ID for a record created in the ARCHIVE table. The key is a GUID string. +Parameters- + ParentRecordId - The key ID of the parent record. + ArchiveType - The table of the parent record. +*/ +Service CreateArchiveRecord(ParentRecordId, ArchiveType, ReArchive, AddToQueue) + + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive\ArchiveRecordCreation' + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ArchiveCreation.csv' + Headers = 'Logging DTM' : @FM : 'Record Table' : @FM : 'Record Id' : @FM : 'Success' : @FM : 'Message' + objRecordArchival = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) ErrorMsg = '' - If WOLogId NE '' then - If RowExists('WO_LOG', WOLogId) then - WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WOLogId, True$, 0, False$) - If Error_Services('NoError') then - ArchiveRecordId = 'WO_LOG*' : WOLogId + ArchiveId = '' + ArchiveSeq = 1 + + If ParentRecordId NE '' then + If ArchiveType NE '' then + if Not(ReArchive) then + ArchiveId = ArchiveType : '*' : ParentRecordId : '*' : ArchiveSeq + end else + ValidId = False$ + for ArchiveSeq = 1 to 99 + Until ValidId = True$ + ArchiveId = ArchiveType : '*' : ParentRecordId : '*' : ArchiveSeq + If Not(RowExists('ARCHIVE', ArchiveId)) then + ValidId = True$ + end + Next ArchiveSeq + end + If Not(RowExists('ARCHIVE', ArchiveId)) then ArchiveRecord = '' - WOMatKeys = Wo_Mat_Services('GetWOMatKeys', WOLogId) - If Error_Services('NoError') then - WOMatQAKeys = WOMatKeys - WOStepKey = WOLogRec - WMInKeys = Wm_In_Services('GetWMInKeys', WOLogId) - if Error_Services('NoError') then - WMOutKeys = Wm_Out_Services('GetWMOutKeys', WOLogId) - if Error_Services('NoError') then - RDSKeys = RDS_Services('GetRDSKeys', WOLogId) - if Error_Services('NoError') then - ReactRunKeys = RDSKeys - RDSLayerKeys = '' - CleanInspKeys = '' - for each ReactRunKey in ReactRunKeys using @VM setting iPos - ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', ReactRunKey, True$, 0, False$) - If Error_Services('NoError') then - CleanInspKeys<1, -1> = ReactRunRec - RDSLayerKeys<1, -1> = ReactRunRec - end else - ErrorMsg = Error_Services('GetMessage') - end - Next ReactRunKey - RDSTestKeys = '' - If ErrorMsg EQ '' then - For each RDSLayerKey in RDSLayerKeys using @VM - RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey, True$, 0, False$) - If Error_Services('NoError') then - RDSTestKeys<1, -1> = RDSLayerRec - end else - ErrorMsg = Error_Services('GetMessage') - end - Next RDSLayerKey - TWUseKeys = '' - end - TWUseKeys = '' - If ErrorMsg EQ '' then - for each RDSTestKey in RDSTestKeys using @VM - RDSTestRec = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKey, True$, 0, False$) - If Error_Services('NoError') then - TWUseKeys<1,-1> = RDSTestRec - end else - ErrorMsg = Error_Services('GetMessage') - end - Next RDSTestKey - end - If ErrorMsg EQ '' then - //ArchiveRecord - //WOLogId - ArchiveRecord = WOLogId - ArchiveRecord = 'WO_LOG' - ArchiveRecord = False$ - ArchiveRecord = False$ - //WOStepKey - ArchiveRecord = WOStepKey - ArchiveRecord = 'WO_STEP' - ArchiveRecord = False$ - ArchiveRecord = False$ - //WOMatKeys - for each WOMatKey in WOMatKeys using @VM - ArchiveRecord = WOMatKey - ArchiveRecord = 'WO_MAT' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next WOMatKey - //WOMatQAKeys - for each WOMatQAKey in WOMatQAKeys using @VM - ArchiveRecord = WOMatQAKey - ArchiveRecord = 'WO_MAT_QA' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next WOMatQAKey - //WMInKeys (EpiPro Specific) - for each WMInKey in WMInKeys using @VM - ArchiveRecord = WMInKey - ArchiveRecord = 'WM_IN' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next WMInKey - //WMOutKeys (EpiPro Specific) - for each WMOutKey in WMOutKeys using @VM - ArchiveRecord = WMOutKey - ArchiveRecord = 'WM_OUT' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next WMOutKey - //RDSKeys - for each RDSKey in RDSKeys using @VM - ArchiveRecord = RDSKey - ArchiveRecord = 'RDS' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next RDSKey - //ReactRunKeys - for each ReactRunKey in ReactRunKeys using @VM - ArchiveRecord = ReactRunKey - ArchiveRecord = 'REACT_RUN' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next ReactRunKey - //RDSLayerKeys - for each RDSLayerKey in RDSLayerKeys using @VM - ArchiveRecord = RDSLayerKey - ArchiveRecord = 'RDS_LAYER' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next RDSLayerKey - //CleanInspKeys - for each CleanInspKey in CleanInspKeys using @VM - ArchiveRecord = CleanInspKey - ArchiveRecord = 'CLEAN_INSP' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next CleanInspKey - //RDSTestKeys - for each RDSTestKey in RDSTestKeys using @VM - ArchiveRecord = RDSTestKey - ArchiveRecord = 'RDS_TEST' - ArchiveRecord = False$ - ArchiveRecord = False$ - Next RDSTestKey - //TWUseKeys - for each TWUseKey in TWUseKeys using @VM - if TWUseKey NE '' then - ArchiveRecord = TWUseKey - ArchiveRecord = 'TW_USE' - ArchiveRecord = False$ - ArchiveRecord = False$ - end - Next TWUseKey - Database_Services('WriteDataRow', 'ARCHIVE', ArchiveRecordId, ArchiveRecord) - If Error_Services('HasError') then - ErrorMsg = Error_Services('GetMessage') - end - end - end else + ChildRecords = '' + Begin Case + Case ArchiveType EQ 'WO_LOG' + ChildRecords = Work_Order_Services('GetWOLogHierachy', ParentRecordId) + MetaData = Work_Order_Services('GetWOMetaData', ParentRecordId) + If Error_Services('NoError') then + ChildRecordCount = DCount(ChildRecords, @VM) + If ChildRecordCount LE 0 then + ErrorMsg = '0 child records returned.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Case Otherwise$ + ErrorMsg = 'Unsupported Archive Type.' + End Case + If ErrorMsg EQ '' then + ArchivePath = Environment_Services('GetTextDataBackupRootDir'):ArchiveType:'\':ParentRecordId:'\':ArchiveSeq:'\' + DirectoryCreated = RTI_OS_Directory( 'CREATE', ArchivePath) + If DirectoryCreated then + ArchiveRecord = Datetime() + ArchiveRecord = ArchivePath + ArchiveRecord = MetaData<1> + ArchiveRecord = MetaData<2> + ArchiveRecord = MetaData<3> + for RecPos = 1 to DCount(ChildRecords<1>, @VM) + ArchiveRecord = ChildRecords<1, RecPos> + ArchiveRecord = ChildRecords<2, RecPos> + ArchiveRecord = False$ + ArchiveRecord = False$ + Next i + Database_Services('WriteDataRow', 'ARCHIVE', ArchiveId, ArchiveRecord) + If Error_Services('NoError') then + CreatedArchiveId = ArchiveId + If AddToQueue then + AddedToArchiveQueue = Archive_Services('AddToArchiveQueue', CreatedArchiveId) + If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage') end + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Error creating text file backup directory.' + end + end + end else + ErrorMsg = 'Archive record already exists.' + end + end else + ErrorMsg = 'Archive Type was null.' + end + end else + ErrorMsg = 'Record ID was null.' + end + + If ErrorMsg EQ '' then + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveType + LogData<3> = ParentRecordId + LogData<4> = True$ + LogData<5> = 'Successfully created ARCHIVE record - ' : ArchiveId + Logging_Services('AppendLog', objRecordArchival, LogData, @RM, @FM, False$) + Response = ArchiveId + end else + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveType + LogData<3> = ParentRecordId + LogData<4> = False$ + LogData<5> = 'Error creating ARCHIVE record - ' : ErrorMsg + Logging_Services('AppendLog', objRecordArchival, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMsg) + end + +end service + + +/* +AddToArchiveQueue +Step 1.3 of data archiving procedures. + Responsible for creating record in the ARCHIVE_QUEUE table. + These records relate to an ARCHIVE record. + Returns the GUID key ID of the ARCHIVE_QUEUE record created. +Parameters- + ArchiveId - The key ID of the ARCHIVE record which is being queued for child record archival. +*/ +Service AddToArchiveQueue(ArchiveId) + + ErrorMsg = '' + AddedToArchiveQueue = False$ + + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + ArchiveQueueId = RTI_CreateGUID() + ArchiveQueueRec = '' + ArchiveQueueRec = ArchiveId + Database_Services('WriteDataRow', 'ARCHIVE_QUEUE', ArchiveQueueId, ArchiveQueueRec) + If Error_Services('NoError') then + AddedToArchiveQueue = True$ + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive record ' : ArchiveId : ' was not found in ARCHIVE table.' + end + end else + ErrorMsg = 'Archive Id was null' + end + + If ErrorMsg NE '' then + Error_Services('Add', 'Error adding archive to archive queue : ' : ErrorMsg) + end + + Response = AddedToArchiveQueue + +end service + +/* +ProcessArchiveQueue +Step 2.1 of data archiving procedures. + Responsible for getting and looping through keys in the ARCHIVE_QUEUE table. + Then processing the record with that key and passing it off to the ArchiveRecords service + If the ArchiveRecords service returns true then deletes the ARCHIVE_QUEUE record. + If the ArchiveRecords service returns false, then tranfers the ARCHIVE_QUEUE record to the + ARCHIVE_QUEUE_ERROR table. Deletes the ARCHIVE_QUEUE record. +Parameters- + None. +*/ +Service ProcessArchiveQueue() + + ErrorMsg = '' + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive\RecordArchiving' + ServiceErrMsg = '' + ServiceLogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ServiceLog.csv' + ServiceHeaders = 'Logging DTM' : @FM : 'Message' + ServiceLogObj = Logging_Services('NewLog', LogPath, ServiceLogFileName, CRLF$, ',', ServiceHeaders, '', False$, False$) + + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') + Lock hSysLists, ServiceKeyID then + open 'ARCHIVE_QUEUE' to FileIn then + SelectStmt = 'SELECT ARCHIVE_QUEUE' + RList(SelectStmt,TARGET_ACTIVELIST$,'','','') + Done = False$ + loop + readnext ArchiveQueueId else Done = 1 + until Done + ArchiveId = XLATE('ARCHIVE_QUEUE', ArchiveQueueId, ARCHIVE_QUEUE_ARCHIVE_ID$, 'X') + Archive_Services('ArchiveRecords', ArchiveId) + If Error_Services('HasError') then + ProcessError = Error_Services('GetMessage') + Error_Services('Clear') + ArchiveErrQueueRec = '' + ArchiveErrQueueRec = ArchiveId + ArchiveErrQueueRec = ProcessError + Database_Services('WriteDataRow', 'ARCHIVE_QUEUE_ERROR', ArchiveQueueId, ArchiveErrQueueRec) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + Database_Services('DeleteDataRow', 'ARCHIVE_QUEUE', ArchiveQueueId, True$, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + Done = True$; // Limits service to run one record at a time. + REPEAT + end else + ErrorMsg = 'Error opening RECORD_ARCHIVE_QUEUE table.' + end + + // Service level Logging + if ErrorMsg EQ '' then + ServiceMessage = 'Archive queue service finished without error.' + end else + ServiceMessage = ErrorMsg + end + + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = ServiceMessage + Logging_Services('AppendLog', ServiceLogObj, LogData, @RM, @FM, False$) + end + Unlock hSysLists, ServiceKeyID else Null + +end service + + +/* +ArchiveRecords +Step 2.2 of data archiving procedures. + Responsible for looping through an ARCHIVE records CHILD_RECORDS field. Then for each record + pass it to the ArchiveRecordToTxtFile service to be backed up(Or any new methods meant to back up a record). + If all records successfully archive returns a True. + If any records fail then processing of the ARCHIVE record pauses and returns a false. +Parameters - + ArchiveId - The key ID to the ARCHIVE record being processed. +*/ +Service ArchiveRecords(ArchiveId) + + ErrorMsg = '' + + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive\RecordArchiving' + LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ExecutionLog.csv' + Headers = 'Logging DTM' : @FM : 'Archive Queue ID' : @FM : 'Archive ID' : @FM : 'Message' + objArchiveRecordsLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) + + AllRecordsArchived = False$ + + If ArchiveId NE '' then + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId, True$, 0, False$) + If Error_Services('NoError') then + ArchiveSavePath = ArchiveRec + NumRecordsToArchive = DCOUNT(ArchiveRec, @VM) + if NumRecordsToArchive GT 0 then + for each Record in ArchiveRec using @VM setting RecPos + Until ErrorMsg NE '' + ThisRecord = ArchiveRec + ThisTable = ArchiveRec + + ThisRecordArchived = ArchiveRec + If Not(ThisRecordArchived) then + RecordArchivedTxt = Archive_Services('ArchiveRecordToTxtFile', ThisTable, ThisRecord, ArchiveSavePath) + if Error_Services('NoError') then + RecordArchivedJson = Archive_Services('ArchiveRecordToJson', ThisRecord, ThisTable, ArchiveSavePath) + If Error_Services('NoError') then + If RecordArchivedTxt AND RecordArchivedJson then + ArchiveRec = True$ + Database_Services('WriteDataRow', 'ARCHIVE', ArchiveId, ArchiveRec, True$, 0, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'One or more archive methods failed.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end + Next Record + If ErrorMsg EQ '' then + Archive_Services('AddToDeleteQueue', ArchiveId) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + end else + ErrorMsg = 'Archive record had zero child records.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive ID was null.' + end + + If ErrorMsg EQ '' then + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveId + LogData<3> = 'Successfully archived all records in ARCHIVE.' + Logging_Services('AppendLog', objArchiveRecordsLog, LogData, @RM, @FM, False$) + AllRecordsArchived = True$ + end else + ErrorMsg = 'Error in ArchiveRecords service - ' : ErrorMsg + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveId + LogData<3> = ErrorMsg + Logging_Services('AppendLog', objArchiveRecordsLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMsg) + end + + Response = AllRecordsArchived + +end service + +/* +ArchiveRecordToTxtFile +Step 2.3 of data archiving procedures. + One of the possible methods that can used to backup a file. + This service reads a specific record and backs up the data to raw text in a .txt file. + Then verifies content by calling the VerifyTextBackup service. + If VerifyTextBackup service returns false then this service returns false. + If VerifyTextBackup service returns true then this service returns true. +Parameters- + RecordTable - The table of the record being backed up + RecordId - The key id of the record being backed up + SavePath - The location to save the txt file backup. +*/ +Service ArchiveRecordToTxtFile(RecordTable, RecordId, SavePath) + + ErrorMsg = '' + RecordBackedUp = False$ + + If RecordTable NE '' then + If RecordId NE '' then + If RowExists(RecordTable, RecordId) then + If SavePath NE '' then + SavePathExists = DirExists(SavePath) + If SavePathExists then + Record = Database_Services('ReadDataRow', RecordTable, RecordId, True$, 0, False$) + If Error_Services('NoError') then + FileName = RecordTable:'-':RecordId:'.txt' + FullSavePath = SavePath : FileName + swap '*' with '%2A' in FullSavePath + Set_Status(0) + OSWrite Record to FullSavePath; // Todo Error checking for write and read + TextBackupVerified = Archive_Services('VerifyTextBackup', RecordTable, RecordId, FullSavePath, True$) + if Error_Services('NoError') then + if TextBackupVerified then + RecordBackedUp = True$ + end else + ErrorMsg = 'Error in text file backup verification.' + end end else ErrorMsg = Error_Services('GetMessage') end @@ -213,49 +488,1119 @@ Service GetWORelatedRecord(WOLogId) ErrorMsg = Error_Services('GetMessage') end end else - ErrorMsg = Error_Services('GetMessage') + ErrorMsg = 'Specified save path was not found.' end + end else + ErrorMsg = 'Save path was null.' + end end else - ErrorMsg = Error_Services('GetMessage') + ErrorMsg = 'Specific record {':RecordTable:'} {':RecordId:'} was not found in the specified table.' end end else - ErrorMsg = 'WO_LOG record not found in WO_LOG table.' + ErrorMsg = 'Record Id was null.' end end else - ErrorMsg = 'WO_LOG ID was null.' + ErrorMsg = 'Record Table was null.' end If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end + Response = RecordBackedUp + end service -ChangeLogArchive: - StatusMessage = 'Starting Change_Log Archive Script.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) - ChangeLogArchiveDate = SRP_Datetime('AddYears', Datetime(), -1) - Change_Log_Services('ArchiveChangeLogRecByDate', ChangeLogArchiveDate) - If Error_Services('NoError') then - StatusMessage = 'Starting Change_Log Archive Script.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) +Service ArchiveRecordToJson(RecordId, RecordTable, SavePath) + + SavedToJson = False$ + ErrorMsg = '' + + If RecordId NE '' then + If RecordTable NE '' then + If SavePath NE '' then + SavePathExists = DirExists(SavePath) + If SavePathExists then + If RowExists(RecordTable, RecordId) then + FileName = RecordTable:'-':RecordId:'.json' + FullSavePath = SavePath : FileName + swap '*' with '%2A' in FullSavePath + RecordJSonData = Archive_Services('ConvertGenericRecordToJson', RecordId, RecordTable) + If Error_Services('NoError') then + ValidJson = SRP_JsonX_Parse('JsonCheck', RecordJSonData) + If ValidJson then + Set_Status(0) + OSWrite RecordJSonData to FullSavePath + SavedToJson = True$ + end else + ErrorMsg = 'No valid json detected.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Set_Status(0) + OSWrite RecordJSonData to FullSavePath; + If Get_Status(errCode) then + ErrorMsg = 'Error writing archive Json file.' + end + end else + ErrorMsg = RecordId : ' in ' : RecordTable : ' does not exist.' + end + end else + ErrorMsg = 'Specified save path was not found.' + end + end else + ErrorMsg = 'SavePath parameter was null.' + end + end else + ErrorMsg = 'RecordTable parameter was null.' + end end else - StatusMessage = 'Error in Change_Log Archive Script.' - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = StatusMessage - Logging_Services('AppendLog', objLogArchiveService, LogData, @RM, @FM) - Errors<-1> = True$ + ErrorMsg = 'RecordId parameter was null.' end + + If ErrorMsg EQ '' then + Response = SavedToJson + end else + Error_Services('Add', ErrorMsg) + end + +end service + +Service ConvertArchiveRecordToJson(ArchiveId) + + ErrorMsg = '' + JsonData = '' + + If ArchiveId NE '' then + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId, True$, 0, False$) + If Error_Services('NoError') then + SRP_JsonX_Begin('JSON', '{') + SRP_JsonX('ArchiveId', ArchiveId, 'String') + DtmCreated = Date_Services('ConvertDateTimeToISO8601', ArchiveRec) + SRP_JsonX('ArchiveCreationDtm', DtmCreated) + SRP_JsonX('ArchiveFilePath', ArchiveRec, 'String') + SRP_JsonX('ArchiveCompleted', ArchiveRec, 'Bool') + DtmCompleted = Date_Services('ConvertDateTimeToISO8601', ArchiveRec) + SRP_JsonX('ArchiveCompletionDtm', DtmCompleted) + SRP_JsonX('ChildRecords', '[') + for each Record in ArchiveRec using @VM setting RecPos + SRP_JsonX('{') + SRP_JsonX('RecordTable', ArchiveRec, 'String') + SRP_JsonX('RecordId', ArchiveRec, 'String') + SRP_JsonX('RecordArchived', ArchiveRec, 'Bool') + SRP_JsonX('RecordDeleted', ArchiveRec, 'Bool') + SRP_JsonX('}') + Next Record + SRP_JsonX(']') + SRP_JsonX('MetaData', '[') + for each MetaDataField in ArchiveRec using @VM setting mdPos + SRP_JsonX('{') + SRP_JsonX('FieldName', ArchiveRec, 'String') + FieldType = ArchiveRec + FieldValue = ArchiveRec + SRP_JsonX('FieldType', FieldType , 'String') + If FieldType EQ 'DateTime' then + FieldValue = OConv(FieldValue, 'DT') + end + SRP_JsonX('FieldValue', FieldValue, 'String') + + SRP_JsonX('}') + Next MetaDataField + SRP_JsonX(']') + + DtmDeArchived = Date_Services('ConvertDateTimeToISO8601', ArchiveRec) + + SRP_JsonX('DeArchiveDtm', DtmDeArchived, 'String') + + JsonData = SRP_JsonX_End('Pretty') + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'ArchiveId parameter was null.' + end + + If ErrorMsg EQ '' then + Response = JsonData + end else + Error_Services('Add', ErrorMsg) + end + +end service + +Service ConvertGenericRecordToJson(RecordId, RecordTable) + + ErrorMsg = '' + + RecordJson = '' + If RecordId NE '' then + If RecordTable NE '' then + If RowExists(RecordTable, RecordId) then + Record = Database_Services('ReadDataRow', RecordTable, RecordId, True$, 0, False$) + If Error_Services('NoError') then + SRP_JsonX_Begin(RecordTable : '*' : RecordId, '{') + + For each Field in Record using @FM setting FieldPos + If Indexc(Field, @VM, 1) then + //Value Marks Present + SRP_JsonX(FieldPos, '[') + For each Value in Field using @VM setting ValuePos + SRP_JsonX('{') + If Indexc(Value, @SVM, 1) then + SRP_JsonX(ValuePos, '[') + for each SubValue in Value using @SVM setting SubValuePos + SRP_JsonX('{') + SRP_JsonX(SubValuePos, Record) + SRP_JsonX('}') + Next SubValue + SRP_JsonX(']') + end else + SRP_JsonX(ValuePos, Record) + end + SRP_JsonX('}') + Next Value + SRP_JsonX(']') + end else + //No Value Marks Present + SRP_JsonX(FieldPos, Record) + end + Next Field + RecordJson = SRP_JsonX_End('Pretty') + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = RecordId : ' in ' : RecordTable : ' does not exist.' + end + end else + ErrorMsg = 'RecordTable parameter was null.' + end + end else + ErrorMsg = 'RecordId parameter was null.' + end + + If ErrorMsg EQ '' then + Response = RecordJson + end else + Error_Services('Add', ErrorMsg) + end + +end service + +Service ConvertJsonToRecord(JsonData) + ErrorMsg = '' + ConvertedData = '' + + If SRP_JsonX_Parse('JsonTest', JsonData) then + NumFields = SRP_JsonX_Count('') + for FieldPos = 1 to NumFields + NumValueMarks = SRP_JsonX_Count(FieldPos) + If NumValueMarks then + // Field has value marks + For ValueMarkPos = 1 to NumValueMarks + NumSubValueMarks = SRP_JsonX_Count(FieldPos : '[':ValueMarkPos:'].':ValueMarkPos) + If NumSubValueMarks GT 1 then + // Value Mark is further delimited with sub-value marks + For SubValueMarkPos = 1 to NumSubValueMarks + ConvertedData = SRP_JsonX_Get(FieldPos : '[':ValueMarkPos:'].':ValueMarkPos: '[':SubValueMarkPos:']':'.':SubValueMarkPos) + Next SubValueMarkPos + end else + // Value Mark is not delimited. + ConvertedData = SRP_JsonX_Get(FieldPos : '[':ValueMarkPos:'].':ValueMarkPos) + end + Next ValueMarkPos + end else + // The field does not have value marks. + FieldData = SRP_JsonX_Get(FieldPos) + ConvertedData = SRP_JsonX_Get(FieldPos) + end + Next FieldPos + end else + ErrorMsg = 'JsonData passed to routine was invalid.' + end + + + If ErrorMsg EQ '' then + Response = ConvertedData + end else + Error_Services('Add', ErrorMsg) + end + +end service + +/* +VerifyTextBackup +Step 2.4 of data archiving procedures. + This service compares the content of a specified txt file and the raw text data of a record in the system. + OR the existence of a text file. + If the data between the two entities matches this service returns a true + If the data between the two entities does not match then this service returns a false. +Parameters- + RecordTable - The table of the record being compared + RecordId - The key id of the record being compares + SavePath - The location of the txt file containing the data. + VerifyFileContents - Optional parameter. If this parameter is false or null then only the existence of a matching text file occurs + If this parameter is true then the content of the text file is compared. +*/ +Service VerifyTextBackup(RecordTable, RecordId, PathToTextFile, VerifyFileContents) + + ErrorMsg = '' + VerificationPassed = False$ + + If RecordTable NE '' then + If RecordId NE '' then + If RowExists(RecordTable, RecordId) then + If PathToTextFile NE '' then + FileExists = DirExists(PathToTextFile) + If FileExists EQ 0 OR FileExists EQ 1 then + If VerifyFileContents then + Record = Database_Services('ReadDataRow', RecordTable, RecordId, True$, 0, False$) + If Error_Services('NoError') then + Set_Status(0) + OSRead RecordVerify from PathToTextFile then + If RecordVerify EQ Record then + VerificationPassed = True$ + end else + ErrorMsg = 'Record backup verification failed.' + end + end else + ErrorMsg = 'Error verifying record.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + VerificationPassed = True$ + end + end else + ErrorMsg = 'Specific path was not found' + end + end else + ErrorMsg = 'Path to text file was null.' + end + end else + ErrorMsg = 'Specific record was not found in the specified table.' + end + end else + ErrorMsg = 'Record Id was null.' + end + end else + ErrorMsg = 'Record Table was null.' + end + + If ErrorMsg NE '' then + Error_Services('Add', ErrorMsg) + end + + Response = VerificationPassed + +end service + +/* +AddToDeleteQueue +Step 3.1 of data archiving procedures. + Responsible for creating record in the DELETE_QUEUE table. + These records relate to an ARCHIVE record. + Returns the GUID key ID of the DELETE_QUEUE record created. +Parameters- + ArchiveId - The key ID of the ARCHIVE record which is being queued for child record deletion. +*/ +Service AddToDeleteQueue(ArchiveId) + + ErrorMsg = '' + AddedToDeleteQueue = False$ + + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + ArchiveQueueId = RTI_CreateGUID() + ArchiveQueueRec = '' + ArchiveQueueRec = ArchiveId + Database_Services('WriteDataRow', 'DELETE_QUEUE', ArchiveQueueId, ArchiveQueueRec) + If Error_Services('NoError') then + AddedToDeleteQueue = True$ + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive record ' : ArchiveId : ' was not found in ARCHIVE table.' + end + end else + ErrorMsg = 'Archive Id was null' + end + + If ErrorMsg NE '' then + Error_Services('Add', 'Error adding archive to deletion queue : ' : ErrorMsg) + end + + Response = AddedToDeleteQueue + +end service + +/* +ProcessDeleteQueue +Step 3.2 of data archiving procedures. + Responsible for getting and looping through keys in the DELETE_QUEUE table. + Then processing the record with that key by passing it off to the DeleteRecords service + If the DeleteRecords service returns true then deletes the DELETE_QUEUE record. + If the DeleteRecords service returns false, then tranfers the DELETE_QUEUE record to the + DELETE_QUEUE_ERROR table. Deletes the DELETE_QUEUE record. +Parameters- + None. +*/ +Service ProcessDeleteQueue() + + ErrorMsg = '' + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive\RecordDeletion' + + LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ServiceLog.csv' + Headers = 'Logging DTM' : @FM : 'Message' + ServiceLogObj = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) + + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') + Lock hSysLists, ServiceKeyID then + open 'DELETE_QUEUE' to FileIn then + SelectStmt = 'SELECT DELETE_QUEUE' + RList(SelectStmt,TARGET_ACTIVELIST$,'','','') + Done = 0 + loop + readnext DeleteQueueId else Done = 1 + until Done + ExecutionErrMsg = '' + ArchiveId = Database_Services('ReadDataColumn', 'DELETE_QUEUE', DeleteQueueIdm, DELETE_QUEUE_ARCHIVE_ID$, True$, 0, False$) + If Error_Services('NoError') then + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + Archive_Services('DeleteRecords', ArchiveId) + If Error_Services('HasError') then + ProcessError = Error_Services('GetMessage') + Error_Services('Clear') + DeleteErrQueueRec = '' + DeleteErrQueueRec = ArchiveId + DeleteErrQueueRec = ProcessError + Database_Services('WriteDataRow', 'DELETE_QUEUE_ERROR', DeleteQueueId, DeleteErrQueueRec) + If Error_Services('NoError') then + Database_Services('DeleteDataRow', 'DELETE_QUEUE', DeleteQueueId, True$, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + end + Database_Services('DeleteDataRow', 'DELETE_QUEUE', DeleteQueueId, True$, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + end else + ErrorMsg = 'Archive ID within the DELETE Queue record was null.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Done = True$; //Limits each service call to 1 record to process at a time. + REPEAT + end else + ErrorMsg = 'Error opening Delete Queue table.' + end + + // Service level Logging + if ErrorMsg EQ '' then + ServiceMessage = 'Delete queue service finished without error.' + end else + ServiceMessage = ErrorMsg + end + + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = ServiceMessage + Logging_Services('AppendLog', ServiceLogObj, LogData, @RM, @FM, False$) + + + Unlock hSysLists, ServiceKeyID else Null + end + +end service + +Service RetryDeleteErrorQueue() + + ErrorMsg = '' + + open 'DELETE_QUEUE_ERROR' to FileIn then + SelectStmt = 'SELECT DELETE_QUEUE_ERROR' + RList(SelectStmt,TARGET_ACTIVELIST$,'','','') + Done = 0 + loop + readnext DeleteQueueId else Done = 1 + until Done + ExecutionErrMsg = '' + DeleteQueueErrorRec = Database_Services('ReadDataRow', 'DELETE_QUEUE_ERROR', DeleteQueueId, True$, 0, False$) + if Error_Services('NoError') then + ArchiveId = DeleteQueueErrorRec + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + Archive_Services('DeleteRecords', ArchiveId) + If Error_Services('NoError') then + Database_Services('DeleteDataRow', 'DELETE_QUEUE_ERROR', DeleteQueueId, True$, False$) + end else + ProcessError = Error_Services('GetMessage') + DeleteQueueErrorRec = ProcessError + Database_Services('WriteDataRow', 'DELETE_QUEUE_ERROR', DeleteQueueId, DeleteErrQueueRec, True$, 0, False$) + end + end + end + end + REPEAT + end + +end service + +/* +DeleteRecords +Step 3.3 of data archiving procedures. + Responsible for looping through an ARCHIVE records CHILD_RECORDS field. Then for each record + pass it to the DeleteRecord service to be deleted from the database. + If all records successfully delete, returns a True. + If any records fail then processing of the DELETE record pauses and returns a false. +Parameters - + ArchiveId - The key ID to the ARCHIVE record being processed. +*/ +Service DeleteRecords(ArchiveId) + + ErrorMsg = '' + AllRecordsDeleted = False$ + + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Archive\RecordDeletion' + LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ExecutionLog.csv' + Headers = 'Logging DTM' : @FM : 'Archive ID' : @FM : 'Message' + objDeleteRecordsLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$) + + If ArchiveId NE '' then + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId, True$, 0, False$) + for RecPos = DCount(ArchiveRec, @VM) to 1 step -1 + ThisRecord = ArchiveRec + ThisTable = ArchiveRec + Archive_Services('VerifyRelationalIndexes', ThisTable, ThisRecord) + Next RecPos + If Error_Services('NoError') then + for RecPos = DCount(ArchiveRec, @VM) to 1 step -1 + Until ErrorMsg NE '' + ThisRecord = ArchiveRec + ThisTable = ArchiveRec + ThisRecordArchived = ArchiveRec + ThisRecordDeleted = ArchiveRec + If ThisRecordArchived then + If Not(ThisRecordDeleted) then + Archive_Services('DeleteRecord', ThisTable, ThisRecord) + If Error_Services('NoError') then + ArchiveRec = True$ + Locate 0 in ArchiveRec using @VM setting DeletedPos else + ArchiveRec = True$ + ArchiveRec = Datetime() + end + Database_Services('WriteDataRow', 'ARCHIVE', ArchiveId, ArchiveRec, True$, 0, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ArchiveRec = True$ + Database_Services('WriteDataRow', 'ARCHIVE', ArchiveId, ArchiveRec, True$, 0, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + end else + ErrorMsg = 'Record ' : ThisRecord : ' in table ' : ThisTable : ' has not been archived.' + end + Next RecPos + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive ID was null.' + end + + If ErrorMsg EQ '' then + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveId + LogData<3> = 'Successfully deleted all records in ARCHIVE.' + Logging_Services('AppendLog', objDeleteRecordsLog, LogData, @RM, @FM, False$) + AllRecordsDeleted = True$ + end else + ErrorMsg = 'Error in DeleteRecords service - ' : ErrorMsg + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LoggingDTM = LogDate : ' ' : LogTime + LogData = '' + LogData<1> = LoggingDTM; + LogData<2> = ArchiveId + LogData<3> = ErrorMsg + Logging_Services('AppendLog', objDeleteRecordsLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMsg) + end + + Response = AllRecordsDeleted + +end service + +/* +DeleteRecord +Step 3.4 of data archiving procedures. + Responsible for deleting a record. This method is special because it temporarily removes + all MFS's in order to avoid triggering any MFS logic for the specified record. + Once MFS's are removed, the deletion occurs. + Once the deletion attempt is complete the MFS's are added back to the tables. + If the deletion is successful this service returns a true. + If the deletion fails this service returns a false. +Parameters- + TableName - The table of the record being deleted + RecordId - The key id of the record being deleted +*/ +Service DeleteRecord(TableName, RecordId) + ErrorMsg = '' + RecordDeleted = False$ + + If TableName NE '' then + If RecordId NE '' then + If RowExists(TableName, RecordId) then + TableHandle = Database_Services('GetTableHandle', TableName) + If Error_Services('NoError') then + RetryCount = 3 + Done = False$ + for i = 1 to RetryCount + Until Done + if i GT 1 then Delay(2) + //Temporarily remove MFS's to skip their execution + OrigMFSList = TableHandle<1, 1> + NumMFS = DCount(OrigMFSList, @SVM) + TempMFSList = OrigMFSList + ReAddMFSList = OrigMFSList + For MFSCnt = NumMFS to 1 Step -1 + MFSRoutine = TempMFSList<0, 0, MFSCnt> + // Removal of BASE_MFS allows us to delete records + // Removal of SQL_MFS skips any SQL replication which keeps us from deleting the record there as well. + // Need to remove RTP57 because it auto adds itself and causes an error if you add it manually. + If (MFSRoutine EQ 'BASE_MFS') OR (MFSRoutine EQ 'SQL_MFS*LSL2') OR (MFSRoutine EQ 'RTP57') then + TempMFSList = Delete(TempMFSList, 0, 0, MFSCnt) + if MFSRoutine EQ 'RTP57' then + ReAddMFSList = Delete(ReAddMFSList, 0, 0, MFSCnt) + end + end + Next MFSCnt + Set_MFS(TableName, TempMFSList, 4);// Remove all MFS's + If Not(Get_Status(ErrCode)) then + //Archive_Services('VerifyRelationalIndexes', TableName, RecordId, True$) + //Rewrite the record prior to deletion to resolve any index issues. + RecordPriorToDeletion = Database_Services('ReadDataRow', TableName, RecordId) + If Error_Services('NoError') then + Database_Services('WriteDataRow', TableName, RecordId, RecordPriorToDeletion) + if Error_Services('NoError') then + Database_Services('DeleteDataRow', TableName, RecordId) + If Error_Services('NoError') then + RecordDeleted = Not(RowExists(TableName, RecordId)) + If RecordDeleted then + Done = True$ + end else + ErrorMsg = TableName : ' - ' : RecordId : ' failed to delete.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + + Set_MFS(TableName, ReAddMFSList, 4);// Remove all MFS's;//Put MFS Back onto table + end else + ErrorMsg = 'Error removing MFS from ' : TableName + end + + Next i + + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + // Do Nothing as this is okay. Record is deleted one way or the other. + end + end else + ErrorMsg = 'RecordID was null.' + end + end else + ErrorMsg = 'TableName was null.' + end + + If ErrorMsg EQ '' then + RecordDeleted = True$ + end else + RecordDeleted = False$ + Error_Services('Add', ErrorMsg) + end + + Response = RecordDeleted + +end service + + +Service VerifyRelationalIndexes(TableName, RecordId, SkipMFSRemoval) + + ErrorMsg = '' + If ( (TableName NE '') and (RecordId NE '') ) then + TableName = UCase(TableName) + If Not(SkipMFSRemoval) then + GoSub RemoveMFS + end + ServiceModule = TableName:'_SERVICES' + ServiceName = 'VerifyRelationalIndexes' + If RowExists('SYSOBJ', '$':ServiceModule:'*LSL2') then + ServiceModuleContents = Database_Services('ReadDataRow', 'SYSPROCS', ServiceModule:'*LSL2') + If Error_Services('NoError') then + If IndexC(ServiceModuleContents, ServiceName, 1) then + FunctionResponse = Function(@ServiceModule(ServiceName, RecordId)) + If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage') + end + end + end + If Not(SkipMFSRemoval) then + GoSub ReAddMFS + end + end + If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) + +end service + +Service GetAllArchiveIDs() + + ErrorMsg = '' + ArchiveIds = '' + + open 'ARCHIVE' to FileIn then + SelectStmt = 'SELECT ARCHIVE' + RList(SelectStmt,TARGET_ACTIVELIST$,'','','') + if Not(Get_Status(errCode)) then + Done = 0 + loop + readnext ArchiveId else Done = 1 + until Done + ArchiveIds<-1> = ArchiveId + Repeat + end else + ErrorMsg = 'Error querying ARCHIVE records.' + end + end else + ErrorMsg = 'Error opening ARCHIVE table.' + end + + If ErrorMsg EQ '' then + Response = ArchiveIds + end else + Error_Services('Add', ErrorMsg) + end + +end service + + +/* +FindRecordInArchive +Step 1 of the data de-archive process. + Responsible for locating the ARCHIVE record that contains the key id of an archived child record. + If the record is found the ARCHIVE record ID is returned. +Parameters- + RecordId - The key ID of the record being searched for. + Table - The table the RecordId was contained in prior to being archived. +*/ +Service GetArchiveIDsByRecord(RecordId, Table) + + ErrorMsg = '' + ArchiveIds = '' + If RecordId NE '' then + If Table NE '' then + Open 'DICT.ARCHIVE' to hArchiveDict then + ArchiveKeys = '' + SearchString = 'CHILD_RECORD':@VM:RecordId:@FM + SearchString := 'CHILD_TABLE':@VM:Table:@FM + Btree.Extract(SearchString, 'ARCHIVE', hArchiveDict, ArchiveKeys, 0, 0) + If Not(Get_Status(errCode)) then + If ArchiveKeys NE '' then + for each ArchiveKey in ArchiveKeys using @VM + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveKey) + if Error_Services('NoError') then + Locate RecordId in ArchiveRec using @VM setting RecIdPos then + RecTable = ArchiveRec + If RecTable EQ Table then + ArchiveIds<-1> = ArchiveKey + end + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Next ArchiveKey + end else + ErrorMsg = 'No Archive keys found for matching the parameter combination.' + end + end else + ErrorMsg = 'Error in querying the Archive table.' + end + end else + ErrorMsg = 'Error opening Archive dictionary.' + end + end else + ErrorMsg = 'Table parameter was null.' + end + end else + ErrorMsg = 'RecordId parameter was null.' + end + + If ErrorMsg NE '' then + Error_Services('Add', ErrorMsg) + end + + Response = ArchiveIds + +end service + +Service GetArchiveIDsByMetaData(Fields, Values) + + ErrorMsg = '' + ArchiveIds = '' + + If Fields NE '' then + If Values NE '' then + SearchString = '' + PossibleRecords = '' + Table = 'ARCHIVE' + for each SearchTerm in Values using @VM setting TermPos + SearchString := 'METADATA_FIELD':@VM:Fields<1, TermPos>:@FM + SearchString := 'METADATA_VALUE':@VM:Values<1, TermPos>:@FM + Next SearchTerm + Open 'DICT.ARCHIVE' to hArchiveDict then + Flag = "" + Btree.Extract(SearchString, 'ARCHIVE', hArchiveDict, PossibleRecords, 0, Flag) + + if PossibleRecords NE '' then + for each RecordId in PossibleRecords using @VM setting RecIdPos + Until ErrorMsg NE '' + //Need to now verify that the possible found records match the combinations passed in. + FoundComboMatch = False$ + + ThisArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', RecordId, True$, 0, False$) + MetaDataFields = ThisArchiveRec + MetaDataValues = ThisArchiveRec + For each SearchTerm in Values using @VM setting FieldPos + Until FoundComboMatch = True$ + for each MdValue in MetaDataValues using @VM setting mdPos + Until FoundComboMatch EQ True$ + If Fields<1, FieldPos> EQ MetaDataFields<1, mdPos> then + FoundComboMatch = True$ + end + Next MdValue + Next Field + If FoundComboMatch True$ then + ArchiveIds<-1> = RecordId + end + Next RecordId + end else + ErrorMsg = 'No matching records found.' + end + end else + ErrorMsg = 'Error opening ARCHIVE dictionary.' + end + end else + ErrorMsg = 'SearchTerm parameter was null.' + end + end else + ErrorMsg = 'Fields parameter was null.' + end + + If ErrorMsg EQ '' then + Response = ArchiveIds + end else + Error_Services('Add', ErrorMsg) + end + +end service + +/* +DeArchiveData +Step 2 of the data de-archive process. + Responsible for reading data back in from a backup to the OpenInsight live system. + Reads an ARCHIVE record to get the file path of the backup then reads the CHILD_RECORD and CHILD_TABLE fields + to find the text files and write them back into the system. + Upon first attempt of de-archive, the de-archive date in the ARCHIVE record is set. +Parameters- + ArchiveId - The whole ARCHIVE record to be de-archived. +*/ +Service DeArchiveDataFromTxt(ArchiveId) + + ErrorMsg = '' + DeArchiveSuccess = False$ + + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId) + If Error_Services('NoError') then + //Set the de-archive dtm. + ArchiveRec = Datetime() + ArchiveFilesPath = ArchiveRec + for i = DCount(ArchiveRec, @VM) to 1 step -1 + until ErrorMsg NE '' + RecordExists = False$ + RecordId = ArchiveRec + TableName = ArchiveRec + RecordDeArchived = ArchiveRec + If Not(RecordDeArchived) then + If Not(RowExists(RecordTable, TableName)) then + TxtFilePath = ArchiveFilesPath + TxtFileName = TableName : '-' : RecordId : '.txt' + swap '*' with '%2A' in TxtFileName + FullSavePath = TxtFilePath : TxtFileName + Record = '' + OSRead Record from FullSavePath then + GoSub RemoveMFS + If ErrorMsg EQ '' then + Database_Services('WriteDataRow', TableName, RecordId, Record) + if Error_Services('NoError') then + If RowExists(TableName, RecordId) then + RecordExists = True$ + end else + ErrorMsg = 'An unspecified error occured saving the record.' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + GoSub ReAddMFS + end + end + end else + RecordExists = True$ + end + If RecordExists then + ArchiveRec = True$ + ArchiveRec = False$ + ArchiveRec = False$ + end else + ErrorMsg = 'An unspecified error occured saving the record.' + end + end + Next i + Database_Services('WriteDataRow', 'ARCHIVE', ArchiveId, ArchiveRec, True$, 0, False$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive record was not found.' + end + end else + ErrorMsg = 'ArchiveId was null.' + end + + If ErrorMsg EQ '' then + Response = True$ + end else + Response = False$ + Error_Services('Add', ErrorMsg) + end + +end service + +Service DeArchiveDataFromJson(ArchiveId) + + ErrorMsg = '' + DeArchiveSuccess = False$ + + If ArchiveId NE '' then + If RowExists('ARCHIVE', ArchiveId) then + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId) + ArchiveRec = Datetime() + If Error_Services('NoError') then + ArchiveFilesPath = ArchiveRec + for i = DCount(ArchiveRec, @VM) to 1 step -1 + RecordId = ArchiveRec + TableName = ArchiveRec + If Not(RowExists(RecordTable, TableName)) then + JsonFilePath = ArchiveFilesPath + JsonFileName = TableName : '-' : RecordId : '.json' + swap '*' with '%2A' in JsonFileName + FullSavePath = JsonFilePath : JsonFileName + Record = '' + OSRead Json from FullSavePath then + //ParseJson + GoSub RemoveMFS + If ErrorMsg EQ '' then + Database_Services('WriteDataRow', TableName, RecordId, Record) + if Error_Services('NoError') then + DeArchiveSuccess = True$ + end else + ErrorMsg = Error_Services('GetMessage') + end + GoSub ReAddMFS + end + end + end + Next i + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive record was not found.' + end + end else + ErrorMsg = 'ArchiveId was null.' + end + + Response = DeArchiveSuccess + + +end service + +Service ReArchive(ArchiveId) + + ErrorMsg = '' + NewArchiveId = '' + + If RowExists('ARCHIVE', ArchiveId) then + OrigArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId, True$, 0, False$) + If Error_Services('NoError') then + ArchiveType = Field(ArchiveId, '*', 1) + ArchiveParent = Field(ArchiveId, '*', 2) + If ArchiveType NE '' AND ArchiveParent NE '' then + NewArchiveId = Archive_Services('CreateArchiveRecord', ArchiveParent, ArchiveType, True$, True$) + If Error_Services('HasError') then + ErrorMsg = Error_Services('GetMessage') + end + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'Archive record did not exist.' + end + + If ErrorMsg NE '' then + Error_Services('Add', ErrorMsg) + end + + Reponse = NewArchiveId + + +end service + +Service GenerateArchiveCreationReport(ArchiveIds) + + ErrorMsg = '' + ArchiveData = '' + If ArchiveIds NE '' then + For each ArchiveId in ArchiveIds using @VM setting aPos + ArchiveRec = Database_Services('ReadDataRow', 'ARCHIVE', ArchiveId, True$, 0, False$) + if Error_Services('NoError') then + ArchiveData = Field(ArchiveId, '*', 1);// Table Name + ArchiveData = Field(ArchiveId, '*', 2);// Parent Record Id + ArchiveData = DCount(ArchiveRec, @VM) + end else + ErrorMsg = Error_Services('GetMessage') + end + Next ArchiveId + end else + ArchiveData = 'No records found to Archive.' + end + + if ArchiveData NE '' then + MessageDate = OConv(DateTime(), 'DT') + eMailBody = 'Archive Initialization Report' + eMailBody<-1> = 'The following parents records have been detected as ready to archive on ' : MessageDate : '. All records have been queued to for archive.' + eMailBody<-1> = '' + eMailBody<-1> = ArchiveData + swap @VM with ', ' in eMailBody + swap @FM with CRLF$ in eMailBody + emailHeader = 'Archive Report for ' : MessageDate + SentFrom = 'oinotify@infineon.com' + SendTo = 'jonathan.ouellette@infineon.com' + Success = Email_Services('SendEmail', SentFrom, SendTo, eMailHeader, eMailBody) + end else + MessageDate = OConv(DateTime(), 'DT') + + eMailBody = 'Archive Initialization Report' + eMailBody<-1> = 'Archive service ran on ' : MessageDate : '. No records were detected.' + swap @FM with CRLF$ in eMailBody + + emailHeader = 'Archive Report for ' : MessageDate + + SentFrom = 'oinotify@infineon.com' + SendTo = 'jonathan.ouellette@infineon.com' + Success = Email_Services('SendEmail', SentFrom, SendTo, eMailHeader, eMailBody) + end + +end service + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Internal GoSubs +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +RemoveMFS: + + TableHandle = Database_Services('GetTableHandle', TableName) + If Error_Services('NoError') then + //Temporarily remove MFS's to skip their execution + OrigMFSList = TableHandle<1, 1> + NumMFS = DCount(OrigMFSList, @SVM) + TempMFSList = OrigMFSList + ReAddMFSList = OrigMFSList + For MFSCnt = NumMFS to 1 Step -1 + MFSRoutine = TempMFSList<0, 0, MFSCnt> + // Removal of BASE_MFS allows us to delete records + // Removal of SQL_MFS skips any SQL replication which keeps us from deleting the record there as well. + // Need to remove RTP57 because it auto adds itself and causes an error if you add it manually. + If (MFSRoutine EQ 'BASE_MFS') OR (MFSRoutine EQ 'SQL_MFS*LSL2') OR (MFSRoutine EQ 'RTP57') then + TempMFSList = Delete(TempMFSList, 0, 0, MFSCnt) + if MFSRoutine EQ 'RTP57' then + ReAddMFSList = Delete(ReAddMFSList, 0, 0, MFSCnt) + end + end + Next MFSCnt + Set_MFS(TableName, TempMFSList, 4);// Remove all MFS's + If Get_Status(ErrCode) then + ErrorMsg = 'Error Setting MFS' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + +return + +ReAddMFS: + + Set_MFS(TableName, ReAddMFSList, 4);// Remove all MFS's;//Put MFS Back onto table + +return + +ClearCursors: + For counter = 0 to 8 + ClearSelect counter + Next counter return + + + + + diff --git a/LSL2/STPROC/DEARCHIVE_API.txt b/LSL2/STPROC/DEARCHIVE_API.txt new file mode 100644 index 0000000..4503741 --- /dev/null +++ b/LSL2/STPROC/DEARCHIVE_API.txt @@ -0,0 +1,105 @@ +Function Dearchive_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 : Dearchive_API + + Description : API logic for the Dearchive 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 Dearchive[.ID.[]] + - HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc. + Examples: + - Dearchive.POST + - Dearchive.ID.PUT + - Dearchive.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) + 10/14/25 xxx Original programmer. + +***********************************************************************************************************************/ + +#pragma precomp SRP_PreCompiler + +$insert APP_INSERTS +$insert API_SETUP +$insert HTTP_INSERTS +$Insert IFX_EQUATES + +Declare subroutine Service_Services +Declare function OI_Wizard_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 dearchive.ID.POST + + ErrorMsg = '' + 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 + ArchiveId = EndpointSegment + swap '__' with '*' in ArchiveId + If RowExists('ARCHIVE', ArchiveId) then + Service_Services('PostProcedure', 'ARCHIVE_SERVICES', 'DeArchiveDataFromTxt':SD$:ArchiveId) + If Error_Services('NoError') then + Message = 'Successfully queued data for de-archive.' + end else + ErrorMsg = 'Error queueing de-archiving.' + end + end else + ErrorMsg = 'Archive record not found in database.' + end + + If ErrorMsg NE '' then + HTTP_Services('SetResponseStatus', 500, ErrorMsg) + end else + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end + + end else + HTTP_Services('SetResponseStatus', 500, 'Invalid session. Reauthentication required.') + end + +end api diff --git a/LSL2/STPROC/ENVIRONMENT_SERVICES.txt b/LSL2/STPROC/ENVIRONMENT_SERVICES.txt index 5cdde6a..5ce5f34 100644 --- a/LSL2/STPROC/ENVIRONMENT_SERVICES.txt +++ b/LSL2/STPROC/ENVIRONMENT_SERVICES.txt @@ -72,24 +72,24 @@ Options BOOLEAN = True$, False$ // Therefore, this will be removed before returning to the caller. //---------------------------------------------------------------------------------------------------------------------- Service GetServer() - + NumFields = DCount(@Station, '_') Server = Field(@Station, '_', 1, NumFields - 1) - + Response = Server - + end service Service IsProd() - - Machine = Environment_Services('GetServer') - IsProd = False$ - If Machine _NEC "messa012" and Machine _NEC "mestsa01ec" and Machine _NEC "mestsa09ec" and Machine _NEC "mestsa010ec" and Machine _NEC "mestsa011ec" and Machine _NEC "mestsa012ec" and Machine _NEC "mestsa024ec" and Machine _NEC "MESTST1010" and Machine _NEC "MESTST1009" then - IsProd = True$ - end - Response = IsProd - + + Machine = Environment_Services('GetServer') + IsProd = False$ + If Machine _NEC "messa012" and Machine _NEC "mestsa01ec" and Machine _NEC "mestsa09ec" and Machine _NEC "mestsa010ec" and Machine _NEC "mestsa011ec" and Machine _NEC "mestsa012ec" and Machine _NEC "mestsa024ec" and Machine _NEC "MESTST1010" and Machine _NEC "MESTST1009" then + IsProd = True$ + end + Response = IsProd + end service @@ -99,12 +99,12 @@ end service // Returns the application's root path. If this is a server, the shared folder will be included. //---------------------------------------------------------------------------------------------------------------------- Service GetApplicationRootPath() - + RootIP = Environment_Services('GetApplicationRootIP') ApplicationRootPath = RootIP : '\Apps' - + Response = ApplicationRootPath - + end service @@ -114,17 +114,17 @@ end service // Returns the application's root IP. //---------------------------------------------------------------------------------------------------------------------- Service GetApplicationRootIP() - + Machine = Environment_Services('GetServer') - + Begin Case - Case Machine EQ 'MESSA005' ; ApplicationRootIP = '\\messa005.infineon.com' + Case Machine EQ 'MESSA005' ; ApplicationRootIP = '\\messa005.infineon.com' Case Machine EQ 'MESTSA01EC' ; ApplicationRootIP = '\\10.95.140.13' - Case Machine EQ 'MESTSA09EC' ; ApplicationRootIP = '\\10.95.140.62' - Case Machine EQ 'MESTSA010EC' ; ApplicationRootIP = '\\10.95.140.63' - Case Machine EQ 'MESTSA011EC' ; ApplicationRootIP = '\\10.95.140.64' - Case Machine EQ 'MESTSA012EC' ; ApplicationRootIP = '\\10.95.140.65' - Case Machine EQ 'MESTSA024EC' ; ApplicationRootIP = '\\10.95.140.66' + Case Machine EQ 'MESTSA09EC' ; ApplicationRootIP = '\\10.95.140.62' + Case Machine EQ 'MESTSA010EC' ; ApplicationRootIP = '\\10.95.140.63' + Case Machine EQ 'MESTSA011EC' ; ApplicationRootIP = '\\10.95.140.64' + Case Machine EQ 'MESTSA012EC' ; ApplicationRootIP = '\\10.95.140.65' + Case Machine EQ 'MESTSA024EC' ; ApplicationRootIP = '\\10.95.140.66' Case Machine EQ 'MESSA012' ; ApplicationRootIP = '\\10.95.176.50' Case Machine EQ 'MESST5201' ; ApplicationRootIP = '\\10.95.140.14' Case Machine EQ 'MESST5202' ; ApplicationRootIP = '\\10.95.140.14' @@ -132,9 +132,9 @@ Service GetApplicationRootIP() Case Machine EQ 'MESTST1010' ; ApplicationRootIP = '\\10.95.140.13' Case Otherwise$ ; ApplicationRootIP = '\\10.95.140.14' End Case - + Response = ApplicationRootIP - + end service @@ -144,10 +144,10 @@ end service // Returns the FTP root path. This is where the scripts and FTP transfer files will be located. //---------------------------------------------------------------------------------------------------------------------- Service GetFTPRootPath() - + Machine = Environment_Services('GetServer') RootPath = Environment_Services('GetLocalRootPath') - + Begin Case Case Machine EQ 'MESIRWAP001' ; FTPRootPath = RootPath Case Machine EQ 'MESSA005' ; FTPRootPath = RootPath : '\FTP' @@ -156,9 +156,9 @@ Service GetFTPRootPath() Case Machine EQ 'MESST6502' ; FTPRootPath = RootPath : '\FTP' Case Otherwise$ ; FTPRootPath = RootPath : '\FTP' End Case - + Response = FTPRootPath - + end service @@ -168,10 +168,10 @@ end service // Returns the Reports root path. This is where various reports will be located. //---------------------------------------------------------------------------------------------------------------------- Service GetReportsRootPath() - + RootPath = Environment_Services('GetLocalRootPath') Response = RootPath : '\OIReports' - + end service @@ -181,10 +181,10 @@ end service // Returns the user data root path. This is where various reports will be located. //---------------------------------------------------------------------------------------------------------------------- Service GetUserDataRootPath() - + UserDataRootPath = '\\messdv002.na.infineon.com' Response = UserDataRootPath - + end service @@ -194,10 +194,10 @@ end service // Returns the user data production path. This is where various reports will be located. //---------------------------------------------------------------------------------------------------------------------- Service GetUserDataProductionPath() - + ProductionPath = Environment_Services('GetUserDataRootPath') : '\IT' Response = ProductionPath - + end service @@ -207,17 +207,17 @@ end service // Returns the SPC data path. //---------------------------------------------------------------------------------------------------------------------- Service GetSpcFilesharePath() - - IsProd = Environment_Services("IsProd") - - If IsProd EQ True$ then - Response = '\\mesfs.infineon.com\EC_SPC_Si_Import\TXT' - end else - Path = Environment_Services('GetApplicationRootPath'):'\SPC_Data' - MakeDirSuccess = Utility("MAKEDIR", Path) - Response = Path - end - + + IsProd = Environment_Services("IsProd") + + If IsProd EQ True$ then + Response = '\\mesfs.infineon.com\EC_SPC_Si_Import\TXT' + end else + Path = Environment_Services('GetApplicationRootPath'):'\SPC_Data' + MakeDirSuccess = Utility("MAKEDIR", Path) + Response = Path + end + end service @@ -227,17 +227,17 @@ end service // Returns the SPC data path. //---------------------------------------------------------------------------------------------------------------------- Service GetSPCDataPath() - - IsProd = Environment_Services("IsProd") - - If IsProd EQ True$ then - Response = '\\messa04ec.infineon.com\OI_SPC_Data_Transfer' - end else - Path = Environment_Services('GetApplicationRootPath'):'\SPC_Data' - MakeDirSuccess = Utility("MAKEDIR", Path) - Response = Path - end - + + IsProd = Environment_Services("IsProd") + + If IsProd EQ True$ then + Response = '\\messa04ec.infineon.com\OI_SPC_Data_Transfer' + end else + Path = Environment_Services('GetApplicationRootPath'):'\SPC_Data' + MakeDirSuccess = Utility("MAKEDIR", Path) + Response = Path + end + end service @@ -247,10 +247,10 @@ end service // Returns the Metrology Viewer URL. //---------------------------------------------------------------------------------------------------------------------- Service GetMetrologyViewerURL() - + ProductionPath = 'http://messa010ec.infineon.com/' Response = ProductionPath - + end service @@ -260,10 +260,10 @@ end service // Returns the wafer map production path. //---------------------------------------------------------------------------------------------------------------------- Service GetWaferMapProductionPath() - + ProductionPath = '\\mesfs.infineon.com\EC_Metrology_Si\MetrologyAttachments\TencorRunData_' Response = ProductionPath - + end service @@ -276,7 +276,7 @@ Service GetMetrologyProductionPath() ProductionPath = 'messqlec1.infineon.com\PROD1,53959' Response = ProductionPath - + end service @@ -307,11 +307,11 @@ end service // Returns the Control Plan production path. //---------------------------------------------------------------------------------------------------------------------- Service GetControlPlanProductionPath() - + ProductionPath = 'iqsdms1' - + Response = ProductionPath - + end service @@ -321,11 +321,11 @@ end service // Returns the Wafer Track data production path. //---------------------------------------------------------------------------------------------------------------------- Service GetWaferTrackProductionPath() - + ProductionPath = 'IQSDMS1' - + Response = ProductionPath - + end service @@ -335,29 +335,29 @@ end service // Returns the local root path. This is where the scripts and FTP transfer files will be located. //---------------------------------------------------------------------------------------------------------------------- Service GetLocalRootPath() - + Machine = Environment_Services('GetServer') - + Begin Case Case Machine EQ 'MESIRWAP001' ; LocalRootPath = 'C:' Case Machine EQ 'MESSA005' ; LocalRootPath = 'D:' Case Machine EQ 'MESSA012' ; LocalRootPath = 'D:' Case Machine EQ 'MESSA01EC' ; LocalRootPath = 'D:' Case Machine EQ 'MESTSA01EC' ; LocalRootPath = 'D:' - Case Machine EQ 'MESTSA09EC' ; LocalRootPath = 'D:' - Case Machine EQ 'MESTSA010EC' ; LocalRootPath = 'D:' - Case Machine EQ 'MESTSA011EC' ; LocalRootPath = 'D:' - Case Machine EQ 'MESTSA012EC' ; LocalRootPath = 'D:' - Case Machine EQ 'MESTSA024EC' ; LocalRootPath = 'D:' + Case Machine EQ 'MESTSA09EC' ; LocalRootPath = 'D:' + Case Machine EQ 'MESTSA010EC' ; LocalRootPath = 'D:' + Case Machine EQ 'MESTSA011EC' ; LocalRootPath = 'D:' + Case Machine EQ 'MESTSA012EC' ; LocalRootPath = 'D:' + Case Machine EQ 'MESTSA024EC' ; LocalRootPath = 'D:' Case Machine EQ 'MESST6501' ; LocalRootPath = 'C:' ; // This is a map to the user's actual C drive. Case Machine EQ 'MESST6502' ; LocalRootPath = 'C:' ; // This is a map to the user's actual C drive. Case Machine EQ 'MESTST1006' ; LocalRootPath = 'C:' ; // This is a map to the user's actual C drive. Case Machine EQ 'MESTST1007' ; LocalRootPath = 'C:' ; // This is a map to the user's actual C drive. Case Otherwise$ ; LocalRootPath = 'C:' End Case - + Response = LocalRootPath - + end service @@ -367,12 +367,12 @@ end service // Returns the method that label programs should use for printing (i.e., OIPI or DirectPrint). //---------------------------------------------------------------------------------------------------------------------- Service GetLabelPrintMethod() - + LabelPrintMethod = Database_Services('ReadDataRow', 'APP_INFO', 'LABEL_PRINT_METHOD')<1> Locate LabelPrintMethod in 'OIPI,DirectPrint' using ',' setting cPos else LabelPrintMethod = 'OIPI' - + Response = LabelPrintMethod - + end service @@ -396,7 +396,7 @@ end service // Returns printer server UNC path. //---------------------------------------------------------------------------------------------------------------------- Service GetPrintServerPath() - + ServerPath = '\\messp1002.na.infineon.com\' Response = ServerPath @@ -424,10 +424,10 @@ end service // accessing the database. //---------------------------------------------------------------------------------------------------------------------- Service SetServerCanary() - + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then - + DateTimeStamp = Oconv(Date(), 'D4/') : ' - ' : Oconv(Time(), 'MTHS') Database_Services('WriteDataRow', 'APP_INFO', 'CANARY', DateTimeStamp, True$, False$, True$) If Error_Services('NoError') then @@ -443,7 +443,7 @@ Service SetServerCanary() Message<7> = 'TEXT' Message<8> = 'Error in ' : Service : ' service. Message: ' : Error Message<9> = '' - + Config = '' Config<1> = SendUsing_Port$ Config<3> = 25 @@ -454,10 +454,10 @@ Service SetServerCanary() Config<8> = False$ Result = SRP_Send_Mail(Message, Config) end - + Unlock hSysLists, ServiceKeyID else Null end - + end service @@ -465,12 +465,12 @@ Service GetSAPPath() Machine = Environment_Services('GetServer') Environment = 'QA' - + Begin Case Case Machine EQ 'MESSA005' ; Environment = 'PRD' Case Machine EQ 'MESSA01EC' ; Environment = 'PRD' End Case - + Response = Environment end service @@ -478,25 +478,25 @@ end service Service GetSQLScrapeConnectionString() - Machine = Environment_Services('GetServer') - Begin Case - Case Machine = 'MESSA01EC' - // PROD SQL Servers - ConnectionString = 'Provider=MSOLEDBSQL.1;Password=0okm9ijn;Persist Security Info=True;User ID=srpadmin;Initial Catalog=LSL2SQL;Data Source=MESSQLEC1.infineon.com\PROD1,53959;Initial File Name="";Trust Server Certificate=True;Server SPN="";Authentication="";Access Token=""' - Case ( (Machine = 'MESTSA01EC') or (Machine = 'MESTSA09EC') or (Machine = 'MESTSA010EC') or (Machine = 'MESTSA011EC') or (Machine = 'MESTSA012EC') ) - // DEV SQL Servers + Machine = Environment_Services('GetServer') + Begin Case + Case Machine = 'MESSA01EC' + // PROD SQL Servers + ConnectionString = 'Provider=MSOLEDBSQL.1;Password=0okm9ijn;Persist Security Info=True;User ID=srpadmin;Initial Catalog=LSL2SQL;Data Source=MESSQLEC1.infineon.com\PROD1,53959;Initial File Name="";Trust Server Certificate=True;Server SPN="";Authentication="";Access Token=""' + Case ( (Machine = 'MESTSA01EC') or (Machine = 'MESTSA09EC') or (Machine = 'MESTSA010EC') or (Machine = 'MESTSA011EC') or (Machine = 'MESTSA012EC') ) + // DEV SQL Servers ConnectionString = 'Provider=MSOLEDBSQL.1;Password=Fisql2023!;Persist Security Info=True;User ID=fisql;Initial Catalog=LSL2SQL;Data Source=10.95.140.27\TEST1,50572;Initial File Name="";Trust Server Certificate=True;Server SPN="";Authentication="";Access Token=""' - Case Otherwise$ - // Default to DEV SQL Servers just in case - ConnectionString = 'Provider=MSOLEDBSQL.1;Password=Fisql2023!;Persist Security Info=True;User ID=fisql;Initial Catalog=LSL2SQL;Data Source=10.95.140.27\TEST1,50572;Initial File Name="";Trust Server Certificate=True;Server SPN="";Authentication="";Access Token=""' - End Case - Response = ConnectionString - + Case Otherwise$ + // Default to DEV SQL Servers just in case + ConnectionString = 'Provider=MSOLEDBSQL.1;Password=Fisql2023!;Persist Security Info=True;User ID=fisql;Initial Catalog=LSL2SQL;Data Source=10.95.140.27\TEST1,50572;Initial File Name="";Trust Server Certificate=True;Server SPN="";Authentication="";Access Token=""' + End Case + Response = ConnectionString + end service Service GetUserDesktopPath() - + Response = '' UserRootPath = '' UserName = RTI_GetNetworkUserName() @@ -514,94 +514,115 @@ end service Service GetTempPath() - - TempDirectory = Str(\00\, 1024) - GetTempPath(Len(TempDirectory), TempDirectory) - Convert \00\ to '' in TempDirectory - Response = TempDirectory - + + TempDirectory = Str(\00\, 1024) + GetTempPath(Len(TempDirectory), TempDirectory) + Convert \00\ to '' in TempDirectory + Response = TempDirectory + end service Service GetMonaResource() - - If Environment_Services("IsProd") then - Response = "OPENINSIGHT_MES_OP_FE" - end else - Response = "OPENINSIGHT_MES_OP_FE_DEV" - end - + + If Environment_Services("IsProd") then + Response = "OPENINSIGHT_MES_OP_FE" + end else + Response = "OPENINSIGHT_MES_OP_FE_DEV" + end + end service Service GetMonInBufferedWorkerApiUrl() - - If Environment_Services("IsProd") then - Response = "https://messa014.infineon.com:7851" - end else - Response = "https://mestsa008.infineon.com:7851" - end - + + If Environment_Services("IsProd") then + Response = "https://messa014.infineon.com:7851" + end else + Response = "https://mestsa008.infineon.com:7851" + end + end service Service GetProveInApiUrl() - - If Environment_Services("IsProd") then - Response = "https://messa014.infineon.com:8851" - end else - Response = "https://mestsa008.infineon.com:8851" - end - + + If Environment_Services("IsProd") then + Response = "https://messa014.infineon.com:8851" + end else + Response = "https://mestsa008.infineon.com:8851" + end + end service Service GetIfxEmailServer() - - Response = 'smtp.intra.infineon.com' - + + Response = 'smtp.intra.infineon.com' + end service Service GetEnvironmentVariable(VariableName) - - If VariableName NE '' then - VarLength = GetEnvironmentVariable(VariableName, "", 0) + 1 - VarValue = space(VarLength+1) - VarLength = GetEnvironmentVariable(VariableName, VarValue, VarLength) - VarValue = VarValue[1, VarLength] - Response = VarValue - end else - Error_Services('Add', 'Error in service ':Service:'. Null VariableName passed in') - end - + + If VariableName NE '' then + VarLength = GetEnvironmentVariable(VariableName, "", 0) + 1 + VarValue = space(VarLength+1) + VarLength = GetEnvironmentVariable(VariableName, VarValue, VarLength) + VarValue = VarValue[1, VarLength] + Response = VarValue + end else + Error_Services('Add', 'Error in service ':Service:'. Null VariableName passed in') + end + end service Service GetServiceManagerPort() - + FilePath = Drive():'\SRPEngineServer.ini' OSRead IniFile from FilePath then CharIndex = Index(IniFile, 'Port', 1) Line = IniFile[CharIndex, 'F':CRLF$] Response = Trim(Line[-1, 'B=']) end - + end service Service GetScrapeServerPort() - + FilePath = Drive():'\SRPEngineServerScrape.ini' OSRead IniFile from FilePath then CharIndex = Index(IniFile, 'Port', 1) Line = IniFile[CharIndex, 'F':CRLF$] Response = Trim(Line[-1, 'B=']) end - + +end service + +Service GetTextDataBackupRootDir() + + Machine = Environment_Services('GetServer') + DataBackupDir = '' + + Begin Case + Case Machine = 'MESSA01EC' + // PROD SQL Servers + DataBackupDir = '\\MESFS.INFINEON.COM\MES_OpenInsight_Backups\DataBackups\' + Case ( (Machine = 'MESTSA01EC') or (Machine = 'MESTSA09EC') or (Machine = 'MESTSA010EC') or (Machine = 'MESTSA011EC') or (Machine = 'MESTSA012EC') ) + // DEV SQL Servers + DataBackupDir = 'd:\MES_OpenInsight_Backups\DataBackups\' + Case Otherwise$ + // Default to DEV SQL Servers just in case + DataBackupDir = 'd:\MES_OpenInsight_Backups\DataBackups\' + End Case + Response = DataBackupDir + end service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/LSL2/STPROC/REARCHIVE_API.txt b/LSL2/STPROC/REARCHIVE_API.txt new file mode 100644 index 0000000..a22fe39 --- /dev/null +++ b/LSL2/STPROC/REARCHIVE_API.txt @@ -0,0 +1,105 @@ +Function Rearchive_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 : Rearchive_API + + Description : API logic for the Rearchive 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 Rearchive[.ID.[]] + - HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc. + Examples: + - Rearchive.POST + - Rearchive.ID.PUT + - Rearchive.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) + 10/16/25 xxx Original programmer. + +***********************************************************************************************************************/ + +#pragma precomp SRP_PreCompiler + +$insert APP_INSERTS +$insert API_SETUP +$insert HTTP_INSERTS +$Insert IFX_EQUATES + +Declare subroutine Service_Services +Declare function OI_Wizard_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 rearchive.ID.POST + + ErrorMsg = '' + 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 + ArchiveId = EndpointSegment + swap '__' with '*' in ArchiveId + If RowExists('ARCHIVE', ArchiveId) then + Service_Services('PostProcedure', 'ARCHIVE_SERVICES', 'ReArchive':SD$:ArchiveId) + If Error_Services('NoError') then + Message = 'Successfully queued data for re-archive.' + end else + ErrorMsg = 'Error queueing re-archiving.' + end + end else + ErrorMsg = 'Archive record not found in database.' + end + + If ErrorMsg NE '' then + HTTP_Services('SetResponseStatus', 500, ErrorMsg) + end else + HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL) + If Assigned(Message) then + HTTP_Services('SetResponseStatus', 201, Message) + end else + HTTP_Services('SetResponseStatus', 201) + end + end + + end else + HTTP_Services('SetResponseStatus', 500, 'Invalid session. Reauthentication required.') + end + +end api diff --git a/LSL2/STPROC/TW_USE_SERVICES.txt b/LSL2/STPROC/TW_USE_SERVICES.txt new file mode 100644 index 0000000..c1464e8 --- /dev/null +++ b/LSL2/STPROC/TW_USE_SERVICES.txt @@ -0,0 +1,70 @@ +Compile function TW_Use_Services(@Service, @Params) +#pragma precomp SRP_PreCompiler +$Insert SERVICE_SETUP +$Insert LOGICAL +$Insert TW_USE_EQUATES + +Declare subroutine Error_Services, Delay, Update_Index + +Equ NUM_ATTEMPTS$ to 10 + +GoToService + +Return Response or "" + +//----------------------------------------------------------------------------- +// SERVICES +//----------------------------------------------------------------------------- + +Service VerifyRelationalIndexes(TWUseKey) + ErrorMsg = '' + If TWUseKey NE '' then + RDSTestKey = Field(TWUseKey, '*', 1, 1) + If RDSTestKey NE '' then + // Add index transaction to update TW_USE relational index (target RDS_TEST table) + If RowExists('TW_USE', TWUseKey) then + IndexTransactionRow = 'RDS_TEST*TW_USE_ID*AR':@FM:TWUseKey:@FM:"":@FM:RDSTestKey:@FM + end else + IndexTransactionRow = 'RDS_TEST*TW_USE_ID*AR':@FM:TWUseKey:@FM:RDSTestKey:@FM:"":@FM + end + Done = False$ + For AttemptNo = 1 to NUM_ATTEMPTS$ + If AttemptNo GT 1 then Delay(1) + Open "!TW_USE" to BangTable then + Lock BangTable, 0 then + Read PendingTrans from BangTable, 0 else PendingTrans = '0':@FM + PendingTrans := IndexTransactionRow + Write PendingTrans on BangTable, 0 then + Done = True$ + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Error in ':Service:' service. Unable to write index transaction to !TW_USE. ':TWUseKey + end + end + Unlock BangTable, 0 else ErrorMsg = 'Error in ':Service:' service. Unable to Open !TW_USE to add index transaction. ':TWUseKey + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Error in ':Service:' service. Unable to Lock !TW_USE to add index transaction. ':TWUseKey + end + end + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Error in ':Service:' service. Unable to Open !TW_USE to add index transaction. ':TWUseKey + end + end + Until Done or ErrorMsg + Next AttemptNo + If Done then + ErrCode = '' + Update_Index('TW_USE', 'MET_NO', False$, True$) + If Get_Status(ErrCode) then + ErrorMsg = 'Error in ':Service:' service. Update_Index call failed. Error code: ':ErrCode + end + end + end + end + + If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) + +End Service + diff --git a/LSL2/STPROC/WM_OUT_SERVICES.txt b/LSL2/STPROC/WM_OUT_SERVICES.txt index 1e35338..e85aa21 100644 --- a/LSL2/STPROC/WM_OUT_SERVICES.txt +++ b/LSL2/STPROC/WM_OUT_SERVICES.txt @@ -73,7 +73,7 @@ Declare subroutine Database_Services, SRP_JSON, Error_Services, Extract_Si_Keys, Declare subroutine Logging_Services, Btree.Extract, Update_Index, Delay GoToService else - Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') + Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') end Return Response else '' @@ -95,15 +95,15 @@ Service GetComments(WMOutNo) CommentArray = '' WMOutRow = Database_Services('ReadDataRow', 'WM_OUT', WMOutNo) - - CommentDates = Oconv(WMOutRow, 'DT') + + CommentDates = Oconv(WMOutRow, 'DT') CommentUsers = WMOutRow Comments = WMOutRow - + CommentList = CommentDates :@FM: CommentUsers :@FM: Comments CommentArray = SRP_Rotate_Array(CommentList) Response = CommentArray - + End Service @@ -121,35 +121,35 @@ 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 + If UsernameOpt NE '' then + Username = UsernameOpt + end + end CommentTime = Datetime() - - OldDates = WMOutRow - OldUsers = WMOutRow + + OldDates = WMOutRow + OldUsers = WMOutRow OldComments = WMOutRow - If (OldDates EQ '' AND OldUsers EQ '' AND OldComments EQ '') then - WMOutRow = CommentTime - WMOutRow = UserName - WMOutRow = Comment - end else - WMOutRow = CommentTime :@VM: OldDates - WMOutRow = UserName :@VM: OldUsers - WMOutRow = Comment :@VM: OldComments - end - Database_Services('WriteDataRow', 'WM_OUT', WMOutNo, WMOutRow, 1, 0, 0) - + If (OldDates EQ '' AND OldUsers EQ '' AND OldComments EQ '') then + WMOutRow = CommentTime + WMOutRow = UserName + WMOutRow = Comment + end else + WMOutRow = CommentTime :@VM: OldDates + WMOutRow = UserName :@VM: OldUsers + WMOutRow = 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') @@ -169,9 +169,9 @@ Service ConvertRecordToJSON(KeyID, Record, ItemURL) 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 + 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) @@ -231,16 +231,16 @@ Service ConvertRecordToJSON(KeyID, Record, ItemURL) 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, 'DT')) - SRP_JSON(objRTF, 'SetValue', 'Completed', RTFRecord, 'Boolean') - SRP_JSON(objRTFRecords, 'Set', 'ReturnToFabRecord', objRTF) - SRP_JSON(objRTFRecords, 'Add', objRTF) - SRP_JSON(objRTF, 'Release') + 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, 'DT')) + SRP_JSON(objRTF, 'SetValue', 'Completed', RTFRecord, '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 @@ -279,7 +279,7 @@ Service ConvertRecordToJSON(KeyID, Record, ItemURL) end else Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.') end - + Response = jsonRecord End Service @@ -295,9 +295,9 @@ End Service // 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) @@ -333,28 +333,28 @@ Service GetWMOData(WorkOrderNo, Columns, ShowGasGauge, WMOOverrideList) 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 = 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 = Val + Case Column EQ 'HOLD' + HoldStatus = Calculate(Column) + If HoldStatus EQ True$ then + HoldStatus = 'On Hold' + end else + HoldStatus = 'Off Hold' + end + WMOList = 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 = 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$) + If ShowGasGauge then Msg(@Window, MsgUp, fPos, MSGINSTUPDATE$) Next @ID end else Error_Services('Add', 'Error opening WM_OUT dictionary in the ' : Service : ' service.') @@ -365,7 +365,7 @@ Service GetWMOData(WorkOrderNo, Columns, ShowGasGauge, WMOOverrideList) end If ShowGasGauge then Msg(@Window, MsgUp) ;* take down the gauge Response = WMOList - + end service @@ -410,45 +410,45 @@ Service GetWaferMap(WMOKey) end service Service SetVoidFlag(WMOutKey, Username) - ErrorMessage = '' - If RowExists('WM_OUT', WMOutKey) then - WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey, True$, 0, False$) - If Error_Services('NoError') then - WMOutRec = True$ - Database_Services('WriteDataRow', 'WM_OUT', WMOutKey, WMOutRec, True$, False, False$) - If Error_Services('NoError') then - Set_Status(0) - WONo = Field(WMOutKey, '*', 1) - CassNo = Field(WMOutKey, '*', 3) - WOMLParms = '' - LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM - LogDTM = OConv(Datetime(), 'DT') ; WOMLParms := LogDTM:@RM - Action = 'WM_OUT_VOID' ; WOMLParms := Action:@RM - WhCd = 'CR' ; WOMLParms := WhCd:@RM - LocCd = 'VOID' ; WOMLParms := LocCd:@RM - WONos = WONo ; WOMLParms := WONos:@RM - CassNos = CassNo ; WOMLParms := CassNos:@RM - UserID = Username ; WOMLParms := UserID:@RM - Tags = '' ; WOMLParms := Tags:@RM - ToolID = '' ; WOMLParms := ToolID:@RM - WOMLParms := '' - obj_WO_Mat_Log('Create',WOMLParms) - IF Get_Status(errCode) THEN - ErrorMessage = 'Error writing inventory transactions' - end - end else - ErrorMessage = 'Failed to write to the WM_OUT record ' : WMOutKey : ' while attempting to set void status.' - end - end else - ErrorMessage = 'Failed to read WM_OUT record ' : WMOutKey : ' while attempting to set void status.' - end - end else - ErrorMessage = 'Invalid WM_OUT Key ' : WMOutKey : ' passed to SetVoidFlag routine.' - end - If ErrorMessage NE '' then - Error_Services('Add', ErrorMessage) - end - + ErrorMessage = '' + If RowExists('WM_OUT', WMOutKey) then + WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey, True$, 0, False$) + If Error_Services('NoError') then + WMOutRec = True$ + Database_Services('WriteDataRow', 'WM_OUT', WMOutKey, WMOutRec, True$, False, False$) + If Error_Services('NoError') then + Set_Status(0) + WONo = Field(WMOutKey, '*', 1) + CassNo = Field(WMOutKey, '*', 3) + WOMLParms = '' + LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM + LogDTM = OConv(Datetime(), 'DT') ; WOMLParms := LogDTM:@RM + Action = 'WM_OUT_VOID' ; WOMLParms := Action:@RM + WhCd = 'CR' ; WOMLParms := WhCd:@RM + LocCd = 'VOID' ; WOMLParms := LocCd:@RM + WONos = WONo ; WOMLParms := WONos:@RM + CassNos = CassNo ; WOMLParms := CassNos:@RM + UserID = Username ; WOMLParms := UserID:@RM + Tags = '' ; WOMLParms := Tags:@RM + ToolID = '' ; WOMLParms := ToolID:@RM + WOMLParms := '' + obj_WO_Mat_Log('Create',WOMLParms) + IF Get_Status(errCode) THEN + ErrorMessage = 'Error writing inventory transactions' + end + end else + ErrorMessage = 'Failed to write to the WM_OUT record ' : WMOutKey : ' while attempting to set void status.' + end + end else + ErrorMessage = 'Failed to read WM_OUT record ' : WMOutKey : ' while attempting to set void status.' + end + end else + ErrorMessage = 'Invalid WM_OUT Key ' : WMOutKey : ' passed to SetVoidFlag routine.' + end + If ErrorMessage NE '' then + Error_Services('Add', ErrorMessage) + end + end service @@ -531,6 +531,94 @@ Service VerifyWoStepWMOKeyIndex(WMOKey) end service +Service VerifyRelationalIndexes(WMOKey) + + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WM_OUT' + LogDate = Oconv(Date(), 'D4/') + LogTime = Oconv(Time(), 'MTS') + LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' !WM_OUT WO_STEP{WM_OUT_KEYS} Log.csv' + Headers = 'Logging DTM':@FM:'WMOKey':@FM:'WOStep':@FM:'Result' + objVerifyWMOKeyLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, COMMA$, Headers, '', False$, False$) + LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM + + LogData = '' + LogData<1> = LoggingDtm + LogData<2> = WMOKey + LogData<4> = 'Begin ':Service + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + + ErrorMsg = '' + If WMOKey NE '' then + + WOStepKey = Field(WMOKey, '*', 1, 2) + If WOStepKey NE '' then + WOStepWMOKeys = Xlate('WO_STEP', WOStepKey, 'WM_OUT_KEYS', 'X') + LogData<3> = WOStepKey + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + + LogData<4> = 'WMOKey missing from WO_STEP record. Generating index transaction.' + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + // Add index transaction to update WM_OUT_KEYS relational index (target WO_STEP table) + + If RowExists('WM_OUT', WMOKey) then + IndexTransactionRow = 'WO_STEP*WM_OUT_KEYS*AR':@FM:WMOKey:@FM:"":@FM:WOStepKey:@FM + end else + IndexTransactionRow = 'WO_STEP*WM_OUT_KEYS*AR':@FM:WMOKey:@FM:WOStepKey:@FM:"":@FM + end + Done = False$ + For AttemptNo = 1 to NUM_ATTEMPTS$ + If AttemptNo GT 1 then Delay(1) + Open "!WM_OUT" to BangTable then + Lock BangTable, 0 then + Read PendingTrans from BangTable, 0 else PendingTrans = '0':@FM + PendingTrans := IndexTransactionRow + Write PendingTrans on BangTable, 0 then + Done = True$ + LogData<4> = 'Index transaction successfully added.' + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Unable to write index transaction to !WM_OUT. ':WMOKey + end + end + Unlock BangTable, 0 else ErrorMsg = 'Unable to Open !WM_OUT to add index transaction. ':WMOKey + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Unable to Lock !WM_OUT to add index transaction. ':WMOKey + end + end + end else + If AttemptNo GE NUM_ATTEMPTS$ then + ErrorMsg = 'Unable to Open !WM_OUT to add index transaction. ':WMOKey + end + end + Until Done or ErrorMsg + Next AttemptNo + If Done then + ErrCode = '' + Update_Index('WM_OUT', 'WO_STEP_KEY', False$, True$) + If Get_Status(ErrCode) then + ErrorMsg = 'Error in ':Service:' service. Update_Index call failed. Error code: ':ErrCode + end + end + end else + LogData<4> = 'WO_STEP key for WM_OUT ':WMOKey:' is null. Nothing to update.' + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + end + end + + If ErrorMsg NE '' then + LogData<4> = ErrorMsg + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + end + + LogData<4> = 'End ':Service + Logging_Services('AppendLog', objVerifyWMOKeyLog, LogData, @RM, @FM) + + If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) + +end service + Service VerifyWOLogWMOKeyIndex(WMOKey) @@ -744,7 +832,7 @@ Service GetWmOutZpl(WmOutKey) PONo = WORec PSNo = XLATE('WO_STEP',WONo:'*':WOStep,WO_STEP_PROD_SPEC_ID$,'X') PSRec = XLATE('PROD_SPEC',PSNo,'','X') - + CustSpecNo = '' IF Captive THEN CustSpecNos = PSRec @@ -762,7 +850,7 @@ Service GetWmOutZpl(WmOutKey) UNTIL CustSpecNo NE '' NEXT I END - + EpiPartNo = WORec CustEpiPartRec = XLATE('CUST_EPI_PART',CustNo:'*':EpiPartNo,'','X') ShipBagReq = CustEpiPartRec @@ -793,13 +881,13 @@ Service GetWmOutZpl(WmOutKey) RecipeNo = XLATE( 'PROD_SPEC', PSNo, 'RECIPE_NO', 'X' ) RecipeInfo = XLATE( 'RECIPE', RecipeNo, 'RECIPE_NAME_NO', 'X' ) CleaningReqs = '' - + ThickCnt = FIELDCOUNT( ThickTarget<1>, @VM ) PrintThickTargets = '' FOR J = 1 TO ThickCnt PrintThickTargets<1,J> = ThickTarget<1,J>:ThickUnit<1,J> NEXT J - + ResCnt = FIELDCOUNT( ResTarget<1>, @VM ) PrintResTargets = '' FOR J = 1 TO ResCnt @@ -810,30 +898,30 @@ Service GetWmOutZpl(WmOutKey) END PrintResTargets<1,J> = TargetVal:ResUnit<1,J> NEXT J - + APreRec = '' APostRec = '' IF ( PreAkrionRecipe<1> <> '' ) THEN APreRec = ' ':PreAkrionRecipe:' ' SubOxide = 'No' ;* If Akrion then no oxide strip END - + IF ( PostAkrionRecipe<1> <> '' ) THEN APostRec = ' ':PostAkrionRecipe END - + PrintCleaningReqs = TRIM( 'Strip:':SubOxide:' Pre:':SubPreClean:APreRec:' Post:':SubPostClean:APostRec ) - + swap UNIT_MICROMETER$ with 'um' in PrintThickTargets swap UNIT_OHM_CM$ with 'ohm.cm' in PrintThickTargets swap UNIT_OHM_PER_SQ$ with 'ohm/sq' in PrintThickTargets swap UNIT_A$ with 'A' in PrintThickTargets - + swap UNIT_MICROMETER$ with 'um' in PrintResTargets swap UNIT_OHM_CM$ with 'ohm.cm' in PrintResTargets swap UNIT_OHM_PER_SQ$ with 'ohm/sq' in PrintResTargets swap UNIT_A$ with 'A' in PrintResTargets - + MakeupBox = XLATE('WM_OUT',WMOutKey,WM_OUT_MAKEUP_BOX$ ,'X') PrintWMOutKey = WMOutKey @@ -990,3 +1078,5 @@ Service GetWmOutZpl(WmOutKey) end service + + diff --git a/LSL2/STPROC/WORK_ORDER_SERVICES.txt b/LSL2/STPROC/WORK_ORDER_SERVICES.txt index d612377..bc47cdb 100644 --- a/LSL2/STPROC/WORK_ORDER_SERVICES.txt +++ b/LSL2/STPROC/WORK_ORDER_SERVICES.txt @@ -49,6 +49,9 @@ $Insert WM_OUT_EQUATES $Insert VOIDED_LOT_EQUATES $Insert IFX_EQUATES $Insert CUST_EPI_PART_EQUATES +$Insert REACT_RUN_EQUATES +$Insert RDS_LAYER_EQUATES +$Insert RDS_TEST_EQUATES Equ MAX_NUM_CASS$ to 150 Equ NUM_ATTEMPTS$ to 10 @@ -58,11 +61,11 @@ Declare subroutine Btree.Extract, Set_Status, obj_WO_Log, obj_Notes, Print_Wo_M Declare subroutine Print_Wmi_Labels, Print_Wmo_Labels, ErrMsg, Print_Cass_Labels, Logging_Services, Service_Services Declare subroutine obj_WO_Mat_Log, WO_Mat_Services, Work_Order_Services, Transaction_Services, Extract_Si_Keys Declare subroutine Mona_Services, Lot_Event_Services, RDS_Services, Lot_Services, WM_In_Services, WM_Out_Services -Declare subroutine obj_WO_Mat, obj_Post_Log, Delay +Declare subroutine obj_WO_Mat, obj_Post_Log, Delay, Archive_Services Declare function SRP_Array, Work_Order_Services, Memory_Services, Database_Services, SRP_Sort_Array, SRP_JSON Declare function Company_Services, obj_Prod_Spec, Schedule_Services, obj_WO_Log, obj_WO_Step, Memberof, Datetime Declare function Environment_Services, Logging_Services, Hold_Services, Signature_Services, Lot_Services -Declare function SRP_Datetime, RTI_CreateGUID, RDS_Services, UCase, Date_Services +Declare function SRP_Datetime, RTI_CreateGUID, RDS_Services, UCase, Date_Services, WO_Mat_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG' LogDate = Oconv(Date(), 'D4/') @@ -101,7 +104,7 @@ Options BOOLEAN = True$, False$ // Returns an array of unscheduled work order details based on the arguments provided. //---------------------------------------------------------------------------------------------------------------------- Service GetUnscheduledWorkOrders(ReactorType, SusceptorSize, ReactorNo) - + WorkOrders = '' // Select WO_LOG rows that do not have a closed date. OpenWOLogKeyIDs = Database_Services('SearchIndex', 'WO_LOG', 'CLOSE_DATE', '=', True$) @@ -127,7 +130,7 @@ Service GetUnscheduledWorkOrders(ReactorType, SusceptorSize, ReactorNo) end Convert \00\ to '' in WOLogKeyIDs WOLogKeyIDs[-1, 1] = '' - + If Error_Services('NoError') then For Each WOLogKeyID in WOLogKeyIDs using @FM setting fPos WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WOLogKeyID) @@ -171,13 +174,13 @@ Service GetUnscheduledWorkOrders(ReactorType, SusceptorSize, ReactorNo) end end Next WOLogKeyID - + WorkOrders[-1, 1] = '' WorkOrders = SRP_Array('SortRows', WorkOrders, 'AR1' : @FM : 'AR2', 'LIST', @FM, @VM) end - + Response = WorkOrders - + end service @@ -187,18 +190,18 @@ end service // Returns the WO_LOG row for the indicated Key ID. //---------------------------------------------------------------------------------------------------------------------- Service GetWorkOrderLogDetail(WorkOrderLogID) - + WorkOrderDetail = '' - + TableName = 'WO_LOG' If WorkOrderLogID NE '' then WorkOrderDetail = Database_Services('ReadDataRow', Tablename, WorkOrderLogID) end else Error_Services('Add', 'WorkOrderLogID argument was missing from the ' : Service : ' service.') end - + Response = WorkOrderDetail - + end service @@ -209,12 +212,12 @@ end service // determines if extended data related to wafers, product versions, and recipe should be included. The default is false. //---------------------------------------------------------------------------------------------------------------------- Service GetWorkOrder(WorkOrderNo, ExtendedData) -SRP_Stopwatch('Start', Service) + SRP_Stopwatch('Start', Service) If ExtendedData NE True$ then ExtendedData = False$ - + ServiceKeyID := '*' : WorkOrderNo WorkOrder = '' - + If Memory_Services('IsValueCurrent', ServiceKeyID, 15, True$) then WorkOrder = Memory_Services('GetValue', ServiceKeyID) end else @@ -269,9 +272,9 @@ SRP_Stopwatch('Start', Service) Error_Services('Add', 'WorkOrder argument was missing from the ' : Service : ' service.') end end - + Response = WorkOrder -SRP_Stopwatch('Stop', Service) + SRP_Stopwatch('Stop', Service) end service @@ -281,12 +284,12 @@ end service // Returns the number of remaining wafers needed to be scheduled for the indicated work order. //---------------------------------------------------------------------------------------------------------------------- Service GetRemainingWafers(WorkOrderNo) - + RemainingWafers = '' - + If WorkOrderNo NE '' then WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo) - + If Error_Services('NoError') then // Get the total number of unreleased work orders. TotalWafers = WOLogRow @@ -297,7 +300,7 @@ Service GetRemainingWafers(WorkOrderNo) TotalReleased += WOMatRec Next WOMatKey TotalUnreleased = TotalWafers - TotalReleased - + WOStepKeys = WOLogRow TotalUnprocessed = 0 If WOStepKeys NE '' then @@ -326,16 +329,16 @@ Service GetRemainingWafers(WorkOrderNo) end Next WOStepKey end - + // Add the two. RemainingWafers = TotalUnreleased + TotalUnprocessed end end else Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.') end - + Response = RemainingWafers - + end service @@ -347,12 +350,12 @@ end service // Returns the number of released wafers that have not yet been processed. //---------------------------------------------------------------------------------------------------------------------- Service GetUnprocessedWafers(WorkOrderNo) - + RemainingWafers = '' - + If WorkOrderNo NE '' then WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo) - + If Error_Services('NoError') then // Get the total number of unreleased work orders. TotalWafers = WOLogRow @@ -363,7 +366,7 @@ Service GetUnprocessedWafers(WorkOrderNo) TotalReleased += WOMatRec Next WOMatKey TotalUnreleased = TotalWafers - TotalReleased - + WOStepKeys = WOLogRow TotalUnprocessed = 0 If WOStepKeys NE '' then @@ -386,16 +389,16 @@ Service GetUnprocessedWafers(WorkOrderNo) end Next WOStepKey end - + // Add the two. RemainingWafers = TotalUnreleased + TotalUnprocessed end end else Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.') end - + Response = RemainingWafers - + end service @@ -492,7 +495,7 @@ end service // Creates an empty outbound cassette for a GaN work order. //---------------------------------------------------------------------------------------------------------------------- Service CreateOutbound(WONo) - + If WONo NE '' then WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo) CassNos = WORec @@ -523,7 +526,7 @@ end service Service UpdateUnscheduledQuantities(WOList) - + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then SchedList = Database_Services('ReadDataRow', 'APP_INFO', 'SCHED_WO_LIST') @@ -805,7 +808,7 @@ Service ReleaseCassette(WOMatKey, ReleaseUser, RelDtm) RelWONo = Field(WOMatKey, '*', 1, 1) RelCassNo = Field(WOMatKey, '*', 2, 1) Set_Status(0) - obj_WO_Log('ReleaseCassette',RelWONo:@RM:RelCassNo:@RM:ReleaseUser:@RM:RelDtm) + obj_WO_Log('ReleaseCassette',RelWONo:@RM:RelCassNo:@RM:ReleaseUser:@RM:RelDtm) errCode = '' If Get_Status(errCode) then ErrorMsg = 'Error in ':Service:' service. Error code ':errCode:'.' @@ -840,7 +843,7 @@ end service Service ReceiveReleaseCassette(WONo, ReceiveUser, LotNo, CassQty, SubPartNo, SubVendorCode, RecDtm) - + WOMatKey = '' ErrorMsg = '' Begin Case @@ -886,9 +889,9 @@ end service Service PrintLabels(WONo) - - If WONo NE '' then + If WONo NE '' then + WOSteps = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X') If INDEX(WOSteps,@VM,1) then @@ -985,21 +988,21 @@ Service UpdateWOStepStatus(WONo) WOStepKey = WONo:'*':1 WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey) WOStepCurrStatus = obj_WO_Step('CurrStatus', WOStepKey:@RM:WOStepRec) - // Get a fresh copy of the record - WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey) - WOStepCurrStatusStatic = WOStepRec - If WOStepCurrStatus NE WOStepCurrStatusStatic then - WOStepRec = WOStepCurrStatus - Database_Services('WriteDataRow', 'WO_STEP', WOStepKey, WOStepRec, True$, False$, True$) - end - Database_Services('ReleaseKeyIDLock', 'WO_STEP', WOStepKey) + // Get a fresh copy of the record + WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey) + WOStepCurrStatusStatic = WOStepRec + If WOStepCurrStatus NE WOStepCurrStatusStatic then + WOStepRec = WOStepCurrStatus + Database_Services('WriteDataRow', 'WO_STEP', WOStepKey, WOStepRec, True$, False$, True$) + end + Database_Services('ReleaseKeyIDLock', 'WO_STEP', WOStepKey) end end service Service PostWOStepUpdateRequest(WONo) - + If WONo NE '' then StepNo = 1 WOStepKey = WONo:'*':StepNo @@ -1848,42 +1851,42 @@ end service Service RemoveWoMatCassetteFromWO(WoMatKey, Username) - - ErrorMessage = '' - If RowExists('WO_MAT', WoMatKey) then - WoNo = Field(WoMatKey, '*', 1) - WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WoNo, True$, 0, False$) - If Error_Services('NoError') then - WoMatKeys = WOLogRecord - Locate WoMatKey in WoMatKeys using @VM setting CassPos then - WoLogRecord = Delete(WOLogRecord, 1, CassPos, 0) - Database_Services('WriteDataRow', 'WO_LOG', WoNo, WoLogRecord) - If Error_Services('NoError') then - Work_Order_Services('UpdateReceivedQty', WONo) - Work_Order_Services('UpdateReleasedQty', WONo) - Work_Order_Services('UpdateUnscheduledQuantities') - end else - ErrorMessage = Error_Services('GetMessage') - end - end else - ErrorMessage = "Unable to locate cass no " : WoMatKey : ' in the WO_LOG ' : WoNo : ' Record.' - end - end else - ErrorMessage = Error_Services('GetMessage') - end - end else - ErrorMessage = 'Invalid WoMat Key ' : WoMatKey : ' passed to RemoveWoMatCassetteFromWO routine.' - end - If ErrorMessage NE '' then - Error_Services('Add', ErrorMessage) - end - + + ErrorMessage = '' + If RowExists('WO_MAT', WoMatKey) then + WoNo = Field(WoMatKey, '*', 1) + WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WoNo, True$, 0, False$) + If Error_Services('NoError') then + WoMatKeys = WOLogRecord + Locate WoMatKey in WoMatKeys using @VM setting CassPos then + WoLogRecord = Delete(WOLogRecord, 1, CassPos, 0) + Database_Services('WriteDataRow', 'WO_LOG', WoNo, WoLogRecord) + If Error_Services('NoError') then + Work_Order_Services('UpdateReceivedQty', WONo) + Work_Order_Services('UpdateReleasedQty', WONo) + Work_Order_Services('UpdateUnscheduledQuantities') + end else + ErrorMessage = Error_Services('GetMessage') + end + end else + ErrorMessage = "Unable to locate cass no " : WoMatKey : ' in the WO_LOG ' : WoNo : ' Record.' + end + end else + ErrorMessage = Error_Services('GetMessage') + end + end else + ErrorMessage = 'Invalid WoMat Key ' : WoMatKey : ' passed to RemoveWoMatCassetteFromWO routine.' + end + If ErrorMessage NE '' then + Error_Services('Add', ErrorMessage) + end + end service Service CreateVoidedLotRecord(LotId, LegacyLotId, LegacyLotType, WoMatKey, UserId) //Todo: Move to Lot_Services ErrorMessage = '' - + If LotId NE '' OR LegacyLotId NE '' then If LotId EQ '' then //Determine NG Lot id if none was passed to routine. @@ -1894,7 +1897,7 @@ Service CreateVoidedLotRecord(LotId, LegacyLotId, LegacyLotType, WoMatKey, UserI ErrorMessage = Error_Services('GetMessage') end end else - ErrorMessage = 'Invalid Legacy Lot Type passed to routine.' + ErrorMessage = 'Invalid Legacy Lot Type passed to routine.' end end else ErrorMessage = 'A Legacy lot ID was passed to the routine, but the legacy lot type was null.' @@ -1950,11 +1953,11 @@ end service Service SignVoidNonEpp(WOMatKeys, WONo, Username) - - ErrorMessage = '' - WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) - if Error_Services('NoError') then + ErrorMessage = '' + + WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) + if Error_Services('NoError') then for each WoMatKey in WOMatKeys using @VM if WoMatKey NE '' then CassNo = Field(WoMatKey, '*', 2) @@ -2000,30 +2003,30 @@ Service SignVoidNonEpp(WOMatKeys, WONo, Username) end else ErrorMessage = Error_Services('GetMessage') end - - If ErrorMessage EQ '' then - //Commit work order changes all at once here. - Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) - if Error_Services('NoError') then - Work_Order_Services('UpdateReceivedQty', WONo) + + If ErrorMessage EQ '' then + //Commit work order changes all at once here. + Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) + if Error_Services('NoError') then + Work_Order_Services('UpdateReceivedQty', WONo) Work_Order_Services('UpdateReleasedQty', WONo) Work_Order_Services('UpdateUnscheduledQuantities') - end else - Error_Services('Add', ErrorMessage) - end + end else + Error_Services('Add', ErrorMessage) + end end else Error_Services('Add', ErrorMessage) end - + end service Service SignVoidWMI(WMInKeys, WONo, Username) - - ErrorMessage = '' - WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) - if Error_Services('NoError') then + ErrorMessage = '' + + WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) + if Error_Services('NoError') then for each WmInKey in WMInKeys using @VM if WmInKey NE '' then WONo = Field(WMInKey, '*', 1) @@ -2078,37 +2081,37 @@ Service SignVoidWMI(WMInKeys, WONo, Username) end else ErrorMessage = Error_Services('GetMessage') end - - If ErrorMessage EQ '' then - //Commit work order changes all at once here. - Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) - if Error_Services('NoError') then - Work_Order_Services('UpdateReceivedQty', WONo) + + If ErrorMessage EQ '' then + //Commit work order changes all at once here. + Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) + if Error_Services('NoError') then + Work_Order_Services('UpdateReceivedQty', WONo) Work_Order_Services('UpdateReleasedQty', WONo) Work_Order_Services('UpdateUnscheduledQuantities') - end else - Error_Services('Add', ErrorMessage) - end + end else + Error_Services('Add', ErrorMessage) + end end else Error_Services('Add', ErrorMessage) end If ErrorMessage NE '' then - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = Username - LogData<3> = WoNo - LogData<4> = ErrorMessage - Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) - Error_Services('Add', ErrorMessage) + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = Username + LogData<3> = WoNo + LogData<4> = ErrorMessage + Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMessage) end else - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = Username - LogData<3> = WoNo - LogData<4> = 'Void queued successfully.' - Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) - Error_Services('Add', ErrorMessage) + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = Username + LogData<3> = WoNo + LogData<4> = 'Void queued successfully.' + Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMessage) end end service @@ -2116,10 +2119,10 @@ end service Service SignVoidWMO(WMOutKeys, WONo, Username) - ErrorMessage = '' + ErrorMessage = '' - WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) - If Error_Services('NoError') then + WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WONo, True$, 0, False$) + If Error_Services('NoError') then for each WmOutKey in WMOutKeys using @VM if WmOutKey NE '' then WONo = Field(WmOutKey, '*', 1) @@ -2174,43 +2177,43 @@ Service SignVoidWMO(WMOutKeys, WONo, Username) end else ErrorMessage = Error_Services('GetMessage') end - - If ErrorMessage EQ '' then - //Commit work order changes all at once here. - Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) - if Error_Services('NoError') then - Work_Order_Services('UpdateReceivedQty', WONo) + + If ErrorMessage EQ '' then + //Commit work order changes all at once here. + Database_Services('WriteDataRow', 'WO_LOG', WONo, WoLogRecord) + if Error_Services('NoError') then + Work_Order_Services('UpdateReceivedQty', WONo) Work_Order_Services('UpdateReleasedQty', WONo) Work_Order_Services('UpdateUnscheduledQuantities') - end else - Error_Services('Add', ErrorMessage) - end + end else + Error_Services('Add', ErrorMessage) + end end else Error_Services('Add', ErrorMessage) end If ErrorMessage NE '' then - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = Username - LogData<3> = WONo - LogData<4> = ErrorMessage - Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) - Error_Services('Add', ErrorMessage) + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = Username + LogData<3> = WONo + LogData<4> = ErrorMessage + Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMessage) end else - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = Username - LogData<3> = '' - LogData<4> = 'Void processed successfully.' - Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) - Error_Services('Add', ErrorMessage) + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = Username + LogData<3> = '' + LogData<4> = 'Void processed successfully.' + Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) + Error_Services('Add', ErrorMessage) end end service Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType) - + ErrorMessage = '' EligibleCassIds = '' @@ -2219,17 +2222,17 @@ Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType) Case EntityType EQ 'RDS' CassIds = Database_Services('ReadDataColumn', 'WO_LOG', WONo, WO_LOG_WO_MAT_KEY$, True$, 0, False$) for each CassId in CassIds using @VM - RDSNo = XLATE('WO_MAT', CassId, WO_MAT_RDS_NO$, 'X') - Signatures = Signature_Services('GetSigProfile', CassId, 0, RDSNo) - Eligible = True$ - for each Signature in Signatures<1> using @VM setting SigPos - SignatureDtm = Signatures<3, SigPos> - If SignatureDtm NE '' then - Eligible = False$ - end - Until Eligible EQ False$ - Next Signature - If Eligible then EligibleCassIds<1, -1> = CassId + RDSNo = XLATE('WO_MAT', CassId, WO_MAT_RDS_NO$, 'X') + Signatures = Signature_Services('GetSigProfile', CassId, 0, RDSNo) + Eligible = True$ + for each Signature in Signatures<1> using @VM setting SigPos + SignatureDtm = Signatures<3, SigPos> + If SignatureDtm NE '' then + Eligible = False$ + end + Until Eligible EQ False$ + Next Signature + If Eligible then EligibleCassIds<1, -1> = CassId Next CassId Case EntityType EQ 'WM_OUT' //WM_OUTS can be voided when @@ -2268,7 +2271,7 @@ Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType) Until Eligible EQ False$ Next UMWCass end - If Eligible then EligibleCassIds<1, -1> = CassId + If Eligible then EligibleCassIds<1, -1> = CassId Next CassId Case EntityType EQ 'WM_IN' WOStepKey = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X') @@ -2295,7 +2298,7 @@ Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType) Until Eligible EQ False$ Next NCR end - If Eligible then EligibleCassIds<1, -1> = CassId + If Eligible then EligibleCassIds<1, -1> = CassId Next CassId Case EntityType EQ '' ErrorMessage = 'Entity type parameter was invalid.' @@ -2316,18 +2319,18 @@ end service Service UpdateOpenWorkOrderStatuses() - hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') - Lock hSysLists, ServiceKeyID then - - StatusName = Service + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') + Lock hSysLists, ServiceKeyID then + + StatusName = Service IsProd = Environment_Services('IsProd') If IsProd then MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SERVICE_MANAGER' end else MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SERVICE_MANAGER' end - MonaStatus = 'ok' - + MonaStatus = 'ok' + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') @@ -2349,25 +2352,25 @@ Service UpdateOpenWorkOrderStatuses() Extract_Si_Keys('WO_LOG', 'CLOSE_DATE', '', OpenWoLogKeys) If Not(Get_Status(ErrCode)) then If OpenWoLogKeys NE '' then - OpenWoLogKeys = SRP_Array('SortSimpleList', OpenWoLogKeys, 'AscendingNumbers', @VM) - LastOpenWoUpdated = '' - ServiceKey = UCase(Service) - If RowExists('APP_INFO', ServiceKey) then - LastOpenWoUpdated = Database_Services('ReadDataRow', 'APP_INFO', ServiceKey) - end - If (LastOpenWoUpdated NE '') then - Locate LastOpenWoUpdated in OpenWoLogKeys using @VM setting vPos then - vPos += 1 - end else - vPos = 1 - end - end else - vPos = 1 - end - NextOpenWoLogKey = OpenWoLogKeys<0, vPos> - Database_Services('WriteDataRow', 'APP_INFO', ServiceKey, NextOpenWoLogKey, True$, False$, False$) - If NextOpenWoLogKey NE '' then - Work_Order_Services('UpdateWorkOrderStatus', NextOpenWoLogKey) + OpenWoLogKeys = SRP_Array('SortSimpleList', OpenWoLogKeys, 'AscendingNumbers', @VM) + LastOpenWoUpdated = '' + ServiceKey = UCase(Service) + If RowExists('APP_INFO', ServiceKey) then + LastOpenWoUpdated = Database_Services('ReadDataRow', 'APP_INFO', ServiceKey) + end + If (LastOpenWoUpdated NE '') then + Locate LastOpenWoUpdated in OpenWoLogKeys using @VM setting vPos then + vPos += 1 + end else + vPos = 1 + end + end else + vPos = 1 + end + NextOpenWoLogKey = OpenWoLogKeys<0, vPos> + Database_Services('WriteDataRow', 'APP_INFO', ServiceKey, NextOpenWoLogKey, True$, False$, False$) + If NextOpenWoLogKey NE '' then + Work_Order_Services('UpdateWorkOrderStatus', NextOpenWoLogKey) If Error_Services('HasError') then LogData<1> = OConv(Datetime(), 'DT/^S') ErrorMsg = 'Error calling UpdateWorkOrderStatus for WO_LOG ':NextOpenWoLogKey:'. ':Error_Services('GetMessage') @@ -2375,7 +2378,7 @@ Service UpdateOpenWorkOrderStatuses() Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) MonaStatus = 'critical' end - end + end end else LogData<1> = OConv(Datetime(), 'DT/^S') LogData<4> = 'No open work orders to update.' @@ -2622,19 +2625,19 @@ end service Service UpdateWorkOrderData(WONo) - - hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') - Lock hSysLists, ServiceKeyID:'*':WONo then - - StatusName = Service + + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') + Lock hSysLists, ServiceKeyID:'*':WONo then + + StatusName = Service IsProd = Environment_Services('IsProd') If IsProd then MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_SERVICE_MANAGER' end else MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_SERVICE_MANAGER' end - MonaStatus = 'ok' - + MonaStatus = 'ok' + LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_MAT' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') @@ -2686,59 +2689,59 @@ Service UpdateWorkOrderData(WONo) WM_Out_Services('VerifyWOLogWMOKeyIndex', WMOKey) end end - RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X') - If (RDSNo NE '') then - If (DCount(RDSNo, @VM) GT 1) then - NewRDSNo = '' - NumRDS = 0 - For each RDSKey in RDSNo using @VM setting vPos - If RowExists('RDS', RDSKey) then - NumRDS += 1 - NewRDSNo = RDSKey - RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) - RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) - RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) - end - Next RDSKey - If (NumRDS EQ 1) then - Transaction_Services('PostWriteFieldTransaction', 'WO_MAT', WOMatKey, WO_MAT_RDS_NO$, NewRDSNo) - end else - MonaStatus = 'critical' - LogData<1> = OConv(Datetime(), 'DT/^S') - LogData<4> = 'Multiple RDS records associated with WO_MAT ':WOMatKey:'.' - Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) - end - end else - RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) - RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) - RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) - end - end else - If Not(EpiPro) then - Query = 'SELECT RDS WITH WO EQ ':WONo:' AND WITH CASS_NO EQ ':CassNo - RList(Query, TARGET_ACTIVELIST$, '', '', '') - ErrCode = '' - If Not(Get_Status(ErrCode)) then - ReadNext RDSNo then - RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) - RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) - RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) - end else - MonaStatus = 'critical' - LogData<1> = OConv(Datetime(), 'DT/^S') - LogData<4> = 'No RDS found for WO_MAT ':WOMatKey:'.' - Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) - end - end else - MonaStatus = 'critical' - LogData<1> = OConv(Datetime(), 'DT/^S') - LogData<4> = 'Error calling RList to find RDSNo associated with WO_MAT ':WOMatKey:'. Error code: ':ErrCode - Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) - end - end - end - Voided = Xlate('WO_MAT', WOMatKey, 'VOID', 'X') - If Not(Voided) then NewWOLogWOMatKeys<0, -1> = WOMatKey + RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X') + If (RDSNo NE '') then + If (DCount(RDSNo, @VM) GT 1) then + NewRDSNo = '' + NumRDS = 0 + For each RDSKey in RDSNo using @VM setting vPos + If RowExists('RDS', RDSKey) then + NumRDS += 1 + NewRDSNo = RDSKey + RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) + RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) + RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) + end + Next RDSKey + If (NumRDS EQ 1) then + Transaction_Services('PostWriteFieldTransaction', 'WO_MAT', WOMatKey, WO_MAT_RDS_NO$, NewRDSNo) + end else + MonaStatus = 'critical' + LogData<1> = OConv(Datetime(), 'DT/^S') + LogData<4> = 'Multiple RDS records associated with WO_MAT ':WOMatKey:'.' + Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) + end + end else + RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) + RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) + RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) + end + end else + If Not(EpiPro) then + Query = 'SELECT RDS WITH WO EQ ':WONo:' AND WITH CASS_NO EQ ':CassNo + RList(Query, TARGET_ACTIVELIST$, '', '', '') + ErrCode = '' + If Not(Get_Status(ErrCode)) then + ReadNext RDSNo then + RDS_Services('VerifyWOLogRDSKeyIndex', RDSNo) + RDS_Services('VerifyWOMatRDSNoIndex', RDSNo) + RDS_Services('VerifyWOStepRDSKeyIndex', RDSNo) + end else + MonaStatus = 'critical' + LogData<1> = OConv(Datetime(), 'DT/^S') + LogData<4> = 'No RDS found for WO_MAT ':WOMatKey:'.' + Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) + end + end else + MonaStatus = 'critical' + LogData<1> = OConv(Datetime(), 'DT/^S') + LogData<4> = 'Error calling RList to find RDSNo associated with WO_MAT ':WOMatKey:'. Error code: ':ErrCode + Logging_Services('AppendLog', objVerifyWOMatKeysLog, LogData, @RM, @FM) + end + end + end + Voided = Xlate('WO_MAT', WOMatKey, 'VOID', 'X') + If Not(Voided) then NewWOLogWOMatKeys<0, -1> = WOMatKey end else Done = True$ end @@ -2880,15 +2883,290 @@ Service GetVoidedWaferCount(WorkOrderNo) end service +Service GetClosedWOsToArchive(ArchiveYears) + + ErrorMsg = '' + WONos = '' + ArchiveThresholdDate = SRP_Datetime('AddYears', Date(), - ArchiveYears) + Open 'DICT.WO_LOG' to hWOLogDict then + SearchString = 'CLOSE_DATE':@VM:'#':@FM + SearchString := 'CLOSE_DATE':@VM:'<':ArchiveThresholdDate:@FM + SearchString := 'WO_START_DTM':@VM:'#':@FM + Btree.Extract(SearchString, 'WO_LOG', hWOLogDict, WONos) + If Get_Status(errCode) then + ErrorMsg = 'Error querying the WO_LOG table.' + end + end else + ErrorMsg = 'Error opening WO_LOG dictionary.' + end + + If ErrorMsg NE '' then + Error_Services('Add', ErrorMsg) + end + + Response = WONos + +end service + +Service GetWOLogHierachy(WOLogId) + + ErrorMsg = '' + HierarchyKeys = '' + + If WOLogId NE '' then + If RowExists('WO_LOG', WOLogId) then + WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WOLogId, True$, 0, False$) + If Error_Services('NoError') then + WOMatKeys = Wo_Mat_Services('GetWOMatKeys', WOLogId) + If Error_Services('NoError') then + NCRKeys = '' + for each WOMatKey in WOMatKeys using @VM + NCRKeys<1, -1> = Database_Services('ReadDataColumn', 'WO_MAT', WOMatKey, WO_MAT_NCR_KEYS$, True$, 0, False$) + Next WOMatKey + WOMatQAKeys = WOMatKeys + WOStepKey = WOLogRec + WMInKeys = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_IN_KEYS$, True$, 0, False$) + if Error_Services('NoError') then + WMOutKeys = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_OUT_KEYS$, True$, 0, False$) + if Error_Services('NoError') then + RDSKeys = RDS_Services('GetRDSKeys', WOLogId) + if Error_Services('NoError') then + ReactRunKeys = RDSKeys + RDSLayerKeys = '' + CleanInspKeys = '' + for each ReactRunKey in ReactRunKeys using @VM setting iPos + ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', ReactRunKey, True$, 0, False$) + If Error_Services('NoError') then + CleanInspKeys<1, -1> = ReactRunRec + RDSLayerKeys<1, -1> = ReactRunRec + end else + ErrorMsg = Error_Services('GetMessage') + end + Next ReactRunKey + RDSTestKeys = '' + If ErrorMsg EQ '' then + For each RDSLayerKey in RDSLayerKeys using @VM + RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey, True$, 0, False$) + //If Error_Services('NoError') then + ThisLayerRDSTestKeys = RDSLayerRec + for each LayerRDSTestKey in ThisLayerRDSTestKeys using @VM + If LayerRDSTestKey NE '' then + RDSTestKeys<1, -1> = LayerRDSTestKey + end + Next LayerRDSTestKey + +* end else +* ErrorMsg = Error_Services('GetMessage') +* end + Next RDSLayerKey + TWUseKeys = '' + end + NCRKeys = '' + TWUseKeys = '' + If ErrorMsg EQ '' then + for each RDSTestKey in RDSTestKeys using @VM + if RDSTestKey NE '' then + RDSTestRec = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKey, True$, 0, False$) + If Error_Services('NoError') then + TWUseKeys<1,-1> = RDSTestRec + end else + ErrorMsg = Error_Services('GetMessage') + end + end + Next RDSTestKey + end + If ErrorMsg EQ '' then + //ArchiveRecord + //WOLogId + If RowExists('WO_LOG', WOLogId) then + HierarchyKeys<1, -1> = WOLogId + HierarchyKeys<2, -1> = 'WO_LOG' + end + //WOStepKey + If RowExists('WO_STEP', WOStepKey) then + HierarchyKeys<1, -1> = WOStepKey + HierarchyKeys<2, -1> = 'WO_STEP' + end + //WOMatKeys + for each WOMatKey in WOMatKeys using @VM + If RowExists('WO_MAT', WOMatKey) then + HierarchyKeys<1, -1> = WOMatKey + HierarchyKeys<2, -1> = 'WO_MAT' + end + Next WOMatKey + //WOMatQAKeys + for each WOMatQAKey in WOMatQAKeys using @VM + If RowExists('WO_MAT_QA', WOMatQAKey) then + HierarchyKeys<1, -1> = WOMatQAKey + HierarchyKeys<2, -1> = 'WO_MAT_QA' + end + Next WOMatQAKey + //WMInKeys (EpiPro Specific) + for each WMInKey in WMInKeys using @VM + If RowExists('WM_IN', WMInKey) then + HierarchyKeys<1, -1> = WMInKey + HierarchyKeys<2, -1> = 'WM_IN' + end + Next WMInKey + //WMOutKeys (EpiPro Specific) + for each WMOutKey in WMOutKeys using @VM + Archive_Services('VerifyRelationalIndexes', 'WM_OUT', WMOutKey) + if Error_Services('NoError') then + If RowExists('WM_OUT', WMOutKey) then + HierarchyKeys<1, -1> = WMOutKey + HierarchyKeys<2, -1> = 'WM_OUT' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + Next WMOutKey + //RDSKeys + for each RDSKey in RDSKeys using @VM + If RowExists('RDS', RDSKey) then + HierarchyKeys<1, -1> = RDSKey + HierarchyKeys<2, -1> = 'RDS' + end + Next RDSKey + //ReactRunKeys + for each ReactRunKey in ReactRunKeys using @VM + If RowExists('REACT_RUN', ReactRunKey) then + HierarchyKeys<1, -1> = ReactRunKey + HierarchyKeys<2, -1> = 'REACT_RUN' + end + Next ReactRunKey + //RDSLayerKeys + for each RDSLayerKey in RDSLayerKeys using @VM + If RowExists('RDS_LAYER', RDSLayerKey) then + HierarchyKeys<1, -1> = RDSLayerKey + HierarchyKeys<2, -1> = 'RDS_LAYER' + end + Next RDSLayerKey + //CleanInspKeys + for each CleanInspKey in CleanInspKeys using @VM + If RowExists('CLEAN_INSP', CleanInspKey) then + HierarchyKeys<1, -1> = CleanInspKey + HierarchyKeys<2, -1> = 'CLEAN_INSP' + end + Next CleanInspKey + //RDSTestKeys + for each RDSTestKey in RDSTestKeys using @VM + If RowExists('RDS_TEST', RDSTestKey) then + HierarchyKeys<1, -1> = RDSTestKey + HierarchyKeys<2, -1> = 'RDS_TEST' + end + Next RDSTestKey + //NCRKeys + for each NCRKey in NCRKeys using @VM + if NCRKey NE '' then + If RowExists('NCR', NCRKey) then + HierarchyKeys<1, -1> = NCRKey + HierarchyKeys<2, -1> = 'NCR' + end + end + Next NCRKey + //TWUseKeys + for each TWUseKey in TWUseKeys using @VM + if TWUseKey NE '' then + Archive_Services('VerifyRelationalIndexes', 'TW_USE', TWUseKey) + if Error_Services('NoError') then + If RowExists('TW_USE', TWUseKey) then + HierarchyKeys<1, -1> = TWUseKey + HierarchyKeys<2, -1> = 'TW_USE' + end + end else + ErrorMsg = Error_Services('GetMessage') + end + //end + end + Next TWUseKey + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = Error_Services('GetMessage') + end + end else + ErrorMsg = 'WO_LOG record not found in WO_LOG table.' + end + end else + ErrorMsg = 'WO_LOG ID was null.' + end + + If ErrorMsg EQ '' then + Response = HierarchyKeys + end else + Error_Services('Add', ErrorMsg) + end + +end service + +Service GetWOMetaData(WOLogId) + + ErrorMsg = '' + WOMetaData = '' + + + WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WOLogId, True$, 0, False$) + If Error_Services('NoError') then + // Meta Data field Variables + CustNo = WOLogRec + CustPartNo = WOLogRec + EpiPartNo = WOLogRec + ProdVerNo = WOLogRec + ProdSpecNo = XLATE('PROD_VER', ProdVerNo, PROD_VER_PROC_STEP_PSN$, 'X') + SubstratePartNo = WOLogRec + WOStartDate = WOLogRec + WOCloseDate = WOLogRec + ProdOrdNo = WOLogRec + + MetaDataFields = 'CUST_NO' : @VM : 'CUST_PART_NO' : @VM : 'EPI_PART_NO' : @VM : 'PROD_VER_NO' : @VM : 'PSN' : @VM : 'SUB_PART_NO' : @VM : 'ENTRY_DATE' : @VM : 'CLOSE_DATE' : @VM : 'PROD_ORD_NO' + MetaDataTypes = 'string' : @VM : 'string' : @VM : 'string' : @VM : 'string' : @VM : 'string' : @VM : 'string' : @VM : 'DateTime' : @VM : 'DateTime' : @VM : 'string' + MetaDataValues = CustNo : @VM : CustPartNo : @VM : EpiPartNo : @VM : ProdVerNo : @VM : ProdSpecNo : @VM : SubstratePartNo : @VM : WOStartDate : @VM : WOCloseDate : @VM : ProdOrdNo + + // Loop through the data and add only those fields that have a value. + for i = 1 to DCount(MetaDataFields, @VM) + if MetaDataValues<1, i> NE '' then + WOMetaData<1, i> = MetaDataFields<1, i> + WOMetaData<2, i> = MetaDataTypes<1, i> + WOMetaData<3, i> = MetaDataValues<1, i> + end + Next i + + end else + ErrorMsg = Error_Services('GetMessage') + end + + + If ErrorMsg EQ '' then + Response = WOMetaData + end else + Error_Services('Add', ErrorMsg) + end + +end service + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ClearCursors: - + For counter = 0 to 8 ClearSelect counter Next counter return + + + diff --git a/LSL2/STPROCINS/ARCHIVE_EQUATES.txt b/LSL2/STPROCINS/ARCHIVE_EQUATES.txt index 308c481..3c72961 100644 --- a/LSL2/STPROCINS/ARCHIVE_EQUATES.txt +++ b/LSL2/STPROCINS/ARCHIVE_EQUATES.txt @@ -1,19 +1,24 @@ compile insert ARCHIVE_EQUATES /*---------------------------------------- Author : Table Create Insert Routine - Written : 28/08/2025 + Written : 15/10/2025 Description : Insert for Table ARCHIVE ----------------------------------------*/ #ifndef __ARCHIVE_EQUATES__ #define __ARCHIVE_EQUATES__ - equ ARCHIVE_ARCHIVE_DTM$ to 1 - equ ARCHIVE_COMPLETE$ to 2 - equ ARCHIVE_CHILD_RECORD$ to 3 - equ ARCHIVE_CHILD_TABLE$ to 4 - equ ARCHIVE_CHILD_RECORD_ARCHIVED$ to 5 - equ ARCHIVE_CHILD_RECORD_DELETED$ to 6 - equ ARCHIVE_CHILD_RECORD_ARCHIVE_DTM$ to 7 - equ ARCHIVE_CHILD_RECORD_DELETE_DTM$ to 8 + equ ARCHIVE_ARCHIVE_CREATION_DTM$ to 1 + equ ARCHIVE_ARCHIVE_PATH$ to 2 + equ ARCHIVE_COMPLETE$ to 3 + equ ARCHIVE_ARCHIVE_COMPLETION_DTM$ to 4 + equ ARCHIVE_CHILD_RECORD$ to 5 + equ ARCHIVE_CHILD_TABLE$ to 6 + equ ARCHIVE_CHILD_RECORD_ARCHIVED$ to 7 + equ ARCHIVE_CHILD_RECORD_DELETED$ to 8 + equ ARCHIVE_DEARCHIVE_DATETIME$ to 9 + equ ARCHIVE_METADATA_FIELD$ to 10 + equ ARCHIVE_METADATA_TYPE$ to 11 + equ ARCHIVE_METADATA_VALUE$ to 12 + equ ARCHIVE_CHILD_RECORD_DE_ARCHIVED$ to 13 #endif diff --git a/LSL2/STPROCINS/ARCHIVE_QUEUE_EQUATES.txt b/LSL2/STPROCINS/ARCHIVE_QUEUE_EQUATES.txt new file mode 100644 index 0000000..111ace9 --- /dev/null +++ b/LSL2/STPROCINS/ARCHIVE_QUEUE_EQUATES.txt @@ -0,0 +1,13 @@ +compile insert ARCHIVE_QUEUE_EQUATES +/*---------------------------------------- + Author : Table Create Insert Routine + Written : 05/09/2025 + Description : Insert for Table ARCHIVE_QUEUE +----------------------------------------*/ +#ifndef __ARCHIVE_QUEUE_EQUATES__ +#define __ARCHIVE_QUEUE_EQUATES__ + + equ ARCHIVE_QUEUE_ARCHIVE_ID$ to 1 + equ ARCHIVE_QUEUE_COMPLETED$ to 2 + +#endif diff --git a/LSL2/STPROCINS/ARCHIVE_QUEUE_ERROR_EQUATES.txt b/LSL2/STPROCINS/ARCHIVE_QUEUE_ERROR_EQUATES.txt new file mode 100644 index 0000000..10d2a19 --- /dev/null +++ b/LSL2/STPROCINS/ARCHIVE_QUEUE_ERROR_EQUATES.txt @@ -0,0 +1,13 @@ +compile insert ARCHIVE_QUEUE_ERROR_EQUATES +/*---------------------------------------- + Author : Table Create Insert Routine + Written : 02/10/2025 + Description : Insert for Table ARCHIVE_QUEUE_ERROR +----------------------------------------*/ +#ifndef __ARCHIVE_QUEUE_ERROR_EQUATES__ +#define __ARCHIVE_QUEUE_ERROR_EQUATES__ + + equ ARCHIVE_QUEUE_ERROR_ARCHIVE_ID$ to 1 + equ ARCHIVE_QUEUE_ERROR_ERROR_MSG$ to 2 + +#endif diff --git a/LSL2/STPROCINS/DELETE_QUEUE_EQUATES.txt b/LSL2/STPROCINS/DELETE_QUEUE_EQUATES.txt new file mode 100644 index 0000000..99126c9 --- /dev/null +++ b/LSL2/STPROCINS/DELETE_QUEUE_EQUATES.txt @@ -0,0 +1,13 @@ +compile insert DELETE_QUEUE_EQUATES +/*---------------------------------------- + Author : Table Create Insert Routine + Written : 05/09/2025 + Description : Insert for Table DELETE_QUEUE +----------------------------------------*/ +#ifndef __DELETE_QUEUE_EQUATES__ +#define __DELETE_QUEUE_EQUATES__ + + equ DELETE_QUEUE_ARCHIVE_ID$ to 1 + equ DELETE_QUEUE_COMPLETED$ to 2 + +#endif diff --git a/LSL2/STPROCINS/DELETE_QUEUE_ERROR_EQUATES.txt b/LSL2/STPROCINS/DELETE_QUEUE_ERROR_EQUATES.txt new file mode 100644 index 0000000..6831138 --- /dev/null +++ b/LSL2/STPROCINS/DELETE_QUEUE_ERROR_EQUATES.txt @@ -0,0 +1,13 @@ +compile insert DELETE_QUEUE_ERROR_EQUATES +/*---------------------------------------- + Author : Table Create Insert Routine + Written : 29/09/2025 + Description : Insert for Table DELETE_QUEUE_ERROR +----------------------------------------*/ +#ifndef __DELETE_QUEUE_ERROR_EQUATES__ +#define __DELETE_QUEUE_ERROR_EQUATES__ + + equ DELETE_QUEUE_ERROR_ARCHIVE_ID$ to 1 + equ DELETE_QUEUE_ERROR_ERROR_MSG$ to 2 + +#endif diff --git a/LSL2/STPROCINS/MESSAGING_EQUATES.txt b/LSL2/STPROCINS/MESSAGING_EQUATES.txt index b60fe04..c6f6a1b 100644 --- a/LSL2/STPROCINS/MESSAGING_EQUATES.txt +++ b/LSL2/STPROCINS/MESSAGING_EQUATES.txt @@ -25,3 +25,4 @@ Equ Server.Port$ to 25000 Equ Server.KeepAlive$ to 60000 Equ MessageProcessor$ to 'NDW_MESSAGING_PROCESSOR' +