Compare commits
2 Commits
web-multi-
...
c8834dc3be
| Author | SHA1 | Date | |
|---|---|---|---|
| c8834dc3be | |||
| e385fdda95 |
@@ -2,7 +2,6 @@
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Dto;
|
||||
@@ -11,7 +10,7 @@ namespace EnvelopeGenerator.Application.Common.Dto;
|
||||
///
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeDto : IEnvelope
|
||||
public record EnvelopeDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -29,12 +29,15 @@ public class DocStatusHandler : INotificationHandler<DocSignedNotification>
|
||||
/// <param name="notification"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public Task Handle(DocSignedNotification notification, CancellationToken cancel) => _sender.Send(new CreateDocStatusCommand()
|
||||
public async Task Handle(DocSignedNotification notification, CancellationToken cancel)
|
||||
{
|
||||
EnvelopeId = notification.EnvelopeId,
|
||||
ReceiverId = notification.ReceiverId,
|
||||
Value = notification.PsPdfKitAnnotation is PsPdfKitAnnotation annot
|
||||
? JsonSerializer.Serialize(annot.Instant, Format.Json.ForAnnotations)
|
||||
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)
|
||||
: BlankAnnotationJson
|
||||
}, cancel);
|
||||
}, cancel);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
|
||||
using EnvelopeGenerator.Application.Common.Configurations;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.Extensions.Options;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned.Handlers;
|
||||
|
||||
@@ -46,25 +45,6 @@ public class SendSignedMailHandler : SendMailHandler<DocSignedNotification>
|
||||
{ "[DOCUMENT_TITLE]", notification.Envelope?.Title ?? string.Empty },
|
||||
};
|
||||
|
||||
if (notification.Envelope.IsReadAndConfirm())
|
||||
{
|
||||
placeHolders["[SIGNATURE_TYPE]"] = "Lesen und bestätigen";
|
||||
placeHolders["[DOCUMENT_PROCESS]"] = string.Empty;
|
||||
placeHolders["[FINAL_STATUS]"] = "Lesebestätigung";
|
||||
placeHolders["[FINAL_ACTION]"] = "Empfänger bestätigt";
|
||||
placeHolders["[REJECTED_BY_OTHERS]"] = "anderen Empfänger abgelehnt!";
|
||||
placeHolders["[RECEIVER_ACTION]"] = "bestätigt";
|
||||
}
|
||||
else
|
||||
{
|
||||
placeHolders["[SIGNATURE_TYPE]"] = "Signieren";
|
||||
placeHolders["[DOCUMENT_PROCESS]"] = " und elektronisch unterschreiben";
|
||||
placeHolders["[FINAL_STATUS]"] = "Signatur";
|
||||
placeHolders["[FINAL_ACTION]"] = "Vertragspartner unterzeichnet";
|
||||
placeHolders["[REJECTED_BY_OTHERS]"] = "anderen Vertragspartner abgelehnt! Ihre notwendige Unterzeichnung wurde verworfen.";
|
||||
placeHolders["[RECEIVER_ACTION]"] = "unterschrieben";
|
||||
}
|
||||
|
||||
return placeHolders;
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,12 @@ namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record CreateDocStatusCommand : IRequest<DocumentStatus>
|
||||
public record CreateDocStatusCommand : ModifyDocStatusCommandBase, IRequest<DocumentStatus>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
|
||||
/// </summary>
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display value associated with the status.
|
||||
/// </summary>
|
||||
public string? Value { get; set; }
|
||||
public DateTime AddedWhen => StatusChangedWhen;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using EnvelopeGenerator.Application.Common.Query;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record ModifyDocStatusCommandBase : EnvelopeReceiverQueryBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? EnvelopeId => Envelope.Id;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? ReceiverId => Receiver.Id;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override ReceiverQueryBase Receiver { get => base.Receiver; set => base.Receiver = value; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status code.
|
||||
/// </summary>
|
||||
public DocumentStatus Status => Value is null ? DocumentStatus.Created : DocumentStatus.Signed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display value associated with the status.
|
||||
/// </summary>
|
||||
public string? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets timestamp when this record was added.
|
||||
/// </summary>
|
||||
public DateTime StatusChangedWhen { get; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the current command to a new instance of the specified type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDest"></typeparam>
|
||||
/// <returns></returns>
|
||||
public TDest To<TDest>() where TDest : ModifyDocStatusCommandBase, new()
|
||||
=> new()
|
||||
{
|
||||
Key = Key,
|
||||
Envelope = Envelope,
|
||||
Receiver = Receiver,
|
||||
Value = Value
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public record SaveDocStatusCommand : ModifyDocStatusCommandBase, IRequest<DocumentStatusDto?>;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SaveDocStatusCommandHandler : IRequestHandler<SaveDocStatusCommand, DocumentStatusDto?>
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IRepository<DocumentStatus> _repo;
|
||||
|
||||
private readonly IRepository<Envelope> _envRepo;
|
||||
|
||||
private readonly IRepository<Receiver> _rcvRepo;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="repo"></param>
|
||||
/// <param name="rcvRepo"></param>
|
||||
/// <param name="envRepo"></param>
|
||||
public SaveDocStatusCommandHandler(IMapper mapper, IRepository<DocumentStatus> repo, IRepository<Receiver> rcvRepo, IRepository<Envelope> envRepo)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_repo = repo;
|
||||
_rcvRepo = rcvRepo;
|
||||
_envRepo = envRepo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DocumentStatusDto?> 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<UpdateDocStatusCommand>();
|
||||
await _repo.UpdateAsync(uReq, q => q.Where(request), cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cReq = request.To<CreateDocStatusCommand>();
|
||||
await _repo.CreateAsync(cReq, cancel);
|
||||
}
|
||||
|
||||
var docStatus = await _repo.ReadOnly().Where(request).SingleOrDefaultAsync(cancel);
|
||||
|
||||
return _mapper.Map<DocumentStatusDto>(docStatus);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,14 @@
|
||||
using EnvelopeGenerator.Application.Common.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using System.Linq.Expressions;
|
||||
using EnvelopeGenerator.Domain;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Value"></param>
|
||||
public record DocStatusUpdateDto(string? Value);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record UpdateDocStatusCommand : UpdateCommand<DocStatusUpdateDto, DocumentStatus>
|
||||
public record UpdateDocStatusCommand : ModifyDocStatusCommandBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
|
||||
/// </summary>
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display value associated with the status.
|
||||
/// </summary>
|
||||
public string? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Expression<Func<DocumentStatus, bool>> BuildQueryExpression()
|
||||
{
|
||||
return ds => ds.EnvelopeId == EnvelopeId && ds.ReceiverId == ReceiverId;
|
||||
}
|
||||
public DateTime? ChangedWhen => StatusChangedWhen;
|
||||
}
|
||||
@@ -18,16 +18,11 @@ public class MappingProfile : Profile
|
||||
CreateMap<CreateDocStatusCommand, DocumentStatus>()
|
||||
.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<UpdateDocStatusCommand, DocumentStatus>()
|
||||
.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();
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>7.0.5</Version>
|
||||
</PackageReference>
|
||||
@@ -88,6 +88,7 @@
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>8.1.1</Version>
|
||||
</PackageReference>
|
||||
@@ -95,6 +96,7 @@
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>8.1.1</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -34,7 +34,7 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<History
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; } = DateTime.UtcNow;
|
||||
public DateTime AddedWhen { get; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.Histories.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
@@ -18,7 +17,6 @@ public class MappingProfile: Profile
|
||||
CreateMap<CreateHistoryCommand, History>()
|
||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Sender, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
||||
.MapAddedWhen();
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore());
|
||||
}
|
||||
}
|
||||
@@ -190,13 +190,6 @@ public static class Extensions
|
||||
/// <returns></returns>
|
||||
public static string SignDoc(this IStringLocalizer localizer) => localizer[nameof(SignDoc)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="localizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string ConfirmDoc(this IStringLocalizer localizer) => localizer[nameof(ConfirmDoc)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -211,13 +204,6 @@ public static class Extensions
|
||||
/// <returns></returns>
|
||||
public static string DocSigned(this IStringLocalizer localizer) => localizer[nameof(DocSigned)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="localizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string DocConfirmed(this IStringLocalizer localizer) => localizer[nameof(DocConfirmed)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -253,13 +239,6 @@ public static class Extensions
|
||||
/// <returns></returns>
|
||||
public static string SigAgree(this IStringLocalizer localizer) => localizer[nameof(SigAgree)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="localizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string ConfirmAgree(this IStringLocalizer localizer) => localizer[nameof(ConfirmAgree)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -288,13 +267,6 @@ public static class Extensions
|
||||
/// <returns></returns>
|
||||
public static string RejectionInfo1(this IStringLocalizer localizer) => localizer[nameof(RejectionInfo1)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="localizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string RejectionInfo1ForConfirmation(this IStringLocalizer localizer) => localizer[nameof(RejectionInfo1ForConfirmation)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -323,13 +295,6 @@ public static class Extensions
|
||||
/// <returns></returns>
|
||||
public static string SigningProcessTitle(this IStringLocalizer localizer) => localizer[nameof(SigningProcessTitle)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="localizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string ConfirmationProcessTitle(this IStringLocalizer localizer) => localizer[nameof(ConfirmationProcessTitle)].Value;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
<value>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.</value>
|
||||
</data>
|
||||
<data name="RejectionInfo2_ext" xml:space="preserve">
|
||||
<value>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.</value>
|
||||
<value>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.</value>
|
||||
</data>
|
||||
<data name="RejectionReasonQ" xml:space="preserve">
|
||||
<value>Bitte geben Sie einen Grund an:</value>
|
||||
@@ -447,34 +447,4 @@
|
||||
<data name="DocumentReset" xml:space="preserve">
|
||||
<value>Dokument wurde zurückgesetzt.</value>
|
||||
</data>
|
||||
<data name="DocumentSuccessfullyConfirmed" xml:space="preserve">
|
||||
<value>Dokument erfolgreich gelesen und bestätigt!</value>
|
||||
</data>
|
||||
<data name="DocumentConfirmedConfirmationMessage" xml:space="preserve">
|
||||
<value>Sie haben das Dokument gelesen und bestätigt. Im Anschluss erhalten Sie eine schriftliche Bestätigung.</value>
|
||||
</data>
|
||||
<data name="Confirm" xml:space="preserve">
|
||||
<value>Bestätigen</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1Confirmation" xml:space="preserve">
|
||||
<value>Dieser Bestätigungsvorgang wurde abgelehnt!</value>
|
||||
</data>
|
||||
<data name="ConfirmDoc" xml:space="preserve">
|
||||
<value>Dokument bestätigen</value>
|
||||
</data>
|
||||
<data name="DocConfirmed" xml:space="preserve">
|
||||
<value>Dokument bestätigt</value>
|
||||
</data>
|
||||
<data name="ConfirmAgree" xml:space="preserve">
|
||||
<value>Durch Klick auf Abschließen bestätige ich, das Dokument gelesen und zur Kenntnis genommen zu haben.</value>
|
||||
</data>
|
||||
<data name="ConfirmedBy" xml:space="preserve">
|
||||
<value>Bestätigt von</value>
|
||||
</data>
|
||||
<data name="ConfirmationProcessTitle" xml:space="preserve">
|
||||
<value>Titel des Lesebetätigungs-Vorgangs</value>
|
||||
</data>
|
||||
<data name="Confirmations" xml:space="preserve">
|
||||
<value>Bestätigungen</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -447,34 +447,4 @@
|
||||
<data name="DocumentReset" xml:space="preserve">
|
||||
<value>Document has been reset.</value>
|
||||
</data>
|
||||
<data name="DocumentSuccessfullyConfirmed" xml:space="preserve">
|
||||
<value>Document successfully red and confirmed!</value>
|
||||
</data>
|
||||
<data name="DocumentConfirmedConfirmationMessage" xml:space="preserve">
|
||||
<value>You have read and confirmed the document. You will receive a written confirmation afterwards.</value>
|
||||
</data>
|
||||
<data name="Confirm" xml:space="preserve">
|
||||
<value>Confirm</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1Confirmation" xml:space="preserve">
|
||||
<value>This confirmation process has been rejected!</value>
|
||||
</data>
|
||||
<data name="ConfirmDoc" xml:space="preserve">
|
||||
<value>Confirm Document</value>
|
||||
</data>
|
||||
<data name="DocConfirmed" xml:space="preserve">
|
||||
<value>Document confirmed</value>
|
||||
</data>
|
||||
<data name="ConfirmAgree" xml:space="preserve">
|
||||
<value>By clicking on “Complete”, I confirm that I have read and taken note of the document.</value>
|
||||
</data>
|
||||
<data name="ConfirmedBy" xml:space="preserve">
|
||||
<value>Confirmed by</value>
|
||||
</data>
|
||||
<data name="ConfirmationProcessTitle" xml:space="preserve">
|
||||
<value>Title of the read confirmation process</value>
|
||||
</data>
|
||||
<data name="Confirmations" xml:space="preserve">
|
||||
<value>Confirmations</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -447,34 +447,4 @@
|
||||
<data name="DocumentReset" xml:space="preserve">
|
||||
<value>Le document a été réinitialisé.</value>
|
||||
</data>
|
||||
<data name="DocumentSuccessfullyConfirmed" xml:space="preserve">
|
||||
<value>Document lu et confirmé avec succès !</value>
|
||||
</data>
|
||||
<data name="DocumentConfirmedConfirmationMessage" xml:space="preserve">
|
||||
<value>Vous avez lu et confirmé le document. Vous recevrez une confirmation écrite par la suite.</value>
|
||||
</data>
|
||||
<data name="Confirm" xml:space="preserve">
|
||||
<value>Confirmer</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1Confirmation" xml:space="preserve">
|
||||
<value>Cette procédure de confirmation a été rejetée !</value>
|
||||
</data>
|
||||
<data name="ConfirmDoc" xml:space="preserve">
|
||||
<value>Confirmer le document</value>
|
||||
</data>
|
||||
<data name="DocConfirmed" xml:space="preserve">
|
||||
<value>Document confirmé</value>
|
||||
</data>
|
||||
<data name="ConfirmAgree" xml:space="preserve">
|
||||
<value>En cliquant sur « Terminer », je confirme avoir lu et pris connaissance du document.</value>
|
||||
</data>
|
||||
<data name="ConfirmedBy" xml:space="preserve">
|
||||
<value>Confirmé par</value>
|
||||
</data>
|
||||
<data name="ConfirmationProcessTitle" xml:space="preserve">
|
||||
<value>Titre de la procédure de confirmation de lecture</value>
|
||||
</data>
|
||||
<data name="Confirmations" xml:space="preserve">
|
||||
<value>Confirmations</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -12,7 +12,6 @@ using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||
using MediatR;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
@@ -50,33 +49,14 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? er = null)
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
||||
{
|
||||
if (er!.Envelope.IsReadAndConfirm())
|
||||
{
|
||||
_placeholders["[SIGNATURE_TYPE]"] = "Lesen und bestätigen";
|
||||
_placeholders["[DOCUMENT_PROCESS]"] = string.Empty;
|
||||
_placeholders["[FINAL_STATUS]"] = "Lesebestätigung";
|
||||
_placeholders["[FINAL_ACTION]"] = "Empfänger bestätigt";
|
||||
_placeholders["[REJECTED_BY_OTHERS]"] = "anderen Empfänger abgelehnt!";
|
||||
_placeholders["[RECEIVER_ACTION]"] = "bestätigt";
|
||||
}
|
||||
else
|
||||
{
|
||||
_placeholders["[SIGNATURE_TYPE]"] = "Signieren";
|
||||
_placeholders["[DOCUMENT_PROCESS]"] = " und elektronisch unterschreiben";
|
||||
_placeholders["[FINAL_STATUS]"] = "Signatur";
|
||||
_placeholders["[FINAL_ACTION]"] = "Vertragspartner unterzeichnet";
|
||||
_placeholders["[REJECTED_BY_OTHERS]"] = "anderen Vertragspartner abgelehnt! Ihre notwendige Unterzeichnung wurde verworfen.";
|
||||
_placeholders["[RECEIVER_ACTION]"] = "unterschrieben";
|
||||
}
|
||||
|
||||
if (accessCode is not null)
|
||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||
|
||||
if (er?.Envelope is not null && er.Receiver is not null)
|
||||
if (envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||
{
|
||||
var erId = (er.Envelope.Uuid, er.Receiver.Signature).ToEnvelopeKey();
|
||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).ToEnvelopeKey();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
@@ -86,8 +66,7 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
// TODO: merge the two CreatePlaceholders methods by using a common parameter object containing all the required information to create the place holders.
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
{
|
||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||
{
|
||||
@@ -145,7 +124,7 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
||||
var accessCode = acResult.Data;
|
||||
|
||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, er: dto);
|
||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||
|
||||
// Add optional place holders.
|
||||
if (optionalPlaceholders is not null)
|
||||
|
||||
@@ -35,10 +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; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using Newtonsoft.Json;
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
#if NETFRAMEWORK
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,7 +13,7 @@ using System.Linq;
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
{
|
||||
[Table("TBSIG_ENVELOPE", Schema = "dbo")]
|
||||
public class Envelope : IHasAddedWhen, IHasChangedWhen, IEnvelope
|
||||
public class Envelope : IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
public Envelope()
|
||||
{
|
||||
@@ -107,8 +106,7 @@ namespace EnvelopeGenerator.Domain.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
[Obsolete("Use EnvelopeGenerator.Domain.Interfaces.EnvelopeExtensions.IsReadAndConfirm extension method instead.")]
|
||||
public bool ReadOnly => this.IsReadAndConfirm();
|
||||
public bool ReadOnly => EnvelopeTypeId == 2;
|
||||
|
||||
[Column("CERTIFICATION_TYPE")]
|
||||
public int? CertificationType { get; set; }
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace EnvelopeGenerator.Domain.Entities
|
||||
[Column("ACTION_DATE", TypeName = "datetime")]
|
||||
public DateTime? ActionDate { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public DateTime? ChangedWhen { get => ActionDate; set => ActionDate = value; }
|
||||
|
||||
[Column("COMMENT", TypeName = "nvarchar(max)")]
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces
|
||||
{
|
||||
public interface IEnvelope
|
||||
{
|
||||
int? EnvelopeTypeId { get; set; }
|
||||
}
|
||||
|
||||
public static class EnvelopeExtensions
|
||||
{
|
||||
public static bool IsReadAndConfirm(this IEnvelope envelope)
|
||||
{
|
||||
return envelope.EnvelopeTypeId == 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.6.1" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
|
||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.82.1" />
|
||||
<PackageReference Include="QuestPDF" Version="2025.7.1" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.2.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
@@ -31,7 +31,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.4.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
@@ -59,7 +59,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.3" newVersion="8.0.0.3" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
@@ -67,7 +67,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.Caching.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
|
||||
@@ -181,11 +181,11 @@
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.8.0.2\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=8.0.0.3, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.8.0.3\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
|
||||
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net48" />
|
||||
<package id="Microsoft.Extensions.DependencyInjection" version="7.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.2" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="8.0.3" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="7.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="7.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.VisualBasic" version="10.3.0" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net48" />
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
29
EnvelopeGenerator.ServiceHost/Program.cs
Normal file
29
EnvelopeGenerator.ServiceHost/Program.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using EnvelopeGenerator.ServiceHost;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddHostedService<Worker>();
|
||||
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
41
EnvelopeGenerator.ServiceHost/Properties/launchSettings.json
Normal file
41
EnvelopeGenerator.ServiceHost/Properties/launchSettings.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:27420",
|
||||
"sslPort": 44372
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "http://localhost:5088",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7234;http://localhost:5088",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
EnvelopeGenerator.ServiceHost/Worker.cs
Normal file
23
EnvelopeGenerator.ServiceHost/Worker.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace EnvelopeGenerator.ServiceHost;
|
||||
|
||||
public class Worker : BackgroundService
|
||||
{
|
||||
private readonly ILogger<Worker> _logger;
|
||||
|
||||
public Worker(ILogger<Worker> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
||||
}
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
EnvelopeGenerator.ServiceHost/appsettings.json
Normal file
9
EnvelopeGenerator.ServiceHost/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@@ -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", er);
|
||||
return View("EnvelopeSigned");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PackageId>EnvelopeGenerator.Web</PackageId>
|
||||
@@ -12,9 +12,9 @@
|
||||
<PackageTags>digital data envelope generator web</PackageTags>
|
||||
<Description>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.</Description>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<Version>3.12.0</Version> <!-- NuGet package version -->
|
||||
<AssemblyVersion>3.12.0.0</AssemblyVersion> <!-- Assembly version for API compatibility -->
|
||||
<FileVersion>3.12.0.0</FileVersion> <!-- Windows file version -->
|
||||
<Version>3.10.0</Version> <!-- NuGet package version -->
|
||||
<AssemblyVersion>3.10.0.0</AssemblyVersion> <!-- Assembly version for API compatibility -->
|
||||
<FileVersion>3.10.0.0</FileVersion> <!-- Windows file version -->
|
||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -2093,14 +2093,39 @@
|
||||
<None Include="wwwroot\lib\bootstrap-icons\icons\zoom-out.svg" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" />
|
||||
<PackageReference Include="DigitalData.Core.API" Version="2.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.2.5" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
|
||||
<PackageReference Include="Quartz" Version="3.8.0" />
|
||||
<PackageReference Include="Quartz.AspNetCore" Version="3.8.0" />
|
||||
<PackageReference Include="Quartz.Plugins" Version="3.8.0" />
|
||||
<PackageReference Include="Quartz.Serialization.Json" Version="3.8.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
|
||||
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="7.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" />
|
||||
<PackageReference Include="DigitalData.Core.API" Version="2.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.17" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="8.0.17" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.2.5" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
|
||||
@@ -2124,8 +2149,8 @@
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.2.5" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
@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();
|
||||
}
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
@@ -56,11 +54,7 @@
|
||||
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"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1>@(isExt
|
||||
? _localizer.RejectionInfo1Ext()
|
||||
: IsReadAndConfirm
|
||||
? _localizer.RejectionInfo1ForConfirmation()
|
||||
: _localizer.RejectionInfo1())</h1>
|
||||
<h1>@(isExt ? _localizer.RejectionInfo1Ext() : _localizer.RejectionInfo1())</h1>
|
||||
</header>
|
||||
<section class="text-center">
|
||||
<div class="card-body p-0 m-0 ms-4">
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
@{
|
||||
@using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
|
||||
@using EnvelopeGenerator.Domain.Interfaces;
|
||||
@model EnvelopeReceiverDto;
|
||||
bool IsReadAndConfirm = Model!.Envelope!.IsReadAndConfirm();
|
||||
ViewData["Title"] = IsReadAndConfirm
|
||||
? _localizer.DocConfirmed()
|
||||
: _localizer.DocSigned();
|
||||
ViewData["Title"] = _localizer.DocSigned();
|
||||
}
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
@@ -15,13 +9,9 @@
|
||||
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1>@(IsReadAndConfirm
|
||||
? _localizer["DocumentSuccessfullyConfirmed"]
|
||||
: _localizer["DocumentSuccessfullySigned"])</h1>
|
||||
<h1>@_localizer["DocumentSuccessfullySigned"]</h1>
|
||||
</header>
|
||||
<section class="text-center">
|
||||
<p>@(IsReadAndConfirm
|
||||
? _localizer["DocumentConfirmedConfirmationMessage"]
|
||||
: _localizer["DocumentSignedConfirmationMessage"])</p>
|
||||
<p>@_localizer["DocumentSignedConfirmationMessage"]</p>
|
||||
</section>
|
||||
</div>
|
||||
@@ -9,7 +9,6 @@
|
||||
@using EnvelopeGenerator.Web.Extensions
|
||||
@using Newtonsoft.Json
|
||||
@using Newtonsoft.Json.Serialization
|
||||
@using EnvelopeGenerator.Domain.Interfaces
|
||||
@model EnvelopeReceiverDto;
|
||||
@{
|
||||
var userCulture = ViewData["UserCulture"] as Culture;
|
||||
@@ -25,13 +24,7 @@
|
||||
if (ViewData["IsReadOnly"] is bool isReadOnly_bool)
|
||||
isReadOnly = isReadOnly_bool;
|
||||
|
||||
var isReadAndConfirm = envelope.IsReadAndConfirm();
|
||||
|
||||
ViewData["Title"] = isReadOnly
|
||||
? _localizer.ViewDoc()
|
||||
: isReadAndConfirm
|
||||
? _localizer.ConfirmDoc()
|
||||
: _localizer.SignDoc();
|
||||
ViewData["Title"] = isReadOnly ? _localizer.ViewDoc() : _localizer.SignDoc();
|
||||
}
|
||||
<div class="envelope-view">
|
||||
@if (!isReadOnly)
|
||||
@@ -69,9 +62,7 @@
|
||||
<div class="progress-container">
|
||||
<div id="signed-count-bar" class="progress"></div>
|
||||
<span class="progress-text">
|
||||
<span id="signed-count">0</span>/<span id="signature-count">@signatureCount</span> @(isReadAndConfirm
|
||||
? _localizer["Confirmations"]
|
||||
: _localizer["Signatures"])
|
||||
<span id="signed-count">0</span>/<span id="signature-count">@signatureCount</span> @_localizer["Signatures"]
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"MailParams": {
|
||||
"Placeholders": {
|
||||
"[NAME_PORTAL]": "signFlow",
|
||||
"[SIGNATURE_TYPE]": "signieren",
|
||||
"[REASON]": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ async function createAnnotationFrameBlob(receiverName, receiverSignature, timest
|
||||
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.font = `${fontSize * scale}px sans-serif`
|
||||
ctx.fillText((READ_AND_CONFIRM ? localized.confirmedBy : localized.signedBy) ?? 'Signed by', 15 * scale, 10 * scale)
|
||||
ctx.fillText(localized.signedBy ?? 'Signed by', 15 * scale, 10 * scale)
|
||||
ctx.fillText(receiverName, 15 * scale, 60 * scale)
|
||||
ctx.fillText(signatureString, 15 * scale, 70 * scale)
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ class App {
|
||||
|
||||
return Swal.fire({
|
||||
title: localized.confirmation,
|
||||
html: `<div class="text-start fs-6 p-0 m-0">${READ_AND_CONFIRM ? localized.confirmAgree : localized.sigAgree}</div>`,
|
||||
html: `<div class="text-start fs-6 p-0 m-0">${localized.sigAgree}</div>`,
|
||||
icon: "question",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
|
||||
2
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
2
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
@@ -1,3 +1,3 @@
|
||||
const formatLocalized=(n,...t)=>typeof n=="string"?n.replace(/\{(\d+)\}/g,(n,i)=>t[i]??""):"";class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.pdfKit=null;this.currentDocument=t.envelope.documents[0];this.currentReceiver=t.receiver;this.signatureCount=t.envelope.documents[0].elements.length;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){if(this.pdfKit=await loadPSPDFKit(this.documentBytes,this.container,this.licenseKey,this.locale),addToolbarItems(this.pdfKit,this.handleClick.bind(this)),this.pdfKit.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this)),this.pdfKit.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this)),this.pdfKit.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this)),this.pdfKit.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()}),!READ_AND_CONFIRM)try{let n=await createAnnotations(this.currentDocument,this.envelopeReceiver.envelopeId,this.envelopeReceiver.receiverId);await this.pdfKit.create(n)}catch(n){console.error("Error loading annotations:",n)}READ_AND_CONFIRM||[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.pdfKit.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h,generateId(this.envelopeReceiver.envelopeId,this.envelopeReceiver.receiverId,this.fakeElementId--,"signed"));this.pdfKit.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:localized.success,text:localized.documentReset,icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/Envelope/${this.envelopeKey}`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(`
|
||||
Request failed: ${t}
|
||||
`)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?reload():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify(localized.copyLinkSuccess,{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify(localized.copyLinkFailure??localized.unexpectedErrorTitle,{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){let n=undefined;if(READ_AND_CONFIRM){const n=JSON.parse(sessionStorage.getItem("pspdf_all_pages_rendered")||"false")===!0;if(!n){const n=JSON.parse(sessionStorage.getItem("pspdf_unviewed_pages")||"[]"),t=n.length?formatLocalized(localized.viewRemainingPages,n.join(", ")):localized.viewAllPages;return await Swal.fire({title:localized.warning,text:t,icon:"warning"}),!1}}else{const i=await this.pdfKit.exportInstantJSON(),r=i.formFieldValues,u=r.filter(n=>isFieldRequired(n)),f=u.some(n=>n.value===undefined||n.value===null||n.value==="");if(f)return Swal.fire({title:localized.warning,text:localized.locationFieldsRequired,icon:"warning"}),!1;const e=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),o=r.filter(n=>isCityField(n));for(var t of o)if(!IS_MOBILE_DEVICE&&!e.test(t.value))return Swal.fire({title:localized.warning,text:formatLocalized(localized.cityFormatInvalid,t.value),icon:"warning"}),!1;const s=await this.validateAnnotations(this.signatureCount);if(s===!1)return Swal.fire({title:localized.warning,text:localized.missingSignatures,icon:"warning"}),!1;n={instant:i,structured:mapSignature(i)}}return Swal.fire({title:localized.confirmation,html:`<div class="text-start fs-6 p-0 m-0">${READ_AND_CONFIRM?localized.confirmAgree:localized.sigAgree}</div>`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.pdfKit.save()}catch(i){return Swal.fire({title:localized.warning,text:localized.envelopeSignError,icon:"error"}),!1}try{const t=READ_AND_CONFIRM?await signEnvelope():await signEnvelope(n);if(t.ok)return!0;if(t.status===409)return Swal.fire({title:localized.warning,text:localized.envelopeUnavailable,icon:"warning"}),!1;if(t.status===423)Swal.fire({title:localized.info??localized.warning,text:localized.envelopeRejectedRedirect,icon:"info",timer:2e3,showConfirmButton:!1}).then(()=>{location.reload()});else throw new Error;}catch(i){return Swal.fire({title:localized.warning,text:localized.envelopeSignError,icon:"error"}),!1}}else return!1})}async validateAnnotations(n){const t=await getAnnotations(this.pdfKit),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n<=i.length}async handleReset(){const n=Swal.fire({title:localized.resetConfirmTitle,text:localized.resetConfirmText,icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await deleteAnnotations(this.pdfKit)}return n}fakeElementId=0;}
|
||||
`)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?reload():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify(localized.copyLinkSuccess,{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify(localized.copyLinkFailure??localized.unexpectedErrorTitle,{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){let n=undefined;if(READ_AND_CONFIRM){const n=JSON.parse(sessionStorage.getItem("pspdf_all_pages_rendered")||"false")===!0;if(!n){const n=JSON.parse(sessionStorage.getItem("pspdf_unviewed_pages")||"[]"),t=n.length?formatLocalized(localized.viewRemainingPages,n.join(", ")):localized.viewAllPages;return await Swal.fire({title:localized.warning,text:t,icon:"warning"}),!1}}else{const i=await this.pdfKit.exportInstantJSON(),r=i.formFieldValues,u=r.filter(n=>isFieldRequired(n)),f=u.some(n=>n.value===undefined||n.value===null||n.value==="");if(f)return Swal.fire({title:localized.warning,text:localized.locationFieldsRequired,icon:"warning"}),!1;const e=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),o=r.filter(n=>isCityField(n));for(var t of o)if(!IS_MOBILE_DEVICE&&!e.test(t.value))return Swal.fire({title:localized.warning,text:formatLocalized(localized.cityFormatInvalid,t.value),icon:"warning"}),!1;const s=await this.validateAnnotations(this.signatureCount);if(s===!1)return Swal.fire({title:localized.warning,text:localized.missingSignatures,icon:"warning"}),!1;n={instant:i,structured:mapSignature(i)}}return Swal.fire({title:localized.confirmation,html:`<div class="text-start fs-6 p-0 m-0">${localized.sigAgree}</div>`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.pdfKit.save()}catch(i){return Swal.fire({title:localized.warning,text:localized.envelopeSignError,icon:"error"}),!1}try{const t=READ_AND_CONFIRM?await signEnvelope():await signEnvelope(n);if(t.ok)return!0;if(t.status===409)return Swal.fire({title:localized.warning,text:localized.envelopeUnavailable,icon:"warning"}),!1;if(t.status===423)Swal.fire({title:localized.info??localized.warning,text:localized.envelopeRejectedRedirect,icon:"info",timer:2e3,showConfirmButton:!1}).then(()=>{location.reload()});else throw new Error;}catch(i){return Swal.fire({title:localized.warning,text:localized.envelopeSignError,icon:"error"}),!1}}else return!1})}async validateAnnotations(n){const t=await getAnnotations(this.pdfKit),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n<=i.length}async handleReset(){const n=Swal.fire({title:localized.resetConfirmTitle,text:localized.resetConfirmText,icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await deleteAnnotations(this.pdfKit)}return n}fakeElementId=0;}
|
||||
@@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Tests", "
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.API", "EnvelopeGenerator.API\EnvelopeGenerator.API.csproj", "{EC768913-6270-14F4-1DD3-69C87A659462}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.ServiceHost", "EnvelopeGenerator.ServiceHost\EnvelopeGenerator.ServiceHost.csproj", "{5DD82482-E560-405F-BF55-04D647B05BEF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -53,8 +55,8 @@ Global
|
||||
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
@@ -85,6 +87,10 @@ Global
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5DD82482-E560-405F-BF55-04D647B05BEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5DD82482-E560-405F-BF55-04D647B05BEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5DD82482-E560-405F-BF55-04D647B05BEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5DD82482-E560-405F-BF55-04D647B05BEF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -104,6 +110,7 @@ Global
|
||||
{211619F5-AE25-4BA5-A552-BACAFE0632D3} = {9943209E-1744-4944-B1BA-4F87FC1A0EEB}
|
||||
{224C4845-1CDE-22B7-F3A9-1FF9297F70E8} = {0CBC2432-A561-4440-89BC-671B66A24146}
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{5DD82482-E560-405F-BF55-04D647B05BEF} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73E60370-756D-45AD-A19A-C40A02DACCC7}
|
||||
|
||||
Reference in New Issue
Block a user