From 43d89699a93509c2f85d69b2349f1171d3698eaf Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 18 Feb 2026 12:47:23 +0100 Subject: [PATCH 01/24] Add StatusChangedWhen to DocumentStatus entity Added a nullable DateTime property, StatusChangedWhen, to the DocumentStatus entity. This property is required and mapped to the "STATUS_CHANGED_WHEN" column, enabling tracking of when the document status was last updated. --- EnvelopeGenerator.Domain/Entities/DocumentStatus.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs index c61bb4cd..3bec79c7 100644 --- a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs +++ b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs @@ -35,6 +35,10 @@ namespace EnvelopeGenerator.Domain.Entities [Column("STATUS")] public Constants.DocumentStatus Status { get; set; } + [Required] + [Column("STATUS_CHANGED_WHEN", TypeName = "datetime")] + public DateTime? StatusChangedWhen { get; set; } + [Required] [Column("ADDED_WHEN", TypeName = "datetime")] public DateTime AddedWhen { get; set; } From 711f7d12e8e436e2889e21f0e3217fe327a2615d Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 18 Feb 2026 12:48:11 +0100 Subject: [PATCH 02/24] Update MappingProfile for improved DocumentStatus mapping Enhanced mapping logic in MappingProfile: - Set Status to Created or Signed in CreateDocStatusCommand mapping based on Value property. - Automatically set StatusChangedWhen to current UTC time in UpdateDocStatusCommand mapping. --- EnvelopeGenerator.Application/DocStatus/MappingProfile.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EnvelopeGenerator.Application/DocStatus/MappingProfile.cs b/EnvelopeGenerator.Application/DocStatus/MappingProfile.cs index e1474d7e..bfa86dd5 100644 --- a/EnvelopeGenerator.Application/DocStatus/MappingProfile.cs +++ b/EnvelopeGenerator.Application/DocStatus/MappingProfile.cs @@ -18,11 +18,16 @@ public class MappingProfile : Profile CreateMap() .ForMember(dest => dest.Envelope, opt => opt.Ignore()) .ForMember(dest => dest.Receiver, opt => opt.Ignore()) + .ForMember(dest => dest.Status, opt => opt.MapFrom( + src => src.Value == null + ? Domain.Constants.DocumentStatus.Created + : Domain.Constants.DocumentStatus.Signed)) .MapAddedWhen(); CreateMap() .ForMember(dest => dest.Envelope, opt => opt.Ignore()) .ForMember(dest => dest.Receiver, opt => opt.Ignore()) + .ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.UtcNow)) .MapChangedWhen(); } } \ No newline at end of file From 1d0c758e00ff67e106060a7e2a61b538ce5d5935 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 18 Feb 2026 12:48:44 +0100 Subject: [PATCH 03/24] Refactor CreateDocStatusCommand structure and properties Refactored CreateDocStatusCommand to remove inheritance from ModifyDocStatusCommandBase and define its own properties. Added EnvelopeId, ReceiverId, and Value properties. Removed the AddedWhen property. The class now directly implements IRequest. --- .../DocStatus/Commands/CreateDocStatusCommand.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/EnvelopeGenerator.Application/DocStatus/Commands/CreateDocStatusCommand.cs b/EnvelopeGenerator.Application/DocStatus/Commands/CreateDocStatusCommand.cs index 01b5d0a9..e8f78240 100644 --- a/EnvelopeGenerator.Application/DocStatus/Commands/CreateDocStatusCommand.cs +++ b/EnvelopeGenerator.Application/DocStatus/Commands/CreateDocStatusCommand.cs @@ -8,12 +8,22 @@ namespace EnvelopeGenerator.Application.DocStatus.Commands; /// /// /// -public record CreateDocStatusCommand : ModifyDocStatusCommandBase, IRequest +public record CreateDocStatusCommand : IRequest { /// - /// Gets timestamp when this record was added. Returns the StatusChangedWhen value. + /// + /// + public int EnvelopeId { get; set; } + + /// + /// + /// + public int ReceiverId { get; set; } + + /// + /// Gets or sets the display value associated with the status. /// - public DateTime AddedWhen => StatusChangedWhen; + public string? Value { get; set; } } /// From 01f3335238b45563b14f6340ee4c25fa95ef2c05 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 19 Feb 2026 14:32:35 +0100 Subject: [PATCH 04/24] Refactor ModifyDocStatusCommandBase properties Replaced computed EnvelopeId and ReceiverId with virtual settable properties for greater flexibility. Removed Status, Receiver, and StatusChangedWhen properties. Made Value property virtual and cleaned up related code and comments. --- .../Commands/ModifyDocStatusCommandBase.cs | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs b/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs index 259cb500..683e57e8 100644 --- a/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs +++ b/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs @@ -1,5 +1,4 @@ using EnvelopeGenerator.Application.Common.Query; -using EnvelopeGenerator.Domain.Constants; namespace EnvelopeGenerator.Application.DocStatus.Commands; @@ -11,32 +10,17 @@ public record ModifyDocStatusCommandBase : EnvelopeReceiverQueryBase /// /// /// - public int? EnvelopeId => Envelope.Id; + public virtual int EnvelopeId { get; set; } /// /// /// - public int? ReceiverId => Receiver.Id; - - /// - /// - /// - public override ReceiverQueryBase Receiver { get => base.Receiver; set => base.Receiver = value; } - - /// - /// Gets the current status code. - /// - public DocumentStatus Status => Value is null ? DocumentStatus.Created : DocumentStatus.Signed; + public virtual int ReceiverId { get; set; } /// /// Gets or sets the display value associated with the status. /// - public string? Value { get; set; } - - /// - /// Gets timestamp when this record was added. - /// - public DateTime StatusChangedWhen { get; } = DateTime.Now; + public virtual string? Value { get; set; } /// /// Maps the current command to a new instance of the specified type. From 8258d9f43fe0ca3485794bba9dbef4bad4a2a7e8 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 19 Feb 2026 14:32:45 +0100 Subject: [PATCH 05/24] Refactor UpdateDocStatusCommand to use generic base class Refactored UpdateDocStatusCommand to inherit from a generic UpdateCommand base class with a new DocStatusUpdateDto record. Added explicit EnvelopeId, ReceiverId, and Value properties. Removed ChangedWhen property and implemented BuildQueryExpression for querying. Updated using directives and improved XML documentation. --- .../Commands/UpdateDocStatusCommand.cs | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/EnvelopeGenerator.Application/DocStatus/Commands/UpdateDocStatusCommand.cs b/EnvelopeGenerator.Application/DocStatus/Commands/UpdateDocStatusCommand.cs index f6c3b57f..dcdd8b18 100644 --- a/EnvelopeGenerator.Application/DocStatus/Commands/UpdateDocStatusCommand.cs +++ b/EnvelopeGenerator.Application/DocStatus/Commands/UpdateDocStatusCommand.cs @@ -1,14 +1,41 @@ -using EnvelopeGenerator.Domain; +using EnvelopeGenerator.Application.Common.Commands; +using EnvelopeGenerator.Domain.Entities; +using System.Linq.Expressions; namespace EnvelopeGenerator.Application.DocStatus.Commands; /// /// /// -public record UpdateDocStatusCommand : ModifyDocStatusCommandBase +/// +public record DocStatusUpdateDto(string? Value); + +/// +/// +/// +public record UpdateDocStatusCommand : UpdateCommand { /// - /// Gets timestamp when this record was added. Returns the StatusChangedWhen value. + /// + /// + public int EnvelopeId { get; set; } + + /// + /// + /// + public int ReceiverId { get; set; } + + /// + /// Gets or sets the display value associated with the status. + /// + public string? Value { get; set; } + + /// + /// /// - public DateTime? ChangedWhen => StatusChangedWhen; + /// + public override Expression> BuildQueryExpression() + { + return ds => ds.EnvelopeId == EnvelopeId && ds.ReceiverId == ReceiverId; + } } \ No newline at end of file From f9b1e583df388f6b0a80b2750a50307a64a35b99 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 27 Feb 2026 11:31:41 +0100 Subject: [PATCH 06/24] Remove SaveDocStatusCommand and always create doc status Removed SaveDocStatusCommand and its handler, eliminating logic for updating existing document statuses. DocStatusHandler now always sends CreateDocStatusCommand with simplified parameters when handling DocSignedNotification. This change ensures a new document status is always created instead of updating existing ones. --- .../DocSigned/Handlers/DocStatusHandler.cs | 15 ++-- .../Commands/SaveDocStatusCommand.cs | 77 ------------------- 2 files changed, 6 insertions(+), 86 deletions(-) delete mode 100644 EnvelopeGenerator.Application/DocStatus/Commands/SaveDocStatusCommand.cs diff --git a/EnvelopeGenerator.Application/Common/Notifications/DocSigned/Handlers/DocStatusHandler.cs b/EnvelopeGenerator.Application/Common/Notifications/DocSigned/Handlers/DocStatusHandler.cs index adae66cf..dd90d3c5 100644 --- a/EnvelopeGenerator.Application/Common/Notifications/DocSigned/Handlers/DocStatusHandler.cs +++ b/EnvelopeGenerator.Application/Common/Notifications/DocSigned/Handlers/DocStatusHandler.cs @@ -29,15 +29,12 @@ public class DocStatusHandler : INotificationHandler /// /// /// - public async Task Handle(DocSignedNotification notification, CancellationToken cancel) + public Task Handle(DocSignedNotification notification, CancellationToken cancel) => _sender.Send(new CreateDocStatusCommand() { - await _sender.Send(new SaveDocStatusCommand() - { - Envelope = new() { Id = notification.EnvelopeId }, - Receiver = new() { Id = notification.ReceiverId}, - Value = notification.PsPdfKitAnnotation is PsPdfKitAnnotation annot - ? JsonSerializer.Serialize(annot.Instant, Format.Json.ForAnnotations) + EnvelopeId = notification.EnvelopeId, + ReceiverId = notification.ReceiverId, + Value = notification.PsPdfKitAnnotation is PsPdfKitAnnotation annot + ? JsonSerializer.Serialize(annot.Instant, Format.Json.ForAnnotations) : BlankAnnotationJson - }, cancel); - } + }, cancel); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DocStatus/Commands/SaveDocStatusCommand.cs b/EnvelopeGenerator.Application/DocStatus/Commands/SaveDocStatusCommand.cs deleted file mode 100644 index 0f041e8a..00000000 --- a/EnvelopeGenerator.Application/DocStatus/Commands/SaveDocStatusCommand.cs +++ /dev/null @@ -1,77 +0,0 @@ -using DigitalData.Core.Abstraction.Application.Repository; -using EnvelopeGenerator.Domain.Entities; -using MediatR; -using Microsoft.EntityFrameworkCore; -using AutoMapper; -using EnvelopeGenerator.Application.Common.Dto; -using EnvelopeGenerator.Application.Common.Extensions; - -namespace EnvelopeGenerator.Application.DocStatus.Commands; - -/// -/// Represents a command to save the status of a document, either by creating a new status or updating an existing one based on the provided envelope and receiver identifiers. -/// It returns the identifier of the saved document status. -/// -public record SaveDocStatusCommand : ModifyDocStatusCommandBase, IRequest; - -/// -/// -/// -public class SaveDocStatusCommandHandler : IRequestHandler -{ - private readonly IMapper _mapper; - - private readonly IRepository _repo; - - private readonly IRepository _envRepo; - - private readonly IRepository _rcvRepo; - - /// - /// - /// - /// - /// - /// - /// - public SaveDocStatusCommandHandler(IMapper mapper, IRepository repo, IRepository rcvRepo, IRepository envRepo) - { - _mapper = mapper; - _repo = repo; - _rcvRepo = rcvRepo; - _envRepo = envRepo; - } - - /// - /// - /// - /// - /// - /// - public async Task Handle(SaveDocStatusCommand request, CancellationToken cancel) - { - // ceck if exists - bool isExists = await _repo.ReadOnly().Where(request).AnyAsync(cancel); - - var env = await _envRepo.ReadOnly().Where(request.Envelope).FirstAsync(cancel); - var rcv = await _rcvRepo.ReadOnly().Where(request.Receiver).FirstAsync(cancel); - - request.Envelope.Id = env.Id; - request.Receiver.Id = rcv.Id; - - if (isExists) - { - var uReq = request.To(); - await _repo.UpdateAsync(uReq, q => q.Where(request), cancel); - } - else - { - var cReq = request.To(); - await _repo.CreateAsync(cReq, cancel); - } - - var docStatus = await _repo.ReadOnly().Where(request).SingleOrDefaultAsync(cancel); - - return _mapper.Map(docStatus); - } -} \ No newline at end of file From 74c4ddda83e2ca606f7c87d519ea6325207fd2f4 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 27 Feb 2026 11:32:45 +0100 Subject: [PATCH 07/24] Remove ModifyDocStatusCommandBase and its properties Deleted the entire ModifyDocStatusCommandBase.cs file, including the record definition, its properties (EnvelopeId, ReceiverId, Value), and the To() mapping method. No code or class definitions remain in this file. --- .../Commands/ModifyDocStatusCommandBase.cs | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs diff --git a/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs b/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs deleted file mode 100644 index 683e57e8..00000000 --- a/EnvelopeGenerator.Application/DocStatus/Commands/ModifyDocStatusCommandBase.cs +++ /dev/null @@ -1,38 +0,0 @@ -using EnvelopeGenerator.Application.Common.Query; - -namespace EnvelopeGenerator.Application.DocStatus.Commands; - -/// -/// -/// -public record ModifyDocStatusCommandBase : EnvelopeReceiverQueryBase -{ - /// - /// - /// - public virtual int EnvelopeId { get; set; } - - /// - /// - /// - public virtual int ReceiverId { get; set; } - - /// - /// Gets or sets the display value associated with the status. - /// - public virtual string? Value { get; set; } - - /// - /// Maps the current command to a new instance of the specified type. - /// - /// - /// - public TDest To() where TDest : ModifyDocStatusCommandBase, new() - => new() - { - Key = Key, - Envelope = Envelope, - Receiver = Receiver, - Value = Value - }; -} \ No newline at end of file From 48f4ea0c50c4d4e0d1f2417b8791dee60b49e6ea Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 27 Feb 2026 11:33:53 +0100 Subject: [PATCH 08/24] Use UTC for AddedWhen timestamp in CreateHistoryCommand Changed AddedWhen to use DateTime.UtcNow instead of DateTime.Now to ensure timestamps are stored in UTC, improving consistency across different time zones and deployment environments. --- .../Histories/Commands/CreateHistoryCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs b/EnvelopeGenerator.Application/Histories/Commands/CreateHistoryCommand.cs index 4cd83f01..c8a53f59 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.Now; + public DateTime AddedWhen { get; } = DateTime.UtcNow; /// /// From afa3694cd72122208a875453cc1c2009c553f461 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 27 Feb 2026 11:34:17 +0100 Subject: [PATCH 09/24] Add MapAddedWhen to History mapping in MappingProfile Imported necessary namespaces and updated the CreateHistoryCommand-to-History mapping to include the MapAddedWhen extension method, likely to handle automatic setting of creation timestamps or similar metadata. --- EnvelopeGenerator.Application/Histories/MappingProfile.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Application/Histories/MappingProfile.cs b/EnvelopeGenerator.Application/Histories/MappingProfile.cs index 6261d5db..71e8916f 100644 --- a/EnvelopeGenerator.Application/Histories/MappingProfile.cs +++ b/EnvelopeGenerator.Application/Histories/MappingProfile.cs @@ -1,4 +1,5 @@ using AutoMapper; +using EnvelopeGenerator.Application.Common.Extensions; using EnvelopeGenerator.Application.Histories.Commands; using EnvelopeGenerator.Domain.Entities; @@ -17,6 +18,7 @@ public class MappingProfile: Profile CreateMap() .ForMember(dest => dest.Envelope, opt => opt.Ignore()) .ForMember(dest => dest.Sender, opt => opt.Ignore()) - .ForMember(dest => dest.Receiver, opt => opt.Ignore()); + .ForMember(dest => dest.Receiver, opt => opt.Ignore()) + .MapAddedWhen(); } } \ No newline at end of file From 3d43d1896dafbbca5f9fdde21ef043c1974cba45 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 01:20:12 +0100 Subject: [PATCH 10/24] Add DocConfirmed extension method to Resource.cs Added a new DocConfirmed extension method to the Extensions class in Resource.cs. This method enables retrieval of the "DocConfirmed" localized string via IStringLocalizer, similar to the existing DocSigned method. --- EnvelopeGenerator.Application/Resources/Resource.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/EnvelopeGenerator.Application/Resources/Resource.cs b/EnvelopeGenerator.Application/Resources/Resource.cs index 53c11359..18585f98 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.cs +++ b/EnvelopeGenerator.Application/Resources/Resource.cs @@ -204,6 +204,13 @@ public static class Extensions /// public static string DocSigned(this IStringLocalizer localizer) => localizer[nameof(DocSigned)].Value; + /// + /// + /// + /// + /// + public static string DocConfirmed(this IStringLocalizer localizer) => localizer[nameof(DocConfirmed)].Value; + /// /// /// From 9b660cb25a200fa5a5708d1bcf2da28c4e0fdf99 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 01:20:25 +0100 Subject: [PATCH 11/24] Pass model to EnvelopeSigned view on already signed check Previously, the "EnvelopeSigned" view was returned without a model when an envelope was already signed. Now, the er model object is passed to the view to provide additional context or data. --- EnvelopeGenerator.Web/Controllers/EnvelopeController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index fed685c4..4bc9692e 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -91,7 +91,7 @@ public class EnvelopeController : ViewControllerBase if (await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress)) { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - return View("EnvelopeSigned"); + return View("EnvelopeSigned", er); } #endregion From 7cd6ca3a5f127d42e340ed50918e619a437137c2 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 01:20:47 +0100 Subject: [PATCH 12/24] Update EnvelopeSigned view model and title logic Set model to EnvelopeReceiverDto and import required types. Update ViewData["Title"] to use DocSigned or DocConfirmed based on Envelope.IsReadAndConfirm() result. --- EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml index e2c5ae4d..39036493 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml @@ -1,5 +1,10 @@ @{ - ViewData["Title"] = _localizer.DocSigned(); + @using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver; + @using EnvelopeGenerator.Domain.Interfaces; + @model EnvelopeReceiverDto; + ViewData["Title"] = Model!.Envelope!.IsReadAndConfirm() + ? _localizer.DocSigned() + : _localizer.DocConfirmed(); }
From 9cfc74aa8864cdf7c02f079e09951957feaebb63 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 01:23:06 +0100 Subject: [PATCH 13/24] Refactor title logic and fix localizer syntax in view Refactored EnvelopeSigned.cshtml to use a local variable for IsReadAndConfirm when setting the page title, improving readability. Also updated Razor syntax for localizer calls in

and

elements to ensure correct evaluation and formatting. --- EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml index 39036493..491266fc 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml @@ -2,7 +2,8 @@ @using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver; @using EnvelopeGenerator.Domain.Interfaces; @model EnvelopeReceiverDto; - ViewData["Title"] = Model!.Envelope!.IsReadAndConfirm() + bool IsReadAndConfirm = Model!.Envelope!.IsReadAndConfirm(); + ViewData["Title"] = IsReadAndConfirm ? _localizer.DocSigned() : _localizer.DocConfirmed(); } @@ -14,9 +15,9 @@

-

@_localizer["DocumentSuccessfullySigned"]

+

@(_localizer["DocumentSuccessfullySigned"])

-

@_localizer["DocumentSignedConfirmationMessage"]

+

@(_localizer["DocumentSignedConfirmationMessage"])

\ No newline at end of file From e095860b17f587706fc2eeda72c63702fd6aced1 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 01:25:07 +0100 Subject: [PATCH 14/24] Update EnvelopeSigned page to handle confirm vs sign Add conditional logic to EnvelopeSigned.cshtml to display different headings and confirmation messages based on whether the document was signed or confirmed, using the IsReadAndConfirm flag. This improves user feedback by distinguishing between signing and confirming actions. --- .../Views/Envelope/EnvelopeSigned.cshtml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml index 491266fc..246d3a52 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml @@ -15,9 +15,13 @@ -

@(_localizer["DocumentSuccessfullySigned"])

+

@(IsReadAndConfirm + ? _localizer["DocumentSuccessfullySigned"] + : _localizer["DocumentSuccessfullyConfirmed"])

-

@(_localizer["DocumentSignedConfirmationMessage"])

+

@(IsReadAndConfirm + ? _localizer["DocumentSignedConfirmationMessage"] + : _localizer["DocumentConfirmedConfirmationMessage"])

\ No newline at end of file From f1e38e3bd35ad04e6d093fd5e3eb1f469ec371da Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:17:17 +0100 Subject: [PATCH 15/24] Reverse IsReadAndConfirm logic for envelope status texts Swapped the display logic for localized titles and messages based on the IsReadAndConfirm flag. Now, "confirmed" texts are shown when IsReadAndConfirm is true, and "signed" texts when false. This update ensures correct status messaging throughout the envelope confirmation flow. --- .../Views/Envelope/EnvelopeSigned.cshtml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml index 246d3a52..0aed7cf2 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeSigned.cshtml @@ -4,8 +4,8 @@ @model EnvelopeReceiverDto; bool IsReadAndConfirm = Model!.Envelope!.IsReadAndConfirm(); ViewData["Title"] = IsReadAndConfirm - ? _localizer.DocSigned() - : _localizer.DocConfirmed(); + ? _localizer.DocConfirmed() + : _localizer.DocSigned(); }
@@ -16,12 +16,12 @@

@(IsReadAndConfirm - ? _localizer["DocumentSuccessfullySigned"] - : _localizer["DocumentSuccessfullyConfirmed"])

+ ? _localizer["DocumentSuccessfullyConfirmed"] + : _localizer["DocumentSuccessfullySigned"])

@(IsReadAndConfirm - ? _localizer["DocumentSignedConfirmationMessage"] - : _localizer["DocumentConfirmedConfirmationMessage"])

+ ? _localizer["DocumentConfirmedConfirmationMessage"] + : _localizer["DocumentSignedConfirmationMessage"])

\ No newline at end of file From bcc53bf9f1fcbea3ed26960a4f2c7f44f432341e Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:27:41 +0100 Subject: [PATCH 16/24] Update rejection header for read and confirm envelopes Add logic to display a specific rejection message when an envelope is rejected as part of a "read and confirm" process. The header now distinguishes between external, confirmation-related, and default rejection scenarios for improved user feedback. --- .../Views/Envelope/EnvelopeRejected.cshtml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeRejected.cshtml b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeRejected.cshtml index 218dd2c0..2ee0a73b 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/EnvelopeRejected.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/EnvelopeRejected.cshtml @@ -9,12 +9,14 @@ @using EnvelopeGenerator.Web.Extensions @using Newtonsoft.Json @using Newtonsoft.Json.Serialization +@using EnvelopeGenerator.Domain.Interfaces; @model EnvelopeReceiverDto; @{ var envelope = Model.Envelope; var document = Model.Envelope?.Documents?.FirstOrDefault(); var sender = Model.Envelope?.User; var isExt = ViewBag.IsExt ?? false; + bool IsReadAndConfirm = Model!.Envelope!.IsReadAndConfirm(); }
@@ -54,7 +56,11 @@ c-5.791,5.79-15.176,5.79-20.969,0l-30.32-30.322l-11.676,11.676l30.32,30.32c5.79,5.79,5.79,15.178,0,20.969L299.11,404.045z"/>
-

@(isExt ? _localizer.RejectionInfo1Ext() : _localizer.RejectionInfo1())

+

@(isExt + ? _localizer.RejectionInfo1Ext() + : IsReadAndConfirm + ? _localizer.RejectionInfo1ForConfirmation() + : _localizer.RejectionInfo1())

From 4ce1d2a3706ee2cd2cc4b426d279cab74ea563e9 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:28:12 +0100 Subject: [PATCH 17/24] Add RejectionInfo1ForConfirmation extension method Introduced a new extension method, RejectionInfo1ForConfirmation, to the Extensions class in Resource.cs. This method retrieves the localized string for "RejectionInfo1ForConfirmation" from an IStringLocalizer instance, providing functionality similar to the existing RejectionInfo1 method. --- EnvelopeGenerator.Application/Resources/Resource.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/EnvelopeGenerator.Application/Resources/Resource.cs b/EnvelopeGenerator.Application/Resources/Resource.cs index 18585f98..06a29276 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.cs +++ b/EnvelopeGenerator.Application/Resources/Resource.cs @@ -274,6 +274,13 @@ public static class Extensions /// public static string RejectionInfo1(this IStringLocalizer localizer) => localizer[nameof(RejectionInfo1)].Value; + /// + /// + /// + /// + /// + public static string RejectionInfo1ForConfirmation(this IStringLocalizer localizer) => localizer[nameof(RejectionInfo1ForConfirmation)].Value; + /// /// /// From 647c5d235315d34f4fbd2b56ef3e23206b36d251 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:31:19 +0100 Subject: [PATCH 18/24] Add localization extensions for confirmation resources Added three new extension methods to the Extensions class in Resource.cs: ConfirmDoc, ConfirmAgree, and ConfirmationProcessTitle. Each method retrieves the localized value for its respective resource key and includes XML documentation, consistent with existing localization methods. --- .../Resources/Resource.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/EnvelopeGenerator.Application/Resources/Resource.cs b/EnvelopeGenerator.Application/Resources/Resource.cs index 06a29276..13223106 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.cs +++ b/EnvelopeGenerator.Application/Resources/Resource.cs @@ -190,6 +190,13 @@ public static class Extensions /// public static string SignDoc(this IStringLocalizer localizer) => localizer[nameof(SignDoc)].Value; + /// + /// + /// + /// + /// + public static string ConfirmDoc(this IStringLocalizer localizer) => localizer[nameof(ConfirmDoc)].Value; + /// /// /// @@ -246,6 +253,13 @@ public static class Extensions /// public static string SigAgree(this IStringLocalizer localizer) => localizer[nameof(SigAgree)].Value; + /// + /// + /// + /// + /// + public static string ConfirmAgree(this IStringLocalizer localizer) => localizer[nameof(ConfirmAgree)].Value; + /// /// /// @@ -309,6 +323,13 @@ public static class Extensions /// public static string SigningProcessTitle(this IStringLocalizer localizer) => localizer[nameof(SigningProcessTitle)].Value; + /// + /// + /// + /// + /// + public static string ConfirmationProcessTitle(this IStringLocalizer localizer) => localizer[nameof(ConfirmationProcessTitle)].Value; + /// /// /// From 44edef8ba1bbba614520c5f2b314011b0fe75622 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:43:16 +0100 Subject: [PATCH 19/24] Update envelope view title logic for confirm state Refined the logic for setting ViewData["Title"] in ShowEnvelope.cshtml. Now, if the envelope requires read and confirm, the title displays "Confirm Document" instead of just "Sign Document" or "View Document", providing clearer context for users. --- EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml index b710f772..6e850e11 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml @@ -9,6 +9,7 @@ @using EnvelopeGenerator.Web.Extensions @using Newtonsoft.Json @using Newtonsoft.Json.Serialization +@using EnvelopeGenerator.Domain.Interfaces @model EnvelopeReceiverDto; @{ var userCulture = ViewData["UserCulture"] as Culture; @@ -24,7 +25,11 @@ if (ViewData["IsReadOnly"] is bool isReadOnly_bool) isReadOnly = isReadOnly_bool; - ViewData["Title"] = isReadOnly ? _localizer.ViewDoc() : _localizer.SignDoc(); + ViewData["Title"] = isReadOnly + ? _localizer.ViewDoc() + : envelope.IsReadAndConfirm() + ? _localizer.ConfirmDoc() + : _localizer.SignDoc(); }
@if (!isReadOnly) From f8c7f60cf9c5e91120ac9d07718c621354e401bf Mon Sep 17 00:00:00 2001 From: OlgunR Date: Fri, 6 Mar 2026 09:50:21 +0100 Subject: [PATCH 20/24] Add resource strings for document confirmation workflows Added new localized strings for document confirmation processes in de-DE, en-US, and fr-FR resource files, including confirmation messages, UI labels, and process titles. Fixed a typo in the German resource and ensured consistency for the "SigningProcessTitle" key across languages. --- .../Resources/Resource.de-DE.resx | 38 +++++++++++++++++-- .../Resources/Resource.en-US.resx | 36 ++++++++++++++++-- .../Resources/Resource.fr-FR.resx | 36 ++++++++++++++++-- 3 files changed, 100 insertions(+), 10 deletions(-) diff --git a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx index e16727d0..70182b7b 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx @@ -250,7 +250,7 @@ Sie können bei Bedarf mit {0}, <a href="mailto:{1}?subject={2}&body=Sehr geehrte(r)%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen. - Das Vorgang wurde von einer der beteiligten Parteien abgelehnt. Sie können bei Bedarf mit {0}, <a href="mailto:{1}?subject={2}&body=Sehr geehrte(r)%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen. + Der Vorgang wurde von einer der beteiligten Parteien abgelehnt. Sie können bei Bedarf mit {0}, <a href="mailto:{1}?subject={2}&body=Sehr geehrte(r)%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen. Bitte geben Sie einen Grund an: @@ -261,9 +261,6 @@ Dokument unterschreiben - - Titel des Unterzeichnungs-Vorgangs - Ein unerwarteter Fehler ist aufgetreten. @@ -447,4 +444,37 @@ Dokument wurde zurückgesetzt. + + Dokument erfolgreich gelesen und bestätigt! + + + Sie haben das Dokument gelesen und bestätigt. Im Anschluss erhalten Sie eine schriftliche Bestätigung. + + + Bestätigen + + + Dieser Bestätigungsvorgang wurde abgelehnt! + + + Dokument bestätigen + + + Dokument bestätigt + + + Durch Klick auf Abschließen bestätige ich, das Dokument gelesen und zur Kenntnis genommen zu haben. + + + Bestätigt von + + + Titel des Lesebetätigungs-Vorgangs + + + Titel des Unterzeichnungs-Vorgangs + + + Bestätigungen + \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx index e12eb3bc..1c284156 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx @@ -261,9 +261,6 @@ Sign document - - Title of the signing process - An unexpected error has occurred. @@ -447,4 +444,37 @@ Document has been reset. + + Document successfully red and confirmed! + + + You have read and confirmed the document. You will receive a written confirmation afterwards. + + + Confirm + + + This confirmation process has been rejected! + + + Confirm Document + + + Document confirmed + + + By clicking on “Complete”, I confirm that I have read and taken note of the document. + + + Confirmed by + + + Title of the read confirmation process + + + Title of the signing process + + + Confirmations + \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx index 766e4fb9..034c7a83 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx @@ -261,9 +261,6 @@ Signer le document - - Titre du processus de signature - Une erreur inattendue s’est produite. @@ -447,4 +444,37 @@ Le document a été réinitialisé. + + Document lu et confirmé avec succès ! + + + Vous avez lu et confirmé le document. Vous recevrez une confirmation écrite par la suite. + + + Confirmer + + + Cette procédure de confirmation a été rejetée ! + + + Confirmer le document + + + Document confirmé + + + En cliquant sur « Terminer », je confirme avoir lu et pris connaissance du document. + + + Confirmé par + + + Titre de la procédure de confirmation de lecture + + + Titre du processus de signature + + + Confirmations + \ No newline at end of file From b64d2b7478a9b1db8b4ce0bf5a6cead4df592ca2 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:50:33 +0100 Subject: [PATCH 21/24] Refactor: cache IsReadAndConfirm() result in variable Store envelope.IsReadAndConfirm() in isReadAndConfirm variable to avoid redundant calls and improve code readability when setting ViewData["Title"]. No change to logic or behavior. --- EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml index 6e850e11..7bdf3fd1 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml @@ -25,9 +25,11 @@ if (ViewData["IsReadOnly"] is bool isReadOnly_bool) isReadOnly = isReadOnly_bool; + var isReadAndConfirm = envelope.IsReadAndConfirm(); + ViewData["Title"] = isReadOnly ? _localizer.ViewDoc() - : envelope.IsReadAndConfirm() + : isReadAndConfirm ? _localizer.ConfirmDoc() : _localizer.SignDoc(); } From f6d57b1e386fdc1a7eed314f50f52fb5b3b99688 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 09:52:12 +0100 Subject: [PATCH 22/24] Update progress bar to show Confirmations or Signatures Progress bar label now displays "Confirmations" if isReadAndConfirm is true, otherwise it shows "Signatures". This improves clarity for users based on the envelope's required action. --- EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml index 7bdf3fd1..8a454993 100644 --- a/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml +++ b/EnvelopeGenerator.Web/Views/Envelope/ShowEnvelope.cshtml @@ -69,7 +69,9 @@
- 0/@signatureCount @_localizer["Signatures"] + 0/@signatureCount @(isReadAndConfirm + ? _localizer["Confirmations"] + : _localizer["Signatures"])
} From ad0c8471726b58fdab632fc4f9c1f6cd59d17f58 Mon Sep 17 00:00:00 2001 From: OlgunR Date: Fri, 6 Mar 2026 09:53:18 +0100 Subject: [PATCH 23/24] Add SigningProcessTitle resource; rename rejection key Added localized SigningProcessTitle entry to de-DE, en-US, and fr-FR resource files. Renamed RejectionInfoConfirmation to RejectionInfo1Confirmation. Removed duplicate SigningProcessTitle entries. No changes to localized values. --- .../Resources/Resource.de-DE.resx | 8 ++++---- .../Resources/Resource.en-US.resx | 8 ++++---- .../Resources/Resource.fr-FR.resx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx index 70182b7b..16fb00f5 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx @@ -261,6 +261,9 @@ Dokument unterschreiben + + Titel des Unterzeichnungs-Vorgangs + Ein unerwarteter Fehler ist aufgetreten. @@ -453,7 +456,7 @@ Bestätigen - + Dieser Bestätigungsvorgang wurde abgelehnt! @@ -471,9 +474,6 @@ Titel des Lesebetätigungs-Vorgangs - - Titel des Unterzeichnungs-Vorgangs - Bestätigungen diff --git a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx index 1c284156..0e3a1af7 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx @@ -261,6 +261,9 @@ Sign document + + Title of the signing process + An unexpected error has occurred. @@ -453,7 +456,7 @@ Confirm - + This confirmation process has been rejected! @@ -471,9 +474,6 @@ Title of the read confirmation process - - Title of the signing process - Confirmations diff --git a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx index 034c7a83..be60d7bb 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx @@ -261,6 +261,9 @@ Signer le document + + Titre du processus de signature + Une erreur inattendue s’est produite. @@ -453,7 +456,7 @@ Confirmer - + Cette procédure de confirmation a été rejetée ! @@ -471,9 +474,6 @@ Titre de la procédure de confirmation de lecture - - Titre du processus de signature - Confirmations From d4eee1718efa71591e5f011cb45de77a9070af0e Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 6 Mar 2026 10:13:45 +0100 Subject: [PATCH 24/24] Bump version to 3.12.0 in project file Updated , , and fields in EnvelopeGenerator.Web.csproj from 3.11.0 to 3.12.0. No other changes were made. --- EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 4612b69b..f2d2c9fe 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -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.11.0 - 3.11.0.0 - 3.11.0.0 + 3.12.0 + 3.12.0.0 + 3.12.0.0 Copyright © 2025 Digital Data GmbH. All rights reserved.