Compile function Notes_Services(@Service, @Params) /*********************************************************************************************************************** Name : RDS_Services Description : Handler program for all RDS services. Notes : Application errors should be logged using the Error Services module. There are a few methodological assumptions built into way errors are managed which are important to understand in order to properly work with Error Services: - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger this will appear backwards since the originating procedure always appears at the bottom of the list and the current routine appears at the top of the list. We are using this orientation because it is common to refer to the process of calling other procedures as 'drilling down'. - The reason for defining the orientation of the call stack is because Error_Services allows for multiple error conditions to be appended to an original error. In most cases this will happen when a procedure at the bottom of the stack generates an error condition and then returns to its calling procedure. This higher level procedure can optionally add more information relevant to itself. This continues as the call stack 'bubbles' its way back to the top to where the originating procedure is waiting. - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus) preserve their error state until explicitly cleared. This can hinder the normal execution of code since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists. Our philosophy is that error conditions should automatically be cleared before a new procedure is executed to avoid this problem. However, the nature of Basic+ does not make this easy to automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our philosophy then it should include a call into the 'Clear' service request at the top of the program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.) - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any error conditions that were set before. Parameters : Service [in] -- Name of the service being requested Param1-10 [in/out] -- Additional request parameter holders Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure Metadata : History : (Date, Initials, Notes) 10/16/24 djs Added service to process notes queue. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $Insert SERVICE_SETUP $Insert LOGICAL $Insert NOTE_PTRS_EQUATES $Insert MSG_EQUATES $Insert NOTES_EQUATES $Insert LSL_USERS_EQUATES $Insert EMAIL_BOX_EQUATES $Insert NOTES_QUEUE_EQUATES $Insert NOTIFICATION_EQUATES $Insert SEC_GROUPS_EQUATES Declare function Database_Services, obj_Notes_Sent, Get_Status, Error_Services, Obj_Tables, Datetime, SRP_Datetime Declare function SRP_Array, Environment_Services, Logging_Services, RTI_CreateGuid, LSL_Users_Services Declare subroutine Obj_Tables, Obj_Notes_Sent, Update_Index, Errmsg, Database_Services, Btree.Extract, Error_Services Declare subroutine Notes_Services, Logging_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\NOTES' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Notes Queue Processing Log.csv' Headers = 'Logging DTM' : @FM : 'Notes Queue ID' : @FM : 'Notes' objNotesQProcLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Notes Queue Log.csv' Headers = 'Logging DTM' : @FM : 'Notes Queue ID' : @FM : 'Notes' objNotesQueueLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM GoToService Return Response or "" //----------------------------------------------------------------------------- // SERVICES //----------------------------------------------------------------------------- Service SnoozeNewMessageNotifications(UserID) Open 'NOTE_PTRS' to hTable then SnoozeTime = Datetime() WriteV SnoozeTime to hTable, UserID, NOTE_PTRS_SNOOZE$ else Errmsg('Error setting snooze.') end end else Errmsg('Error setting snooze.') end end service Service AllowNewMessageNotifications(UserID) Open 'NOTE_PTRS' to hTable then SnoozeTime = '' WriteV SnoozeTime to hTable, UserID, NOTE_PTRS_SNOOZE$ else Errmsg('Error setting snooze.') end end else Errmsg('Error setting snooze.') end end service Service CheckForNotificationSnooze(UserID) SnoozeRow = '' Snoozed = FALSE$ UserRec = Database_Services('ReadDataRow','NOTE_PTRS', @USER4, '', '', '') CurrentTime = Datetime() SnoozeRow = UserRec If SnoozeRow NE '' then CutoffTime = SRP_DateTime("AddMinutes", SnoozeRow, 30) If CurrentTime LE CutoffTime then Snoozed = TRUE$ end else Notes_Services('AllowNewMessageNotifications', @USER4) end end Response = Snoozed end service Service GetInboxMessages(UserID) InboxList = '' UserRec = Database_Services('ReadDataRow','NOTE_PTRS', @USER4, '', '', '') MessageCount = Dcount(UserRec<1>, @VM) For index = 1 to MessageCount ArchiveFlag = UserRec If ArchiveFlag = '' or ArchiveFlag = False$ then InboxList = UserRec InboxList = UserRec InboxList = UserRec InboxList = UserRec InboxList = UserRec InboxList = UserRec InboxList = UserRec end Next index Response = InboxList end service Service GetArchivedMessages(UserID) ArchiveList = '' UserRec = Database_Services('ReadDataRow','NOTE_PTRS', @USER4, '', '', '') MessageCount = Dcount(UserRec<1>, @VM) For index = 1 to MessageCount ArchiveFlag = UserRec If ArchiveFlag = True$ then ArchiveList = UserRec ArchiveList = UserRec ArchiveList = UserRec ArchiveList = UserRec ArchiveList = UserRec ArchiveList = UserRec ArchiveList = UserRec end Next index Response = ArchiveList end service Service UpdateNotes(UserID) ErrorMsg = '' IF UserID NE '' then If RowExists('NOTE_PTRS', UserID) then NPRec = Database_Services('ReadDataRow', 'NOTE_PTRS', UserID) end else NPRec = '' Database_Services('WriteDataRow', 'NOTE_PTRS', UserID, NPRec, True$, False$, True$) end If Error_Services('NoError') then IF LEN(NPRec) > 60000 THEN * Dump the oldest note pointers PtrCnt = COUNT(NPRec, @vm) + (NPRec NE '') FOR N = PtrCnt TO (PtrCnt - 100) STEP -1 NPRec = Delete(NPRec, note_ptrs_subject$, N, 0) NPRec = Delete(NPRec, note_ptrs_from$, N, 0) NPRec = Delete(NPRec, note_ptrs_date$, N, 0) NPRec = Delete(NPRec, note_ptrs_time$, N, 0) NPRec = Delete(NPRec, note_ptrs_new$, N, 0) NPRec = Delete(NPRec, note_ptrs_note_ids$, N, 0) NPRec = Delete(NPRec, note_ptrs_attachment$, N, 0) NPRec = Delete(NPRec, note_ptrs_archived$, N, 0) NEXT N TLen = LEN(NPRec) END NotesSentKeys = obj_Notes_Sent('GetUserKeys',UserID) IF NotesSentKeys NE '' THEN FOR I = 1 TO COUNT(NotesSentKeys,@VM) + (NotesSentKeys NE '') NotesSentKey = NotesSentKeys<1,I> NoteID = FIELD(NotesSentKey,'*',2) LOCATE NoteID IN NPRec USING @VM SETTING POS ELSE NoteRec = XLATE('NOTES',NoteID,'','X') SentFrom = NoteRec SentDate = NoteRec SentTime = NoteRec AttachWindow = NoteRec AttachKeys = NoteRec Subject = NoteRec IF AttachWindow NE '' AND AttachKeys NE '' THEN Attachment = 'Yes' END ELSE Attachment = 'No' END NPRec = INSERT( NPRec, note_ptrs_subject$, 1, 0, Subject ) ;* Add the subject ConvSentFrom = OCONV(SentFrom,'[XLATE_CONV,LSL_USERS*FIRST_LAST]') IF ConvSentFrom NE '' THEN SentFrom = ConvSentFrom NPRec = INSERT( NPRec, note_ptrs_from$, 1, 0, SentFrom ) NPRec = INSERT( NPRec, note_ptrs_date$, 1, 0, OCONV(SentDate,'D2/') ) NPRec = INSERT( NPRec, note_ptrs_time$, 1, 0, OCONV(SentTime,'MTH') ) NPRec = INSERT( NPRec, note_ptrs_new$, 1, 0, 'Yes' ) NPRec = INSERT( NPRec, note_ptrs_note_ids$, 1, 0, NoteID ) NPRec = INSERT( NPRec, note_ptrs_attachment$, 1, 0, Attachment ) NPRec = INSERT( NPRec, note_ptrs_archived$, 1, 0, '0' ) END Database_Services('WriteDataRow', 'NOTE_PTRS', UserID, NPRec, True$, False$, True$) NEXT I IF Get_Status(errCode) THEN ErrorMsg = 'Error in service: ':Service:'. Error code: ':errCode END ELSE obj_Notes_Sent('Delete',NotesSentKeys) Update_Index('NOTES_SENT','USER_ID', False$, True$) END END end else ErrorMsg = Error_Services('GetMessage') end end else ErrorMsg = 'Error in service: ':Service:'. Unassigned Parameter "UserID" passed into service.' end If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end service Service GetUnreadMessageCount(UserID) unreadMessageCount = 0 IF UserID NE '' then if xlate( 'NOTE_PTRS', @user4, 'NEW_MESSAGES', 'X' ) then NotePtrRec = xlate( 'NOTE_PTRS', @user4, '', 'X' ) LOCATE 'Yes' in NotePtrRec using @VM setting mPos then *If any are marked as yes, that means there are unread messages for each messageRead in NotePtrRec using @VM if messageRead EQ 'Yes' then unreadMessageCount += 1 Next message end end end Response = unreadMessageCount end service Service GetNewMessages(UserId) NotesSentKeys = '' IF UserId NE '' THEN OPEN 'DICT.NOTES_SENT' TO DictVar THEN SearchString = 'USER_ID':@VM:UserId:@FM Flag = '' Btree.Extract(SearchString,'NOTES_SENT',DictVar,NotesSentKeys,'',Flag) IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END END end Response = NotesSentKeys end service Service MarkAllAsRead(UserId) if UserID NE '' then NotePtrsRec = Database_Services('ReadDataRow', 'NOTE_PTRS', UserId) NotePtrsStatus = NotePtrsRec for each NotePtrsRead in NotePtrsStatus using @VM setting nPos NotePtrsRec = 'No' Next NotePtrsRead isNPRecCurrent = NotePtrsRec EQ Database_Services('ReadDataRow', 'NOTE_PTRS', UserId) if isNPRecCurrent then Database_Services('WriteDataRow','NOTE_PTRS', UserId, NotePtrsRec, '','', true$) end end else Error_Services('Set', 'Error in Notes Service, MarkAllAsRead. UserId parameter not supplied') end end service Service SendNotes() hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then ErrorMsg = '' Open 'NOTES_QUEUE' to hNotesQueue then Select hNotesQueue EOF = False$ Loop ReadNext NotesQueueId else EOF = True$ Until EOF // Send NOTES record LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Being processing NOTES_QUEUE record, "':NotesQueueID:'".' Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) DeleteRec = False$ Read NotesQueueRec from hNotesQueue, NotesQueueId then NotesId = NotesQueueRec If NotesId NE '' then NotesRec = Database_Services('ReadDataRow', 'NOTES', NotesId) If Error_Services('NoError') then If NotesRec NE '' then DeleteRec = True$ Recipients = NotesRec SentFrom = NotesRec Subject = NotesRec Message = NotesRec AttachWindow = NotesRec AttachKeys = NotesRec SendToGroup = NotesRec GroupRecipients = '' If SendToGroup NE '' then NotifyGroupRecipients = '' SecGroupRecipients = '' For each GroupID in SendToGroup using @VM If RowExists('NOTIFICATION', GroupID) then GroupRec = Database_Services('ReadDataRow', 'NOTIFICATION', GroupID) If Error_Services('NoError') then GroupUsers = GroupRec LimitToOnShift = GroupRec If LimitToOnShift then UsersOnShift = LSL_Users_Services('GetOnShiftUsers') NotifyGroupRecipients = SRP_Array('Join', GroupUsers, UsersOnShift, 'AND', @VM) end else NotifyGroupRecipients = GroupUsers end end end If RowExists('SEC_GROUPS', GroupID) then GroupRec = Database_Services('ReadDataRow', 'SEC_GROUPS', GroupID) If Error_Services('NoError') then GroupUsers = GroupRec SecGroupRecipients = GroupUsers end end GroupRecipients = SRP_Array('Join', NotifyGroupRecipients, GroupRecipients, 'OR', @VM) GroupRecipients = SRP_Array('Join', SecGroupRecipients, GroupRecipients, 'OR', @VM) Next GroupID end thisRecipients = '' RecipCnt = 0 Recipients = SRP_Array('Join', GroupRecipients, Recipients, 'OR', @VM) thisRecipients = SRP_Array('Clean', Recipients, 'TrimAndMakeUnique', @VM) RecipCnt = DCount(thisRecipients, @VM) // Previous logic from obj_Notes CurrDTM = OConv(Date(),'D4/'):' ':OConv(Time(),'MTHS') RecipientsText = thisRecipients SWAP @VM WITH ', ' IN RecipientsText FOR RecipIndex = 1 TO RecipCnt thisRecipient = thisRecipients<1, RecipIndex> obj_Notes_Sent('Create',thisRecipient:@RM:NotesId:@RM:CurrDTM) ;* Add to Notes Sent buffer table UserRec = XLATE('LSL_USERS',thisRecipient,'','X') FwdFlag = UserRec eMailAddr = UserRec IF FwdFlag = 1 AND eMailAddr NE '' THEN Text = '' Text<-1> = 'OI eMail From: ':OCONV(SentFrom,'[XLATE_CONV,LSL_USERS*FIRST_LAST]'):' at ':CurrDTM Text<-1> = '' Text<-1> = 'Recipients: ':RecipientsText Text<-1> = '' Text<-1> = 'Subject: ':Subject Text<-1> = '' Text<-1> = 'Message: ' Text<-1> = '' Text<-1> = Message Text<-1> = '' IF AttachWindow NE '' THEN Text<-1> = '' Text<-1> = 'Attached Window: ':AttachWindow END IF AttachKeys NE '' THEN Text<-1> = '' Text<-1> = 'Record Key: ':AttachKeys END IF SendToGroup NE '' THEN Text<-1> = '' Text<-1> = 'Sent to Group: ':SendToGroup END HeaderText = Text<1> CONVERT \00\ TO ',' IN Text SWAP @VM WITH ':@VM:' IN Text SWAP @FM WITH CHAR(13):CHAR(10) IN Text SWAP @TM WITH CHAR(13):CHAR(10) IN Text eMailBoxKey = NotesId:'*':thisRecipient eMailBoxRec = '' eMailBoxRec = eMailAddr eMailBoxRec = Text eMailBoxRec = HeaderText eMailBoxRec = SentFrom ebParms = 'EMAIL_BOX':@RM:eMailBoxKey:@RM:@RM:eMailBoxRec obj_Tables('WriteRec',ebParms) END ;* End of check for forwarding flag Next RecipIndex end else // Log this condition, but delete record since we have nothing to send. DeleteRec = True$ LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Error in ':Service:' service. Failed to send Note due to null NOTES record, "':NotesId:'", read in.' Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Error in ':Service:' service. Failed to read NOTES record, "':NotesId:'". Error message: ':Error_Services('GetMessage') Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end else // Log this condition, but delete record since we have nothing to send. DeleteRec = True$ LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Error in ':Service:' service. Null NotesId in NOTES_QUEUE record, "':NotesQueueId:'".' Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Error in ':Service:' service. Error reading NOTES_QUEUE record, "':NotesQueueId:'". File error: ':@File.Error Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end If DeleteRec then Database_Services('DeleteDataRow', 'NOTES_QUEUE', NotesQueueId, True$, False$) If Error_Services('NoError') then LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Successfuly deleted NOTES_QUEUE record, "':NotesQueueID:'".' Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end Repeat end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesQueueId LogData<3> = 'Error in ':Service:' service. Failed to open NOTES_QUEUE table.' Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end Unlock hSysLists, ServiceKeyID else Null end end service Service AddToQueue(NotesId) If NotesId NE '' then If RowExists('NOTES', NotesId) then QueueId = RTI_CreateGuid() If QueueId NE '' then QueueRec = NotesId Database_Services('WriteDataRow', 'NOTES_QUEUE', QueueId, QueueRec) If Error_Services('HasError') then LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesId ErrorMsg = 'Error in ':Service:' service. Failed to write NOTES_QUEUE record, "':QueueID:'", for NOTES record, "':NotesId:'".' ErrorMsg := 'Error message: ':Error_Services('GetMessage') LogData<3> = ErrorMsg Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesId ErrorMsg = 'Error in ':Service:' service. Failed to genereate NOTES_QUEUE Id for NOTES record, "':NotesId:'".' LogData<3> = ErrorMsg Logging_Services('AppendLog', objNotesQProcLog, LogData, @RM, @FM) end end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesId ErrorMsg = 'Error in ':Service:' service. NOTES record, "':NotesId:'", does not exist!.' LogData<3> = ErrorMsg end end else LogData = '' LogData<1> = LoggingDtm LogData<2> = NotesId ErrorMsg = 'Error in ':Service:' service. Null NOTES Id passed into service.' LogData<3> = ErrorMsg end end service