feat: E-Mail-Vorlagenverarbeitung hinzufügen
- Methode `FillTemplate` für Platzhalterersetzung hinzugefügt. - `TemplatePlaceholderAttribute` eingeführt. - `EmailOutService` mit Vorlagenmethoden aktualisiert. - Unit-Tests für Vorlagenverarbeitung hinzugefügt.
This commit is contained in:
parent
1adc0c4d93
commit
a2bd369ed1
@ -1,8 +1,12 @@
|
|||||||
using DigitalData.Core.API;
|
using DigitalData.Core.API;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.API.Resources;
|
||||||
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
|
||||||
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Application.Services;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Domain.Attributes;
|
||||||
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
||||||
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace DigitalData.EmailProfilerGateway.API.Controllers
|
namespace DigitalData.EmailProfilerGateway.API.Controllers
|
||||||
{
|
{
|
||||||
@ -11,5 +15,45 @@ namespace DigitalData.EmailProfilerGateway.API.Controllers
|
|||||||
public MailController(ILogger<MailController> logger, IEmailOutService service) : base(logger, service)
|
public MailController(ILogger<MailController> logger, IEmailOutService service) : base(logger, service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
[HttpGet("fill-out")]
|
||||||
|
public IActionResult FillOut(string? template = null)
|
||||||
|
{
|
||||||
|
template ??= @"Guten Tag [NAME_RECEIVER],<br />
|
||||||
|
<br />
|
||||||
|
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B>.<br />
|
||||||
|
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
|
||||||
|
<br />
|
||||||
|
Mit freundlichen Grüßen<br />
|
||||||
|
<br />
|
||||||
|
[NAME_PORTAL]";
|
||||||
|
|
||||||
|
var mailData = new MailData();
|
||||||
|
|
||||||
|
var expectedOutput = @"Guten Tag Tom,<br />
|
||||||
|
<br />
|
||||||
|
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'Vertragsdokument'</I></B>.<br />
|
||||||
|
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
|
||||||
|
<br />
|
||||||
|
Mit freundlichen Grüßen<br />
|
||||||
|
<br />
|
||||||
|
DokumentenPortal";
|
||||||
|
|
||||||
|
var result = EmailOutService<Resource>.FillTemplate(template, mailData);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MailData
|
||||||
|
{
|
||||||
|
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
||||||
|
public string NameReceiver { get; set; } = "Tom";
|
||||||
|
|
||||||
|
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
|
||||||
|
public string DocumentTitle { get; set; } = "Vertragsdokument";
|
||||||
|
|
||||||
|
[TemplatePlaceholder("[NAME_PORTAL]")]
|
||||||
|
public string NamePortal { get; set; } = "DokumentenPortal";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,9 @@
|
|||||||
<Reference Include="DigitalData.Core.API">
|
<Reference Include="DigitalData.Core.API">
|
||||||
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.API.dll</HintPath>
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.API.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="DigitalData.Core.Application">
|
||||||
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.Application.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="DigitalData.Core.Contracts">
|
<Reference Include="DigitalData.Core.Contracts">
|
||||||
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ var config = builder.Configuration;
|
|||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
builder.Services.AddCookieBasedLocalizer();
|
builder.Services.AddCookieBasedLocalizer();
|
||||||
builder.Services.AddDispatcher(options => options.UseSqlServer(config.GetConnectionString("Default")));
|
builder.Services.AddDispatcher<Resource>(options => options.UseSqlServer(config.GetConnectionString("Default")));
|
||||||
|
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using DigitalData.Core.Contracts.Application;
|
using DigitalData.Core.Contracts.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
||||||
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
||||||
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
||||||
@ -7,5 +8,6 @@ namespace DigitalData.EmailProfilerDispatcher.Application.Contracts
|
|||||||
{
|
{
|
||||||
public interface IEmailOutService : ICRUDService<IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOutDto, EmailOut, int>
|
public interface IEmailOutService : ICRUDService<IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOutDto, EmailOut, int>
|
||||||
{
|
{
|
||||||
}
|
Task<DataResult<int>> CreateWithTemplateAsync(EmailOutCreateDto createDto, params object[] models);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,23 +1,25 @@
|
|||||||
namespace DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut
|
namespace DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut
|
||||||
{
|
{
|
||||||
public record EmailOutCreateDto(
|
public record EmailOutCreateDto
|
||||||
int ReminderTypeId,
|
{
|
||||||
int SendingProfile,
|
public int ReminderTypeId { get; set; }
|
||||||
int ReferenceId,
|
public int SendingProfile { get; set; }
|
||||||
string? ReferenceString,
|
public int ReferenceId { get; set; }
|
||||||
int? EntityId,
|
public int WfId { get; set; }
|
||||||
int WfId,
|
public string EmailAddress { get; set; }
|
||||||
string? WfReference,
|
public string EmailSubj { get; set; }
|
||||||
string EmailAddress,
|
public string EmailBody { get; set; }
|
||||||
string EmailSubj,
|
public string? ReferenceString { get; set; } = null;
|
||||||
string EmailBody,
|
public int? EntityId { get; set; } = null;
|
||||||
string? EmailAttmt1,
|
public string? WfReference { get; set; } = null;
|
||||||
DateTime? EmailSent,
|
public string? EmailAttmt1 { get; set; } = null;
|
||||||
string? Comment,
|
public DateTime? EmailSent { get; set; } = null;
|
||||||
string? AddedWho, // Default value will be 'DEFAULT', made nullable
|
public string? Comment { get; set; } = null;
|
||||||
string? ChangedWho,
|
public string? AddedWho { get; set; } = "DEFAULT";
|
||||||
DateTime? ChangedWhen,
|
public string? ChangedWho { get; set; } = null;
|
||||||
DateTime? ErrorTimestamp,
|
public DateTime? ChangedWhen { get; set; } = null;
|
||||||
string? ErrorMsg
|
public DateTime? ErrorTimestamp { get; set; } = null;
|
||||||
);
|
public string? ErrorMsg { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using DigitalData.Core.Application;
|
using DigitalData.Core.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
|
||||||
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Domain.Attributes;
|
||||||
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
||||||
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace DigitalData.EmailProfilerDispatcher.Application.Services
|
namespace DigitalData.EmailProfilerDispatcher.Application.Services
|
||||||
{
|
{
|
||||||
@ -13,5 +16,36 @@ namespace DigitalData.EmailProfilerDispatcher.Application.Services
|
|||||||
public EmailOutService(IEmailOutRepository repository, IStringLocalizer<TResource> localizer, IMapper mapper) : base(repository, localizer, mapper)
|
public EmailOutService(IEmailOutRepository repository, IStringLocalizer<TResource> localizer, IMapper mapper) : base(repository, localizer, mapper)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public string ApplyTemplate(string template, params object[] models) => FillTemplate(template: template, models: models);
|
||||||
|
|
||||||
|
public async Task<DataResult<int>> CreateWithTemplateAsync(EmailOutCreateDto createDto, params object[] models)
|
||||||
|
{
|
||||||
|
createDto.EmailSubj = FillTemplate(createDto.EmailSubj, models);
|
||||||
|
createDto.EmailBody = FillTemplate(createDto.EmailBody, models);
|
||||||
|
|
||||||
|
return await base.CreateAsync(createDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FillTemplate(string template, params object[] models)
|
||||||
|
{
|
||||||
|
foreach(var model in models)
|
||||||
|
{
|
||||||
|
var properties = model.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (var property in properties)
|
||||||
|
{
|
||||||
|
var attribute = property.GetCustomAttribute<TemplatePlaceholderAttribute>();
|
||||||
|
|
||||||
|
if (attribute != null)
|
||||||
|
{
|
||||||
|
var value = property.GetValue(model)?.ToString();
|
||||||
|
template = template.Replace(attribute.Placeholder, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
namespace DigitalData.EmailProfilerDispatcher.Domain.Attributes
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class TemplatePlaceholderAttribute : Attribute
|
||||||
|
{
|
||||||
|
public readonly string Placeholder;
|
||||||
|
|
||||||
|
public TemplatePlaceholderAttribute(string placeholder)
|
||||||
|
{
|
||||||
|
Placeholder = placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDi
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Infrastructure", "DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj", "{F02B6F5B-FB2F-4E20-996D-BE99E9768039}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Infrastructure", "DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj", "{F02B6F5B-FB2F-4E20-996D-BE99E9768039}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmailProfilerDispatcher.Tests", "EmailProfilerDispatcher.Tests\EmailProfilerDispatcher.Tests.csproj", "{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -33,6 +35,10 @@ Global
|
|||||||
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
|
||||||
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
|
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.API\DigitalData.EmailProfilerDispatcher.API.csproj" />
|
||||||
|
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Application\DigitalData.EmailProfilerDispatcher.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Domain\DigitalData.EmailProfilerDispatcher.Domain.csproj" />
|
||||||
|
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="DigitalData.Core.Application">
|
||||||
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.Application.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DigitalData.Core.Contracts">
|
||||||
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DigitalData.Core.DTO">
|
||||||
|
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.DTO.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="NUnit.Framework" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
68
EmailProfilerDispatcher.Tests/FillTemplateTests.cs
Normal file
68
EmailProfilerDispatcher.Tests/FillTemplateTests.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using DigitalData.EmailProfilerDispatcher.Application.Services;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Domain.Attributes;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
|
||||||
|
|
||||||
|
namespace EmailProfilerDispatcher.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class FillTemplateTests
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void FillTemplate_ShouldReplacePlaceholdersWithPropertyValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var template = @"Guten Tag [NAME_RECEIVER],<br />
|
||||||
|
<br />
|
||||||
|
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B>.<br />
|
||||||
|
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
|
||||||
|
<br />
|
||||||
|
Mit freundlichen Grüßen<br />
|
||||||
|
<br />
|
||||||
|
[NAME_PORTAL]";
|
||||||
|
|
||||||
|
var mailData1 = new MailData1();
|
||||||
|
var mailData2 = new MailData2();
|
||||||
|
var mailData3 = new MailData3();
|
||||||
|
|
||||||
|
var expectedOutput = @"Guten Tag Tom,<br />
|
||||||
|
<br />
|
||||||
|
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'Vertragsdokument'</I></B>.<br />
|
||||||
|
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
|
||||||
|
<br />
|
||||||
|
Mit freundlichen Grüßen<br />
|
||||||
|
<br />
|
||||||
|
DokumentenPortal";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = EmailOutService<Resource>.FillTemplate(template, mailData1, mailData2, mailData3);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo(expectedOutput));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Resource {}
|
||||||
|
|
||||||
|
public class MailData1
|
||||||
|
{
|
||||||
|
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
||||||
|
public string NameReceiver { get; set; } = "Tom";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MailData2
|
||||||
|
{
|
||||||
|
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
|
||||||
|
public string DocumentTitle { get; set; } = "Vertragsdokument";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MailData3
|
||||||
|
{
|
||||||
|
[TemplatePlaceholder("[NAME_PORTAL]")]
|
||||||
|
public string NamePortal { get; set; } = "DokumentenPortal";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user