Compare commits
73 Commits
feat/blazo
...
bugfix/rea
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cb1546934 | |||
| 60db762bcc | |||
| 5e840db04c | |||
| e724a74f9c | |||
| 48b7afcdc1 | |||
| 717da90c01 | |||
| 8054bb377d | |||
| 200258ff73 | |||
| fa73d939b5 | |||
| ca9e25abcb | |||
| 82831991b0 | |||
|
|
260e8d53ba | ||
|
|
0fd174ee0c | ||
|
|
ab4cd7c254 | ||
| 1f5468b1ac | |||
| b20aafe7a5 | |||
| 466d0a3a7a | |||
| 7281cb47c3 | |||
| eb5db3d6be | |||
| 8a534b84d0 | |||
| c523153654 | |||
| 82c85643c8 | |||
| 69892d566c | |||
| 2f41348c59 | |||
| 0d56ac7448 | |||
| 18a563ecd1 | |||
| 73df248d15 | |||
| 7c7674c822 | |||
| 65f606f573 | |||
| 0341505f8d | |||
| d4eee1718e | |||
| 9b042d8f45 | |||
|
|
ad0c847172 | ||
| f6d57b1e38 | |||
| b64d2b7478 | |||
|
|
f8c7f60cf9 | ||
| 44edef8ba1 | |||
| 647c5d2353 | |||
| 4ce1d2a370 | |||
| bcc53bf9f1 | |||
| f1e38e3bd3 | |||
| e095860b17 | |||
| 9cfc74aa88 | |||
| 7cd6ca3a5f | |||
| 9b660cb25a | |||
| 3d43d1896d | |||
| bcc17f6def | |||
| 8e3c334fa3 | |||
| 08299451bb | |||
| 59d6d25bdd | |||
| 9a516ab3c9 | |||
| 8fed342dc5 | |||
| f44643aa3e | |||
| 86c99596c4 | |||
| 2d0c08b2ce | |||
| e0aa963184 | |||
| afa3694cd7 | |||
| 48f4ea0c50 | |||
| 74c4ddda83 | |||
| f9b1e583df | |||
| 7c8e0d8481 | |||
| 6d2ec4cc0b | |||
| 898097cdb5 | |||
| 689a1b355a | |||
| 3b3330bd54 | |||
| 511fad3950 | |||
| f5f137396e | |||
| 0d78e9b8f5 | |||
| 8258d9f43f | |||
| 01f3335238 | |||
| 1d0c758e00 | |||
| 711f7d12e8 | |||
| 43d89699a9 |
@@ -2,6 +2,7 @@
|
|||||||
using DigitalData.UserManager.Application.DTOs.User;
|
using DigitalData.UserManager.Application.DTOs.User;
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
using EnvelopeGenerator.Domain.Constants;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using EnvelopeGenerator.Domain.Interfaces;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Common.Dto;
|
namespace EnvelopeGenerator.Application.Common.Dto;
|
||||||
@@ -10,7 +11,7 @@ namespace EnvelopeGenerator.Application.Common.Dto;
|
|||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeDto
|
public record EnvelopeDto : IEnvelope
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -74,10 +75,12 @@ public record EnvelopeDto
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int? EnvelopeTypeId { get; set; }
|
public int? EnvelopeTypeId { get; set; }
|
||||||
|
|
||||||
|
// TODO: use ReadAndConfirm property name
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ReadOnly => EnvelopeTypeId == 2;
|
[Obsolete("Use EnvelopeExtensions.IsReadAndConfirm extension metot instead.")]
|
||||||
|
public bool ReadOnly => this.IsReadAndConfirm();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -29,15 +29,12 @@ public class DocStatusHandler : INotificationHandler<DocSignedNotification>
|
|||||||
/// <param name="notification"></param>
|
/// <param name="notification"></param>
|
||||||
/// <param name="cancel"></param>
|
/// <param name="cancel"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task Handle(DocSignedNotification notification, CancellationToken cancel)
|
public Task Handle(DocSignedNotification notification, CancellationToken cancel) => _sender.Send(new CreateDocStatusCommand()
|
||||||
{
|
{
|
||||||
await _sender.Send(new SaveDocStatusCommand()
|
EnvelopeId = notification.EnvelopeId,
|
||||||
{
|
ReceiverId = notification.ReceiverId,
|
||||||
Envelope = new() { Id = notification.EnvelopeId },
|
Value = notification.PsPdfKitAnnotation is PsPdfKitAnnotation annot
|
||||||
Receiver = new() { Id = notification.ReceiverId},
|
? JsonSerializer.Serialize(annot.Instant, Format.Json.ForAnnotations)
|
||||||
Value = notification.PsPdfKitAnnotation is PsPdfKitAnnotation annot
|
|
||||||
? JsonSerializer.Serialize(annot.Instant, Format.Json.ForAnnotations)
|
|
||||||
: BlankAnnotationJson
|
: BlankAnnotationJson
|
||||||
}, cancel);
|
}, cancel);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
|
|||||||
using EnvelopeGenerator.Application.Common.Configurations;
|
using EnvelopeGenerator.Application.Common.Configurations;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using EnvelopeGenerator.Domain.Interfaces;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned.Handlers;
|
namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned.Handlers;
|
||||||
|
|
||||||
@@ -45,6 +46,25 @@ public class SendSignedMailHandler : SendMailHandler<DocSignedNotification>
|
|||||||
{ "[DOCUMENT_TITLE]", notification.Envelope?.Title ?? string.Empty },
|
{ "[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;
|
return placeHolders;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,12 +8,22 @@ namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record CreateDocStatusCommand : ModifyDocStatusCommandBase, IRequest<DocumentStatus>
|
public record CreateDocStatusCommand : IRequest<DocumentStatus>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime AddedWhen => StatusChangedWhen;
|
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>
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
|
|
||||||
/// <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,14 +1,41 @@
|
|||||||
using EnvelopeGenerator.Domain;
|
using EnvelopeGenerator.Application.Common.Commands;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record UpdateDocStatusCommand : ModifyDocStatusCommandBase
|
/// <param name="Value"></param>
|
||||||
|
public record DocStatusUpdateDto(string? Value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public record UpdateDocStatusCommand : UpdateCommand<DocStatusUpdateDto, DocumentStatus>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? ChangedWhen => StatusChangedWhen;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -18,11 +18,16 @@ public class MappingProfile : Profile
|
|||||||
CreateMap<CreateDocStatusCommand, DocumentStatus>()
|
CreateMap<CreateDocStatusCommand, DocumentStatus>()
|
||||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.Receiver, 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();
|
.MapAddedWhen();
|
||||||
|
|
||||||
CreateMap<UpdateDocStatusCommand, DocumentStatus>()
|
CreateMap<UpdateDocStatusCommand, DocumentStatus>()
|
||||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
||||||
|
.ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.UtcNow))
|
||||||
.MapChangedWhen();
|
.MapChangedWhen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||||
<PackageReference Include="CommandDotNet">
|
<PackageReference Include="CommandDotNet">
|
||||||
<Version>7.0.5</Version>
|
<Version>7.0.5</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@@ -88,7 +88,6 @@
|
|||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
|
||||||
<PackageReference Include="CommandDotNet">
|
<PackageReference Include="CommandDotNet">
|
||||||
<Version>8.1.1</Version>
|
<Version>8.1.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@@ -96,7 +95,6 @@
|
|||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
|
||||||
<PackageReference Include="CommandDotNet">
|
<PackageReference Include="CommandDotNet">
|
||||||
<Version>8.1.1</Version>
|
<Version>8.1.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<History
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime AddedWhen { get; } = DateTime.Now;
|
public DateTime AddedWhen { get; } = DateTime.UtcNow;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using EnvelopeGenerator.Application.Common.Extensions;
|
||||||
using EnvelopeGenerator.Application.Histories.Commands;
|
using EnvelopeGenerator.Application.Histories.Commands;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ public class MappingProfile: Profile
|
|||||||
CreateMap<CreateHistoryCommand, History>()
|
CreateMap<CreateHistoryCommand, History>()
|
||||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.Sender, 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,6 +190,13 @@ public static class Extensions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string SignDoc(this IStringLocalizer localizer) => localizer[nameof(SignDoc)].Value;
|
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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -204,6 +211,13 @@ public static class Extensions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string DocSigned(this IStringLocalizer localizer) => localizer[nameof(DocSigned)].Value;
|
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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -239,6 +253,13 @@ public static class Extensions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string SigAgree(this IStringLocalizer localizer) => localizer[nameof(SigAgree)].Value;
|
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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -267,6 +288,13 @@ public static class Extensions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string RejectionInfo1(this IStringLocalizer localizer) => localizer[nameof(RejectionInfo1)].Value;
|
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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -295,6 +323,13 @@ public static class Extensions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string SigningProcessTitle(this IStringLocalizer localizer) => localizer[nameof(SigningProcessTitle)].Value;
|
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>
|
||||||
///
|
///
|
||||||
/// </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>
|
<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>
|
||||||
<data name="RejectionInfo2_ext" xml:space="preserve">
|
<data name="RejectionInfo2_ext" xml:space="preserve">
|
||||||
<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>
|
<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>
|
||||||
</data>
|
</data>
|
||||||
<data name="RejectionReasonQ" xml:space="preserve">
|
<data name="RejectionReasonQ" xml:space="preserve">
|
||||||
<value>Bitte geben Sie einen Grund an:</value>
|
<value>Bitte geben Sie einen Grund an:</value>
|
||||||
@@ -447,4 +447,34 @@
|
|||||||
<data name="DocumentReset" xml:space="preserve">
|
<data name="DocumentReset" xml:space="preserve">
|
||||||
<value>Dokument wurde zurückgesetzt.</value>
|
<value>Dokument wurde zurückgesetzt.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
@@ -447,4 +447,34 @@
|
|||||||
<data name="DocumentReset" xml:space="preserve">
|
<data name="DocumentReset" xml:space="preserve">
|
||||||
<value>Document has been reset.</value>
|
<value>Document has been reset.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
@@ -447,4 +447,34 @@
|
|||||||
<data name="DocumentReset" xml:space="preserve">
|
<data name="DocumentReset" xml:space="preserve">
|
||||||
<value>Le document a été réinitialisé.</value>
|
<value>Le document a été réinitialisé.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
@@ -12,6 +12,7 @@ using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly;
|
|||||||
using EnvelopeGenerator.Application.Common.Extensions;
|
using EnvelopeGenerator.Application.Common.Extensions;
|
||||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
using EnvelopeGenerator.Domain.Interfaces;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services;
|
namespace EnvelopeGenerator.Application.Services;
|
||||||
|
|
||||||
@@ -49,14 +50,33 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
|||||||
_sender = sender;
|
_sender = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? er = 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)
|
if (accessCode is not null)
|
||||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||||
|
|
||||||
if (envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
if (er?.Envelope is not null && er.Receiver is not null)
|
||||||
{
|
{
|
||||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).ToEnvelopeKey();
|
var erId = (er.Envelope.Uuid, er.Receiver.Signature).ToEnvelopeKey();
|
||||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||||
@@ -66,7 +86,8 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
|||||||
return _placeholders;
|
return _placeholders;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
// 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)
|
||||||
{
|
{
|
||||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||||
{
|
{
|
||||||
@@ -124,7 +145,7 @@ public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
|||||||
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
||||||
var accessCode = acResult.Data;
|
var accessCode = acResult.Data;
|
||||||
|
|
||||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
var placeholders = await CreatePlaceholders(accessCode: accessCode, er: dto);
|
||||||
|
|
||||||
// Add optional place holders.
|
// Add optional place holders.
|
||||||
if (optionalPlaceholders is not null)
|
if (optionalPlaceholders is not null)
|
||||||
|
|||||||
@@ -487,10 +487,6 @@
|
|||||||
<Project>{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}</Project>
|
<Project>{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}</Project>
|
||||||
<Name>EnvelopeGenerator.CommonServices</Name>
|
<Name>EnvelopeGenerator.CommonServices</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.CommonServices\EnvelopeGenerator.CommonServices.vbproj">
|
|
||||||
<Project>{6ea0c51f-c2b1-4462-8198-3de0b32b74f8}</Project>
|
|
||||||
<Name>EnvelopeGenerator.CommonServices</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj">
|
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj">
|
||||||
<Project>{4f32a98d-e6f0-4a09-bd97-1cf26107e837}</Project>
|
<Project>{4f32a98d-e6f0-4a09-bd97-1cf26107e837}</Project>
|
||||||
<Name>EnvelopeGenerator.Domain</Name>
|
<Name>EnvelopeGenerator.Domain</Name>
|
||||||
|
|||||||
12
EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb
generated
12
EnvelopeGenerator.BBTests/frmFinalizePDF.Designer.vb
generated
@@ -27,6 +27,7 @@ Partial Class frmFinalizePDF
|
|||||||
Me.Label2 = New System.Windows.Forms.Label()
|
Me.Label2 = New System.Windows.Forms.Label()
|
||||||
Me.Button1 = New System.Windows.Forms.Button()
|
Me.Button1 = New System.Windows.Forms.Button()
|
||||||
Me.Button2 = New System.Windows.Forms.Button()
|
Me.Button2 = New System.Windows.Forms.Button()
|
||||||
|
Me.Button3 = New System.Windows.Forms.Button()
|
||||||
Me.txtResult = New System.Windows.Forms.TextBox()
|
Me.txtResult = New System.Windows.Forms.TextBox()
|
||||||
Me.txtEnvelope = New System.Windows.Forms.TextBox()
|
Me.txtEnvelope = New System.Windows.Forms.TextBox()
|
||||||
Me.SuspendLayout()
|
Me.SuspendLayout()
|
||||||
@@ -75,6 +76,15 @@ Partial Class frmFinalizePDF
|
|||||||
Me.Button2.Text = "Merge Json"
|
Me.Button2.Text = "Merge Json"
|
||||||
Me.Button2.UseVisualStyleBackColor = True
|
Me.Button2.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
|
'Button3
|
||||||
|
'
|
||||||
|
Me.Button3.Location = New System.Drawing.Point(15, 160)
|
||||||
|
Me.Button3.Name = "Button3"
|
||||||
|
Me.Button3.Size = New System.Drawing.Size(166, 23)
|
||||||
|
Me.Button3.TabIndex = 5
|
||||||
|
Me.Button3.Text = "Full Finalize Test"
|
||||||
|
Me.Button3.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
'txtResult
|
'txtResult
|
||||||
'
|
'
|
||||||
Me.txtResult.Location = New System.Drawing.Point(333, 12)
|
Me.txtResult.Location = New System.Drawing.Point(333, 12)
|
||||||
@@ -97,6 +107,7 @@ Partial Class frmFinalizePDF
|
|||||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
Me.ClientSize = New System.Drawing.Size(800, 450)
|
Me.ClientSize = New System.Drawing.Size(800, 450)
|
||||||
Me.Controls.Add(Me.txtResult)
|
Me.Controls.Add(Me.txtResult)
|
||||||
|
Me.Controls.Add(Me.Button3)
|
||||||
Me.Controls.Add(Me.Button2)
|
Me.Controls.Add(Me.Button2)
|
||||||
Me.Controls.Add(Me.Button1)
|
Me.Controls.Add(Me.Button1)
|
||||||
Me.Controls.Add(Me.Label2)
|
Me.Controls.Add(Me.Label2)
|
||||||
@@ -116,5 +127,6 @@ Partial Class frmFinalizePDF
|
|||||||
Friend WithEvents Label2 As Label
|
Friend WithEvents Label2 As Label
|
||||||
Friend WithEvents Button1 As Button
|
Friend WithEvents Button1 As Button
|
||||||
Friend WithEvents Button2 As Button
|
Friend WithEvents Button2 As Button
|
||||||
|
Friend WithEvents Button3 As Button
|
||||||
Friend WithEvents txtResult As TextBox
|
Friend WithEvents txtResult As TextBox
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ Imports GdPicture14
|
|||||||
Imports Newtonsoft.Json.Linq
|
Imports Newtonsoft.Json.Linq
|
||||||
Imports EnvelopeGenerator.Infrastructure
|
Imports EnvelopeGenerator.Infrastructure
|
||||||
Imports Microsoft.EntityFrameworkCore
|
Imports Microsoft.EntityFrameworkCore
|
||||||
Imports System.Text
|
|
||||||
Imports DigitalData.Core.Abstractions
|
Imports DigitalData.Core.Abstractions
|
||||||
|
Imports DigitalData.Core.Abstraction.Application.Repository
|
||||||
|
Imports EnvelopeGenerator.Domain.Entities
|
||||||
|
|
||||||
Public Class frmFinalizePDF
|
Public Class frmFinalizePDF
|
||||||
Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;"
|
Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;" + "Encrypt=True;TrustServerCertificate=True;"
|
||||||
|
|
||||||
Private Database As MSSQLServer
|
Private Database As MSSQLServer
|
||||||
Private LogConfig As LogConfig
|
Private LogConfig As LogConfig
|
||||||
@@ -93,56 +94,118 @@ Public Class frmFinalizePDF
|
|||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
|
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
|
||||||
Try
|
Dim oTable = LoadAnnotationDataForEnvelope()
|
||||||
|
Dim oJsonList = oTable.Rows.
|
||||||
|
Cast(Of DataRow).
|
||||||
|
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
||||||
|
ToList()
|
||||||
|
|
||||||
Dim oTable = LoadAnnotationDataForEnvelope()
|
Dim envelopeId As Integer = CInt(txtEnvelope.Text)
|
||||||
Dim oJsonList = oTable.Rows.
|
Dim oBuffer As Byte() = ReadEnvelope(envelopeId)
|
||||||
Cast(Of DataRow).
|
Dim oNewBuffer = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId)
|
||||||
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
|
||||||
ToList()
|
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}R{txtReceiver.Text}.burned.pdf")
|
||||||
|
|
||||||
Dim envelopeId As Integer = CInt(txtEnvelope.Text)
|
File.WriteAllBytes(oNewPath, oNewBuffer)
|
||||||
Dim oBuffer As Byte() = ReadEnvelope(envelopeId)
|
|
||||||
Dim oNewBuffer = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId)
|
|
||||||
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
|
|
||||||
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}R{txtReceiver.Text}.burned.pdf")
|
|
||||||
|
|
||||||
File.WriteAllBytes(oNewPath, oNewBuffer)
|
|
||||||
|
|
||||||
Process.Start(oNewPath)
|
|
||||||
Catch ex As Exception
|
|
||||||
Dim exMsg As StringBuilder = New StringBuilder(ex.Message).AppendLine()
|
|
||||||
|
|
||||||
Dim innerEx = ex.InnerException
|
|
||||||
While (innerEx IsNot Nothing)
|
|
||||||
exMsg.AppendLine(innerEx.Message)
|
|
||||||
innerEx = innerEx.InnerException
|
|
||||||
End While
|
|
||||||
|
|
||||||
MsgBox(exMsg.ToString(), MsgBoxStyle.Critical)
|
|
||||||
End Try
|
|
||||||
|
|
||||||
|
Process.Start(oNewPath)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
|
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
|
||||||
|
Dim oTable = LoadAnnotationDataForEnvelope()
|
||||||
|
Dim oJsonList = oTable.Rows.
|
||||||
|
Cast(Of DataRow).
|
||||||
|
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
||||||
|
Select(Function(s As String) JObject.Parse(s)).
|
||||||
|
ToList()
|
||||||
|
|
||||||
|
Dim oJObject1 = oJsonList.First()
|
||||||
|
Dim oJObject2 = oJsonList.ElementAt(1)
|
||||||
|
|
||||||
|
oJObject1.Merge(oJObject2)
|
||||||
|
|
||||||
|
txtResult.Text = oJObject1.ToString()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
|
||||||
Try
|
Try
|
||||||
|
Dim envelopeId As Integer = CInt(txtEnvelope.Text)
|
||||||
|
Dim log As New System.Text.StringBuilder()
|
||||||
|
|
||||||
|
' 1. Load annotation JSON data (same as Service)
|
||||||
Dim oTable = LoadAnnotationDataForEnvelope()
|
Dim oTable = LoadAnnotationDataForEnvelope()
|
||||||
Dim oJsonList = oTable.Rows.
|
Dim oJsonList = oTable.Rows.
|
||||||
Cast(Of DataRow).
|
Cast(Of DataRow).
|
||||||
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
||||||
Select(Function(s As String) JObject.Parse(s)).
|
|
||||||
ToList()
|
ToList()
|
||||||
|
log.AppendLine($"Annotation JSON count: {oJsonList.Count}")
|
||||||
|
|
||||||
Dim oJObject1 = oJsonList.First()
|
' 2. Load document bytes (same as Service)
|
||||||
Dim oJObject2 = oJsonList.ElementAt(1)
|
Dim oBuffer As Byte() = ReadEnvelope(envelopeId)
|
||||||
|
log.AppendLine($"Document bytes: {oBuffer.Length}")
|
||||||
|
|
||||||
oJObject1.Merge(oJObject2)
|
' 3. Check what BurnAnnotsToPDF will do internally
|
||||||
|
Using scope = Factory.Shared.ScopeFactory.CreateScope()
|
||||||
|
Dim envRepo = scope.ServiceProvider.Repository(Of Envelope)()
|
||||||
|
Dim envelope = envRepo.Where(Function(env) env.Id = envelopeId).FirstOrDefault()
|
||||||
|
|
||||||
txtResult.Text = oJObject1.ToString()
|
If envelope Is Nothing Then
|
||||||
|
log.AppendLine("ERROR: Envelope not found in EF Core!")
|
||||||
|
txtResult.Text = log.ToString()
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
log.AppendLine($"Envelope found: Id={envelope.Id}, EnvelopeTypeId={envelope.EnvelopeTypeId}")
|
||||||
|
log.AppendLine($"ReadOnly (IsReadAndConfirm): {envelope.ReadOnly}")
|
||||||
|
|
||||||
|
If envelope.ReadOnly Then
|
||||||
|
log.AppendLine(">>> EARLY RETURN: ReadOnly=True, original PDF returned without burning")
|
||||||
|
txtResult.Text = log.ToString()
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim sigRepo = scope.ServiceProvider.Repository(Of Signature)()
|
||||||
|
Dim elements = sigRepo _
|
||||||
|
.Where(Function(sig) sig.Document.EnvelopeId = envelopeId) _
|
||||||
|
.Include(Function(sig) sig.Annotations) _
|
||||||
|
.ToList()
|
||||||
|
|
||||||
|
log.AppendLine($"Elements (Signature) count: {elements.Count}")
|
||||||
|
|
||||||
|
If elements.Any() Then
|
||||||
|
log.AppendLine(">>> PATH: BurnElementAnnotsToPDF (new element-based path)")
|
||||||
|
For Each elem In elements
|
||||||
|
Dim annotCount = If(elem.Annotations IsNot Nothing, elem.Annotations.Count(), 0)
|
||||||
|
log.AppendLine($" Element Id={elem.Id}, Page={elem.Page}, X={elem.X}, Y={elem.Y}, W={elem.Width}, H={elem.Height}, Annotations={annotCount}")
|
||||||
|
If elem.Annotations IsNot Nothing Then
|
||||||
|
For Each annot In elem.Annotations
|
||||||
|
log.AppendLine($" Annot: Name={annot.Name}, Type={annot.Type}, X={annot.X}, Y={annot.Y}, W={annot.Width}, H={annot.Height}")
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
Else
|
||||||
|
log.AppendLine(">>> PATH: BurnInstantJSONAnnotsToPDF (old JSON-based path)")
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
|
||||||
|
' 4. Actually call BurnAnnotsToPDF (same as Service)
|
||||||
|
log.AppendLine("")
|
||||||
|
log.AppendLine("Calling BurnAnnotsToPDF...")
|
||||||
|
Dim oNewBuffer = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId)
|
||||||
|
log.AppendLine($"Result bytes: {oNewBuffer.Length}")
|
||||||
|
log.AppendLine($"Same as input: {oBuffer.Length = oNewBuffer.Length AndAlso oBuffer.SequenceEqual(oNewBuffer)}")
|
||||||
|
|
||||||
|
' 5. Write output
|
||||||
|
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
|
||||||
|
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}_FullTest.burned.pdf")
|
||||||
|
File.WriteAllBytes(oNewPath, oNewBuffer)
|
||||||
|
log.AppendLine($"Output: {oNewPath}")
|
||||||
|
|
||||||
|
txtResult.Text = log.ToString()
|
||||||
|
Process.Start(oNewPath)
|
||||||
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
MsgBox(ex.Message, MsgBoxStyle.Critical)
|
txtResult.Text = $"ERROR: {ex.Message}{vbCrLf}{vbCrLf}{ex.ToString()}"
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
@@ -15,13 +15,13 @@
|
|||||||
<package id="DigitalData.Modules.Messaging" version="1.9.8" targetFramework="net462" />
|
<package id="DigitalData.Modules.Messaging" version="1.9.8" targetFramework="net462" />
|
||||||
<package id="DocumentFormat.OpenXml" version="3.2.0" targetFramework="net462" />
|
<package id="DocumentFormat.OpenXml" version="3.2.0" targetFramework="net462" />
|
||||||
<package id="DocumentFormat.OpenXml.Framework" version="3.2.0" targetFramework="net462" />
|
<package id="DocumentFormat.OpenXml.Framework" version="3.2.0" targetFramework="net462" />
|
||||||
<package id="EntityFramework" version="6.5.1" targetFramework="net462" />
|
<package id="EntityFramework" version="6.4.4" targetFramework="net462" />
|
||||||
<package id="EntityFramework.Firebird" version="6.4.0" targetFramework="net462" />
|
<package id="EntityFramework.Firebird" version="6.4.0" targetFramework="net462" />
|
||||||
<package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net462" />
|
<package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net462" />
|
||||||
<package id="GdPicture" version="14.3.3" targetFramework="net462" />
|
<package id="GdPicture" version="14.3.3" targetFramework="net462" />
|
||||||
<package id="GdPicture.runtimes.windows" version="14.3.3" targetFramework="net462" />
|
<package id="GdPicture.runtimes.windows" version="14.3.3" targetFramework="net462" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Client" version="6.0.0" targetFramework="net462" />
|
<package id="Microsoft.AspNet.WebApi.Client" version="6.0.0" targetFramework="net462" />
|
||||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.0" targetFramework="net462" />
|
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net462" />
|
||||||
<package id="Microsoft.Bcl.Cryptography" version="9.0.0" targetFramework="net462" />
|
<package id="Microsoft.Bcl.Cryptography" version="9.0.0" targetFramework="net462" />
|
||||||
<package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net462" />
|
<package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net462" />
|
||||||
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net462" />
|
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net462" />
|
||||||
@@ -62,10 +62,10 @@
|
|||||||
<package id="protobuf-net.Core" version="3.2.46" targetFramework="net462" />
|
<package id="protobuf-net.Core" version="3.2.46" targetFramework="net462" />
|
||||||
<package id="RtfPipe" version="2.0.7677.4303" targetFramework="net462" />
|
<package id="RtfPipe" version="2.0.7677.4303" targetFramework="net462" />
|
||||||
<package id="S22.Imap" version="3.6.0.0" targetFramework="net462" />
|
<package id="S22.Imap" version="3.6.0.0" targetFramework="net462" />
|
||||||
<package id="System.Buffers" version="4.6.1" targetFramework="net462" />
|
<package id="System.Buffers" version="4.6.0" targetFramework="net462" />
|
||||||
<package id="System.ClientModel" version="1.8.0" targetFramework="net462" />
|
<package id="System.ClientModel" version="1.8.0" targetFramework="net462" />
|
||||||
<package id="System.CodeDom" version="9.0.0" targetFramework="net462" />
|
<package id="System.CodeDom" version="8.0.0" targetFramework="net462" />
|
||||||
<package id="System.Collections.Immutable" version="9.0.0" targetFramework="net462" />
|
<package id="System.Collections.Immutable" version="8.0.0" targetFramework="net462" />
|
||||||
<package id="System.ComponentModel.Annotations" version="4.7.0" targetFramework="net462" />
|
<package id="System.ComponentModel.Annotations" version="4.7.0" targetFramework="net462" />
|
||||||
<package id="System.Data.Common" version="4.3.0" targetFramework="net462" />
|
<package id="System.Data.Common" version="4.3.0" targetFramework="net462" />
|
||||||
<package id="System.Data.Odbc" version="6.0.1" targetFramework="net462" />
|
<package id="System.Data.Odbc" version="6.0.1" targetFramework="net462" />
|
||||||
@@ -74,23 +74,23 @@
|
|||||||
<package id="System.Formats.Asn1" version="10.0.3" targetFramework="net462" />
|
<package id="System.Formats.Asn1" version="10.0.3" targetFramework="net462" />
|
||||||
<package id="System.IdentityModel.Tokens.Jwt" version="7.7.1" targetFramework="net462" />
|
<package id="System.IdentityModel.Tokens.Jwt" version="7.7.1" targetFramework="net462" />
|
||||||
<package id="System.IO.FileSystem.AccessControl" version="5.0.0" targetFramework="net462" />
|
<package id="System.IO.FileSystem.AccessControl" version="5.0.0" targetFramework="net462" />
|
||||||
<package id="System.IO.Packaging" version="9.0.0" targetFramework="net462" />
|
<package id="System.IO.Packaging" version="8.0.1" targetFramework="net462" />
|
||||||
<package id="System.IO.Pipelines" version="9.0.0" targetFramework="net462" />
|
<package id="System.IO.Pipelines" version="9.0.0" targetFramework="net462" />
|
||||||
<package id="System.Management" version="9.0.0" targetFramework="net462" />
|
<package id="System.Management" version="8.0.0" targetFramework="net462" />
|
||||||
<package id="System.Memory" version="4.6.3" targetFramework="net462" />
|
<package id="System.Memory" version="4.6.0" targetFramework="net462" />
|
||||||
<package id="System.Memory.Data" version="8.0.1" targetFramework="net462" />
|
<package id="System.Memory.Data" version="8.0.1" targetFramework="net462" />
|
||||||
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net462" />
|
<package id="System.Numerics.Vectors" version="4.6.0" targetFramework="net462" />
|
||||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net462" />
|
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.0" targetFramework="net462" />
|
||||||
<package id="System.Security.AccessControl" version="6.0.1" targetFramework="net462" />
|
<package id="System.Security.AccessControl" version="6.0.1" targetFramework="net462" />
|
||||||
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net462" />
|
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net462" />
|
||||||
<package id="System.Security.Cryptography.Cng" version="5.0.0" targetFramework="net462" />
|
<package id="System.Security.Cryptography.Cng" version="5.0.0" targetFramework="net462" />
|
||||||
<package id="System.Security.Cryptography.Pkcs" version="9.0.0" targetFramework="net462" />
|
<package id="System.Security.Cryptography.Pkcs" version="8.0.1" targetFramework="net462" />
|
||||||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net462" />
|
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net462" />
|
||||||
<package id="System.Security.Cryptography.ProtectedData" version="4.5.0" targetFramework="net462" />
|
<package id="System.Security.Cryptography.ProtectedData" version="4.5.0" targetFramework="net462" />
|
||||||
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net462" />
|
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net462" />
|
||||||
<package id="System.Text.Encodings.Web" version="9.0.0" targetFramework="net462" />
|
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net462" />
|
||||||
<package id="System.Text.Json" version="9.0.0" targetFramework="net462" />
|
<package id="System.Text.Json" version="8.0.6" targetFramework="net462" />
|
||||||
<package id="System.Text.RegularExpressions" version="4.3.1" targetFramework="net462" />
|
<package id="System.Text.RegularExpressions" version="4.3.1" targetFramework="net462" />
|
||||||
<package id="System.Threading.Tasks.Extensions" version="4.6.0" targetFramework="net462" />
|
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
|
||||||
<package id="System.ValueTuple" version="4.6.1" targetFramework="net462" />
|
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -230,6 +230,29 @@ Namespace Jobs
|
|||||||
|
|
||||||
Return Task.FromResult(True)
|
Return Task.FromResult(True)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
#Region "From BBTests"
|
||||||
|
Private Function ReadEnvelope(pEnvID As Integer) As Byte()
|
||||||
|
Dim strSql As String = "Select [BYTE_DATA] from [TBSIG_ENVELOPE_DOCUMENT] WHERE ENVELOPE_ID = " & pEnvID
|
||||||
|
Dim obyteDB = Database.GetScalarValue(strSql)
|
||||||
|
If Not IsDBNull(obyteDB) Then
|
||||||
|
Dim fileData As Byte() = DirectCast(Database.GetScalarValue(strSql), Byte())
|
||||||
|
If fileData IsNot Nothing Then
|
||||||
|
Return fileData
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
Throw New InvalidOperationException($"Byte data is null. Envelope ID: {pEnvID}")
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function LoadAnnotationDataForEnvelope(pEnvID As Integer) As DataTable
|
||||||
|
Dim oSql = $"SELECT VALUE FROM [TBSIG_DOCUMENT_STATUS] WHERE ENVELOPE_ID = {pEnvID}"
|
||||||
|
Return Database.GetDatatable(oSql)
|
||||||
|
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
|
||||||
Private Sub Update_File_DB(pFilePath As String, pEnvelopeID As Long)
|
Private Sub Update_File_DB(pFilePath As String, pEnvelopeID As Long)
|
||||||
Dim SqlCom As SqlCommand
|
Dim SqlCom As SqlCommand
|
||||||
Dim imageData As Byte()
|
Dim imageData As Byte()
|
||||||
@@ -418,7 +441,18 @@ Namespace Jobs
|
|||||||
End Try
|
End Try
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Return PDFBurner.BurnAnnotsToPDF(oInputDocumentBuffer, oAnnotations, pEnvelopeData.EnvelopeId)
|
#Region "From BBTests"
|
||||||
|
Dim oTable = LoadAnnotationDataForEnvelope(pEnvelopeId)
|
||||||
|
Dim oJsonList = oTable.Rows.
|
||||||
|
Cast(Of DataRow).
|
||||||
|
Select(Function(r As DataRow) r.Item("VALUE").ToString()).
|
||||||
|
ToList()
|
||||||
|
|
||||||
|
Dim oBuffer As Byte() = ReadEnvelope(pEnvelopeId)
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
Return PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, pEnvelopeId)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData
|
Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData
|
||||||
|
|||||||
@@ -85,16 +85,37 @@ Namespace Jobs.FinalizeDocument
|
|||||||
|
|
||||||
'Add annotations
|
'Add annotations
|
||||||
For Each element In elements
|
For Each element In elements
|
||||||
|
If element Is Nothing Then
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim elementAnnotations = If(element.Annotations, Enumerable.Empty(Of ElementAnnotation)())
|
||||||
|
If Not elementAnnotations.Any() Then
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
|
||||||
Dim frameX = (element.Left - 0.7 - margin)
|
Dim frameX = (element.Left - 0.7 - margin)
|
||||||
|
|
||||||
Dim frame = element.Annotations.FirstOrDefault(Function(a) a.Name = "frame")
|
Dim frame = elementAnnotations.FirstOrDefault(Function(a) a.Name = "frame")
|
||||||
Dim frameY = element.Top - 0.5 - margin
|
Dim frameY = element.Top - 0.5 - margin
|
||||||
Dim frameYShift = frame.Y - frameY * inchFactor
|
Dim frameYShift As Double = 0
|
||||||
Dim frameXShift = frame.X - frameX * inchFactor
|
Dim frameXShift As Double = 0
|
||||||
|
|
||||||
|
If frame IsNot Nothing Then
|
||||||
|
frameYShift = frame.Y - frameY * inchFactor
|
||||||
|
frameXShift = frame.X - frameX * inchFactor
|
||||||
|
End If
|
||||||
|
|
||||||
|
For Each annot In elementAnnotations
|
||||||
|
If annot Is Nothing Then
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim yOffsetofFF As Double = 0
|
||||||
|
If Not String.IsNullOrEmpty(annot.Name) Then
|
||||||
|
yOffsetsOfFF.TryGetValue(annot.Name, yOffsetofFF)
|
||||||
|
End If
|
||||||
|
|
||||||
For Each annot In element.Annotations
|
|
||||||
Dim yOffsetofFF As Double = If(yOffsetsOfFF.TryGetValue(annot.Name, yOffsetofFF), yOffsetofFF, 0)
|
|
||||||
Dim y = frameY + yOffsetofFF
|
Dim y = frameY + yOffsetofFF
|
||||||
|
|
||||||
If annot.Type = AnnotationType.FormField Then
|
If annot.Type = AnnotationType.FormField Then
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Public Class PDFMerger
|
|||||||
|
|
||||||
' Convert to PDF/A
|
' Convert to PDF/A
|
||||||
oMergedPDF.ConvertToPDFA(oFinalStream, PDFAConformanceLevel, ALLOW_VECTORIZATION, ALLOW_RASTERIZATION)
|
oMergedPDF.ConvertToPDFA(oFinalStream, PDFAConformanceLevel, ALLOW_VECTORIZATION, ALLOW_RASTERIZATION)
|
||||||
oStatus = oDocumentPDF.GetStat()
|
oStatus = oMergedPDF.GetStat()
|
||||||
If oStatus <> GdPictureStatus.OK Then
|
If oStatus <> GdPictureStatus.OK Then
|
||||||
Throw New MergeDocumentException($"Document could not be converted to PDF/A: {oStatus}")
|
Throw New MergeDocumentException($"Document could not be converted to PDF/A: {oStatus}")
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -270,12 +270,26 @@ Public Class ReceiverModel
|
|||||||
Private Function GetSignedDate(pEmailAddress As String, pEnvelopeId As Integer) As Date
|
Private Function GetSignedDate(pEmailAddress As String, pEnvelopeId As Integer) As Date
|
||||||
Try
|
Try
|
||||||
Dim oStatusInt As Integer = EnvelopeStatus.DocumentSigned
|
Dim oStatusInt As Integer = EnvelopeStatus.DocumentSigned
|
||||||
Return Database.GetScalarValue($"SELECT ACTION_DATE FROM [DD_ECM].[dbo].[TBSIG_ENVELOPE_HISTORY] WHERE ENVELOPE_ID = {pEnvelopeId}
|
Dim value = Database.GetScalarValue($"SELECT ACTION_DATE FROM [DD_ECM].[dbo].[TBSIG_ENVELOPE_HISTORY] WHERE ENVELOPE_ID = {pEnvelopeId}
|
||||||
And USER_REFERENCE = '{pEmailAddress}' AND [STATUS] = {oStatusInt}")
|
And USER_REFERENCE = '{pEmailAddress}' AND [STATUS] = {oStatusInt}")
|
||||||
|
|
||||||
|
If value Is Nothing OrElse value Is DBNull.Value Then
|
||||||
|
Return DateTime.MinValue
|
||||||
|
End If
|
||||||
|
|
||||||
|
If TypeOf value Is DateTime Then
|
||||||
|
Return DirectCast(value, DateTime)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim parsedDate As DateTime
|
||||||
|
If DateTime.TryParse(value.ToString(), parsedDate) Then
|
||||||
|
Return parsedDate
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return DateTime.MinValue
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Logger.Error(ex)
|
Logger.Error(ex)
|
||||||
Return Nothing
|
Return DateTime.MinValue
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
'------------------------------------------------------------------------------
|
'------------------------------------------------------------------------------
|
||||||
' <auto-generated>
|
' <auto-generated>
|
||||||
' Dieser Code wurde von einem Tool generiert.
|
' This code was generated by a tool.
|
||||||
' Laufzeitversion:4.0.30319.42000
|
' Runtime Version:4.0.30319.42000
|
||||||
'
|
'
|
||||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
' der Code erneut generiert wird.
|
' the code is regenerated.
|
||||||
' </auto-generated>
|
' </auto-generated>
|
||||||
'------------------------------------------------------------------------------
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@ Imports System
|
|||||||
|
|
||||||
Namespace My.Resources
|
Namespace My.Resources
|
||||||
|
|
||||||
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
'class via a tool like ResGen or Visual Studio.
|
||||||
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
'with the /str option, or rebuild your VS project.
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
|
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
|
||||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
@@ -37,7 +37,7 @@ Namespace My.Resources
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
Public Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
Public Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||||
@@ -51,8 +51,8 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
''' Overrides the current thread's CurrentUICulture property for all
|
||||||
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
''' resource lookups using this strongly typed resource class.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
Public Shared Property Culture() As Global.System.Globalization.CultureInfo
|
Public Shared Property Culture() As Global.System.Globalization.CultureInfo
|
||||||
@@ -65,7 +65,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode korrekt eingegeben ähnelt.
|
''' Looks up a localized string similar to Zugriffscode korrekt eingegeben.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property AccessCodeCorrect() As String
|
Public Shared ReadOnly Property AccessCodeCorrect() As String
|
||||||
Get
|
Get
|
||||||
@@ -74,7 +74,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode falsch eingegeben ähnelt.
|
''' Looks up a localized string similar to Zugriffscode falsch eingegeben.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property AccessCodeIncorrect() As String
|
Public Shared ReadOnly Property AccessCodeIncorrect() As String
|
||||||
Get
|
Get
|
||||||
@@ -83,7 +83,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode angefordert ähnelt.
|
''' Looks up a localized string similar to Zugriffscode angefordert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property AccessCodeRequested() As String
|
Public Shared ReadOnly Property AccessCodeRequested() As String
|
||||||
Get
|
Get
|
||||||
@@ -92,7 +92,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Fortgeschrittene Elektronische Signatur ähnelt.
|
''' Looks up a localized string similar to Fortgeschrittene Elektronische Signatur.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property AdvancedElectronicSignature() As String
|
Public Shared ReadOnly Property AdvancedElectronicSignature() As String
|
||||||
Get
|
Get
|
||||||
@@ -101,7 +101,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Abgeschlossen ähnelt.
|
''' Looks up a localized string similar to Abgeschlossen.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Completed() As String
|
Public Shared ReadOnly Property Completed() As String
|
||||||
Get
|
Get
|
||||||
@@ -110,7 +110,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Vollständig Signiert ähnelt.
|
''' Looks up a localized string similar to Vollständig bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property CompletelyConfirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("CompletelyConfirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Vollständig signiert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property CompletelySigned() As String
|
Public Shared ReadOnly Property CompletelySigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -119,7 +128,25 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Vertrag ähnelt.
|
''' Looks up a localized string similar to Lesebestätigung.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property Confirmation() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("Confirmation", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Gelesen und Bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property Confirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("Confirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Vertrag.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Contract() As String
|
Public Shared ReadOnly Property Contract() As String
|
||||||
Get
|
Get
|
||||||
@@ -128,7 +155,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Erstellt ähnelt.
|
''' Looks up a localized string similar to Erstellt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Created() As String
|
Public Shared ReadOnly Property Created() As String
|
||||||
Get
|
Get
|
||||||
@@ -137,7 +164,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Dokument Rotation geändert ähnelt.
|
''' Looks up a localized string similar to Dokument gelesen und bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property DocumentConfirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("DocumentConfirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Dokument Rotation geändert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property DocumentMod_Rotation() As String
|
Public Shared ReadOnly Property DocumentMod_Rotation() As String
|
||||||
Get
|
Get
|
||||||
@@ -146,7 +182,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Dokument geöffnet ähnelt.
|
''' Looks up a localized string similar to Dokument geöffnet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property DocumentOpened() As String
|
Public Shared ReadOnly Property DocumentOpened() As String
|
||||||
Get
|
Get
|
||||||
@@ -155,7 +191,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Unterzeichnung abgelehnt ähnelt.
|
''' Looks up a localized string similar to Unterzeichnung abgelehnt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property DocumentRejected() As String
|
Public Shared ReadOnly Property DocumentRejected() As String
|
||||||
Get
|
Get
|
||||||
@@ -164,7 +200,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Dokument unterzeichnet ähnelt.
|
''' Looks up a localized string similar to Lesebestätigung abgelehnt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property DocumentRejectedRaC() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("DocumentRejectedRaC", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Dokument unterzeichnet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property DocumentSigned() As String
|
Public Shared ReadOnly Property DocumentSigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -173,7 +218,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Entwurf ähnelt.
|
''' Looks up a localized string similar to Entwurf.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Draft() As String
|
Public Shared ReadOnly Property Draft() As String
|
||||||
Get
|
Get
|
||||||
@@ -182,7 +227,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Archiviert ähnelt.
|
''' Looks up a localized string similar to Archiviert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeArchived() As String
|
Public Shared ReadOnly Property EnvelopeArchived() As String
|
||||||
Get
|
Get
|
||||||
@@ -191,7 +236,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Vollständig signiert ähnelt.
|
''' Looks up a localized string similar to Vollständig bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property EnvelopeCompletelyConfirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("EnvelopeCompletelyConfirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Vollständig signiert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeCompletelySigned() As String
|
Public Shared ReadOnly Property EnvelopeCompletelySigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -200,7 +254,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag Erstellt ähnelt.
|
''' Looks up a localized string similar to Umschlag Erstellt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeCreated() As String
|
Public Shared ReadOnly Property EnvelopeCreated() As String
|
||||||
Get
|
Get
|
||||||
@@ -209,7 +263,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag Gelöscht ähnelt.
|
''' Looks up a localized string similar to Umschlag Gelöscht.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeDeleted() As String
|
Public Shared ReadOnly Property EnvelopeDeleted() As String
|
||||||
Get
|
Get
|
||||||
@@ -218,7 +272,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Teil-Signiert ähnelt.
|
''' Looks up a localized string similar to Teil-Bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property EnvelopePartlyConfirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("EnvelopePartlyConfirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Teil-Signiert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopePartlySigned() As String
|
Public Shared ReadOnly Property EnvelopePartlySigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -227,7 +290,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag in Queue ähnelt.
|
''' Looks up a localized string similar to Umschlag in Queue.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeQueued() As String
|
Public Shared ReadOnly Property EnvelopeQueued() As String
|
||||||
Get
|
Get
|
||||||
@@ -236,7 +299,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag abgelehnt ähnelt.
|
''' Looks up a localized string similar to Umschlag abgelehnt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeRejected() As String
|
Public Shared ReadOnly Property EnvelopeRejected() As String
|
||||||
Get
|
Get
|
||||||
@@ -245,7 +308,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Signierungszertifikat erstellt ähnelt.
|
''' Looks up a localized string similar to Signierungszertifikat erstellt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeReportCreated() As String
|
Public Shared ReadOnly Property EnvelopeReportCreated() As String
|
||||||
Get
|
Get
|
||||||
@@ -254,7 +317,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Gespeichert ähnelt.
|
''' Looks up a localized string similar to Lesebestätigungszertifikat erstellt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property EnvelopeReportCreatedRaC() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("EnvelopeReportCreatedRaC", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Gespeichert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeSaved() As String
|
Public Shared ReadOnly Property EnvelopeSaved() As String
|
||||||
Get
|
Get
|
||||||
@@ -263,7 +335,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Gesendet ähnelt.
|
''' Looks up a localized string similar to Gesendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeSent() As String
|
Public Shared ReadOnly Property EnvelopeSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -272,7 +344,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag zurückgezogen ähnelt.
|
''' Looks up a localized string similar to Umschlag zurückgezogen.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property EnvelopeWithdrawn() As String
|
Public Shared ReadOnly Property EnvelopeWithdrawn() As String
|
||||||
Get
|
Get
|
||||||
@@ -281,7 +353,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode versendet ähnelt.
|
''' Looks up a localized string similar to Zugriffscode versendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property MessageAccessCodeSent() As String
|
Public Shared ReadOnly Property MessageAccessCodeSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -290,7 +362,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Abschlussemail versendet ähnelt.
|
''' Looks up a localized string similar to Abschlussemail versendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property MessageCompletionSent() As String
|
Public Shared ReadOnly Property MessageCompletionSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -299,7 +371,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Signaturbestätigung versendet ähnelt.
|
''' Looks up a localized string similar to Signaturbestätigung versendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property MessageConfirmationSent() As String
|
Public Shared ReadOnly Property MessageConfirmationSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -308,7 +380,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Löschinformation versendet ähnelt.
|
''' Looks up a localized string similar to Lesebestätigung versendet.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property MessageConfirmationSentRaC() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("MessageConfirmationSentRaC", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Löschinformation versendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property MessageDeletionSent() As String
|
Public Shared ReadOnly Property MessageDeletionSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -317,7 +398,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Dokumentenlink versendet ähnelt.
|
''' Looks up a localized string similar to Dokumentenlink versendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property MessageInvitationSent() As String
|
Public Shared ReadOnly Property MessageInvitationSent() As String
|
||||||
Get
|
Get
|
||||||
@@ -326,7 +407,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Nein ähnelt.
|
''' Looks up a localized string similar to Nein.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property No() As String
|
Public Shared ReadOnly Property No() As String
|
||||||
Get
|
Get
|
||||||
@@ -335,7 +416,16 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Teil-Signiert ähnelt.
|
''' Looks up a localized string similar to Teil-Bestätigt.
|
||||||
|
'''</summary>
|
||||||
|
Public Shared ReadOnly Property PartlyConfirmed() As String
|
||||||
|
Get
|
||||||
|
Return ResourceManager.GetString("PartlyConfirmed", resourceCulture)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized string similar to Teil-Signiert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property PartlySigned() As String
|
Public Shared ReadOnly Property PartlySigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -344,7 +434,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Qualifizierte Signatur ähnelt.
|
''' Looks up a localized string similar to Qualifizierte Signatur.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property QualifiedSignature() As String
|
Public Shared ReadOnly Property QualifiedSignature() As String
|
||||||
Get
|
Get
|
||||||
@@ -353,7 +443,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Arbeitsanweisung ähnelt.
|
''' Looks up a localized string similar to Lesebestätigung.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property ReadAndSign() As String
|
Public Shared ReadOnly Property ReadAndSign() As String
|
||||||
Get
|
Get
|
||||||
@@ -362,7 +452,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren! ähnelt.
|
''' Looks up a localized string similar to Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property ResetTOTPUser() As String
|
Public Shared ReadOnly Property ResetTOTPUser() As String
|
||||||
Get
|
Get
|
||||||
@@ -371,7 +461,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Gespeichert ähnelt.
|
''' Looks up a localized string similar to Gespeichert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Saved() As String
|
Public Shared ReadOnly Property Saved() As String
|
||||||
Get
|
Get
|
||||||
@@ -380,7 +470,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Gesendet ähnelt.
|
''' Looks up a localized string similar to Gesendet.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Sent() As String
|
Public Shared ReadOnly Property Sent() As String
|
||||||
Get
|
Get
|
||||||
@@ -389,7 +479,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Signatur ähnelt.
|
''' Looks up a localized string similar to Signatur.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Signature() As String
|
Public Shared ReadOnly Property Signature() As String
|
||||||
Get
|
Get
|
||||||
@@ -398,7 +488,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Signatur bestätigt ähnelt.
|
''' Looks up a localized string similar to Abschluss bestätigt.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property SignatureConfirmed() As String
|
Public Shared ReadOnly Property SignatureConfirmed() As String
|
||||||
Get
|
Get
|
||||||
@@ -407,7 +497,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Signiert ähnelt.
|
''' Looks up a localized string similar to Signiert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Signed() As String
|
Public Shared ReadOnly Property Signed() As String
|
||||||
Get
|
Get
|
||||||
@@ -416,7 +506,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Erfolgreich! Dialog wird geschlossen. ähnelt.
|
''' Looks up a localized string similar to Erfolgreich! Dialog wird geschlossen..
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Success_FormClose() As String
|
Public Shared ReadOnly Property Success_FormClose() As String
|
||||||
Get
|
Get
|
||||||
@@ -425,7 +515,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Unsigniert ähnelt.
|
''' Looks up a localized string similar to Unsigniert.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Unsigned() As String
|
Public Shared ReadOnly Property Unsigned() As String
|
||||||
Get
|
Get
|
||||||
@@ -434,7 +524,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Ja ähnelt.
|
''' Looks up a localized string similar to Ja.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property Yes() As String
|
Public Shared ReadOnly Property Yes() As String
|
||||||
Get
|
Get
|
||||||
@@ -443,7 +533,7 @@ Namespace My.Resources
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Sucht eine lokalisierte Zeichenfolge, die Ja, mit Anhang ähnelt.
|
''' Looks up a localized string similar to Ja, mit Anhang.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
Public Shared ReadOnly Property YesWithAttachment() As String
|
Public Shared ReadOnly Property YesWithAttachment() As String
|
||||||
Get
|
Get
|
||||||
|
|||||||
@@ -132,12 +132,27 @@
|
|||||||
<data name="Completed" xml:space="preserve">
|
<data name="Completed" xml:space="preserve">
|
||||||
<value>Completed</value>
|
<value>Completed</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Completely confirmed</value>
|
||||||
|
</data>
|
||||||
|
<data name="CompletelySigned" xml:space="preserve">
|
||||||
|
<value>Completely signed</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmation" xml:space="preserve">
|
||||||
|
<value>Read Confirmation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmed" xml:space="preserve">
|
||||||
|
<value>Read and signed</value>
|
||||||
|
</data>
|
||||||
<data name="Contract" xml:space="preserve">
|
<data name="Contract" xml:space="preserve">
|
||||||
<value>Contract</value>
|
<value>Contract</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Created" xml:space="preserve">
|
<data name="Created" xml:space="preserve">
|
||||||
<value>Created</value>
|
<value>Created</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentConfirmed" xml:space="preserve">
|
||||||
|
<value>Document read and confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentMod_Rotation" xml:space="preserve">
|
<data name="DocumentMod_Rotation" xml:space="preserve">
|
||||||
<value>Document rotation adapted</value>
|
<value>Document rotation adapted</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -147,6 +162,9 @@
|
|||||||
<data name="DocumentRejected" xml:space="preserve">
|
<data name="DocumentRejected" xml:space="preserve">
|
||||||
<value>Signing rejected</value>
|
<value>Signing rejected</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentRejectedRaC" xml:space="preserve">
|
||||||
|
<value>Read confirmation rejected</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentSigned" xml:space="preserve">
|
<data name="DocumentSigned" xml:space="preserve">
|
||||||
<value>Document signed</value>
|
<value>Document signed</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -156,6 +174,9 @@
|
|||||||
<data name="EnvelopeArchived" xml:space="preserve">
|
<data name="EnvelopeArchived" xml:space="preserve">
|
||||||
<value>Archived</value>
|
<value>Archived</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeCompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Completely confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
||||||
<value>Completely signed</value>
|
<value>Completely signed</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -165,8 +186,11 @@
|
|||||||
<data name="EnvelopeDeleted" xml:space="preserve">
|
<data name="EnvelopeDeleted" xml:space="preserve">
|
||||||
<value>Envelope Deleted</value>
|
<value>Envelope Deleted</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopePartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Partially confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopePartlySigned" xml:space="preserve">
|
<data name="EnvelopePartlySigned" xml:space="preserve">
|
||||||
<value>Partly signed</value>
|
<value>Partially signed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EnvelopeQueued" xml:space="preserve">
|
<data name="EnvelopeQueued" xml:space="preserve">
|
||||||
<value>Envelope Queued</value>
|
<value>Envelope Queued</value>
|
||||||
@@ -177,6 +201,9 @@
|
|||||||
<data name="EnvelopeReportCreated" xml:space="preserve">
|
<data name="EnvelopeReportCreated" xml:space="preserve">
|
||||||
<value>Signature certificate created</value>
|
<value>Signature certificate created</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeReportCreatedRaC" xml:space="preserve">
|
||||||
|
<value>Read Confirmation Certificate Created</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeSaved" xml:space="preserve">
|
<data name="EnvelopeSaved" xml:space="preserve">
|
||||||
<value>Saved</value>
|
<value>Saved</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -195,6 +222,9 @@
|
|||||||
<data name="MessageConfirmationSent" xml:space="preserve">
|
<data name="MessageConfirmationSent" xml:space="preserve">
|
||||||
<value>Confirmation Sent</value>
|
<value>Confirmation Sent</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MessageConfirmationSentRaC" xml:space="preserve">
|
||||||
|
<value>Read Confirmation Sent</value>
|
||||||
|
</data>
|
||||||
<data name="MessageDeletionSent" xml:space="preserve">
|
<data name="MessageDeletionSent" xml:space="preserve">
|
||||||
<value>Deletion Notice Sent</value>
|
<value>Deletion Notice Sent</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -204,6 +234,12 @@
|
|||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>No</value>
|
<value>No</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Partially confirmed</value>
|
||||||
|
</data>
|
||||||
|
<data name="PartlySigned" xml:space="preserve">
|
||||||
|
<value>Partially signed</value>
|
||||||
|
</data>
|
||||||
<data name="QualifiedSignature" xml:space="preserve">
|
<data name="QualifiedSignature" xml:space="preserve">
|
||||||
<value>Qualified Signature</value>
|
<value>Qualified Signature</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -223,7 +259,7 @@
|
|||||||
<value>Signature</value>
|
<value>Signature</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SignatureConfirmed" xml:space="preserve">
|
<data name="SignatureConfirmed" xml:space="preserve">
|
||||||
<value>Signature confirmed</value>
|
<value>Finalization confirmed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Signed" xml:space="preserve">
|
<data name="Signed" xml:space="preserve">
|
||||||
<value>Signed</value>
|
<value>Signed</value>
|
||||||
|
|||||||
@@ -132,8 +132,17 @@
|
|||||||
<data name="Completed" xml:space="preserve">
|
<data name="Completed" xml:space="preserve">
|
||||||
<value>Abgeschlossen</value>
|
<value>Abgeschlossen</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Vollständig bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="CompletelySigned" xml:space="preserve">
|
<data name="CompletelySigned" xml:space="preserve">
|
||||||
<value>Vollständig Signiert</value>
|
<value>Vollständig signiert</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmation" xml:space="preserve">
|
||||||
|
<value>Lesebestätigung</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmed" xml:space="preserve">
|
||||||
|
<value>Gelesen und Bestätigt</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Contract" xml:space="preserve">
|
<data name="Contract" xml:space="preserve">
|
||||||
<value>Vertrag</value>
|
<value>Vertrag</value>
|
||||||
@@ -141,6 +150,9 @@
|
|||||||
<data name="Created" xml:space="preserve">
|
<data name="Created" xml:space="preserve">
|
||||||
<value>Erstellt</value>
|
<value>Erstellt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentConfirmed" xml:space="preserve">
|
||||||
|
<value>Dokument gelesen und bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentMod_Rotation" xml:space="preserve">
|
<data name="DocumentMod_Rotation" xml:space="preserve">
|
||||||
<value>Dokument Rotation geändert</value>
|
<value>Dokument Rotation geändert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -150,6 +162,9 @@
|
|||||||
<data name="DocumentRejected" xml:space="preserve">
|
<data name="DocumentRejected" xml:space="preserve">
|
||||||
<value>Unterzeichnung abgelehnt</value>
|
<value>Unterzeichnung abgelehnt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentRejectedRaC" xml:space="preserve">
|
||||||
|
<value>Lesebestätigung abgelehnt</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentSigned" xml:space="preserve">
|
<data name="DocumentSigned" xml:space="preserve">
|
||||||
<value>Dokument unterzeichnet</value>
|
<value>Dokument unterzeichnet</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -159,6 +174,9 @@
|
|||||||
<data name="EnvelopeArchived" xml:space="preserve">
|
<data name="EnvelopeArchived" xml:space="preserve">
|
||||||
<value>Archiviert</value>
|
<value>Archiviert</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeCompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Vollständig bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
||||||
<value>Vollständig signiert</value>
|
<value>Vollständig signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -168,6 +186,9 @@
|
|||||||
<data name="EnvelopeDeleted" xml:space="preserve">
|
<data name="EnvelopeDeleted" xml:space="preserve">
|
||||||
<value>Umschlag Gelöscht</value>
|
<value>Umschlag Gelöscht</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopePartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Teil-Bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopePartlySigned" xml:space="preserve">
|
<data name="EnvelopePartlySigned" xml:space="preserve">
|
||||||
<value>Teil-Signiert</value>
|
<value>Teil-Signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -180,6 +201,9 @@
|
|||||||
<data name="EnvelopeReportCreated" xml:space="preserve">
|
<data name="EnvelopeReportCreated" xml:space="preserve">
|
||||||
<value>Signierungszertifikat erstellt</value>
|
<value>Signierungszertifikat erstellt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeReportCreatedRaC" xml:space="preserve">
|
||||||
|
<value>Lesebestätigungszertifikat erstellt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeSaved" xml:space="preserve">
|
<data name="EnvelopeSaved" xml:space="preserve">
|
||||||
<value>Gespeichert</value>
|
<value>Gespeichert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -198,6 +222,9 @@
|
|||||||
<data name="MessageConfirmationSent" xml:space="preserve">
|
<data name="MessageConfirmationSent" xml:space="preserve">
|
||||||
<value>Signaturbestätigung versendet</value>
|
<value>Signaturbestätigung versendet</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MessageConfirmationSentRaC" xml:space="preserve">
|
||||||
|
<value>Lesebestätigung versendet</value>
|
||||||
|
</data>
|
||||||
<data name="MessageDeletionSent" xml:space="preserve">
|
<data name="MessageDeletionSent" xml:space="preserve">
|
||||||
<value>Löschinformation versendet</value>
|
<value>Löschinformation versendet</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -207,6 +234,9 @@
|
|||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>Nein</value>
|
<value>Nein</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Teil-Bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="PartlySigned" xml:space="preserve">
|
<data name="PartlySigned" xml:space="preserve">
|
||||||
<value>Teil-Signiert</value>
|
<value>Teil-Signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -214,7 +244,7 @@
|
|||||||
<value>Qualifizierte Signatur</value>
|
<value>Qualifizierte Signatur</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ReadAndSign" xml:space="preserve">
|
<data name="ReadAndSign" xml:space="preserve">
|
||||||
<value>Arbeitsanweisung</value>
|
<value>Lesebestätigung</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ResetTOTPUser" xml:space="preserve">
|
<data name="ResetTOTPUser" xml:space="preserve">
|
||||||
<value>Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!</value>
|
<value>Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!</value>
|
||||||
@@ -229,7 +259,7 @@
|
|||||||
<value>Signatur</value>
|
<value>Signatur</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SignatureConfirmed" xml:space="preserve">
|
<data name="SignatureConfirmed" xml:space="preserve">
|
||||||
<value>Signatur bestätigt</value>
|
<value>Abschluss bestätigt</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Signed" xml:space="preserve">
|
<data name="Signed" xml:space="preserve">
|
||||||
<value>Signiert</value>
|
<value>Signiert</value>
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ namespace EnvelopeGenerator.Domain.Entities
|
|||||||
[Column("STATUS")]
|
[Column("STATUS")]
|
||||||
public Constants.DocumentStatus Status { get; set; }
|
public Constants.DocumentStatus Status { get; set; }
|
||||||
|
|
||||||
|
[Column("STATUS_CHANGED_WHEN", TypeName = "datetime")]
|
||||||
|
public DateTime? StatusChangedWhen { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||||
public DateTime AddedWhen { get; set; }
|
public DateTime AddedWhen { get; set; }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
using EnvelopeGenerator.Domain.Constants;
|
using EnvelopeGenerator.Domain.Constants;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||||
|
using EnvelopeGenerator.Domain.Interfaces;
|
||||||
#if NETFRAMEWORK
|
#if NETFRAMEWORK
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -13,7 +14,7 @@ using System.Linq;
|
|||||||
namespace EnvelopeGenerator.Domain.Entities
|
namespace EnvelopeGenerator.Domain.Entities
|
||||||
{
|
{
|
||||||
[Table("TBSIG_ENVELOPE", Schema = "dbo")]
|
[Table("TBSIG_ENVELOPE", Schema = "dbo")]
|
||||||
public class Envelope : IHasAddedWhen, IHasChangedWhen
|
public class Envelope : IHasAddedWhen, IHasChangedWhen, IEnvelope
|
||||||
{
|
{
|
||||||
public Envelope()
|
public Envelope()
|
||||||
{
|
{
|
||||||
@@ -106,7 +107,8 @@ namespace EnvelopeGenerator.Domain.Entities
|
|||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool ReadOnly => EnvelopeTypeId == 2;
|
[Obsolete("Use EnvelopeGenerator.Domain.Interfaces.EnvelopeExtensions.IsReadAndConfirm extension method instead.")]
|
||||||
|
public bool ReadOnly => this.IsReadAndConfirm();
|
||||||
|
|
||||||
[Column("CERTIFICATION_TYPE")]
|
[Column("CERTIFICATION_TYPE")]
|
||||||
public int? CertificationType { get; set; }
|
public int? CertificationType { get; set; }
|
||||||
|
|||||||
@@ -35,8 +35,11 @@ namespace EnvelopeGenerator.Domain.Entities
|
|||||||
public DateTime AddedWhen { get; set; }
|
public DateTime AddedWhen { get; set; }
|
||||||
|
|
||||||
[Column("ACTION_DATE", TypeName = "datetime")]
|
[Column("ACTION_DATE", TypeName = "datetime")]
|
||||||
public DateTime? ChangedWhen { get; set; }
|
public DateTime? ActionDate { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime? ChangedWhen { get => ActionDate; set => ActionDate = value; }
|
||||||
|
|
||||||
[Column("COMMENT", TypeName = "nvarchar(max)")]
|
[Column("COMMENT", TypeName = "nvarchar(max)")]
|
||||||
public string
|
public string
|
||||||
#if nullable
|
#if nullable
|
||||||
|
|||||||
20
EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs
Normal file
20
EnvelopeGenerator.Domain/Interfaces/IEnvelope.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsReadAndSign(this IEnvelope envelope)
|
||||||
|
{
|
||||||
|
return envelope.EnvelopeTypeId != 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
200
EnvelopeGenerator.Domain/Resources/Model.Designer.cs
generated
200
EnvelopeGenerator.Domain/Resources/Model.Designer.cs
generated
@@ -1,10 +1,10 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// Dieser Code wurde von einem Tool generiert.
|
// This code was generated by a tool.
|
||||||
// Laufzeitversion:4.0.30319.42000
|
// Runtime Version:4.0.30319.42000
|
||||||
//
|
//
|
||||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// der Code erneut generiert wird.
|
// the code is regenerated.
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -13,12 +13,12 @@ namespace My.Resources {
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
@@ -33,7 +33,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
public static global::System.Resources.ResourceManager ResourceManager {
|
public static global::System.Resources.ResourceManager ResourceManager {
|
||||||
@@ -47,8 +47,8 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
/// resource lookups using this strongly typed resource class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
public static global::System.Globalization.CultureInfo Culture {
|
public static global::System.Globalization.CultureInfo Culture {
|
||||||
@@ -61,7 +61,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Zugriffscode korrekt eingegeben ähnelt.
|
/// Looks up a localized string similar to Zugriffscode korrekt eingegeben.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string AccessCodeCorrect {
|
public static string AccessCodeCorrect {
|
||||||
get {
|
get {
|
||||||
@@ -70,7 +70,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Zugriffscode falsch eingegeben ähnelt.
|
/// Looks up a localized string similar to Zugriffscode falsch eingegeben.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string AccessCodeIncorrect {
|
public static string AccessCodeIncorrect {
|
||||||
get {
|
get {
|
||||||
@@ -79,7 +79,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Zugriffscode angefordert ähnelt.
|
/// Looks up a localized string similar to Zugriffscode angefordert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string AccessCodeRequested {
|
public static string AccessCodeRequested {
|
||||||
get {
|
get {
|
||||||
@@ -88,7 +88,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Fortgeschrittene Elektronische Signatur ähnelt.
|
/// Looks up a localized string similar to Fortgeschrittene Elektronische Signatur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string AdvancedElectronicSignature {
|
public static string AdvancedElectronicSignature {
|
||||||
get {
|
get {
|
||||||
@@ -97,7 +97,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Abgeschlossen ähnelt.
|
/// Looks up a localized string similar to Abgeschlossen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Completed {
|
public static string Completed {
|
||||||
get {
|
get {
|
||||||
@@ -106,7 +106,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Vollständig Signiert ähnelt.
|
/// Looks up a localized string similar to Vollständig bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string CompletelyConfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("CompletelyConfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Vollständig signiert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CompletelySigned {
|
public static string CompletelySigned {
|
||||||
get {
|
get {
|
||||||
@@ -115,7 +124,25 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Vertrag ähnelt.
|
/// Looks up a localized string similar to Lesebestätigung.
|
||||||
|
/// </summary>
|
||||||
|
public static string Confirmation {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Confirmation", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Gelesen und bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string Confirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Confirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Vertrag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Contract {
|
public static string Contract {
|
||||||
get {
|
get {
|
||||||
@@ -124,7 +151,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Erstellt ähnelt.
|
/// Looks up a localized string similar to Erstellt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Created {
|
public static string Created {
|
||||||
get {
|
get {
|
||||||
@@ -133,7 +160,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Dokument Rotation geändert ähnelt.
|
/// Looks up a localized string similar to Dokument gelesen und bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string DocumentConfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("DocumentConfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Dokument Rotation geändert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string DocumentMod_Rotation {
|
public static string DocumentMod_Rotation {
|
||||||
get {
|
get {
|
||||||
@@ -142,7 +178,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Dokument geöffnet ähnelt.
|
/// Looks up a localized string similar to Dokument geöffnet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string DocumentOpened {
|
public static string DocumentOpened {
|
||||||
get {
|
get {
|
||||||
@@ -151,7 +187,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Unterzeichnung abgelehnt ähnelt.
|
/// Looks up a localized string similar to Unterzeichnung abgelehnt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string DocumentRejected {
|
public static string DocumentRejected {
|
||||||
get {
|
get {
|
||||||
@@ -160,7 +196,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Dokument unterzeichnet ähnelt.
|
/// Looks up a localized string similar to Lesebestätigung abgelehnt.
|
||||||
|
/// </summary>
|
||||||
|
public static string DocumentRejectedRaC {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("DocumentRejectedRaC", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Dokument unterzeichnet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string DocumentSigned {
|
public static string DocumentSigned {
|
||||||
get {
|
get {
|
||||||
@@ -169,7 +214,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Entwurf ähnelt.
|
/// Looks up a localized string similar to Entwurf.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Draft {
|
public static string Draft {
|
||||||
get {
|
get {
|
||||||
@@ -178,7 +223,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Archiviert ähnelt.
|
/// Looks up a localized string similar to Archiviert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeArchived {
|
public static string EnvelopeArchived {
|
||||||
get {
|
get {
|
||||||
@@ -187,7 +232,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Vollständig signiert ähnelt.
|
/// Looks up a localized string similar to Vollständig gelesen und bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string EnvelopeCompletelyConfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("EnvelopeCompletelyConfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Vollständig signiert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeCompletelySigned {
|
public static string EnvelopeCompletelySigned {
|
||||||
get {
|
get {
|
||||||
@@ -196,7 +250,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Umschlag Erstellt ähnelt.
|
/// Looks up a localized string similar to Umschlag Erstellt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeCreated {
|
public static string EnvelopeCreated {
|
||||||
get {
|
get {
|
||||||
@@ -205,7 +259,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Umschlag Gelöscht ähnelt.
|
/// Looks up a localized string similar to Umschlag Gelöscht.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeDeleted {
|
public static string EnvelopeDeleted {
|
||||||
get {
|
get {
|
||||||
@@ -214,7 +268,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Teil-Signiert ähnelt.
|
/// Looks up a localized string similar to Teil-Bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string EnvelopePartlyConfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("EnvelopePartlyConfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Teil-Signiert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopePartlySigned {
|
public static string EnvelopePartlySigned {
|
||||||
get {
|
get {
|
||||||
@@ -223,7 +286,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Umschlag in Queue ähnelt.
|
/// Looks up a localized string similar to Umschlag in Queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeQueued {
|
public static string EnvelopeQueued {
|
||||||
get {
|
get {
|
||||||
@@ -232,7 +295,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Umschlag abgelehnt ähnelt.
|
/// Looks up a localized string similar to Umschlag abgelehnt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeRejected {
|
public static string EnvelopeRejected {
|
||||||
get {
|
get {
|
||||||
@@ -241,7 +304,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Signierungszertifikat erstellt ähnelt.
|
/// Looks up a localized string similar to Signierungszertifikat erstellt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeReportCreated {
|
public static string EnvelopeReportCreated {
|
||||||
get {
|
get {
|
||||||
@@ -250,7 +313,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Gespeichert ähnelt.
|
/// Looks up a localized string similar to Lesebestätigungszertifikat erstellt.
|
||||||
|
/// </summary>
|
||||||
|
public static string EnvelopeReportCreatedRaC {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("EnvelopeReportCreatedRaC", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Gespeichert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeSaved {
|
public static string EnvelopeSaved {
|
||||||
get {
|
get {
|
||||||
@@ -259,7 +331,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Gesendet ähnelt.
|
/// Looks up a localized string similar to Gesendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeSent {
|
public static string EnvelopeSent {
|
||||||
get {
|
get {
|
||||||
@@ -268,7 +340,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Umschlag zurückgezogen ähnelt.
|
/// Looks up a localized string similar to Umschlag zurückgezogen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string EnvelopeWithdrawn {
|
public static string EnvelopeWithdrawn {
|
||||||
get {
|
get {
|
||||||
@@ -277,7 +349,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Zugriffscode versendet ähnelt.
|
/// Looks up a localized string similar to Zugriffscode versendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessageAccessCodeSent {
|
public static string MessageAccessCodeSent {
|
||||||
get {
|
get {
|
||||||
@@ -286,7 +358,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Abschlussemail versendet ähnelt.
|
/// Looks up a localized string similar to Abschlussemail versendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessageCompletionSent {
|
public static string MessageCompletionSent {
|
||||||
get {
|
get {
|
||||||
@@ -295,7 +367,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Signaturbestätigung versendet ähnelt.
|
/// Looks up a localized string similar to Abschlussbestätigung versendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessageConfirmationSent {
|
public static string MessageConfirmationSent {
|
||||||
get {
|
get {
|
||||||
@@ -304,7 +376,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Löschinformation versendet ähnelt.
|
/// Looks up a localized string similar to Löschinformation versendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessageDeletionSent {
|
public static string MessageDeletionSent {
|
||||||
get {
|
get {
|
||||||
@@ -313,7 +385,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Dokumentenlink versendet ähnelt.
|
/// Looks up a localized string similar to Dokumentenlink versendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessageInvitationSent {
|
public static string MessageInvitationSent {
|
||||||
get {
|
get {
|
||||||
@@ -322,7 +394,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Nein ähnelt.
|
/// Looks up a localized string similar to Nein.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string No {
|
public static string No {
|
||||||
get {
|
get {
|
||||||
@@ -331,7 +403,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Teil-Signiert ähnelt.
|
/// Looks up a localized string similar to Teil-Bestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string PartlyConfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("PartlyConfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Teil-Signiert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string PartlySigned {
|
public static string PartlySigned {
|
||||||
get {
|
get {
|
||||||
@@ -340,7 +421,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Qualifizierte Signatur ähnelt.
|
/// Looks up a localized string similar to Qualifizierte Signatur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string QualifiedSignature {
|
public static string QualifiedSignature {
|
||||||
get {
|
get {
|
||||||
@@ -349,7 +430,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Arbeitsanweisung ähnelt.
|
/// Looks up a localized string similar to Lesebestätigung.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ReadAndSign {
|
public static string ReadAndSign {
|
||||||
get {
|
get {
|
||||||
@@ -358,7 +439,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren! ähnelt.
|
/// Looks up a localized string similar to Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ResetTOTPUser {
|
public static string ResetTOTPUser {
|
||||||
get {
|
get {
|
||||||
@@ -367,7 +448,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Gespeichert ähnelt.
|
/// Looks up a localized string similar to Gespeichert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Saved {
|
public static string Saved {
|
||||||
get {
|
get {
|
||||||
@@ -376,7 +457,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Gesendet ähnelt.
|
/// Looks up a localized string similar to Gesendet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Sent {
|
public static string Sent {
|
||||||
get {
|
get {
|
||||||
@@ -385,7 +466,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Signatur ähnelt.
|
/// Looks up a localized string similar to Signatur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Signature {
|
public static string Signature {
|
||||||
get {
|
get {
|
||||||
@@ -394,7 +475,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Signatur bestätigt ähnelt.
|
/// Looks up a localized string similar to Abschluss bestätigt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string SignatureConfirmed {
|
public static string SignatureConfirmed {
|
||||||
get {
|
get {
|
||||||
@@ -403,7 +484,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Signiert ähnelt.
|
/// Looks up a localized string similar to Signiert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Signed {
|
public static string Signed {
|
||||||
get {
|
get {
|
||||||
@@ -412,7 +493,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Erfolgreich! Dialog wird geschlossen. ähnelt.
|
/// Looks up a localized string similar to Erfolgreich! Dialog wird geschlossen..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Success_FormClose {
|
public static string Success_FormClose {
|
||||||
get {
|
get {
|
||||||
@@ -421,7 +502,16 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Unsigniert ähnelt.
|
/// Looks up a localized string similar to Unbestätigt.
|
||||||
|
/// </summary>
|
||||||
|
public static string Unconfirmed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Unconfirmed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Unsigniert.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Unsigned {
|
public static string Unsigned {
|
||||||
get {
|
get {
|
||||||
@@ -430,7 +520,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Ja ähnelt.
|
/// Looks up a localized string similar to Ja.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Yes {
|
public static string Yes {
|
||||||
get {
|
get {
|
||||||
@@ -439,7 +529,7 @@ namespace My.Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sucht eine lokalisierte Zeichenfolge, die Ja, mit Anhang ähnelt.
|
/// Looks up a localized string similar to Ja, mit Anhang.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string YesWithAttachment {
|
public static string YesWithAttachment {
|
||||||
get {
|
get {
|
||||||
|
|||||||
@@ -132,15 +132,27 @@
|
|||||||
<data name="Completed" xml:space="preserve">
|
<data name="Completed" xml:space="preserve">
|
||||||
<value>Completed</value>
|
<value>Completed</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Completely confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="CompletelySigned" xml:space="preserve">
|
<data name="CompletelySigned" xml:space="preserve">
|
||||||
<value>Completely signed</value>
|
<value>Completely signed</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Confirmation" xml:space="preserve">
|
||||||
|
<value>Read Confirmation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmed" xml:space="preserve">
|
||||||
|
<value>Read and signed</value>
|
||||||
|
</data>
|
||||||
<data name="Contract" xml:space="preserve">
|
<data name="Contract" xml:space="preserve">
|
||||||
<value>Contract</value>
|
<value>Contract</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Created" xml:space="preserve">
|
<data name="Created" xml:space="preserve">
|
||||||
<value>Created</value>
|
<value>Created</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentConfirmed" xml:space="preserve">
|
||||||
|
<value>Document read and signed</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentMod_Rotation" xml:space="preserve">
|
<data name="DocumentMod_Rotation" xml:space="preserve">
|
||||||
<value>Document rotation adapted</value>
|
<value>Document rotation adapted</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -150,6 +162,9 @@
|
|||||||
<data name="DocumentRejected" xml:space="preserve">
|
<data name="DocumentRejected" xml:space="preserve">
|
||||||
<value>Signing rejected</value>
|
<value>Signing rejected</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentRejectedRaC" xml:space="preserve">
|
||||||
|
<value>Read confirmation rejected</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentSigned" xml:space="preserve">
|
<data name="DocumentSigned" xml:space="preserve">
|
||||||
<value>Document signed</value>
|
<value>Document signed</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -159,6 +174,9 @@
|
|||||||
<data name="EnvelopeArchived" xml:space="preserve">
|
<data name="EnvelopeArchived" xml:space="preserve">
|
||||||
<value>Archived</value>
|
<value>Archived</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeCompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Completely confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
||||||
<value>Completely signed</value>
|
<value>Completely signed</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -168,8 +186,11 @@
|
|||||||
<data name="EnvelopeDeleted" xml:space="preserve">
|
<data name="EnvelopeDeleted" xml:space="preserve">
|
||||||
<value>Envelope Deleted</value>
|
<value>Envelope Deleted</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopePartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Partially confirmed</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopePartlySigned" xml:space="preserve">
|
<data name="EnvelopePartlySigned" xml:space="preserve">
|
||||||
<value>Partly signed</value>
|
<value>Partially signed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EnvelopeQueued" xml:space="preserve">
|
<data name="EnvelopeQueued" xml:space="preserve">
|
||||||
<value>Envelope Queued</value>
|
<value>Envelope Queued</value>
|
||||||
@@ -180,6 +201,9 @@
|
|||||||
<data name="EnvelopeReportCreated" xml:space="preserve">
|
<data name="EnvelopeReportCreated" xml:space="preserve">
|
||||||
<value>Signature certificate created</value>
|
<value>Signature certificate created</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeReportCreatedRaC" xml:space="preserve">
|
||||||
|
<value>Read confirmartion certificate created</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeSaved" xml:space="preserve">
|
<data name="EnvelopeSaved" xml:space="preserve">
|
||||||
<value>Saved</value>
|
<value>Saved</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -196,7 +220,7 @@
|
|||||||
<value>Final email sent</value>
|
<value>Final email sent</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageConfirmationSent" xml:space="preserve">
|
<data name="MessageConfirmationSent" xml:space="preserve">
|
||||||
<value>Confirmation Sent</value>
|
<value>Finalization Confirmation Sent</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageDeletionSent" xml:space="preserve">
|
<data name="MessageDeletionSent" xml:space="preserve">
|
||||||
<value>Deletion Notice Sent</value>
|
<value>Deletion Notice Sent</value>
|
||||||
@@ -207,6 +231,12 @@
|
|||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>No</value>
|
<value>No</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Partially confirmed</value>
|
||||||
|
</data>
|
||||||
|
<data name="PartlySigned" xml:space="preserve">
|
||||||
|
<value>Partially signed</value>
|
||||||
|
</data>
|
||||||
<data name="QualifiedSignature" xml:space="preserve">
|
<data name="QualifiedSignature" xml:space="preserve">
|
||||||
<value>Qualified Signature</value>
|
<value>Qualified Signature</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -226,7 +256,7 @@
|
|||||||
<value>Signature</value>
|
<value>Signature</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SignatureConfirmed" xml:space="preserve">
|
<data name="SignatureConfirmed" xml:space="preserve">
|
||||||
<value>Signature confirmed</value>
|
<value>Finalization confirmed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Signed" xml:space="preserve">
|
<data name="Signed" xml:space="preserve">
|
||||||
<value>Signed</value>
|
<value>Signed</value>
|
||||||
@@ -234,6 +264,9 @@
|
|||||||
<data name="Success_FormClose" xml:space="preserve">
|
<data name="Success_FormClose" xml:space="preserve">
|
||||||
<value>Successful! Dialog is closed.successful! Dialog is closed.</value>
|
<value>Successful! Dialog is closed.successful! Dialog is closed.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Unconfirmed" xml:space="preserve">
|
||||||
|
<value>Unconfirmed</value>
|
||||||
|
</data>
|
||||||
<data name="Unsigned" xml:space="preserve">
|
<data name="Unsigned" xml:space="preserve">
|
||||||
<value>Unsigned</value>
|
<value>Unsigned</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -132,8 +132,17 @@
|
|||||||
<data name="Completed" xml:space="preserve">
|
<data name="Completed" xml:space="preserve">
|
||||||
<value>Abgeschlossen</value>
|
<value>Abgeschlossen</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Vollständig bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="CompletelySigned" xml:space="preserve">
|
<data name="CompletelySigned" xml:space="preserve">
|
||||||
<value>Vollständig Signiert</value>
|
<value>Vollständig signiert</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmation" xml:space="preserve">
|
||||||
|
<value>Lesebestätigung</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirmed" xml:space="preserve">
|
||||||
|
<value>Gelesen und bestätigt</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Contract" xml:space="preserve">
|
<data name="Contract" xml:space="preserve">
|
||||||
<value>Vertrag</value>
|
<value>Vertrag</value>
|
||||||
@@ -141,6 +150,9 @@
|
|||||||
<data name="Created" xml:space="preserve">
|
<data name="Created" xml:space="preserve">
|
||||||
<value>Erstellt</value>
|
<value>Erstellt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentConfirmed" xml:space="preserve">
|
||||||
|
<value>Dokument gelesen und bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentMod_Rotation" xml:space="preserve">
|
<data name="DocumentMod_Rotation" xml:space="preserve">
|
||||||
<value>Dokument Rotation geändert</value>
|
<value>Dokument Rotation geändert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -150,6 +162,9 @@
|
|||||||
<data name="DocumentRejected" xml:space="preserve">
|
<data name="DocumentRejected" xml:space="preserve">
|
||||||
<value>Unterzeichnung abgelehnt</value>
|
<value>Unterzeichnung abgelehnt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DocumentRejectedRaC" xml:space="preserve">
|
||||||
|
<value>Lesebestätigung abgelehnt</value>
|
||||||
|
</data>
|
||||||
<data name="DocumentSigned" xml:space="preserve">
|
<data name="DocumentSigned" xml:space="preserve">
|
||||||
<value>Dokument unterzeichnet</value>
|
<value>Dokument unterzeichnet</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -159,6 +174,9 @@
|
|||||||
<data name="EnvelopeArchived" xml:space="preserve">
|
<data name="EnvelopeArchived" xml:space="preserve">
|
||||||
<value>Archiviert</value>
|
<value>Archiviert</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeCompletelyConfirmed" xml:space="preserve">
|
||||||
|
<value>Vollständig gelesen und bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
<data name="EnvelopeCompletelySigned" xml:space="preserve">
|
||||||
<value>Vollständig signiert</value>
|
<value>Vollständig signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -168,6 +186,9 @@
|
|||||||
<data name="EnvelopeDeleted" xml:space="preserve">
|
<data name="EnvelopeDeleted" xml:space="preserve">
|
||||||
<value>Umschlag Gelöscht</value>
|
<value>Umschlag Gelöscht</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopePartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Teil-Bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopePartlySigned" xml:space="preserve">
|
<data name="EnvelopePartlySigned" xml:space="preserve">
|
||||||
<value>Teil-Signiert</value>
|
<value>Teil-Signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -180,6 +201,9 @@
|
|||||||
<data name="EnvelopeReportCreated" xml:space="preserve">
|
<data name="EnvelopeReportCreated" xml:space="preserve">
|
||||||
<value>Signierungszertifikat erstellt</value>
|
<value>Signierungszertifikat erstellt</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnvelopeReportCreatedRaC" xml:space="preserve">
|
||||||
|
<value>Lesebestätigungszertifikat erstellt</value>
|
||||||
|
</data>
|
||||||
<data name="EnvelopeSaved" xml:space="preserve">
|
<data name="EnvelopeSaved" xml:space="preserve">
|
||||||
<value>Gespeichert</value>
|
<value>Gespeichert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -196,7 +220,7 @@
|
|||||||
<value>Abschlussemail versendet</value>
|
<value>Abschlussemail versendet</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageConfirmationSent" xml:space="preserve">
|
<data name="MessageConfirmationSent" xml:space="preserve">
|
||||||
<value>Signaturbestätigung versendet</value>
|
<value>Abschlussbestätigung versendet</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageDeletionSent" xml:space="preserve">
|
<data name="MessageDeletionSent" xml:space="preserve">
|
||||||
<value>Löschinformation versendet</value>
|
<value>Löschinformation versendet</value>
|
||||||
@@ -207,6 +231,9 @@
|
|||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>Nein</value>
|
<value>Nein</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PartlyConfirmed" xml:space="preserve">
|
||||||
|
<value>Teil-Bestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="PartlySigned" xml:space="preserve">
|
<data name="PartlySigned" xml:space="preserve">
|
||||||
<value>Teil-Signiert</value>
|
<value>Teil-Signiert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -214,7 +241,7 @@
|
|||||||
<value>Qualifizierte Signatur</value>
|
<value>Qualifizierte Signatur</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ReadAndSign" xml:space="preserve">
|
<data name="ReadAndSign" xml:space="preserve">
|
||||||
<value>Arbeitsanweisung</value>
|
<value>Lesebestätigung</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ResetTOTPUser" xml:space="preserve">
|
<data name="ResetTOTPUser" xml:space="preserve">
|
||||||
<value>Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!</value>
|
<value>Wollen Sie die 2-Faktor Definition für diesen Empfänger zurücksetzen. Der Empfänger muss sich dann neu identifizieren!</value>
|
||||||
@@ -229,7 +256,7 @@
|
|||||||
<value>Signatur</value>
|
<value>Signatur</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SignatureConfirmed" xml:space="preserve">
|
<data name="SignatureConfirmed" xml:space="preserve">
|
||||||
<value>Signatur bestätigt</value>
|
<value>Abschluss bestätigt</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Signed" xml:space="preserve">
|
<data name="Signed" xml:space="preserve">
|
||||||
<value>Signiert</value>
|
<value>Signiert</value>
|
||||||
@@ -237,6 +264,9 @@
|
|||||||
<data name="Success_FormClose" xml:space="preserve">
|
<data name="Success_FormClose" xml:space="preserve">
|
||||||
<value>Erfolgreich! Dialog wird geschlossen.</value>
|
<value>Erfolgreich! Dialog wird geschlossen.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Unconfirmed" xml:space="preserve">
|
||||||
|
<value>Unbestätigt</value>
|
||||||
|
</data>
|
||||||
<data name="Unsigned" xml:space="preserve">
|
<data name="Unsigned" xml:space="preserve">
|
||||||
<value>Unsigniert</value>
|
<value>Unsigniert</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.6.0" />
|
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.6.0" />
|
||||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.6.1" />
|
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.6.1" />
|
||||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.82.1" />
|
<PackageReference Include="Microsoft.Identity.Client" Version="4.82.1" />
|
||||||
<PackageReference Include="QuestPDF" Version="2025.7.1" />
|
<PackageReference Include="QuestPDF" Version="2025.7.1" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
|
|
||||||
<PackageReference Include="HtmlSanitizer" Version="9.0.892" />
|
|
||||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.82.1" />
|
|
||||||
<PackageReference Include="Quartz" Version="3.9.0" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
|
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
|
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.PdfEditor\EnvelopeGenerator.PdfEditor.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
|
||||||
using Quartz;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.APIBackendJobs;
|
|
||||||
|
|
||||||
public class APIEnvelopeJob(ILogger<APIEnvelopeJob>? logger = null) : IJob
|
|
||||||
{
|
|
||||||
private readonly ILogger<APIEnvelopeJob> _logger = logger ?? NullLogger<APIEnvelopeJob>.Instance;
|
|
||||||
|
|
||||||
public async Task Execute(IJobExecutionContext context)
|
|
||||||
{
|
|
||||||
var jobId = context.JobDetail.Key.ToString();
|
|
||||||
_logger.LogDebug("API Envelopes - Starting job {JobId}", jobId);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var connectionString = context.MergedJobDataMap.GetString(Value.DATABASE);
|
|
||||||
if (string.IsNullOrWhiteSpace(connectionString))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("API Envelopes - Connection string missing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await using var connection = new SqlConnection(connectionString);
|
|
||||||
await connection.OpenAsync(context.CancellationToken);
|
|
||||||
|
|
||||||
await ProcessInvitationsAsync(connection, context.CancellationToken);
|
|
||||||
await ProcessWithdrawnAsync(connection, context.CancellationToken);
|
|
||||||
|
|
||||||
_logger.LogDebug("API Envelopes - Completed job {JobId} successfully", jobId);
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "API Envelopes job failed");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_logger.LogDebug("API Envelopes execution for {JobId} ended", jobId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ProcessInvitationsAsync(SqlConnection connection, System.Threading.CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "SELECT GUID FROM TBSIG_ENVELOPE WHERE SOURCE = 'API' AND STATUS = 1003 ORDER BY GUID";
|
|
||||||
var envelopeIds = new List<int>();
|
|
||||||
|
|
||||||
await using (var command = new SqlCommand(sql, connection))
|
|
||||||
await using (var reader = await command.ExecuteReaderAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
while (await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
if (reader[0] is int id)
|
|
||||||
{
|
|
||||||
envelopeIds.Add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (envelopeIds.Count == 0)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("SendInvMail - No envelopes found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("SendInvMail - Found {Count} envelopes", envelopeIds.Count);
|
|
||||||
var total = envelopeIds.Count;
|
|
||||||
var current = 1;
|
|
||||||
|
|
||||||
foreach (var id in envelopeIds)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("SendInvMail - Processing Envelope {EnvelopeId} ({Current}/{Total})", id, current, total);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Placeholder for invitation email sending logic.
|
|
||||||
_logger.LogDebug("SendInvMail - Marking envelope {EnvelopeId} as queued", id);
|
|
||||||
const string updateSql = "UPDATE TBSIG_ENVELOPE SET CURRENT_WORK_APP = @App WHERE GUID = @Id";
|
|
||||||
await using var updateCommand = new SqlCommand(updateSql, connection);
|
|
||||||
updateCommand.Parameters.AddWithValue("@App", "signFLOW_API_EnvJob_InvMail");
|
|
||||||
updateCommand.Parameters.AddWithValue("@Id", id);
|
|
||||||
await updateCommand.ExecuteNonQueryAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "SendInvMail - Unhandled exception while working envelope {EnvelopeId}", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
current++;
|
|
||||||
_logger.LogInformation("SendInvMail - Envelope finalized");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ProcessWithdrawnAsync(SqlConnection connection, System.Threading.CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = @"SELECT ENV.GUID, REJ.COMMENT AS REJECTION_REASON FROM
|
|
||||||
(SELECT * FROM TBSIG_ENVELOPE WHERE STATUS = 1009 AND SOURCE = 'API') ENV INNER JOIN
|
|
||||||
(SELECT MAX(GUID) GUID, ENVELOPE_ID, MAX(ADDED_WHEN) ADDED_WHEN, MAX(ACTION_DATE) ACTION_DATE, COMMENT FROM TBSIG_ENVELOPE_HISTORY WHERE STATUS = 1009 GROUP BY ENVELOPE_ID, COMMENT ) REJ ON ENV.GUID = REJ.ENVELOPE_ID LEFT JOIN
|
|
||||||
(SELECT * FROM TBSIG_ENVELOPE_HISTORY WHERE STATUS = 3004 ) M_Send ON ENV.GUID = M_Send.ENVELOPE_ID
|
|
||||||
WHERE M_Send.GUID IS NULL";
|
|
||||||
|
|
||||||
var withdrawn = new List<(int EnvelopeId, string Reason)>();
|
|
||||||
await using (var command = new SqlCommand(sql, connection))
|
|
||||||
await using (var reader = await command.ExecuteReaderAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
while (await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
var id = reader.GetInt32(0);
|
|
||||||
var reason = reader.IsDBNull(1) ? string.Empty : reader.GetString(1);
|
|
||||||
withdrawn.Add((id, reason));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (withdrawn.Count == 0)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("WithdrawnEnv - No envelopes found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("WithdrawnEnv - Found {Count} envelopes", withdrawn.Count);
|
|
||||||
var total = withdrawn.Count;
|
|
||||||
var current = 1;
|
|
||||||
|
|
||||||
foreach (var (envelopeId, reason) in withdrawn)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("WithdrawnEnv - Processing Envelope {EnvelopeId} ({Current}/{Total})", envelopeId, current, total);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Log withdrawn mail trigger placeholder
|
|
||||||
const string insertHistory = "INSERT INTO TBSIG_ENVELOPE_HISTORY (ENVELOPE_ID, STATUS, USER_REFERENCE, ADDED_WHEN, ACTION_DATE, COMMENT) VALUES (@EnvelopeId, @Status, @UserReference, GETDATE(), GETDATE(), @Comment)";
|
|
||||||
await using var insertCommand = new SqlCommand(insertHistory, connection);
|
|
||||||
insertCommand.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
insertCommand.Parameters.AddWithValue("@Status", 3004);
|
|
||||||
insertCommand.Parameters.AddWithValue("@UserReference", "API");
|
|
||||||
insertCommand.Parameters.AddWithValue("@Comment", reason ?? string.Empty);
|
|
||||||
await insertCommand.ExecuteNonQueryAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "WithdrawnEnv - Unhandled exception while working envelope {EnvelopeId}", envelopeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
current++;
|
|
||||||
_logger.LogInformation("WithdrawnEnv - Envelope finalized");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Data;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs;
|
|
||||||
|
|
||||||
public static class DataRowExtensions
|
|
||||||
{
|
|
||||||
public static T? GetValueOrDefault<T>(this DataRow row, string columnName, T? defaultValue = default)
|
|
||||||
{
|
|
||||||
if (!row.Table.Columns.Contains(columnName))
|
|
||||||
{
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var value = row[columnName];
|
|
||||||
if (value == DBNull.Value)
|
|
||||||
{
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return (T)Convert.ChangeType(value, typeof(T));
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public static class FinalizeDocumentExceptions
|
|
||||||
{
|
|
||||||
public class MergeDocumentException : ApplicationException
|
|
||||||
{
|
|
||||||
public MergeDocumentException(string message) : base(message) { }
|
|
||||||
public MergeDocumentException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BurnAnnotationException : ApplicationException
|
|
||||||
{
|
|
||||||
public BurnAnnotationException(string message) : base(message) { }
|
|
||||||
public BurnAnnotationException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CreateReportException : ApplicationException
|
|
||||||
{
|
|
||||||
public CreateReportException(string message) : base(message) { }
|
|
||||||
public CreateReportException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExportDocumentException : ApplicationException
|
|
||||||
{
|
|
||||||
public ExportDocumentException(string message) : base(message) { }
|
|
||||||
public ExportDocumentException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Quartz;
|
|
||||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class FinalizeDocumentJob : IJob
|
|
||||||
{
|
|
||||||
private readonly ILogger<FinalizeDocumentJob> _logger;
|
|
||||||
private readonly PDFBurner _pdfBurner;
|
|
||||||
private readonly PDFMerger _pdfMerger;
|
|
||||||
private readonly ReportCreator _reportCreator;
|
|
||||||
|
|
||||||
private record ConfigSettings(string DocumentPath, string DocumentPathOrigin, string ExportPath);
|
|
||||||
|
|
||||||
public FinalizeDocumentJob(
|
|
||||||
ILogger<FinalizeDocumentJob> logger,
|
|
||||||
PDFBurner pdfBurner,
|
|
||||||
PDFMerger pdfMerger,
|
|
||||||
ReportCreator reportCreator)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_pdfBurner = pdfBurner;
|
|
||||||
_pdfMerger = pdfMerger;
|
|
||||||
_reportCreator = reportCreator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Execute(IJobExecutionContext context)
|
|
||||||
{
|
|
||||||
var jobId = context.JobDetail.Key.ToString();
|
|
||||||
_logger.LogDebug("Starting job {JobId}", jobId);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var connectionString = context.MergedJobDataMap.GetString(Value.DATABASE);
|
|
||||||
if (string.IsNullOrWhiteSpace(connectionString))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("FinalizeDocument - Connection string missing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await using var connection = new SqlConnection(connectionString);
|
|
||||||
await connection.OpenAsync(context.CancellationToken);
|
|
||||||
|
|
||||||
var config = await LoadConfigurationAsync(connection, context.CancellationToken);
|
|
||||||
var envelopes = await LoadCompletedEnvelopesAsync(connection, context.CancellationToken);
|
|
||||||
|
|
||||||
if (envelopes.Count == 0)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("No completed envelopes found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var total = envelopes.Count;
|
|
||||||
var current = 1;
|
|
||||||
|
|
||||||
foreach (var envelopeId in envelopes)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Finalizing Envelope {EnvelopeId} ({Current}/{Total})", envelopeId, current, total);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var envelopeData = await GetEnvelopeDataAsync(connection, envelopeId, context.CancellationToken);
|
|
||||||
if (envelopeData is null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Envelope data not found for {EnvelopeId}", envelopeId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = envelopeData.Value;
|
|
||||||
|
|
||||||
var envelope = new Envelope
|
|
||||||
{
|
|
||||||
Id = envelopeId,
|
|
||||||
Uuid = data.EnvelopeUuid ?? string.Empty,
|
|
||||||
Title = data.Title ?? string.Empty,
|
|
||||||
FinalEmailToCreator = (int)FinalEmailType.No,
|
|
||||||
FinalEmailToReceivers = (int)FinalEmailType.No
|
|
||||||
};
|
|
||||||
|
|
||||||
var burned = _pdfBurner.BurnAnnotsToPDF(data.DocumentBytes, data.AnnotationData, envelopeId);
|
|
||||||
var report = _reportCreator.CreateReport(connection, envelope);
|
|
||||||
var merged = _pdfMerger.MergeDocuments(burned, report);
|
|
||||||
|
|
||||||
var outputDirectory = Path.Combine(config.ExportPath, data.ParentFolderUid);
|
|
||||||
Directory.CreateDirectory(outputDirectory);
|
|
||||||
var outputPath = Path.Combine(outputDirectory, $"{envelope.Uuid}.pdf");
|
|
||||||
await File.WriteAllBytesAsync(outputPath, merged, context.CancellationToken);
|
|
||||||
|
|
||||||
await UpdateDocumentResultAsync(connection, envelopeId, merged, context.CancellationToken);
|
|
||||||
await ArchiveEnvelopeAsync(connection, envelopeId, context.CancellationToken);
|
|
||||||
}
|
|
||||||
catch (MergeDocumentException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Certificate Document job failed at merging documents");
|
|
||||||
}
|
|
||||||
catch (ExportDocumentException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Certificate Document job failed at exporting document");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Unhandled exception while working envelope {EnvelopeId}", envelopeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
current++;
|
|
||||||
_logger.LogInformation("Envelope {EnvelopeId} finalized", envelopeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogDebug("Completed job {JobId} successfully", jobId);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Certificate Document job failed");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Job execution for {JobId} ended", jobId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<ConfigSettings> LoadConfigurationAsync(SqlConnection connection, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "SELECT TOP 1 DOCUMENT_PATH, EXPORT_PATH FROM TBSIG_CONFIG";
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
|
||||||
if (await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
var documentPath = reader.IsDBNull(0) ? string.Empty : reader.GetString(0);
|
|
||||||
var exportPath = reader.IsDBNull(1) ? string.Empty : reader.GetString(1);
|
|
||||||
return new ConfigSettings(documentPath, documentPath, exportPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ConfigSettings(string.Empty, string.Empty, Path.GetTempPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<int>> LoadCompletedEnvelopesAsync(SqlConnection connection, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "SELECT GUID FROM TBSIG_ENVELOPE WHERE STATUS = @Status AND DATEDIFF(minute, CHANGED_WHEN, GETDATE()) >= 1 ORDER BY GUID";
|
|
||||||
var ids = new List<int>();
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@Status", (int)EnvelopeStatus.EnvelopeCompletelySigned);
|
|
||||||
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
|
||||||
while (await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
ids.Add(reader.GetInt32(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<(int EnvelopeId, string? EnvelopeUuid, string? Title, byte[] DocumentBytes, List<string> AnnotationData, string ParentFolderUid)?> GetEnvelopeDataAsync(SqlConnection connection, int envelopeId, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = @"SELECT T.GUID, T.ENVELOPE_UUID, T.TITLE, T2.FILEPATH, T2.BYTE_DATA FROM [dbo].[TBSIG_ENVELOPE] T
|
|
||||||
JOIN TBSIG_ENVELOPE_DOCUMENT T2 ON T.GUID = T2.ENVELOPE_ID
|
|
||||||
WHERE T.GUID = @EnvelopeId";
|
|
||||||
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
await using var reader = await command.ExecuteReaderAsync(CommandBehavior.SingleRow, cancellationToken);
|
|
||||||
if (!await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var envelopeUuid = reader.IsDBNull(1) ? string.Empty : reader.GetString(1);
|
|
||||||
var title = reader.IsDBNull(2) ? string.Empty : reader.GetString(2);
|
|
||||||
var filePath = reader.IsDBNull(3) ? string.Empty : reader.GetString(3);
|
|
||||||
var bytes = reader.IsDBNull(4) ? Array.Empty<byte>() : (byte[])reader[4];
|
|
||||||
await reader.CloseAsync();
|
|
||||||
|
|
||||||
if (bytes.Length == 0 && !string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
|
|
||||||
{
|
|
||||||
bytes = await File.ReadAllBytesAsync(filePath, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
var annotations = await GetAnnotationDataAsync(connection, envelopeId, cancellationToken);
|
|
||||||
|
|
||||||
var parentFolderUid = !string.IsNullOrWhiteSpace(filePath)
|
|
||||||
? Path.GetFileName(Path.GetDirectoryName(filePath) ?? string.Empty)
|
|
||||||
: envelopeUuid;
|
|
||||||
|
|
||||||
return (envelopeId, envelopeUuid, title, bytes, annotations, parentFolderUid ?? envelopeUuid ?? envelopeId.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<string>> GetAnnotationDataAsync(SqlConnection connection, int envelopeId, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "SELECT VALUE FROM TBSIG_DOCUMENT_STATUS WHERE ENVELOPE_ID = @EnvelopeId";
|
|
||||||
var result = new List<string>();
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
|
||||||
while (await reader.ReadAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
if (!reader.IsDBNull(0))
|
|
||||||
{
|
|
||||||
result.Add(reader.GetString(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task UpdateDocumentResultAsync(SqlConnection connection, int envelopeId, byte[] bytes, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "UPDATE TBSIG_ENVELOPE SET DOC_RESULT = @ImageData WHERE GUID = @EnvelopeId";
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@ImageData", bytes);
|
|
||||||
command.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
await command.ExecuteNonQueryAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task ArchiveEnvelopeAsync(SqlConnection connection, int envelopeId, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
const string sql = "UPDATE TBSIG_ENVELOPE SET STATUS = @Status, CHANGED_WHEN = GETDATE() WHERE GUID = @EnvelopeId";
|
|
||||||
await using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@Status", (int)EnvelopeStatus.EnvelopeArchived);
|
|
||||||
command.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
await command.ExecuteNonQueryAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
|
||||||
using iText.IO.Image;
|
|
||||||
using iText.Kernel.Colors;
|
|
||||||
using iText.Kernel.Pdf;
|
|
||||||
using iText.Kernel.Pdf.Canvas;
|
|
||||||
using iText.Layout;
|
|
||||||
using iText.Layout.Element;
|
|
||||||
using iText.Layout.Font;
|
|
||||||
using iText.Layout.Properties;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
|
||||||
using LayoutImage = iText.Layout.Element.Image;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class PDFBurner
|
|
||||||
{
|
|
||||||
private static readonly FontProvider FontProvider = CreateFontProvider();
|
|
||||||
private readonly ILogger<PDFBurner> _logger;
|
|
||||||
private readonly PDFBurnerParams _pdfBurnerParams;
|
|
||||||
|
|
||||||
public PDFBurner() : this(NullLogger<PDFBurner>.Instance, new PDFBurnerParams())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public PDFBurner(ILogger<PDFBurner> logger, PDFBurnerParams? pdfBurnerParams = null)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_pdfBurnerParams = pdfBurnerParams ?? new PDFBurnerParams();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] BurnAnnotsToPDF(byte[] sourceBuffer, IList<string> instantJsonList, int envelopeId)
|
|
||||||
{
|
|
||||||
if (sourceBuffer is null || sourceBuffer.Length == 0)
|
|
||||||
{
|
|
||||||
throw new BurnAnnotationException("Source document is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var inputStream = new MemoryStream(sourceBuffer);
|
|
||||||
using var outputStream = new MemoryStream();
|
|
||||||
using var reader = new PdfReader(inputStream);
|
|
||||||
using var writer = new PdfWriter(outputStream);
|
|
||||||
using var pdf = new PdfDocument(reader, writer);
|
|
||||||
|
|
||||||
foreach (var json in instantJsonList ?? Enumerable.Empty<string>())
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(json))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var annotationData = JsonConvert.DeserializeObject<AnnotationData>(json);
|
|
||||||
if (annotationData?.annotations is null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
annotationData.annotations.Reverse();
|
|
||||||
|
|
||||||
foreach (var annotation in annotationData.annotations)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (annotation.type)
|
|
||||||
{
|
|
||||||
case AnnotationType.Image:
|
|
||||||
AddImageAnnotation(pdf, annotation, annotationData.attachments);
|
|
||||||
break;
|
|
||||||
case AnnotationType.Ink:
|
|
||||||
AddInkAnnotation(pdf, annotation);
|
|
||||||
break;
|
|
||||||
case AnnotationType.Widget:
|
|
||||||
var formFieldValue = annotationData.formFieldValues?.FirstOrDefault(fv => fv.name == annotation.id);
|
|
||||||
if (formFieldValue is not null && !_pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value))
|
|
||||||
{
|
|
||||||
AddFormFieldValue(pdf, annotation, formFieldValue.value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Error applying annotation {AnnotationId} on envelope {EnvelopeId}", annotation.id, envelopeId);
|
|
||||||
throw new BurnAnnotationException("Adding annotation failed", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pdf.Close();
|
|
||||||
return outputStream.ToArray();
|
|
||||||
}
|
|
||||||
catch (BurnAnnotationException)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to burn annotations for envelope {EnvelopeId}", envelopeId);
|
|
||||||
throw new BurnAnnotationException("Annotations could not be burned", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddImageAnnotation(PdfDocument pdf, Annotation annotation, Dictionary<string, Attachment>? attachments)
|
|
||||||
{
|
|
||||||
if (attachments is null || string.IsNullOrWhiteSpace(annotation.imageAttachmentId) || !attachments.TryGetValue(annotation.imageAttachmentId, out var attachment))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var page = pdf.GetPage(annotation.pageIndex + 1);
|
|
||||||
var bounds = annotation.bbox.Select(ToInches).ToList();
|
|
||||||
var x = (float)bounds[0];
|
|
||||||
var y = (float)bounds[1];
|
|
||||||
var width = (float)bounds[2];
|
|
||||||
var height = (float)bounds[3];
|
|
||||||
|
|
||||||
var imageBytes = Convert.FromBase64String(attachment.binary);
|
|
||||||
var imageData = ImageDataFactory.Create(imageBytes);
|
|
||||||
var image = new LayoutImage(imageData)
|
|
||||||
.ScaleAbsolute(width, height)
|
|
||||||
.SetFixedPosition(annotation.pageIndex + 1, x, y);
|
|
||||||
|
|
||||||
using var canvas = new Canvas(new PdfCanvas(page), page.GetPageSize());
|
|
||||||
canvas.Add(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddInkAnnotation(PdfDocument pdf, Annotation annotation)
|
|
||||||
{
|
|
||||||
if (annotation.lines?.points is null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var page = pdf.GetPage(annotation.pageIndex + 1);
|
|
||||||
var canvas = new PdfCanvas(page);
|
|
||||||
var color = ParseColor(annotation.strokeColor);
|
|
||||||
canvas.SetStrokeColor(color);
|
|
||||||
canvas.SetLineWidth(1);
|
|
||||||
|
|
||||||
foreach (var segment in annotation.lines.points)
|
|
||||||
{
|
|
||||||
var first = true;
|
|
||||||
foreach (var point in segment)
|
|
||||||
{
|
|
||||||
var (px, py) = (ToInches(point[0]), ToInches(point[1]));
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
canvas.MoveTo(px, py);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
canvas.LineTo(px, py);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canvas.Stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FontProvider CreateFontProvider()
|
|
||||||
{
|
|
||||||
var provider = new FontProvider();
|
|
||||||
provider.AddStandardPdfFonts();
|
|
||||||
provider.AddSystemFonts();
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddFormFieldValue(PdfDocument pdf, Annotation annotation, string value)
|
|
||||||
{
|
|
||||||
var bounds = annotation.bbox.Select(ToInches).ToList();
|
|
||||||
var x = (float)bounds[0];
|
|
||||||
var y = (float)bounds[1];
|
|
||||||
var width = (float)bounds[2];
|
|
||||||
var height = (float)bounds[3];
|
|
||||||
|
|
||||||
var page = pdf.GetPage(annotation.pageIndex + 1);
|
|
||||||
var canvas = new Canvas(new PdfCanvas(page), page.GetPageSize());
|
|
||||||
canvas.SetProperty(Property.FONT_PROVIDER, FontProvider);
|
|
||||||
canvas.SetProperty(Property.FONT, FontProvider.GetFontSet());
|
|
||||||
|
|
||||||
var paragraph = new Paragraph(value)
|
|
||||||
.SetFontSize(_pdfBurnerParams.FontSize)
|
|
||||||
.SetFontColor(ColorConstants.BLACK)
|
|
||||||
.SetFontFamily(_pdfBurnerParams.FontName);
|
|
||||||
|
|
||||||
if (_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Italic))
|
|
||||||
{
|
|
||||||
paragraph.SetItalic();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Bold))
|
|
||||||
{
|
|
||||||
paragraph.SetBold();
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.ShowTextAligned(
|
|
||||||
paragraph,
|
|
||||||
x + (float)_pdfBurnerParams.TopMargin,
|
|
||||||
y + (float)_pdfBurnerParams.YOffset,
|
|
||||||
annotation.pageIndex + 1,
|
|
||||||
iText.Layout.Properties.TextAlignment.LEFT,
|
|
||||||
iText.Layout.Properties.VerticalAlignment.TOP,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DeviceRgb ParseColor(string? color)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(color))
|
|
||||||
{
|
|
||||||
return new DeviceRgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var drawingColor = ColorTranslator.FromHtml(color);
|
|
||||||
return new DeviceRgb(drawingColor.R, drawingColor.G, drawingColor.B);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return new DeviceRgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double ToInches(double value) => value / 72d;
|
|
||||||
private static double ToInches(float value) => value / 72d;
|
|
||||||
|
|
||||||
#region Model
|
|
||||||
private static class AnnotationType
|
|
||||||
{
|
|
||||||
public const string Image = "pspdfkit/image";
|
|
||||||
public const string Ink = "pspdfkit/ink";
|
|
||||||
public const string Widget = "pspdfkit/widget";
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class AnnotationData
|
|
||||||
{
|
|
||||||
public List<Annotation>? annotations { get; set; }
|
|
||||||
public Dictionary<string, Attachment>? attachments { get; set; }
|
|
||||||
public List<FormFieldValue>? formFieldValues { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class Annotation
|
|
||||||
{
|
|
||||||
public string id { get; set; } = string.Empty;
|
|
||||||
public List<double> bbox { get; set; } = new();
|
|
||||||
public string type { get; set; } = string.Empty;
|
|
||||||
public string imageAttachmentId { get; set; } = string.Empty;
|
|
||||||
public Lines? lines { get; set; }
|
|
||||||
public int pageIndex { get; set; }
|
|
||||||
public string strokeColor { get; set; } = string.Empty;
|
|
||||||
public string egName { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class Lines
|
|
||||||
{
|
|
||||||
public List<List<List<float>>> points { get; set; } = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class Attachment
|
|
||||||
{
|
|
||||||
public string binary { get; set; } = string.Empty;
|
|
||||||
public string contentType { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class FormFieldValue
|
|
||||||
{
|
|
||||||
public string name { get; set; } = string.Empty;
|
|
||||||
public string value { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class PDFBurnerParams
|
|
||||||
{
|
|
||||||
public List<string> IgnoredLabels { get; } = new() { "Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung" };
|
|
||||||
|
|
||||||
public double TopMargin { get; set; } = 0.1;
|
|
||||||
|
|
||||||
public double YOffset { get; set; } = -0.3;
|
|
||||||
|
|
||||||
public string FontName { get; set; } = "Arial";
|
|
||||||
|
|
||||||
public int FontSize { get; set; } = 8;
|
|
||||||
|
|
||||||
public FontStyle FontStyle { get; set; } = FontStyle.Italic;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using iText.Kernel.Pdf;
|
|
||||||
using iText.Kernel.Utils;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
|
||||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class PDFMerger
|
|
||||||
{
|
|
||||||
private readonly ILogger<PDFMerger> _logger;
|
|
||||||
|
|
||||||
public PDFMerger() : this(NullLogger<PDFMerger>.Instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public PDFMerger(ILogger<PDFMerger> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] MergeDocuments(byte[] document, byte[] report)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var finalStream = new MemoryStream();
|
|
||||||
using var documentReader = new PdfReader(new MemoryStream(document));
|
|
||||||
using var reportReader = new PdfReader(new MemoryStream(report));
|
|
||||||
using var writer = new PdfWriter(finalStream);
|
|
||||||
using var targetDoc = new PdfDocument(documentReader, writer);
|
|
||||||
using var reportDoc = new PdfDocument(reportReader);
|
|
||||||
|
|
||||||
var merger = new PdfMerger(targetDoc);
|
|
||||||
merger.Merge(reportDoc, 1, reportDoc.GetNumberOfPages());
|
|
||||||
|
|
||||||
targetDoc.Close();
|
|
||||||
return finalStream.ToArray();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to merge PDF documents");
|
|
||||||
throw new MergeDocumentException("Documents could not be merged", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
using System.Data;
|
|
||||||
using System.IO;
|
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
|
||||||
using iText.Kernel.Pdf;
|
|
||||||
using iText.Layout.Element;
|
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
|
||||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
|
||||||
using LayoutDocument = iText.Layout.Document;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class ReportCreator
|
|
||||||
{
|
|
||||||
private readonly ILogger<ReportCreator> _logger;
|
|
||||||
|
|
||||||
public ReportCreator() : this(NullLogger<ReportCreator>.Instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReportCreator(ILogger<ReportCreator> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] CreateReport(SqlConnection connection, Envelope envelope)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var reportItems = LoadReportItems(connection, envelope.Id);
|
|
||||||
using var stream = new MemoryStream();
|
|
||||||
using var writer = new PdfWriter(stream);
|
|
||||||
using var pdf = new PdfDocument(writer);
|
|
||||||
using var document = new LayoutDocument(pdf);
|
|
||||||
|
|
||||||
document.Add(new Paragraph("Envelope Finalization Report").SetFontSize(16));
|
|
||||||
document.Add(new Paragraph($"Envelope Id: {envelope.Id}"));
|
|
||||||
document.Add(new Paragraph($"UUID: {envelope.Uuid}"));
|
|
||||||
document.Add(new Paragraph($"Title: {envelope.Title}"));
|
|
||||||
document.Add(new Paragraph($"Subject: {envelope.Comment}"));
|
|
||||||
document.Add(new Paragraph($"Generated: {DateTime.UtcNow:O}"));
|
|
||||||
document.Add(new Paragraph(" "));
|
|
||||||
|
|
||||||
var table = new Table(4).UseAllAvailableWidth();
|
|
||||||
table.AddHeaderCell("Date");
|
|
||||||
table.AddHeaderCell("Status");
|
|
||||||
table.AddHeaderCell("User");
|
|
||||||
table.AddHeaderCell("EnvelopeId");
|
|
||||||
|
|
||||||
foreach (var item in reportItems.OrderByDescending(r => r.ItemDate))
|
|
||||||
{
|
|
||||||
table.AddCell(item.ItemDate.ToString("u"));
|
|
||||||
table.AddCell(item.ItemStatus.ToString());
|
|
||||||
table.AddCell(item.ItemUserReference);
|
|
||||||
table.AddCell(item.EnvelopeId.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
document.Add(table);
|
|
||||||
document.Close();
|
|
||||||
return stream.ToArray();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Could not create report for envelope {EnvelopeId}", envelope.Id);
|
|
||||||
throw new CreateReportException("Could not prepare report data", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ReportItem> LoadReportItems(SqlConnection connection, int envelopeId)
|
|
||||||
{
|
|
||||||
const string sql = "SELECT ENVELOPE_ID, POS_WHEN, POS_STATUS, POS_WHO FROM VWSIG_ENVELOPE_REPORT WHERE ENVELOPE_ID = @EnvelopeId";
|
|
||||||
var result = new List<ReportItem>();
|
|
||||||
|
|
||||||
using var command = new SqlCommand(sql, connection);
|
|
||||||
command.Parameters.AddWithValue("@EnvelopeId", envelopeId);
|
|
||||||
using var reader = command.ExecuteReader();
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
result.Add(new ReportItem
|
|
||||||
{
|
|
||||||
EnvelopeId = reader.GetInt32(0),
|
|
||||||
ItemDate = reader.IsDBNull(1) ? DateTime.MinValue : reader.GetDateTime(1),
|
|
||||||
ItemStatus = reader.IsDBNull(2) ? default : (EnvelopeGenerator.Domain.Constants.EnvelopeStatus)reader.GetInt32(2),
|
|
||||||
ItemUserReference = reader.IsDBNull(3) ? string.Empty : reader.GetString(3)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using EnvelopeGenerator.Domain.Constants;
|
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class ReportItem
|
|
||||||
{
|
|
||||||
public Envelope? Envelope { get; set; }
|
|
||||||
public int EnvelopeId { get; set; }
|
|
||||||
public string EnvelopeTitle { get; set; } = string.Empty;
|
|
||||||
public string EnvelopeSubject { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public EnvelopeStatus ItemStatus { get; set; }
|
|
||||||
|
|
||||||
public string ItemStatusTranslated => ItemStatus.ToString();
|
|
||||||
|
|
||||||
public string ItemUserReference { get; set; } = string.Empty;
|
|
||||||
public DateTime ItemDate { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
|
||||||
|
|
||||||
public class ReportSource
|
|
||||||
{
|
|
||||||
public List<ReportItem> Items { get; set; } = new();
|
|
||||||
}
|
|
||||||
@@ -105,17 +105,13 @@ namespace EnvelopeGenerator.PdfEditor
|
|||||||
public Pdf<TInputStream, TOutputStream> Background<TSignature>(IEnumerable<TSignature> signatures, double widthPx = 1.9500000000000002, double heightPx = 2.52)
|
public Pdf<TInputStream, TOutputStream> Background<TSignature>(IEnumerable<TSignature> signatures, double widthPx = 1.9500000000000002, double heightPx = 2.52)
|
||||||
where TSignature : ISignature
|
where TSignature : ISignature
|
||||||
{
|
{
|
||||||
// once per page
|
|
||||||
Page(page =>
|
|
||||||
{
|
|
||||||
var canvas = new PdfCanvas(page);
|
|
||||||
canvas.ConcatMatrix(1, 0, 0, -1, 0, page.GetPageSize().GetHeight());
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var signature in signatures)
|
foreach (var signature in signatures)
|
||||||
Page(signature.Page, page =>
|
Page(signature.Page, page =>
|
||||||
{
|
{
|
||||||
var canvas = new PdfCanvas(page);
|
var canvas = new PdfCanvas(page);
|
||||||
|
canvas.SaveState();
|
||||||
|
canvas.ConcatMatrix(1, 0, 0, -1, 0, page.GetPageSize().GetHeight());
|
||||||
|
|
||||||
double inchFactor = 72;
|
double inchFactor = 72;
|
||||||
double magin = .2;
|
double magin = .2;
|
||||||
double x = (signature.X - .7 - magin) * inchFactor;
|
double x = (signature.X - .7 - magin) * inchFactor;
|
||||||
@@ -134,6 +130,8 @@ namespace EnvelopeGenerator.PdfEditor
|
|||||||
canvas.SetFillColor(new DeviceRgb(204, 202, 198))
|
canvas.SetFillColor(new DeviceRgb(204, 202, 198))
|
||||||
.Rectangle(x, y + height - bottomLineLength, width, bottomLineLength)
|
.Rectangle(x, y + height - bottomLineLength, width, bottomLineLength)
|
||||||
.Fill();
|
.Fill();
|
||||||
|
|
||||||
|
canvas.RestoreState();
|
||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Auth;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fragt die API, ob der Nutzer eingeloggt ist.
|
|
||||||
///
|
|
||||||
/// WARUM nicht selbst Token lesen?
|
|
||||||
/// - Das Auth-Cookie ist HttpOnly → JavaScript/WASM kann es nicht lesen
|
|
||||||
/// - Stattdessen: Frage die API "bin ich eingeloggt?" → GET /api/auth/check
|
|
||||||
/// - Die API prüft das Cookie serverseitig und antwortet mit 200 oder 401
|
|
||||||
/// </summary>
|
|
||||||
public class ApiAuthStateProvider : AuthenticationStateProvider
|
|
||||||
{
|
|
||||||
private readonly IAuthService _authService;
|
|
||||||
|
|
||||||
public ApiAuthStateProvider(IAuthService authService)
|
|
||||||
{
|
|
||||||
_authService = authService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
|
||||||
{
|
|
||||||
var result = await _authService.CheckAuthAsync();
|
|
||||||
|
|
||||||
if (result.IsSuccess)
|
|
||||||
{
|
|
||||||
// Eingeloggt → Erstelle einen authentifizierten ClaimsPrincipal
|
|
||||||
var identity = new ClaimsIdentity("cookie");
|
|
||||||
return new AuthenticationState(new ClaimsPrincipal(identity));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nicht eingeloggt
|
|
||||||
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Wird nach Login/Logout aufgerufen, damit Blazor den Auth-State aktualisiert.
|
|
||||||
/// </summary>
|
|
||||||
public void NotifyAuthChanged()
|
|
||||||
{
|
|
||||||
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
@* DUMB COMPONENT: Kennt keine Services, nur Parameter und Events *@
|
|
||||||
|
|
||||||
<div class="access-code-container">
|
|
||||||
<h2>Zugangscode eingeben</h2>
|
|
||||||
<p>Ein Zugangscode wurde an Ihre E-Mail-Adresse gesendet.</p>
|
|
||||||
|
|
||||||
<EditForm Model="_model" OnValidSubmit="Submit">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<InputText @bind-Value="_model.Code"
|
|
||||||
class="form-control code-input"
|
|
||||||
placeholder="000000"
|
|
||||||
maxlength="6" />
|
|
||||||
<ValidationMessage For="() => _model.Code" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(ErrorMessage))
|
|
||||||
{
|
|
||||||
<div class="alert alert-danger mt-2">@ErrorMessage</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary mt-3" disabled="@_isSubmitting">
|
|
||||||
@if (_isSubmitting)
|
|
||||||
{
|
|
||||||
<LoadingIndicator Small="true" />
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span>Bestätigen</span>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
// Parameter von der Eltern-Page
|
|
||||||
[Parameter] public required string EnvelopeKey { get; set; }
|
|
||||||
[Parameter] public string? ErrorMessage { get; set; }
|
|
||||||
|
|
||||||
// EventCallback: Informiert die Page, dass ein Code eingegeben wurde
|
|
||||||
[Parameter] public EventCallback<string> OnSubmit { get; set; }
|
|
||||||
|
|
||||||
private AccessCodeModel _model = new();
|
|
||||||
private bool _isSubmitting;
|
|
||||||
|
|
||||||
private async Task Submit()
|
|
||||||
{
|
|
||||||
_isSubmitting = true;
|
|
||||||
await OnSubmit.InvokeAsync(_model.Code);
|
|
||||||
_isSubmitting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AccessCodeModel
|
|
||||||
{
|
|
||||||
[System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Bitte Zugangscode eingeben")]
|
|
||||||
[System.ComponentModel.DataAnnotations.StringLength(6, MinimumLength = 4)]
|
|
||||||
public string Code { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
@inject IJSRuntime JS
|
|
||||||
@implements IAsyncDisposable
|
|
||||||
|
|
||||||
<div id="pspdfkit-container" class="pdf-container" style="width: 100%; height: 80vh;"></div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public byte[]? DocumentBytes { get; set; }
|
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
||||||
{
|
|
||||||
if (firstRender && DocumentBytes is not null)
|
|
||||||
{
|
|
||||||
// TODO: PSPDFKit JS-Interop implementieren (Phase 6)
|
|
||||||
// await JS.InvokeVoidAsync("initPdfViewer", DocumentBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
// TODO: PSPDFKit aufräumen
|
|
||||||
// await JS.InvokeVoidAsync("destroyPdfViewer");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>SignaturePanel</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>TwoFactorForm</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>NavHeader</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>AlertMessage</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<div class="text-center py-5">
|
|
||||||
@if (!string.IsNullOrEmpty(Icon))
|
|
||||||
{
|
|
||||||
<div class="mb-3">
|
|
||||||
<i class="bi bi-@Icon" style="font-size: 3rem;"></i>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<h2>@Title</h2>
|
|
||||||
@if (!string.IsNullOrEmpty(Message))
|
|
||||||
{
|
|
||||||
<p class="text-muted">@Message</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public string Title { get; set; } = "Fehler";
|
|
||||||
[Parameter] public string? Message { get; set; }
|
|
||||||
[Parameter] public string? Icon { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>LanguageSelector</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<div class="d-flex justify-content-center align-items-center @(Small ? "" : "py-5")" style="@(Small ? "" : "min-height: 40vh;")">
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="spinner-border @(Small ? "spinner-border-sm" : "text-primary")"
|
|
||||||
style="@(Small ? "" : "width: 3rem; height: 3rem;")"
|
|
||||||
role="status">
|
|
||||||
<span class="visually-hidden">Laden...</span>
|
|
||||||
</div>
|
|
||||||
@if (!Small && Message is not null)
|
|
||||||
{
|
|
||||||
<p class="mt-3 text-muted">@Message</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public bool Small { get; set; }
|
|
||||||
[Parameter] public string? Message { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
|
|
||||||
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.3" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.3" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hält den aktuellen Authentifizierungs-Zustand im Client.
|
|
||||||
/// Wird vom ApiAuthStateProvider gesetzt und von Komponenten gelesen.
|
|
||||||
/// </summary>
|
|
||||||
public class AuthState
|
|
||||||
{
|
|
||||||
public bool IsAuthenticated { get; set; }
|
|
||||||
public string? Role { get; set; }
|
|
||||||
public string? EnvelopeUuid { get; set; }
|
|
||||||
public string? ReceiverEmail { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client-seitiges DTO für Dokument-Daten.
|
|
||||||
/// </summary>
|
|
||||||
public record DocumentModel
|
|
||||||
{
|
|
||||||
public int Id { get; init; }
|
|
||||||
public int EnvelopeId { get; init; }
|
|
||||||
public DateTime AddedWhen { get; init; }
|
|
||||||
public byte[]? ByteData { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client-seitiges DTO für Umschlag-Daten.
|
|
||||||
/// Muss nur die JSON-Properties matchen, die die API zurückgibt
|
|
||||||
/// und die der Client tatsächlich braucht.
|
|
||||||
///
|
|
||||||
/// WARUM eigene DTOs statt die aus EnvelopeGenerator.Application?
|
|
||||||
/// - Application hat Server-Abhängigkeiten (SqlClient, JwtBearer, EF Core)
|
|
||||||
/// - Diese Pakete existieren nicht für browser-wasm → Build-Fehler
|
|
||||||
/// - Der Client braucht nur eine Teilmenge der Felder
|
|
||||||
/// - Eigene DTOs machen den Client unabhängig vom Server
|
|
||||||
/// </summary>
|
|
||||||
public record EnvelopeModel
|
|
||||||
{
|
|
||||||
public int Id { get; init; }
|
|
||||||
public string Uuid { get; init; } = string.Empty;
|
|
||||||
public string Title { get; init; } = string.Empty;
|
|
||||||
public string Message { get; init; } = string.Empty;
|
|
||||||
public bool UseAccessCode { get; init; }
|
|
||||||
public bool TFAEnabled { get; init; }
|
|
||||||
public bool ReadOnly { get; init; }
|
|
||||||
public string Language { get; init; } = "de-DE";
|
|
||||||
public DateTime AddedWhen { get; init; }
|
|
||||||
public UserModel? User { get; init; }
|
|
||||||
public IEnumerable<DocumentModel>? Documents { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client-seitiges DTO für die Envelope-Receiver-Zuordnung.
|
|
||||||
/// </summary>
|
|
||||||
public record EnvelopeReceiverModel
|
|
||||||
{
|
|
||||||
public EnvelopeModel? Envelope { get; init; }
|
|
||||||
public ReceiverModel? Receiver { get; init; }
|
|
||||||
public int EnvelopeId { get; init; }
|
|
||||||
public int ReceiverId { get; init; }
|
|
||||||
public int Sequence { get; init; }
|
|
||||||
public string? Name { get; init; }
|
|
||||||
public bool HasPhoneNumber { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models
|
|
||||||
{
|
|
||||||
public class EnvelopeViewModel
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client-seitiges DTO für Empfänger-Daten.
|
|
||||||
/// </summary>
|
|
||||||
public record ReceiverModel
|
|
||||||
{
|
|
||||||
public int Id { get; init; }
|
|
||||||
public string EmailAddress { get; init; } = string.Empty;
|
|
||||||
public string Signature { get; init; } = string.Empty;
|
|
||||||
public DateTime AddedWhen { get; init; }
|
|
||||||
public DateTime? TfaRegDeadline { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client-seitiges DTO für Benutzer-Daten (Absender).
|
|
||||||
/// </summary>
|
|
||||||
public record UserModel
|
|
||||||
{
|
|
||||||
public string? Email { get; init; }
|
|
||||||
public string? DisplayName { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>EnvelopeExpired</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>EnvelopeLocked</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
@page "/envelope/{EnvelopeKey}"
|
|
||||||
@rendermode InteractiveAuto
|
|
||||||
@inject IEnvelopeService EnvelopeService
|
|
||||||
@inject EnvelopeState State
|
|
||||||
@implements IDisposable
|
|
||||||
|
|
||||||
<PageTitle>Dokument</PageTitle>
|
|
||||||
|
|
||||||
@switch (State.Status)
|
|
||||||
{
|
|
||||||
case EnvelopePageStatus.Loading:
|
|
||||||
<LoadingIndicator Message="Dokument wird geladen..." />
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EnvelopePageStatus.NotFound:
|
|
||||||
<ErrorDisplay Title="Nicht gefunden"
|
|
||||||
Message="Dieses Dokument existiert nicht oder ist nicht mehr verfügbar." />
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EnvelopePageStatus.AlreadySigned:
|
|
||||||
<ErrorDisplay Title="Bereits unterschrieben"
|
|
||||||
Message="Dieses Dokument wurde bereits unterschrieben."
|
|
||||||
Icon="check-circle" />
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EnvelopePageStatus.RequiresAccessCode:
|
|
||||||
<AccessCodeForm EnvelopeKey="@EnvelopeKey"
|
|
||||||
ErrorMessage="@State.ErrorMessage"
|
|
||||||
OnSubmit="HandleAccessCodeSubmit" />
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EnvelopePageStatus.ShowDocument:
|
|
||||||
<PdfViewer DocumentBytes="@_documentBytes" />
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EnvelopePageStatus.Error:
|
|
||||||
<ErrorDisplay Title="Fehler" Message="@State.ErrorMessage" />
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public string EnvelopeKey { get; set; } = default!;
|
|
||||||
|
|
||||||
private byte[]? _documentBytes;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
State.OnChange += StateHasChanged;
|
|
||||||
await LoadEnvelopeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadEnvelopeAsync()
|
|
||||||
{
|
|
||||||
State.SetLoading();
|
|
||||||
|
|
||||||
// Die genaue API-Logik hängt von den verfügbaren Endpunkten ab.
|
|
||||||
// Dies ist die Struktur — die konkreten Endpoints implementierst du
|
|
||||||
// basierend auf den vorhandenen API-Controllern.
|
|
||||||
var result = await EnvelopeService.GetEnvelopeReceiversAsync();
|
|
||||||
|
|
||||||
if (!result.IsSuccess)
|
|
||||||
{
|
|
||||||
if (result.StatusCode == 401)
|
|
||||||
State.SetAccessCodeRequired();
|
|
||||||
else if (result.StatusCode == 404)
|
|
||||||
State.SetNotFound();
|
|
||||||
else
|
|
||||||
State.SetError(result.ErrorMessage ?? "Unbekannter Fehler");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Daten verarbeiten und Status setzen
|
|
||||||
State.SetDocument();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleAccessCodeSubmit(string code)
|
|
||||||
{
|
|
||||||
// AccessCode an API senden
|
|
||||||
// Bei Erfolg: State.SetDocument() oder State.SetTwoFactorRequired()
|
|
||||||
// Bei Fehler: State.SetError(...)
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => State.OnChange -= StateHasChanged;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>EnvelopeRejected</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>EnvelopeSigned</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>Home</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>NotFound</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.Auth;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.State;
|
|
||||||
|
|
||||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
|
||||||
|
|
||||||
// HttpClient: BaseAddress zeigt auf den ReceiverUI-Server (gleiche Domain)
|
|
||||||
// Von dort werden alle /api/* Calls via YARP an die echte API weitergeleitet
|
|
||||||
builder.Services.AddScoped(sp =>
|
|
||||||
new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
|
||||||
|
|
||||||
// Auth: Blazor fragt über diesen Provider "Ist der Nutzer eingeloggt?"
|
|
||||||
builder.Services.AddAuthorizationCore();
|
|
||||||
builder.Services.AddScoped<ApiAuthStateProvider>();
|
|
||||||
builder.Services.AddScoped<AuthenticationStateProvider>(sp =>
|
|
||||||
sp.GetRequiredService<ApiAuthStateProvider>());
|
|
||||||
|
|
||||||
// API-Services: Je ein Service pro API-Controller
|
|
||||||
builder.Services.AddScoped<IAuthService, AuthService>();
|
|
||||||
builder.Services.AddScoped<IEnvelopeService, EnvelopeService>();
|
|
||||||
|
|
||||||
// State: Ein State-Objekt pro Browser-Tab
|
|
||||||
builder.Services.AddScoped<EnvelopeState>();
|
|
||||||
|
|
||||||
await builder.Build().RunAsync();
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
using EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Spricht mit dem bestehenden AuthController der API.
|
|
||||||
/// Die API erkennt den Nutzer über das Cookie "AuthToken" automatisch.
|
|
||||||
/// </summary>
|
|
||||||
public class AuthService : ApiServiceBase, IAuthService
|
|
||||||
{
|
|
||||||
public AuthService(HttpClient http, ILogger<AuthService> logger) : base(http, logger) { }
|
|
||||||
|
|
||||||
public async Task<ApiResponse> CheckAuthAsync(string? role = null, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
var endpoint = role is not null ? $"api/auth/check?role={role}" : "api/auth/check";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await Http.GetAsync(endpoint, ct);
|
|
||||||
return response.IsSuccessStatusCode
|
|
||||||
? ApiResponse.Success((int)response.StatusCode)
|
|
||||||
: ApiResponse.Failure((int)response.StatusCode);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "HTTP error calling GET {Endpoint}", endpoint);
|
|
||||||
return ApiResponse.Failure(0, "Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
catch (TaskCanceledException)
|
|
||||||
{
|
|
||||||
return ApiResponse.Failure(0, "Anfrage abgebrochen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ApiResponse> LogoutAsync(CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
const string endpoint = "api/auth/logout";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await Http.PostAsync(endpoint, null, ct);
|
|
||||||
return response.IsSuccessStatusCode
|
|
||||||
? ApiResponse.Success((int)response.StatusCode)
|
|
||||||
: ApiResponse.Failure((int)response.StatusCode);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "HTTP error calling POST {Endpoint}", endpoint);
|
|
||||||
return ApiResponse.Failure(0, "Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
catch (TaskCanceledException)
|
|
||||||
{
|
|
||||||
return ApiResponse.Failure(0, "Anfrage abgebrochen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Einheitliches Response-Objekt für ALLE API-Aufrufe.
|
|
||||||
///
|
|
||||||
/// WARUM: Jeder API-Aufruf kann fehlschlagen (Netzwerk, 401, 500...).
|
|
||||||
/// Statt überall try-catch zu haben, kapselt dieses Objekt Erfolg/Fehler einheitlich.
|
|
||||||
/// So kann jede Blazor-Komponente einheitlich darauf reagieren.
|
|
||||||
/// </summary>
|
|
||||||
public record ApiResponse<T>
|
|
||||||
{
|
|
||||||
public bool IsSuccess { get; init; }
|
|
||||||
public T? Data { get; init; }
|
|
||||||
public int StatusCode { get; init; }
|
|
||||||
public string? ErrorMessage { get; init; }
|
|
||||||
|
|
||||||
public static ApiResponse<T> Success(T data, int statusCode = 200)
|
|
||||||
=> new() { IsSuccess = true, Data = data, StatusCode = statusCode };
|
|
||||||
|
|
||||||
public static ApiResponse<T> Failure(int statusCode, string? error = null)
|
|
||||||
=> new() { IsSuccess = false, StatusCode = statusCode, ErrorMessage = error };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Response ohne Daten (für POST/PUT/DELETE die nur Status zurückgeben).
|
|
||||||
/// </summary>
|
|
||||||
public record ApiResponse
|
|
||||||
{
|
|
||||||
public bool IsSuccess { get; init; }
|
|
||||||
public int StatusCode { get; init; }
|
|
||||||
public string? ErrorMessage { get; init; }
|
|
||||||
|
|
||||||
public static ApiResponse Success(int statusCode = 200)
|
|
||||||
=> new() { IsSuccess = true, StatusCode = statusCode };
|
|
||||||
|
|
||||||
public static ApiResponse Failure(int statusCode, string? error = null)
|
|
||||||
=> new() { IsSuccess = false, StatusCode = statusCode, ErrorMessage = error };
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
using System.Net.Http.Json;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Basisklasse für ALLE API-Services.
|
|
||||||
///
|
|
||||||
/// WARUM eine Basisklasse?
|
|
||||||
/// - Einheitliches Error-Handling: Jeder API-Aufruf wird gleich behandelt
|
|
||||||
/// - DRY (Don't Repeat Yourself): Logging, Fehlerbehandlung, Serialisierung nur einmal
|
|
||||||
/// - Einfache Erweiterung: Retry-Logik, Token-Refresh etc. nur hier ändern
|
|
||||||
/// </summary>
|
|
||||||
public abstract class ApiServiceBase
|
|
||||||
{
|
|
||||||
protected readonly HttpClient Http;
|
|
||||||
protected readonly ILogger Logger;
|
|
||||||
|
|
||||||
protected ApiServiceBase(HttpClient http, ILogger logger)
|
|
||||||
{
|
|
||||||
Http = http;
|
|
||||||
Logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GET-Request mit Deserialisierung.
|
|
||||||
/// Alle API GET-Aufrufe gehen durch diese Methode.
|
|
||||||
/// </summary>
|
|
||||||
protected async Task<ApiResponse<T>> GetAsync<T>(string endpoint, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await Http.GetAsync(endpoint, ct);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var errorBody = await response.Content.ReadAsStringAsync(ct);
|
|
||||||
Logger.LogWarning("GET {Endpoint} failed: {Status} - {Body}",
|
|
||||||
endpoint, (int)response.StatusCode, errorBody);
|
|
||||||
return ApiResponse<T>.Failure((int)response.StatusCode, errorBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = await response.Content.ReadFromJsonAsync<T>(cancellationToken: ct);
|
|
||||||
return ApiResponse<T>.Success(data!, (int)response.StatusCode);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "HTTP error calling GET {Endpoint}", endpoint);
|
|
||||||
return ApiResponse<T>.Failure(0, "Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
catch (TaskCanceledException)
|
|
||||||
{
|
|
||||||
Logger.LogWarning("GET {Endpoint} was cancelled", endpoint);
|
|
||||||
return ApiResponse<T>.Failure(0, "Anfrage abgebrochen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// POST-Request mit Body und Response-Deserialisierung.
|
|
||||||
/// </summary>
|
|
||||||
protected async Task<ApiResponse<TResponse>> PostAsync<TRequest, TResponse>(
|
|
||||||
string endpoint, TRequest body, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await Http.PostAsJsonAsync(endpoint, body, ct);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var errorBody = await response.Content.ReadAsStringAsync(ct);
|
|
||||||
Logger.LogWarning("POST {Endpoint} failed: {Status} - {Body}",
|
|
||||||
endpoint, (int)response.StatusCode, errorBody);
|
|
||||||
return ApiResponse<TResponse>.Failure((int)response.StatusCode, errorBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = await response.Content.ReadFromJsonAsync<TResponse>(cancellationToken: ct);
|
|
||||||
return ApiResponse<TResponse>.Success(data!, (int)response.StatusCode);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "HTTP error calling POST {Endpoint}", endpoint);
|
|
||||||
return ApiResponse<TResponse>.Failure(0, "Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// POST-Request ohne Response-Body (z.B. Logout).
|
|
||||||
/// </summary>
|
|
||||||
protected async Task<ApiResponse> PostAsync<TRequest>(
|
|
||||||
string endpoint, TRequest body, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await Http.PostAsJsonAsync(endpoint, body, ct);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var errorBody = await response.Content.ReadAsStringAsync(ct);
|
|
||||||
return ApiResponse.Failure((int)response.StatusCode, errorBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiResponse.Success((int)response.StatusCode);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "HTTP error calling POST {Endpoint}", endpoint);
|
|
||||||
return ApiResponse.Failure(0, "Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
|
|
||||||
public class EnvelopeService : ApiServiceBase, IEnvelopeService
|
|
||||||
{
|
|
||||||
public EnvelopeService(HttpClient http, ILogger<EnvelopeService> logger) : base(http, logger) { }
|
|
||||||
|
|
||||||
public Task<ApiResponse<IEnumerable<EnvelopeModel>>> GetEnvelopesAsync(CancellationToken ct = default)
|
|
||||||
=> GetAsync<IEnumerable<EnvelopeModel>>("api/envelope", ct);
|
|
||||||
|
|
||||||
public Task<ApiResponse<IEnumerable<EnvelopeReceiverModel>>> GetEnvelopeReceiversAsync(
|
|
||||||
CancellationToken ct = default)
|
|
||||||
=> GetAsync<IEnumerable<EnvelopeReceiverModel>>("api/envelopereceiver", ct);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services
|
|
||||||
{
|
|
||||||
public class HistoryService
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Kommuniziert mit dem AuthController der API.
|
|
||||||
///
|
|
||||||
/// WARUM Interface + Implementierung?
|
|
||||||
/// - Testbarkeit: In Unit-Tests kann man einen Mock verwenden
|
|
||||||
/// - Austauschbarkeit: Wenn sich die API ändert, ändert sich nur die Implementierung
|
|
||||||
/// - Blazor-Konvention: Services werden über Interfaces per DI registriert
|
|
||||||
/// </summary>
|
|
||||||
public interface IAuthService
|
|
||||||
{
|
|
||||||
/// <summary>Prüft ob der Nutzer eingeloggt ist → GET /api/auth/check</summary>
|
|
||||||
Task<ApiResponse> CheckAuthAsync(string? role = null, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <summary>Logout → POST /api/auth/logout</summary>
|
|
||||||
Task<ApiResponse> LogoutAsync(CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using EnvelopeGenerator.ReceiverUI.Client.Models;
|
|
||||||
using EnvelopeGenerator.ReceiverUI.Client.Services.Base;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Kommuniziert mit EnvelopeController und EnvelopeReceiverController.
|
|
||||||
/// Verwendet Client-eigene Models statt der Server-DTOs.
|
|
||||||
/// </summary>
|
|
||||||
public interface IEnvelopeService
|
|
||||||
{
|
|
||||||
/// <summary>Lädt Umschläge → GET /api/envelope</summary>
|
|
||||||
Task<ApiResponse<IEnumerable<EnvelopeModel>>> GetEnvelopesAsync(CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <summary>Lädt EnvelopeReceiver → GET /api/envelopereceiver</summary>
|
|
||||||
Task<ApiResponse<IEnumerable<EnvelopeReceiverModel>>> GetEnvelopeReceiversAsync(
|
|
||||||
CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.Services
|
|
||||||
{
|
|
||||||
public interface IHistoryService
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.State
|
|
||||||
{
|
|
||||||
public class AuthState
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.ReceiverUI.Client.State;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hält den aktuellen Zustand des geladenen Umschlags.
|
|
||||||
///
|
|
||||||
/// WARUM ein eigenes State-Objekt?
|
|
||||||
/// - Mehrere Komponenten auf einer Seite brauchen die gleichen Daten
|
|
||||||
/// - Ohne State müsste jede Komponente die Daten selbst laden → doppelte API-Calls
|
|
||||||
/// - StateHasChanged() informiert automatisch alle Subscriber
|
|
||||||
///
|
|
||||||
/// PATTERN: "Observable State" — Services setzen den State, Komponenten reagieren darauf.
|
|
||||||
/// </summary>
|
|
||||||
public class EnvelopeState
|
|
||||||
{
|
|
||||||
private EnvelopePageStatus _status = EnvelopePageStatus.Loading;
|
|
||||||
private string? _errorMessage;
|
|
||||||
|
|
||||||
/// <summary>Aktueller Seitenstatus</summary>
|
|
||||||
public EnvelopePageStatus Status
|
|
||||||
{
|
|
||||||
get => _status;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_status = value;
|
|
||||||
NotifyStateChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fehlermeldung (falls vorhanden)</summary>
|
|
||||||
public string? ErrorMessage
|
|
||||||
{
|
|
||||||
get => _errorMessage;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_errorMessage = value;
|
|
||||||
NotifyStateChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Zustandsübergänge (öffentliche Methoden) ---
|
|
||||||
|
|
||||||
public void SetLoading() => Status = EnvelopePageStatus.Loading;
|
|
||||||
|
|
||||||
public void SetAccessCodeRequired()
|
|
||||||
{
|
|
||||||
ErrorMessage = null;
|
|
||||||
Status = EnvelopePageStatus.RequiresAccessCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTwoFactorRequired() => Status = EnvelopePageStatus.RequiresTwoFactor;
|
|
||||||
|
|
||||||
public void SetDocument() => Status = EnvelopePageStatus.ShowDocument;
|
|
||||||
|
|
||||||
public void SetError(string message)
|
|
||||||
{
|
|
||||||
ErrorMessage = message;
|
|
||||||
Status = EnvelopePageStatus.Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAlreadySigned() => Status = EnvelopePageStatus.AlreadySigned;
|
|
||||||
public void SetRejected() => Status = EnvelopePageStatus.Rejected;
|
|
||||||
public void SetNotFound() => Status = EnvelopePageStatus.NotFound;
|
|
||||||
|
|
||||||
// --- Event: Benachrichtigt Komponenten über Änderungen ---
|
|
||||||
public event Action? OnChange;
|
|
||||||
private void NotifyStateChanged() => OnChange?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Alle möglichen Zustände der Umschlag-Seite</summary>
|
|
||||||
public enum EnvelopePageStatus
|
|
||||||
{
|
|
||||||
Loading,
|
|
||||||
RequiresAccessCode,
|
|
||||||
RequiresTwoFactor,
|
|
||||||
ShowDocument,
|
|
||||||
AlreadySigned,
|
|
||||||
Rejected,
|
|
||||||
NotFound,
|
|
||||||
Expired,
|
|
||||||
Error
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
@using System.Net.Http
|
|
||||||
@using System.Net.Http.Json
|
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
|
||||||
@using Microsoft.AspNetCore.Components.Routing
|
|
||||||
@using Microsoft.AspNetCore.Components.Web
|
|
||||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
|
||||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
|
||||||
@using Microsoft.JSInterop
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Models
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Services
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Services.Base
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.State
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Auth
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Components.Shared
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Client.Components.Envelope
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
body {
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<base href="/" />
|
|
||||||
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
|
|
||||||
<link rel="stylesheet" href="app.css" />
|
|
||||||
<link rel="stylesheet" href="EnvelopeGenerator.ReceiverUI.styles.css" />
|
|
||||||
<link rel="icon" type="image/png" href="favicon.png" />
|
|
||||||
<HeadOutlet />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<Routes />
|
|
||||||
<script src="_framework/blazor.web.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<h3>AuthLayout</h3>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
@inherits LayoutComponentBase
|
|
||||||
|
|
||||||
<div class="app-container">
|
|
||||||
<header class="app-header">
|
|
||||||
<div class="header-content">
|
|
||||||
<span class="app-title">signFLOW</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main class="app-main">
|
|
||||||
<ErrorBoundary @ref="_errorBoundary">
|
|
||||||
<ChildContent>
|
|
||||||
@Body
|
|
||||||
</ChildContent>
|
|
||||||
<ErrorContent Context="ex">
|
|
||||||
<div class="error-container text-center py-5">
|
|
||||||
<h2>😵 Ein unerwarteter Fehler ist aufgetreten</h2>
|
|
||||||
<p class="text-muted">Bitte versuchen Sie es erneut.</p>
|
|
||||||
<button class="btn btn-primary" @onclick="Recover">Erneut versuchen</button>
|
|
||||||
</div>
|
|
||||||
</ErrorContent>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer class="app-footer text-center py-2 text-muted">
|
|
||||||
<small>© @DateTime.Now.Year Digital Data GmbH</small>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private ErrorBoundary? _errorBoundary;
|
|
||||||
|
|
||||||
private void Recover() => _errorBoundary?.Recover();
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
.page {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
border-bottom: 1px solid #d6d5d5;
|
|
||||||
justify-content: flex-end;
|
|
||||||
height: 3.5rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a:first-child {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640.98px) {
|
|
||||||
.top-row {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 641px) {
|
|
||||||
.page {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
width: 250px;
|
|
||||||
height: 100vh;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row.auth ::deep a:first-child {
|
|
||||||
flex: 1;
|
|
||||||
text-align: right;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row, article {
|
|
||||||
padding-left: 2rem !important;
|
|
||||||
padding-right: 1.5rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-error-ui {
|
|
||||||
background: lightyellow;
|
|
||||||
bottom: 0;
|
|
||||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
|
||||||
display: none;
|
|
||||||
left: 0;
|
|
||||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-error-ui .dismiss {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
right: 0.75rem;
|
|
||||||
top: 0.5rem;
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
@page "/Error"
|
|
||||||
@using System.Diagnostics
|
|
||||||
|
|
||||||
<PageTitle>Error</PageTitle>
|
|
||||||
|
|
||||||
<h1 class="text-danger">Error.</h1>
|
|
||||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
|
||||||
|
|
||||||
@if (ShowRequestId)
|
|
||||||
{
|
|
||||||
<p>
|
|
||||||
<strong>Request ID:</strong> <code>@RequestId</code>
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
<h3>Development Mode</h3>
|
|
||||||
<p>
|
|
||||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
|
||||||
It can result in displaying sensitive information from exceptions to end users.
|
|
||||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
|
||||||
and restarting the app.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
@code{
|
|
||||||
[CascadingParameter]
|
|
||||||
private HttpContext? HttpContext { get; set; }
|
|
||||||
|
|
||||||
private string? RequestId { get; set; }
|
|
||||||
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
|
||||||
|
|
||||||
protected override void OnInitialized() =>
|
|
||||||
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
@page "/"
|
|
||||||
|
|
||||||
<PageTitle>Home</PageTitle>
|
|
||||||
|
|
||||||
<h1>Hello, world!</h1>
|
|
||||||
|
|
||||||
Welcome to your new app.
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }">
|
|
||||||
<Found Context="routeData">
|
|
||||||
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
|
|
||||||
<FocusOnNavigate RouteData="routeData" Selector="h1" />
|
|
||||||
</Found>
|
|
||||||
<NotFound>
|
|
||||||
<LayoutView Layout="typeof(Layout.MainLayout)">
|
|
||||||
<div class="text-center py-5">
|
|
||||||
<h1>404</h1>
|
|
||||||
<p>Diese Seite wurde nicht gefunden.</p>
|
|
||||||
</div>
|
|
||||||
</LayoutView>
|
|
||||||
</NotFound>
|
|
||||||
</Router>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
@using System.Net.Http
|
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
|
||||||
@using Microsoft.AspNetCore.Components.Routing
|
|
||||||
@using Microsoft.AspNetCore.Components.Web
|
|
||||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
|
||||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
|
||||||
@using Microsoft.JSInterop
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Components
|
|
||||||
@using EnvelopeGenerator.ReceiverUI.Components.Layout
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.ReceiverUI.Client\EnvelopeGenerator.ReceiverUI.Client.csproj" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.3" />
|
|
||||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.1.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
using EnvelopeGenerator.ReceiverUI.Components;
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
|
||||||
|
|
||||||
builder.Services.AddRazorComponents()
|
|
||||||
.AddInteractiveServerComponents()
|
|
||||||
.AddInteractiveWebAssemblyComponents();
|
|
||||||
|
|
||||||
// API-Proxy: Alle /api/* Aufrufe an die echte API weiterleiten
|
|
||||||
// WARUM: Der Blazor-Client ruft /api/envelope auf. Diese Anfrage geht an den
|
|
||||||
// ReceiverUI-Server (gleiche Domain, kein CORS), der sie an die echte API weiterleitet.
|
|
||||||
var apiBaseUrl = builder.Configuration["ApiBaseUrl"]
|
|
||||||
?? throw new InvalidOperationException("ApiBaseUrl is not configured in appsettings.json.");
|
|
||||||
|
|
||||||
builder.Services.AddHttpForwarder();
|
|
||||||
|
|
||||||
var app = builder.Build();
|
|
||||||
|
|
||||||
if (app.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseWebAssemblyDebugging();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
|
||||||
app.UseHsts();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
app.UseStaticFiles();
|
|
||||||
app.UseAntiforgery();
|
|
||||||
|
|
||||||
// Alle /api/* Requests an die echte EnvelopeGenerator.API weiterleiten
|
|
||||||
// So muss der Browser nie direkt mit der API sprechen → kein CORS, Cookies funktionieren
|
|
||||||
app.MapForwarder("/api/{**catch-all}", apiBaseUrl);
|
|
||||||
|
|
||||||
app.MapRazorComponents<App>()
|
|
||||||
.AddInteractiveServerRenderMode()
|
|
||||||
.AddInteractiveWebAssemblyRenderMode()
|
|
||||||
.AddAdditionalAssemblies(typeof(EnvelopeGenerator.ReceiverUI.Client._Imports).Assembly);
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:3101",
|
|
||||||
"sslPort": 44303
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"http": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
|
||||||
"applicationUrl": "http://localhost:5109",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"https": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
|
||||||
"applicationUrl": "https://localhost:7206;http://localhost:5109",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ApiBaseUrl": "https://localhost:5001",
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user