Imports System.Data.SqlClient Imports System.IO Imports DevExpress.XtraBars.Docking Imports DigitalData.Modules.Logging Imports EnvelopeGenerator.CommonServices Imports EnvelopeGenerator.CommonServices.My Imports EnvelopeGenerator.Domain.Constants Imports EnvelopeGenerator.Domain.Entities Public Class EnvelopeEditorController Inherits BaseController Public ReadOnly Envelope As Envelope = Nothing Public ReadOnly EmailService As EmailService Public ReadOnly ActionService As ActionService Public ReadOnly Thumbnail As Thumbnail Public Sub New(pState As State) MyBase.New(pState) Envelope = CreateEnvelope() Thumbnail = New Thumbnail(pState.LogConfig) EmailService = New EmailService(pState) ActionService = New ActionService(pState, Nothing) End Sub Public Sub New(pState As State, pEnvelope As Envelope) MyBase.New(pState) Envelope = pEnvelope Envelope.Documents = DocumentModel.List(pEnvelope.Id).ToList() Envelope.EnvelopeReceivers = ReceiverModel.ListEnvelopeReceivers(pEnvelope.Id).Cast(Of EnvelopeReceiver)().ToList() Thumbnail = New Thumbnail(pState.LogConfig) ActionService = New ActionService(pState, Nothing) End Sub #Region "Public" Public Function SendEnvelope() As Boolean Return ActionService.SendEnvelope(Envelope) End Function Public Function DocumentRotationChanged() As Boolean Return ActionService.SetStatusDocumentRotationChanged(Envelope) End Function Public Function ResendReceiverInvitation(pEnvelope As Envelope, pReceiver As ReceiverVM) As Boolean Return ActionService.ResendReceiver(pEnvelope, pReceiver) End Function Public Function ValidateEnvelopeForSending(pErrors As List(Of String)) As List(Of String) Dim oEnvelopeErrors = pErrors If ElementModel.ElementsExist(Envelope.Id) = False Then oEnvelopeErrors.Add(Resources.Envelope.Missing_Elements) End If If ElementModel.OneElementPerReceiverExist(Envelope.Id) = False Then For Each receiverItem As EnvelopeReceiver In Envelope.EnvelopeReceivers If ElementModel.ElementsExist(Envelope.Id, receiverItem.Envelope.Id) = False Then oEnvelopeErrors.Add(String.Format(Resources.Envelope.Missing_Elements_for_Receiver, receiverItem.Name)) End If Next End If Return oEnvelopeErrors End Function Public Function CreateEnvelope() As Envelope Dim oEnvelope As New Envelope() With { .UserId = State.UserId, .User = UserModel.SelectUser(), .TfaEnabled = DEF_TF_ENABLED } If EnvelopeModel.Insert(oEnvelope) Then Dim newHistoryEntry As New History With { .EnvelopeId = oEnvelope.Id, .Status = EnvelopeStatus.EnvelopeCreated, .UserReference = oEnvelope.User.Email } HistoryModel.Insert(newHistoryEntry) Return oEnvelope Else Return Nothing End If End Function Public Function SaveReceivers(pEnvelope As Envelope, pReceiversFromGrid As List(Of ReceiverVM)) As Boolean Dim oExistingReceivers As List(Of Receiver) = ReceiverModel.ListReceivers(pReceiversFromGrid).ToList() Dim oExistingAddresses = oExistingReceivers.Select(Function(r) r.EmailAddress) Logger.Debug($"oExistingReceivers.count: {oExistingReceivers.Count}") Logger.Debug($"oExistingAddresses.count: {oExistingAddresses.Count}") Dim oNewReceivers = pReceiversFromGrid.Where(Function(r) If r.EmailAddress Is Nothing Then Return False Return Not oExistingAddresses.Contains(r.EmailAddress) End Function).ToList() Logger.Debug($"oNewReceivers.count: {oNewReceivers.Count}") If CreateNewReceivers(oNewReceivers) = False Then Return False End If Dim oAllReceivers As List(Of Receiver) = ReceiverModel.ListReceivers(pReceiversFromGrid).ToList() pEnvelope.EnvelopeReceivers.Clear() For Each oReceiver In pReceiversFromGrid If oReceiver.EmailAddress Is Nothing Then Continue For If oReceiver.Name Is Nothing Then Continue For Dim oDbReceiver = oAllReceivers.Where(Function(r) r.EmailAddress = oReceiver.EmailAddress).SingleOrDefault() If oDbReceiver IsNot Nothing Then oReceiver.Id = oDbReceiver.Id oReceiver.Signature = oDbReceiver.Signature End If pEnvelope.EnvelopeReceivers.Add(oReceiver) Next Return True End Function Public Function SaveEnvelope() As Boolean Dim oConnection = Database.GetConnection() Dim oTransaction = oConnection.BeginTransaction(IsolationLevel.ReadUncommitted) Try Envelope.Status = EnvelopeStatus.EnvelopeSaved If SaveEnvelopeDocumentsToFilesystem(Envelope) = False Then Throw New ApplicationException End If If EnvelopeModel.Update(Envelope, oTransaction) = False Then Throw New ApplicationException End If If SaveEnvelopeReceivers(Envelope, oTransaction) = False Then Throw New ApplicationException End If If SaveEnvelopeDocuments(Envelope, oTransaction) = False Then Throw New ApplicationException End If oTransaction.Commit() Return True Catch ex As Exception Logger.Error(ex) oTransaction.Rollback() Return False End Try End Function Public Async Function CreateDocument(pDocumentFilePath As String) As Threading.Tasks.Task(Of Document) Try Dim oFixedPath = FixPageRotation.FixPageRotation(pDocumentFilePath) If oFixedPath <> pDocumentFilePath Then DocumentRotationChanged() Logger.Info("PageRotation has been reseted to 0.") End If oFixedPath = FlattenFormFields.FlattenFormFields(oFixedPath) Dim oFileInfo = New FileInfo(oFixedPath) Dim oTempFiles As New TempFiles(State.LogConfig) Dim oTempFilePath = Path.Combine(oTempFiles._TempPath, Guid.NewGuid().ToString + oFileInfo.Extension) Await Helpers.CopyFileAsync(oFileInfo.FullName, oTempFilePath) 'File.Copy(oFileInfo.FullName, oTempFilePath, True) Dim oFileInfoTemp = New FileInfo(oTempFilePath) Dim oDocument = New Document() With { .Filename = oFileInfoTemp.Name, .Filepath = oFileInfoTemp.FullName, .FileNameOriginal = oFileInfo.Name, .Thumbnail = Thumbnail.GetThumbnailFromPDFFile(oTempFilePath), .PageCount = Thumbnail.GetPageCount(oTempFilePath), .ByteData = ReadFile(oFixedPath) } Return oDocument Catch ex As Exception Logger.Error(ex) Logger.Warn($"error in CreateDocument: {ex.Message}") Return Nothing End Try End Function 'Open file in to a filestream and read data in a byte array. Private Function ReadFile(ByVal sPath As String) As Byte() 'Initialize byte array with a null value initially. Dim data As Byte() = Nothing 'Use FileInfo object to get file size. Dim fInfo As New FileInfo(sPath) Dim numBytes As Long = fInfo.Length 'Open FileStream to read file Dim fStream As New FileStream(sPath, FileMode.Open, FileAccess.Read) 'Use BinaryReader to read file stream into byte array. Dim br As New BinaryReader(fStream) 'When you use BinaryReader, you need to supply number of bytes to read from file. 'In this case we want to read entire file. So supplying total number of bytes. data = br.ReadBytes(CInt(numBytes)) Return data End Function Public Function CreateThumbnail(pDocumentPath As String) As Bitmap Try Dim oThumbNail As Bitmap = Thumbnail.GetThumbnailFromPDFFile(pDocumentPath) Return oThumbNail Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Function GetPageCount(pDocumentPath As String) As Integer Try Return Thumbnail.GetPageCount(pDocumentPath) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Overloads Function DeleteDocument(pDocument As Document) As Boolean Dim oConnection As SqlConnection = Database.GetConnection Dim oTransaction As SqlTransaction = oConnection.BeginTransaction If DeleteDocument(pDocument, oTransaction) = True Then oTransaction.Commit() Return True Else oTransaction.Rollback() Return False End If End Function Public Function SaveEnvelopeDocumentsToFilesystem(pEnvelope As Envelope) As Boolean Try For Each oDocument In pEnvelope.Documents.Where(Function(d) d.IsTempFile) Dim oEnvelopePath = GetEnvelopePath(pEnvelope) If oEnvelopePath Is Nothing Then Return False End If Dim oDocumentFilePath = Path.Combine(oEnvelopePath, oDocument.Filename) File.Copy(oDocument.Filepath, oDocumentFilePath) File.Delete(oDocument.Filepath) Dim oFileInfo = New FileInfo(oDocumentFilePath) oDocument.IsTempFile = False oDocument.Filename = oFileInfo.Name oDocument.Filepath = oFileInfo.FullName Next Return True Catch ex As Exception Logger.Error(ex) Return False End Try End Function Public Function GetEnvelopeReceiverAddresses(pUserId As Integer) As List(Of String) Return ReceiverModel.ListAllEnvelopeReceiverAddresses(pUserId) End Function Public Function CreateNewReceivers(pNewReceivers As List(Of ReceiverVM)) As Boolean If pNewReceivers.Count = 0 Then Return True End If Dim oConnection = Database.GetConnection() Dim oTransaction = oConnection.BeginTransaction() Try InsertReceivers(pNewReceivers, oTransaction) oTransaction.Commit() Return True Catch ex As Exception Logger.Error(ex) oTransaction.Rollback() Return False End Try End Function #End Region Private Function GetEnvelopePath(pEnvelope As Envelope) As String Try Dim oTempFiles As New TempFiles(State.LogConfig) Dim oTempFolderPath = oTempFiles._TempPath Dim oEnvelopePath As String = Path.Combine(oTempFolderPath, pEnvelope.Uuid) If Not Directory.Exists(oEnvelopePath) Then Directory.CreateDirectory(oEnvelopePath) End If Return oEnvelopePath Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Private Function SaveEnvelopeDocuments(pEnvelope As Envelope, pTransaction As SqlTransaction) As Boolean Try Return pEnvelope.Documents. Where(Function(d) d.Id = 0). Select(Function(d) DocumentModel.Insert(pEnvelope, d, pTransaction)). All(Function(pResult) pResult = True) Catch ex As Exception Logger.Error(ex) Return False End Try End Function Private Function SaveEnvelopeReceivers(pEnvelope As Envelope, pTransaction As SqlTransaction) As Boolean Try If pEnvelope.Id = Nothing Then Throw New ArgumentNullException("EnvelopeId") End If If AssignReceivers(pEnvelope, pTransaction) = False Then Return False End If Return True Catch ex As Exception Logger.Error(ex) Return False End Try End Function Public Function DeleteReceiver(pReceiver As Receiver) As Boolean Dim oConnection As SqlConnection = Database.GetConnection() Dim oTransaction As SqlTransaction = oConnection.BeginTransaction() Try If ReceiverModel.Delete(pReceiver.Id, Envelope.Id, oTransaction) = True Then Dim oResult = Envelope.Documents. Select(Function(d) ElementModel.DeleteElements(pReceiver.Id, d.Id, oTransaction)). All(Function(pResult) pResult = True) If oResult = False Then Throw New ApplicationException("Could not delete elements!") End If Else Throw New ApplicationException("Could not delete receiver!") End If oTransaction.Commit() Return True Catch ex As Exception Logger.Error(ex) oTransaction.Rollback() Return False End Try End Function Public Function ElementsExist(pReceiverId As Integer) As Boolean Return ElementModel.ElementsExist(Envelope.Id, pReceiverId) End Function Private Sub InsertReceivers(pReceivers As List(Of ReceiverVM), pTransaction As SqlTransaction) Dim status = pReceivers. Select(Function(r) InsertReceiver(r, pTransaction)). All(Function(pResult) pResult = True) If Not status Then Throw New ApplicationException("Could not insert receivers!") End If End Sub Private Function AssignReceivers(pEnvelope As Envelope, pTransaction As SqlTransaction) As Boolean If ReceiverModel.Unassign(pEnvelope, pTransaction) = False Then Return False End If Return pEnvelope.EnvelopeReceivers. Select(Function(r) ReceiverModel.Assign(pEnvelope, r, pTransaction)). All(Function(pResult) pResult = True) End Function Private Function InsertReceiver(pReceiver As ReceiverVM, pTransaction As SqlTransaction) As Boolean Return ReceiverModel.Insert(pReceiver, pTransaction) End Function Public Function GetLastNameByEmailAdress(pEmailAdress As String) As String If (String.IsNullOrEmpty(pEmailAdress) = False) Then Return ReceiverModel.GetLastUsedReceiverName(pEmailAdress, Envelope.UserId) Else Return String.Empty End If End Function Public Function GetLastPhoneByEmailAdress(pEmailAdress As String) As String If (String.IsNullOrEmpty(pEmailAdress) = False) Then Return ReceiverModel.GetLastUsedReceiverPhone(pEmailAdress, Envelope.UserId) Else Return String.Empty End If End Function End Class