cancel
Showing results for 
Search instead for 
Did you mean: 
OSAdmin
Community Manager
Community Manager

Automate sending of emails prior to user expiration.

Imports System
Imports System.Data
Imports System.Data.Common
Imports System.IO
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Linq
Imports Microsoft.VisualBasic
Imports System.Threading
Imports System.Windows.Forms
Imports OneStream.Shared.Common
Imports OneStream.Shared.Wcf
Imports OneStream.Shared.Engine
Imports OneStream.Shared.Database
Imports OneStream.Stage.Engine
Imports OneStream.Stage.Database
Imports OneStream.Finance.Engine
Imports OneStream.Finance.Database

Namespace OneStream.BusinessRule.Extender.InactiveEmailNotification       '<-- Update "InactiveEmailNotification" to the name of the extender business rule
   Public Class MainClass
      Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object
         '------------------------------------------------------------------------------------------------------------------
         'Description:		User Expiration Warning
         '
         'Usage:			Sends an email to users prior their account auto expire date.  This Snippet should replace an entire rule as it includes a non-standard Import [Lines 1-18]
         '
         'Notes:			Administrator must set the following values prior to use:
         '					BusinessRuleName [Line 20]
         '					EmailConnectionName [Line 58]
         '					UserWarningThreshold [Line 61]
         '					EmailTitle [Line 64]
         '					EmailMessage [Line 68-75]
         '					EmailList [Line 78]
         '
         'Created By:		OneStream Software
         'Date Created:		09-15-2020
         '------------------------------------------------------------------------------------------------------------------
         Try
            Select Case args.FunctionType

               Case Is = ExtenderFunctionType.Unknown
                  Me.EmailNotification(si)
               Case Is = ExtenderFunctionType.ExecuteDataMgmtBusinessRuleStep
                  Me.EmailNotification(si)
               End Select

            Return Nothing
         Catch ex As Exception
            Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
         End Try
      End Function

#Region "General Helpers"

   Public Sub EmailNotification(ByVal si As SessionInfo)
      Try
         'Specify the email connection (Defined in Application Server setup)
         Dim emailConnectionName As String = "OneStreamEmail"

         'Enter number of days prior to user expiration that warning will be sent.  Email will only be sent if "Remaining Allowed Inactivity" is less than or equal to threshold days.
         Dim userWarningThreshold As Double = 20							

         'Define the the email title to be sent.  The value [days] will be updated during processing.
         Dim emailTitle As String = "OneStream User ID Expiration - [days] day warning"
			
         'Define the the email body to be sent.  The values [user] & [days] will be updated during processing to OneSteam Name & number of days till expiration.
         Dim emailMessage As New Text.StringBuilder
         emailMessage.AppendLine("Attention: [user]")
         emailMessage.AppendLine("")
         emailMessage.AppendLine("Your login for OneStream will expire in [days] due to inactivity.  Please login as soon as possible.")
         emailMessage.AppendLine("")
         emailMessage.AppendLine("If you require assistance, please contact support by e-mailing xxxx.")			'<-- Replace xxxx with the appropriate support email address
         emailMessage.AppendLine("")
         emailMessage.AppendLine("Thank you.")
         emailMessage.AppendLine("The Support Team")

         'Define any additional email addresses to include other than the user that is expiring.  All emails will be listed in the "To: field" of the email.
         Dim emailList As New List(Of String)
         'emailList.Add("emailaddress1@customer.com")			'<-- Uncomment the line and update with the desired email address
         'emailList.Add("emailaddress2@customer.com")			'<-- Uncomment the line and update with the desired email address
         '									'<-- Additional email addresses may be added by copying the format of the previous line

         'Account Expiration Warning
         Me.ValidateUserExpiration(si, emailConnectionName, userWarningThreshold, emailTitle, emailMessage.ToString, emailList)

      Catch ex As Exception
         Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
      End Try
   End Sub

   Public Sub ValidateUserExpiration(ByVal si As SessionInfo, ByVal emailConnectionName As String, ByVal userWarningThreshold As Double, ByVal emailTitle As String, emailMessage As String, ByVal emailList As List(Of String))
      Try
          Dim dtResults As New DataTable

         Using dbConnApp As DbConnInfo = BRAPi.Database.CreateApplicationDbConnInfo(si)
            Dim ds As DataSet = BRApi.Database.ExecuteMethodCommand(dbConnApp, XFCommandMethodTypeID.Users,  "{}", "Users", Nothing)

            If Not ds Is Nothing Then
               Dim dt As DataTable = ds.Tables(0).Copy
               Dim userID As Guid = Guid.Empty
               Dim userName As String = String.Empty
               Dim remainingDays As Double = 0
               Dim updatedEmailList As New List(Of String)
               Dim updatedEmailTitle As String = String.Empty
               Dim updatedEmailMessage As String = String.Empty
               Dim objUserInfoAndStatus As UserInfoAndStatus = BRApi.Security.Admin.GetUserAndStatus(si, si.UserName)

               For Each dr As DataRow In dt.Rows
                  'Filter out inactive users and users without a defined email address
                  If (dr(3).ToString().XFContainsIgnoreCase("TRUE")) And (Not String.IsNullOrEmpty(dr(6).ToString)) Then
                     'Get UserName and UserInfoAndStatus
                     userName = dr(1)
                     objUserInfoAndStatus = BRApi.Security.Admin.GetUserAndStatus(si, userName)

                     If objUserInfoAndStatus.LogonStatus.GetNumDaysOfRemainingAllowedInactivity <= userWarningThreshold Then
                        remainingDays = objUserInfoAndStatus.LogonStatus.GetNumDaysOfRemainingAllowedInactivity

                        'Reset email list for next user
                        updatedemailList.Clear
                        updatedemailList.AddRange(emailList)

                        'Add user to email list
                        updatedemailList.Add(dr(6).ToString)

                        'Replace [days] & [user] values in email EmailMessage / EmailTitle
                        updatedEmailTitle = emailTitle.Replace("[days]", ConvertHelper.ToInt32(remainingDays))
                        updatedEmailMessage = emailMessage.Replace("[days]", ConvertHelper.ToInt32(remainingDays))
                        updatedEmailMessage = updatedEmailMessage.Replace("[user]", userName)

                        'Send the email using a worker background thread
                        Dim mailThread As New SendMailThread(si, emailConnectionName, updatedemailList, updatedEmailTitle, updatedEmailMessage, Nothing)
                        mailThread.Start
                     End If
                  End If
               Next
            End If
         End Using

      Catch ex As Exception
          Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
      End Try
   End Sub

#End Region

#Region "Constants and Enumerations"

   'String Messages
   Public m_MsgNoEmailConnection As String = "Cannot Send Notifications: Email Connection must be specified."

#End Region

   Public Class SendMailThread

#Region "Module Level Variables"

   Private Const m_ThreadNamePrefix As String = "XF Send Mail Thread"
   Private m_SI As SessionInfo = Nothing
   Private m_MailConnectionName As String = String.Empty
   Private m_ToEmailAddresses As New List(Of String)
   Private m_Subject As String = String.Empty
   Private m_Body As String = String.Empty
   Private m_AttachmentFilePaths As New List(Of String)
   Private m_WorkerThread As Thread

#End Region

#Region "Constructor"

   Public Sub New(ByVal si As SessionInfo, ByVal mailConnectionName As String, ByVal toEmailAddresses As List(Of String), ByVal subject As String, ByVal body As String, ByVal attachmentFilePaths As List(Of String))

      'Copy the input parameters so the background thread can access them.
      m_SI = si
      m_MailConnectionName = mailConnectionName
      m_ToEmailAddresses = toEmailAddresses
      m_Subject = subject
      m_Body = body
      m_AttachmentFilePaths = attachmentFilePaths

   End Sub

#End Region

#Region "Public Methods"

   Public Sub Start()
      Try

         'Create the Background Thread
         m_WorkerThread = New Thread(AddressOf Me.WorkerThreadMethod)
         m_WorkerThread.IsBackground = True 'We don't want this worker thread to keep the process from being shut down.
         m_WorkerThread.Name = m_ThreadNamePrefix & " " & Guid.NewGuid().ToString("N") 'Note: this provides a unique recognizable name when debugging.
         XFWcfOperationInvoker.SetCultureInfoForUserToThread(m_SI, m_WorkerThread)
         m_WorkerThread.Start()

      Catch ex As Exception
         Throw ErrorHandler.LogWrite(m_SI, New XFException(m_SI, ex))
      End Try
   End Sub

#End Region

#Region "Private Methods"

   Private Sub WorkerThreadMethod()
      Try

         'Send the email
         BRApi.Utilities.SendMail(m_SI, m_MailConnectionName, m_ToEmailAddresses, m_Subject, m_Body, m_AttachmentFilePaths)

      Catch ex As Exception
         'Important: do not re-throw the exception from this worker thread since it will be processed by .NET as an unhandled exception.
         'Even if an exception could be processed normally, it couldn't be sent back to the client via WCF because the client isn't
         'waiting for a WCF method to complete and the client might not not even be logged on anymore.
         Try
            BRApi.ErrorLog.LogError(m_SI, ex)
         Catch
         End Try
      End Try
   End Sub

#End Region

   End Class

   End Class
End Namespace
Version history
Last update:
‎04-25-2022 08:25 AM
Updated by:
Contributors