Compare commits
11 Commits
bugfix/rea
...
8a796a2eec
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a796a2eec | |||
| 83957d28e9 | |||
| fe3f1347d5 | |||
| 1e35e0447f | |||
| 7828ed237d | |||
|
|
45377ea61c | ||
|
|
b5748550d1 | ||
| 64c018b92e | |||
| 176672d7eb | |||
| 05d54e87c3 | |||
| 06c2a07fbc |
@@ -13,12 +13,12 @@ public static class AutoMapperAuditingExtensions
|
||||
/// </summary>
|
||||
public static IMappingExpression<TSource, TDestination> MapAddedWhen<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
|
||||
where TDestination : IHasAddedWhen
|
||||
=> expression.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
|
||||
=> expression.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now));
|
||||
|
||||
/// <summary>
|
||||
/// Maps <see cref="IHasChangedWhen.ChangedWhen"/> to the current UTC time.
|
||||
/// </summary>
|
||||
public static IMappingExpression<TSource, TDestination> MapChangedWhen<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
|
||||
where TDestination : IHasChangedWhen
|
||||
=> expression.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
|
||||
=> expression.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.Now));
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public abstract class SendMailHandler<TNotification> : INotificationHandler<TNot
|
||||
EmailAddress = notification.EmailAddress,
|
||||
EmailBody = temp.Body,
|
||||
EmailSubj = temp.Subject,
|
||||
AddedWhen = DateTime.UtcNow,
|
||||
AddedWhen = DateTime.Now,
|
||||
AddedWho = DispatcherParams.AddedWho,
|
||||
SendingProfile = DispatcherParams.SendingProfile,
|
||||
ReminderTypeId = DispatcherParams.ReminderTypeId,
|
||||
|
||||
@@ -27,7 +27,7 @@ public class MappingProfile : Profile
|
||||
CreateMap<UpdateDocStatusCommand, DocumentStatus>()
|
||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.UtcNow))
|
||||
.ForMember(dest => dest.StatusChangedWhen, opt => opt.MapFrom(src => DateTime.Now))
|
||||
.MapChangedWhen();
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<History
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; } = DateTime.UtcNow;
|
||||
public DateTime AddedWhen { get; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -448,7 +448,7 @@
|
||||
<value>Document has been reset.</value>
|
||||
</data>
|
||||
<data name="DocumentSuccessfullyConfirmed" xml:space="preserve">
|
||||
<value>Document successfully red and confirmed!</value>
|
||||
<value>Document successfully read 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>
|
||||
|
||||
@@ -15,6 +15,7 @@ Imports DigitalData.Core.Abstraction.Application
|
||||
Imports EnvelopeGenerator.Infrastructure
|
||||
Imports Microsoft.EntityFrameworkCore
|
||||
Imports DigitalData.Core.Abstractions
|
||||
Imports EnvelopeGenerator.Domain.Interfaces
|
||||
|
||||
Namespace Jobs
|
||||
Public Class FinalizeDocumentJob
|
||||
@@ -350,7 +351,7 @@ Namespace Jobs
|
||||
Logger.Warn($"No SendFinalEmailToCreator - oMailToCreator [{oMailToCreator}] <> [{FinalEmailType.No}] ")
|
||||
End If
|
||||
|
||||
If oMailToReceivers <> FinalEmailType.No Then
|
||||
If oMailToReceivers <> FinalEmailType.No And pEnvelope.IsReadAndSign() Then
|
||||
Logger.Debug("Sending emails to receivers..")
|
||||
SendFinalEmailToReceivers(pEnvelope) ', pAttachment
|
||||
Else
|
||||
|
||||
108
EnvelopeGenerator.DependencyInjection/DependencyInjection.cs
Normal file
108
EnvelopeGenerator.DependencyInjection/DependencyInjection.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using EnvelopeGenerator.Application;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||
using EnvelopeGenerator.Application.Services;
|
||||
using EnvelopeGenerator.Infrastructure;
|
||||
|
||||
namespace EnvelopeGenerator.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for registering EnvelopeGenerator services into an <see cref="IServiceCollection"/>.
|
||||
/// Use <see cref="AddEnvelopeGenerator"/> as the single entry-point for projects that need both the
|
||||
/// application layer (MediatR, AutoMapper, CRUD services, configuration sections) and the infrastructure
|
||||
/// layer (repositories, DbContext, SQL executors).
|
||||
/// For projects that do not need a database (e.g. lightweight API gateways or unit-test hosts), use
|
||||
/// <see cref="AddEnvelopeGeneratorCore"/> to register only the application layer.
|
||||
/// </summary>
|
||||
public static class DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers the full EnvelopeGenerator stack – application <em>and</em> infrastructure services – into
|
||||
/// the provided <see cref="IServiceCollection"/>.
|
||||
/// <para>
|
||||
/// Internally this calls <c>AddEnvelopeGeneratorServices</c> (application layer) and
|
||||
/// <c>AddEnvelopeGeneratorInfrastructureServices</c> (infrastructure layer).
|
||||
/// A <see cref="Microsoft.EntityFrameworkCore.DbContext"/> and / or <c>DbTriggerParams</c> must be
|
||||
/// configured through <paramref name="infrastructureOptions"/>; without it no database connection will
|
||||
/// be established at runtime.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="services">Service collection to register services into.</param>
|
||||
/// <param name="configuration">
|
||||
/// Application configuration. Used to bind <c>DispatcherParams</c>, <c>MailParams</c>,
|
||||
/// <c>AuthenticatorParams</c>, <c>TotpSmsParams</c>, <c>GtxMessagingParams</c> and other
|
||||
/// application-level option sections.
|
||||
/// </param>
|
||||
/// <param name="infrastructureOptions">
|
||||
/// Optional callback to configure the infrastructure layer registration.
|
||||
/// Typical usage:
|
||||
/// <code>
|
||||
/// services.AddEnvelopeGenerator(config, opt =>
|
||||
/// {
|
||||
/// opt.AddDbContext(o => o.UseSqlServer(connectionString));
|
||||
/// opt.AddDbTriggerParams(config);
|
||||
/// });
|
||||
/// </code>
|
||||
/// </param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
#pragma warning disable CS0618 // AddEnvelopeGeneratorServices / AddEnvelopeGeneratorInfrastructureServices are intentionally wrapped here
|
||||
public static IServiceCollection AddEnvelopeGenerator(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration,
|
||||
Action<EnvelopeGenerator.Infrastructure.DependencyInjection.Config>? infrastructureOptions = null)
|
||||
{
|
||||
// Application layer: CRUD services, MediatR, AutoMapper, configuration sections.
|
||||
services.AddEnvelopeGeneratorServices(configuration);
|
||||
|
||||
// Infrastructure layer: repositories, DbContext, Dapper type maps, SQL executors.
|
||||
services.AddEnvelopeGeneratorInfrastructureServices(opt =>
|
||||
{
|
||||
infrastructureOptions?.Invoke(opt);
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
|
||||
/// <summary>
|
||||
/// Registers only the <em>application</em> layer services (MediatR handlers, AutoMapper profiles,
|
||||
/// CRUD services, configuration sections) without any infrastructure / database dependencies.
|
||||
/// <para>
|
||||
/// Useful for projects that already manage their own DbContext or do not require direct database
|
||||
/// access, such as lightweight API gateways, console tools or unit/integration test hosts that
|
||||
/// use an in-memory database configured elsewhere.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="services">Service collection to register services into.</param>
|
||||
/// <param name="configuration">Application configuration used to bind application-level option sections.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
#pragma warning disable CS0618
|
||||
public static IServiceCollection AddEnvelopeGeneratorCore(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
services.AddEnvelopeGeneratorServices(configuration);
|
||||
return services;
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
|
||||
/// <summary>
|
||||
/// Registers <see cref="EnvelopeMailService"/> as the <see cref="IEnvelopeMailService"/> scoped
|
||||
/// implementation.
|
||||
/// <para>
|
||||
/// Call this in addition to <see cref="AddEnvelopeGenerator"/> when the consuming project needs to
|
||||
/// send envelope e-mails directly (e.g. a Worker Service or the Web project). Projects that rely
|
||||
/// purely on MediatR commands to trigger mail delivery do not need to call this.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="services">Service collection to register services into.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
#pragma warning disable CS0618
|
||||
public static IServiceCollection AddEnvelopeMailService(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IEnvelopeMailService, EnvelopeMailService>();
|
||||
return services;
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<!-- NuGet package metadata -->
|
||||
<PackageId>EnvelopeGenerator</PackageId>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>EnvelopeGenerator</Product>
|
||||
<Description>
|
||||
Envelope Generator ist eine Bibliothek zur Verwaltung und Verarbeitung digitaler Umschläge (Envelopes).
|
||||
Dieses Paket enthält die Dependency-Injection-Erweiterungsmethoden und bündelt die Application-
|
||||
sowie Infrastructure-Schicht in einer einzigen NuGet-Referenz.
|
||||
</Description>
|
||||
<Copyright>Copyright 2024 Digital Data GmbH</Copyright>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/EnvelopeGenerator.git</RepositoryUrl>
|
||||
<PackageTags>digital data envelope generator di dependency injection</PackageTags>
|
||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||
<Version>1.0.0</Version>
|
||||
<AssemblyVersion>1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0</FileVersion>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -47,6 +47,8 @@ public abstract class EGDbContextBase : DbContext
|
||||
|
||||
public DbSet<Signature> DocumentReceiverElements { get; set; }
|
||||
|
||||
public DbSet<ElementAnnotation> DocumentReceiverElementAnnotations { get; set; }
|
||||
|
||||
public DbSet<DocumentStatus> DocumentStatus { get; set; }
|
||||
|
||||
public DbSet<EmailTemplate> EmailTemplate { get; set; }
|
||||
|
||||
@@ -215,7 +215,7 @@ public static class Extensions
|
||||
Title = faker.Lorem.Paragraph(faker.Random.Number(1, 2)),
|
||||
Message = faker.Lorem.Paragraph(faker.Random.Number(2, 5)),
|
||||
TfaEnabled = tfaEnabled,
|
||||
AddedWhen = DateTime.UtcNow,
|
||||
AddedWhen = DateTime.Now,
|
||||
CertificationType = (int)CertificationType.AdvancedElectronicSignature,
|
||||
UseAccessCode = false,
|
||||
ContractType = (int)ContractType.Contract,
|
||||
@@ -273,9 +273,9 @@ public static class Extensions
|
||||
EnvelopeId = envelopeId,
|
||||
ReceiverId = receiverId,
|
||||
Status = ReceiverStatus.Unsigned,
|
||||
AddedWhen = DateTime.UtcNow,
|
||||
AddedWhen = DateTime.Now,
|
||||
AccessCode = faker.Random.Number(1000, 9999).ToString(),
|
||||
ChangedWhen = DateTime.UtcNow,
|
||||
ChangedWhen = DateTime.Now,
|
||||
CompanyName = faker.Company.CompanyName(),
|
||||
JobTitle = faker.Name.JobTitle(),
|
||||
Name = faker.Name.FullName(),
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<PackageTags>digital data envelope generator web</PackageTags>
|
||||
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<Version>3.12.2</Version> <!-- NuGet package version -->
|
||||
<AssemblyVersion>3.12.2.0</AssemblyVersion> <!-- Assembly version for API compatibility -->
|
||||
<FileVersion>3.12.2.0</FileVersion> <!-- Windows file version -->
|
||||
<Version>3.12.3</Version> <!-- NuGet package version -->
|
||||
<AssemblyVersion>3.12.3.0</AssemblyVersion> <!-- Assembly version for API compatibility -->
|
||||
<FileVersion>3.12.3.0</FileVersion> <!-- Windows file version -->
|
||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
2
EnvelopeGenerator.Web/wwwroot/js/util.min.js
vendored
2
EnvelopeGenerator.Web/wwwroot/js/util.min.js
vendored
@@ -1 +1 @@
|
||||
function detailedCurrentDate(){return new Intl.DateTimeFormat(getCurrentCulture(),{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"shortOffset"}).format()}function findNearest(e,t,o,n){const r=n.reduce(((n,r)=>{const i=Math.sqrt((t(e)-t(r))**2+(o(e)-o(r))**2);return i<n.dist?{dist:i,dest:r}:n}),{dist:1/0,dest:null});return r.dest}const getCurrentCulture=()=>("undefined"!=typeof localized&&localized.culture)?localized.culture:navigator.language||"en-US";const B64ToBuff=e=>new Uint8Array(Array.from(atob(e),e=>e.charCodeAt(0))).buffer;const getLocaleDateString=e=>new Date().toLocaleDateString(getCurrentCulture());
|
||||
function detailedCurrentDate(){return new Intl.DateTimeFormat(getCurrentCulture(),{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"shortOffset"}).format()}function findNearest(n,t,i,r){const u=r=>Math.sqrt((t(n)-t(r))**2+(i(n)-i(r))**2);return r.reduce((n,t)=>{const i=u(t);return i<n.dist?{dist:i,dest:t}:n},{dist:Infinity,dest:null}).dest}const getCurrentCulture=()=>typeof localized!="undefined"&&localized.culture?localized.culture:navigator.language||"en-US",B64ToBuff=n=>new Uint8Array(Array.from(atob(n),n=>n.charCodeAt(0))).buffer,getLocaleDateString=()=>(new Date).toLocaleDateString(getCurrentCulture());
|
||||
@@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Tests", "
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.API", "EnvelopeGenerator.API\EnvelopeGenerator.API.csproj", "{EC768913-6270-14F4-1DD3-69C87A659462}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.DependencyInjection", "EnvelopeGenerator.DependencyInjection\EnvelopeGenerator.DependencyInjection.csproj", "{90FE0312-8C38-4347-9EA2-0A719E255D5C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -85,6 +87,10 @@ Global
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{90FE0312-8C38-4347-9EA2-0A719E255D5C}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90FE0312-8C38-4347-9EA2-0A719E255D5C}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{90FE0312-8C38-4347-9EA2-0A719E255D5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90FE0312-8C38-4347-9EA2-0A719E255D5C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -104,6 +110,7 @@ Global
|
||||
{211619F5-AE25-4BA5-A552-BACAFE0632D3} = {9943209E-1744-4944-B1BA-4F87FC1A0EEB}
|
||||
{224C4845-1CDE-22B7-F3A9-1FF9297F70E8} = {0CBC2432-A561-4440-89BC-671B66A24146}
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{90FE0312-8C38-4347-9EA2-0A719E255D5C} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73E60370-756D-45AD-A19A-C40A02DACCC7}
|
||||
|
||||
Reference in New Issue
Block a user