diff --git a/EnvelopeGenerator.Application/Common/Dto/EnvelopeDto.cs b/EnvelopeGenerator.Application/Common/Dto/EnvelopeDto.cs index 01c24251..1222c343 100644 --- a/EnvelopeGenerator.Application/Common/Dto/EnvelopeDto.cs +++ b/EnvelopeGenerator.Application/Common/Dto/EnvelopeDto.cs @@ -75,10 +75,12 @@ public record EnvelopeDto : IEnvelope /// public int? EnvelopeTypeId { get; set; } + // TODO: use ReadAndConfirm property name /// /// /// - public bool ReadOnly => EnvelopeTypeId == 2; + [Obsolete("Use EnvelopeExtensions.IsReadAndConfirm extension metot instead.")] + public bool ReadOnly => this.IsReadAndConfirm(); /// /// diff --git a/EnvelopeGenerator.Application/Common/Extensions/AutoMapperAuditingExtensions.cs b/EnvelopeGenerator.Application/Common/Extensions/AutoMapperAuditingExtensions.cs index 4ce31eb1..72f2abef 100644 --- a/EnvelopeGenerator.Application/Common/Extensions/AutoMapperAuditingExtensions.cs +++ b/EnvelopeGenerator.Application/Common/Extensions/AutoMapperAuditingExtensions.cs @@ -13,12 +13,12 @@ public static class AutoMapperAuditingExtensions /// public static IMappingExpression MapAddedWhen(this IMappingExpression expression) where TDestination : IHasAddedWhen - => expression.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow)); + => expression.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now)); /// /// Maps to the current UTC time. /// public static IMappingExpression MapChangedWhen(this IMappingExpression expression) where TDestination : IHasChangedWhen - => expression.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow)); + => expression.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.Now)); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Common/Notifications/SendMailHandler.cs b/EnvelopeGenerator.Application/Common/Notifications/SendMailHandler.cs index 5a97ef03..50cf3662 100644 --- a/EnvelopeGenerator.Application/Common/Notifications/SendMailHandler.cs +++ b/EnvelopeGenerator.Application/Common/Notifications/SendMailHandler.cs @@ -113,7 +113,7 @@ public abstract class SendMailHandler : INotificationHandler() .ForMember(dest => dest.Envelope, opt => opt.Ignore()) .ForMember(dest => dest.Receiver, opt => opt.Ignore()) - .ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.UtcNow)) + .ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.Now)) .MapChangedWhen(); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs b/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs index c8a53f59..4cd83f01 100644 --- a/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs +++ b/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs @@ -34,7 +34,7 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest /// /// - public DateTime AddedWhen { get; } = DateTime.UtcNow; + public DateTime AddedWhen { get; } = DateTime.Now; /// /// diff --git a/EnvelopeGenerator.BBTests/EnvelopeGenerator.BBTests.vbproj b/EnvelopeGenerator.BBTests/EnvelopeGenerator.BBTests.vbproj index de126637..63b3db6d 100644 --- a/EnvelopeGenerator.BBTests/EnvelopeGenerator.BBTests.vbproj +++ b/EnvelopeGenerator.BBTests/EnvelopeGenerator.BBTests.vbproj @@ -487,10 +487,6 @@ {6EA0C51F-C2B1-4462-8198-3DE0B32B74F8} EnvelopeGenerator.CommonServices - - {6ea0c51f-c2b1-4462-8198-3de0b32b74f8} - EnvelopeGenerator.CommonServices - {4f32a98d-e6f0-4a09-bd97-1cf26107e837} EnvelopeGenerator.Domain diff --git a/EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb b/EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb index 5a2794e2..2cd0616b 100644 --- a/EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb +++ b/EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb @@ -27,6 +27,7 @@ Partial Class frmFinalizePDF Me.Label2 = New System.Windows.Forms.Label() Me.Button1 = New System.Windows.Forms.Button() Me.Button2 = New System.Windows.Forms.Button() + Me.Button3 = New System.Windows.Forms.Button() Me.txtResult = New System.Windows.Forms.TextBox() Me.txtEnvelope = New System.Windows.Forms.TextBox() Me.SuspendLayout() @@ -75,6 +76,15 @@ Partial Class frmFinalizePDF Me.Button2.Text = "Merge Json" Me.Button2.UseVisualStyleBackColor = True ' + 'Button3 + ' + Me.Button3.Location = New System.Drawing.Point(15, 160) + Me.Button3.Name = "Button3" + Me.Button3.Size = New System.Drawing.Size(166, 23) + Me.Button3.TabIndex = 5 + Me.Button3.Text = "Full Finalize Test" + Me.Button3.UseVisualStyleBackColor = True + ' 'txtResult ' Me.txtResult.Location = New System.Drawing.Point(333, 12) @@ -97,6 +107,7 @@ Partial Class frmFinalizePDF Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(800, 450) Me.Controls.Add(Me.txtResult) + Me.Controls.Add(Me.Button3) Me.Controls.Add(Me.Button2) Me.Controls.Add(Me.Button1) Me.Controls.Add(Me.Label2) @@ -116,5 +127,6 @@ Partial Class frmFinalizePDF Friend WithEvents Label2 As Label Friend WithEvents Button1 As Button Friend WithEvents Button2 As Button + Friend WithEvents Button3 As Button Friend WithEvents txtResult As TextBox End Class diff --git a/EnvelopeGenerator.BBTests/frmFinalizePDF.vb b/EnvelopeGenerator.BBTests/frmFinalizePDF.vb index 56122a17..24847ec0 100644 --- a/EnvelopeGenerator.BBTests/frmFinalizePDF.vb +++ b/EnvelopeGenerator.BBTests/frmFinalizePDF.vb @@ -8,6 +8,8 @@ Imports Newtonsoft.Json.Linq Imports EnvelopeGenerator.Infrastructure Imports Microsoft.EntityFrameworkCore Imports DigitalData.Core.Abstractions +Imports DigitalData.Core.Abstraction.Application.Repository +Imports EnvelopeGenerator.Domain.Entities Public Class frmFinalizePDF Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;" + "Encrypt=True;TrustServerCertificate=True;" @@ -124,4 +126,86 @@ Public Class frmFinalizePDF txtResult.Text = oJObject1.ToString() End Sub + + Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click + Try + Dim envelopeId As Integer = CInt(txtEnvelope.Text) + Dim log As New System.Text.StringBuilder() + + ' 1. Load annotation JSON data (same as Service) + Dim oTable = LoadAnnotationDataForEnvelope() + Dim oJsonList = oTable.Rows. + Cast(Of DataRow). + Select(Function(r As DataRow) r.Item("VALUE").ToString()). + ToList() + log.AppendLine($"Annotation JSON count: {oJsonList.Count}") + + ' 2. Load document bytes (same as Service) + Dim oBuffer As Byte() = ReadEnvelope(envelopeId) + log.AppendLine($"Document bytes: {oBuffer.Length}") + + ' 3. Check what BurnAnnotsToPDF will do internally + Using scope = Factory.Shared.ScopeFactory.CreateScope() + Dim envRepo = scope.ServiceProvider.Repository(Of Envelope)() + Dim envelope = envRepo.Where(Function(env) env.Id = envelopeId).FirstOrDefault() + + If envelope Is Nothing Then + log.AppendLine("ERROR: Envelope not found in EF Core!") + txtResult.Text = log.ToString() + Return + End If + + log.AppendLine($"Envelope found: Id={envelope.Id}, EnvelopeTypeId={envelope.EnvelopeTypeId}") + log.AppendLine($"ReadOnly (IsReadAndConfirm): {envelope.ReadOnly}") + + If envelope.ReadOnly Then + log.AppendLine(">>> EARLY RETURN: ReadOnly=True, original PDF returned without burning") + txtResult.Text = log.ToString() + Return + End If + + Dim sigRepo = scope.ServiceProvider.Repository(Of Signature)() + Dim elements = sigRepo _ + .Where(Function(sig) sig.Document.EnvelopeId = envelopeId) _ + .Include(Function(sig) sig.Annotations) _ + .ToList() + + log.AppendLine($"Elements (Signature) count: {elements.Count}") + + If elements.Any() Then + log.AppendLine(">>> PATH: BurnElementAnnotsToPDF (new element-based path)") + For Each elem In elements + Dim annotCount = If(elem.Annotations IsNot Nothing, elem.Annotations.Count(), 0) + log.AppendLine($" Element Id={elem.Id}, Page={elem.Page}, X={elem.X}, Y={elem.Y}, W={elem.Width}, H={elem.Height}, Annotations={annotCount}") + If elem.Annotations IsNot Nothing Then + For Each annot In elem.Annotations + log.AppendLine($" Annot: Name={annot.Name}, Type={annot.Type}, X={annot.X}, Y={annot.Y}, W={annot.Width}, H={annot.Height}") + Next + End If + Next + Else + log.AppendLine(">>> PATH: BurnInstantJSONAnnotsToPDF (old JSON-based path)") + End If + End Using + + ' 4. Actually call BurnAnnotsToPDF (same as Service) + log.AppendLine("") + log.AppendLine("Calling BurnAnnotsToPDF...") + Dim oNewBuffer = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId) + log.AppendLine($"Result bytes: {oNewBuffer.Length}") + log.AppendLine($"Same as input: {oBuffer.Length = oNewBuffer.Length AndAlso oBuffer.SequenceEqual(oNewBuffer)}") + + ' 5. Write output + Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}_FullTest.burned.pdf") + File.WriteAllBytes(oNewPath, oNewBuffer) + log.AppendLine($"Output: {oNewPath}") + + txtResult.Text = log.ToString() + Process.Start(oNewPath) + + Catch ex As Exception + txtResult.Text = $"ERROR: {ex.Message}{vbCrLf}{vbCrLf}{ex.ToString()}" + End Try + End Sub End Class \ No newline at end of file diff --git a/EnvelopeGenerator.BBTests/packages.config b/EnvelopeGenerator.BBTests/packages.config index 1114c525..2b6489de 100644 --- a/EnvelopeGenerator.BBTests/packages.config +++ b/EnvelopeGenerator.BBTests/packages.config @@ -15,13 +15,13 @@ - + - + @@ -62,10 +62,10 @@ - + - - + + @@ -74,23 +74,23 @@ - + - - + + - - + + - + - - + + - - + + \ No newline at end of file diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/FinalizeDocumentJob.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/FinalizeDocumentJob.vb index cfd2af5e..9b0ca0fe 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/FinalizeDocumentJob.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/FinalizeDocumentJob.vb @@ -15,6 +15,7 @@ Imports DigitalData.Core.Abstraction.Application Imports EnvelopeGenerator.Infrastructure Imports Microsoft.EntityFrameworkCore Imports DigitalData.Core.Abstractions +Imports EnvelopeGenerator.Domain.Interfaces Namespace Jobs Public Class FinalizeDocumentJob @@ -230,6 +231,29 @@ Namespace Jobs Return Task.FromResult(True) End Function + +#Region "From BBTests" + Private Function ReadEnvelope(pEnvID As Integer) As Byte() + Dim strSql As String = "Select [BYTE_DATA] from [TBSIG_ENVELOPE_DOCUMENT] WHERE ENVELOPE_ID = " & pEnvID + Dim obyteDB = Database.GetScalarValue(strSql) + If Not IsDBNull(obyteDB) Then + Dim fileData As Byte() = DirectCast(Database.GetScalarValue(strSql), Byte()) + If fileData IsNot Nothing Then + Return fileData + End If + End If + + Throw New InvalidOperationException($"Byte data is null. Envelope ID: {pEnvID}") + + End Function + + Private Function LoadAnnotationDataForEnvelope(pEnvID As Integer) As DataTable + Dim oSql = $"SELECT VALUE FROM [TBSIG_DOCUMENT_STATUS] WHERE ENVELOPE_ID = {pEnvID}" + Return Database.GetDatatable(oSql) + + End Function +#End Region + Private Sub Update_File_DB(pFilePath As String, pEnvelopeID As Long) Dim SqlCom As SqlCommand Dim imageData As Byte() @@ -327,7 +351,7 @@ Namespace Jobs Logger.Warn($"No SendFinalEmailToCreator - oMailToCreator [{oMailToCreator}] <> [{FinalEmailType.No}] ") End If - If oMailToReceivers <> FinalEmailType.No Then + If oMailToReceivers <> FinalEmailType.No And pEnvelope.IsReadAndSign() Then Logger.Debug("Sending emails to receivers..") SendFinalEmailToReceivers(pEnvelope) ', pAttachment Else @@ -418,7 +442,18 @@ Namespace Jobs End Try End If - Return PDFBurner.BurnAnnotsToPDF(oInputDocumentBuffer, oAnnotations, pEnvelopeData.EnvelopeId) +#Region "From BBTests" + Dim oTable = LoadAnnotationDataForEnvelope(pEnvelopeId) + Dim oJsonList = oTable.Rows. + Cast(Of DataRow). + Select(Function(r As DataRow) r.Item("VALUE").ToString()). + ToList() + + Dim oBuffer As Byte() = ReadEnvelope(pEnvelopeId) + +#End Region + + Return PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, pEnvelopeId) End Function Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb index 781615ac..97347a72 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb @@ -85,16 +85,37 @@ Namespace Jobs.FinalizeDocument 'Add annotations For Each element In elements + If element Is Nothing Then + Continue For + End If + + Dim elementAnnotations = If(element.Annotations, Enumerable.Empty(Of ElementAnnotation)()) + If Not elementAnnotations.Any() Then + Continue For + End If Dim frameX = (element.Left - 0.7 - margin) - Dim frame = element.Annotations.FirstOrDefault(Function(a) a.Name = "frame") + Dim frame = elementAnnotations.FirstOrDefault(Function(a) a.Name = "frame") Dim frameY = element.Top - 0.5 - margin - Dim frameYShift = frame.Y - frameY * inchFactor - Dim frameXShift = frame.X - frameX * inchFactor + Dim frameYShift As Double = 0 + Dim frameXShift As Double = 0 + + If frame IsNot Nothing Then + frameYShift = frame.Y - frameY * inchFactor + frameXShift = frame.X - frameX * inchFactor + End If + + For Each annot In elementAnnotations + If annot Is Nothing Then + Continue For + End If + + Dim yOffsetofFF As Double = 0 + If Not String.IsNullOrEmpty(annot.Name) Then + yOffsetsOfFF.TryGetValue(annot.Name, yOffsetofFF) + End If - For Each annot In element.Annotations - Dim yOffsetofFF As Double = If(yOffsetsOfFF.TryGetValue(annot.Name, yOffsetofFF), yOffsetofFF, 0) Dim y = frameY + yOffsetofFF If annot.Type = AnnotationType.FormField Then diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFMerger.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFMerger.vb index 207a916c..f0c3f963 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFMerger.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFMerger.vb @@ -56,7 +56,7 @@ Public Class PDFMerger ' Convert to PDF/A oMergedPDF.ConvertToPDFA(oFinalStream, PDFAConformanceLevel, ALLOW_VECTORIZATION, ALLOW_RASTERIZATION) - oStatus = oDocumentPDF.GetStat() + oStatus = oMergedPDF.GetStat() If oStatus <> GdPictureStatus.OK Then Throw New MergeDocumentException($"Document could not be converted to PDF/A: {oStatus}") End If diff --git a/EnvelopeGenerator.CommonServices/Models/ReceiverModel.vb b/EnvelopeGenerator.CommonServices/Models/ReceiverModel.vb index 2d2395c9..78408d40 100644 --- a/EnvelopeGenerator.CommonServices/Models/ReceiverModel.vb +++ b/EnvelopeGenerator.CommonServices/Models/ReceiverModel.vb @@ -270,12 +270,26 @@ Public Class ReceiverModel Private Function GetSignedDate(pEmailAddress As String, pEnvelopeId As Integer) As Date Try Dim oStatusInt As Integer = EnvelopeStatus.DocumentSigned - Return Database.GetScalarValue($"SELECT ACTION_DATE FROM [DD_ECM].[dbo].[TBSIG_ENVELOPE_HISTORY] WHERE ENVELOPE_ID = {pEnvelopeId} + Dim value = Database.GetScalarValue($"SELECT ACTION_DATE FROM [DD_ECM].[dbo].[TBSIG_ENVELOPE_HISTORY] WHERE ENVELOPE_ID = {pEnvelopeId} And USER_REFERENCE = '{pEmailAddress}' AND [STATUS] = {oStatusInt}") + If value Is Nothing OrElse value Is DBNull.Value Then + Return DateTime.MinValue + End If + + If TypeOf value Is DateTime Then + Return DirectCast(value, DateTime) + End If + + Dim parsedDate As DateTime + If DateTime.TryParse(value.ToString(), parsedDate) Then + Return parsedDate + End If + + Return DateTime.MinValue Catch ex As Exception Logger.Error(ex) - Return Nothing + Return DateTime.MinValue End Try End Function diff --git a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs index 3bec79c7..7a3a8fcd 100644 --- a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs +++ b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs @@ -35,7 +35,6 @@ namespace EnvelopeGenerator.Domain.Entities [Column("STATUS")] public Constants.DocumentStatus Status { get; set; } - [Required] [Column("STATUS_CHANGED_WHEN", TypeName = "datetime")] public DateTime? StatusChangedWhen { get; set; } diff --git a/EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs b/EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs index bdc709c6..f4647701 100644 --- a/EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs +++ b/EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs @@ -11,5 +11,10 @@ { return envelope.EnvelopeTypeId == 2; } + + public static bool IsReadAndSign(this IEnvelope envelope) + { + return envelope.EnvelopeTypeId != 2; + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/EGDbContext.cs b/EnvelopeGenerator.Infrastructure/EGDbContext.cs index 468aaa4c..cff50672 100644 --- a/EnvelopeGenerator.Infrastructure/EGDbContext.cs +++ b/EnvelopeGenerator.Infrastructure/EGDbContext.cs @@ -47,6 +47,8 @@ public abstract class EGDbContextBase : DbContext public DbSet DocumentReceiverElements { get; set; } + public DbSet DocumentReceiverElementAnnotations { get; set; } + public DbSet DocumentStatus { get; set; } public DbSet EmailTemplate { get; set; } diff --git a/EnvelopeGenerator.PdfEditor/Pdf.cs b/EnvelopeGenerator.PdfEditor/Pdf.cs index 03b629f0..22011f72 100644 --- a/EnvelopeGenerator.PdfEditor/Pdf.cs +++ b/EnvelopeGenerator.PdfEditor/Pdf.cs @@ -105,17 +105,13 @@ namespace EnvelopeGenerator.PdfEditor public Pdf Background(IEnumerable signatures, double widthPx = 1.9500000000000002, double heightPx = 2.52) where TSignature : ISignature { - // once per page - Page(page => - { - var canvas = new PdfCanvas(page); - canvas.ConcatMatrix(1, 0, 0, -1, 0, page.GetPageSize().GetHeight()); - }); - foreach (var signature in signatures) Page(signature.Page, page => { var canvas = new PdfCanvas(page); + canvas.SaveState(); + canvas.ConcatMatrix(1, 0, 0, -1, 0, page.GetPageSize().GetHeight()); + double inchFactor = 72; double magin = .2; double x = (signature.X - .7 - magin) * inchFactor; @@ -134,6 +130,8 @@ namespace EnvelopeGenerator.PdfEditor canvas.SetFillColor(new DeviceRgb(204, 202, 198)) .Rectangle(x, y + height - bottomLineLength, width, bottomLineLength) .Fill(); + + canvas.RestoreState(); }); return this; diff --git a/EnvelopeGenerator.Service/App.config b/EnvelopeGenerator.Service/App.config index 445dd0b3..9349ae8f 100644 --- a/EnvelopeGenerator.Service/App.config +++ b/EnvelopeGenerator.Service/App.config @@ -15,7 +15,7 @@ - + @@ -23,15 +23,15 @@ - + - + - + @@ -39,7 +39,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -135,7 +135,7 @@ - + diff --git a/EnvelopeGenerator.Service/EnvelopeGenerator.Service.vbproj b/EnvelopeGenerator.Service/EnvelopeGenerator.Service.vbproj index 03df4c62..17e5ead9 100644 --- a/EnvelopeGenerator.Service/EnvelopeGenerator.Service.vbproj +++ b/EnvelopeGenerator.Service/EnvelopeGenerator.Service.vbproj @@ -1,4 +1,4 @@ - + @@ -17,7 +17,8 @@ - publish\ + false + P:\Install .Net\0 DD - Smart UP\signFLOW\Finalization\%24%28Version%29\ true Disk false @@ -27,10 +28,11 @@ false false true + true 0 1.0.0.%2a - false false + true true @@ -65,6 +67,18 @@ On + + 905CDA07C40CC715F90A2F2A0C5C0E5BAACE138B + + + EnvelopeGenerator.Service_TemporaryKey.pfx + + + true + + + true + ..\packages\BouncyCastle.Cryptography.2.6.2\lib\net461\BouncyCastle.Cryptography.dll @@ -212,8 +226,8 @@ ..\packages\RtfPipe.2.0.7677.4303\lib\net45\RtfPipe.dll - - ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll + + ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll ..\packages\System.CodeDom.8.0.0\lib\net462\System.CodeDom.dll @@ -221,6 +235,9 @@ ..\packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll + + ..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + @@ -234,18 +251,18 @@ ..\packages\System.IO.Packaging.8.0.1\lib\net462\System.IO.Packaging.dll - - ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll + + ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll ..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll - - ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll + + ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll @@ -258,15 +275,15 @@ ..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll - - ..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll + + ..\packages\System.Text.Json.8.0.6\lib\net462\System.Text.Json.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll - - ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + ..\packages\System.ValueTuple.4.6.1\lib\net462\System.ValueTuple.dll @@ -274,6 +291,63 @@ + + ..\packages\Microsoft.Data.SqlClient.6.1.4\lib\net462\Microsoft.Data.SqlClient.dll + + + ..\packages\AutoMapper.10.1.1\lib\net461\AutoMapper.dll + + + ..\packages\DigitalData.Core.Abstraction.Application.1.6.0\lib\net462\DigitalData.Core.Abstraction.Application.dll + + + ..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\packages\Microsoft.EntityFrameworkCore.3.1.32\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.32\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\packages\Microsoft.EntityFrameworkCore.Relational.3.1.32\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Relational.dll + + + ..\packages\Microsoft.EntityFrameworkCore.SqlServer.3.1.32\lib\netstandard2.0\Microsoft.EntityFrameworkCore.SqlServer.dll + + + ..\packages\Microsoft.Extensions.Caching.Abstractions.8.0.0\lib\net462\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Caching.Memory.8.0.1\lib\net462\Microsoft.Extensions.Caching.Memory.dll + + + ..\packages\Microsoft.Extensions.Configuration.7.0.0\lib\net462\Microsoft.Extensions.Configuration.dll + + + ..\packages\Microsoft.Extensions.Configuration.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Configuration.Binder.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Binder.dll + + + ..\packages\Microsoft.Extensions.Logging.7.0.0\lib\net462\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Options.8.0.2\lib\net462\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.7.0.0\lib\net462\Microsoft.Extensions.Options.ConfigurationExtensions.dll + + + ..\packages\Microsoft.Extensions.Primitives.8.0.0\lib\net462\Microsoft.Extensions.Primitives.dll + + + ..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll + + + ..\packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll + @@ -337,6 +411,7 @@ + MyApplicationCodeGenerator Application.Designer.vb @@ -380,6 +455,8 @@ + + \ No newline at end of file diff --git a/EnvelopeGenerator.Service/packages.config b/EnvelopeGenerator.Service/packages.config index 6ccec828..86c8073d 100644 --- a/EnvelopeGenerator.Service/packages.config +++ b/EnvelopeGenerator.Service/packages.config @@ -1,6 +1,8 @@  + + @@ -11,11 +13,26 @@ + + + + + + + + + + + + + - + + + @@ -24,18 +41,20 @@ - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/EnvelopeGenerator.Tests/Application/Fake.cs b/EnvelopeGenerator.Tests/Application/Fake.cs index 1281e7bb..66b3e168 100644 --- a/EnvelopeGenerator.Tests/Application/Fake.cs +++ b/EnvelopeGenerator.Tests/Application/Fake.cs @@ -215,7 +215,7 @@ public static class Extensions Title = faker.Lorem.Paragraph(faker.Random.Number(1, 2)), Message = faker.Lorem.Paragraph(faker.Random.Number(2, 5)), TfaEnabled = tfaEnabled, - AddedWhen = DateTime.UtcNow, + AddedWhen = DateTime.Now, CertificationType = (int)CertificationType.AdvancedElectronicSignature, UseAccessCode = false, ContractType = (int)ContractType.Contract, @@ -273,9 +273,9 @@ public static class Extensions EnvelopeId = envelopeId, ReceiverId = receiverId, Status = ReceiverStatus.Unsigned, - AddedWhen = DateTime.UtcNow, + AddedWhen = DateTime.Now, AccessCode = faker.Random.Number(1000, 9999).ToString(), - ChangedWhen = DateTime.UtcNow, + ChangedWhen = DateTime.Now, CompanyName = faker.Company.CompanyName(), JobTitle = faker.Name.JobTitle(), Name = faker.Name.FullName(), diff --git a/EnvelopeGenerator.Web/Controllers/AnnotationController.cs b/EnvelopeGenerator.Web/Controllers/AnnotationController.cs index e2d64966..0cecccf0 100644 --- a/EnvelopeGenerator.Web/Controllers/AnnotationController.cs +++ b/EnvelopeGenerator.Web/Controllers/AnnotationController.cs @@ -6,6 +6,7 @@ using EnvelopeGenerator.Application.Common.Notifications.DocSigned; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries; using EnvelopeGenerator.Application.Histories.Queries; using EnvelopeGenerator.Domain.Constants; +using EnvelopeGenerator.Domain.Interfaces; using EnvelopeGenerator.Web.Extensions; using MediatR; using Microsoft.AspNetCore.Authentication; @@ -65,7 +66,7 @@ public class AnnotationController : ControllerBase // Again check if receiver has already signed if (await _mediator.IsSignedAsync(uuid, signature, cancel)) return Problem(statusCode: 409); - else if (await _mediator.AnyHistoryAsync(uuid, new[] { EnvelopeStatus.EnvelopeRejected, EnvelopeStatus.DocumentRejected }, cancel)) + else if (er.Envelope.IsReadAndSign() && await _mediator.AnyHistoryAsync(uuid, new[] { EnvelopeStatus.EnvelopeRejected, EnvelopeStatus.DocumentRejected }, cancel)) return Problem(statusCode: 423); var docSignedNotification = await _mediator @@ -80,6 +81,7 @@ public class AnnotationController : ControllerBase return Ok(); } + //TODO: add logic to check if it is already rejected or signed [Authorize(Roles = Role.ReceiverFull)] [HttpPost("reject")] [Obsolete("Use DigitalData.Core.Exceptions and .Middleware")] @@ -100,7 +102,7 @@ public class AnnotationController : ControllerBase if (envRcvRes.IsFailed) { _logger.LogNotice(envRcvRes.Notices); - return Unauthorized("you are not authirized"); + return Unauthorized(); } var histRes = await _histService.RecordAsync(envRcvRes.Data.EnvelopeId, userReference: mail, EnvelopeStatus.DocumentRejected, comment: reason); diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index 4bc9692e..e8068bd2 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -7,6 +7,7 @@ using EnvelopeGenerator.Application.Common.Interfaces.Services; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries; using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Constants; +using EnvelopeGenerator.Domain.Interfaces; using EnvelopeGenerator.PdfEditor; using EnvelopeGenerator.Web.Extensions; using EnvelopeGenerator.Web.Models; @@ -78,13 +79,18 @@ public class EnvelopeController : ViewControllerBase return this.ViewEnvelopeNotFound(); #region Rejected or Signed - //check rejection var rejRcvrs = await _historyService.ReadRejectingReceivers(er.Envelope!.Id); if (rejRcvrs.Any()) { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - ViewBag.IsExt = !rejRcvrs.Contains(er.Receiver); //external if the current user is not rejected - return View("EnvelopeRejected", er); + var isExt = !rejRcvrs.Where(rcv => rcv.Id == er.Receiver!.Id).Any(); //external if the current user is not rejected + + if (er.Envelope.IsReadAndSign() || !isExt) + { + //TODO: Normally assigned to the isExt variable. However, since the relevant keys are not defined in the resx files, it was assigned false. Fix this. + ViewBag.IsExt = true; + return View("EnvelopeRejected", er); + } } //check if it has already signed @@ -162,13 +168,19 @@ public class EnvelopeController : ViewControllerBase } var er_secret = er_secret_res.Data; - //check rejection var rejRcvrs = await _historyService.ReadRejectingReceivers(er_secret.Envelope!.Id); if (rejRcvrs.Any()) { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - ViewBag.IsExt = !rejRcvrs.Contains(er_secret.Receiver); //external if the current user is not rejected - return View("EnvelopeRejected", er_secret); + var isExt = !rejRcvrs.Where(rcv => rcv.Id == er_secret.Receiver!.Id).Any(); //external if the current user is not rejected + + //check rejection if the envelope is read-and-sign or non-external (internal) + if (er_secret.Envelope.IsReadAndSign() || !isExt) + { + //TODO: Normally assigned to the isExt variable. However, since the relevant keys are not defined in the resx files, it was assigned false. Fix this. + ViewBag.IsExt = true; + return View("EnvelopeRejected", er_secret); + } } // show envelope if already logged in diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index f2d2c9fe..6c0e5d59 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -1,7 +1,7 @@  - net8.0;net9.0 + net7.0;net8.0;net9.0 enable enable EnvelopeGenerator.Web @@ -12,9 +12,9 @@ digital data envelope generator web EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly. Assets\icon.ico - 3.12.0 - 3.12.0.0 - 3.12.0.0 + 3.12.3 + 3.12.3.0 + 3.12.3.0 Copyright © 2025 Digital Data GmbH. All rights reserved. @@ -626,7 +626,6 @@ - @@ -2093,6 +2092,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + +