Refactor UpdateEmailTemplateCommand and handler

- Introduce EmailTemplateUpdateDto for update payloads.
- Expose Id and Type directly on UpdateEmailTemplateCommand; remove EmailTemplateQuery property.
- Add QueryExpression for flexible template selection by Id or Type.
- Remove AutoMapper and EmailTemplateDto usage from handler; update repository call to use EmailTemplateUpdateDto.
- Update MappingProfile to map EmailTemplateUpdateDto to EmailTemplate and set ChangedWhen to DateTime.UtcNow.
- Remove obsolete code and improve documentation.
This commit is contained in:
2026-02-09 11:20:34 +01:00
parent de36e29743
commit b227eb4051
2 changed files with 44 additions and 55 deletions

View File

@@ -1,37 +1,56 @@
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using MediatR;
using System.Text.Json.Serialization;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using System.Linq.Expressions;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands;
/// <summary>
///
/// </summary>
/// <param name="Body"></param>
/// <param name="Subject"></param>
public record EmailTemplateUpdateDto(string Body, string Subject);
/// <summary>
/// Befehl zum Aktualisieren einer E-Mail-Vorlage.
/// </summary>
/// <param name="Body">
/// (Optional)Der neue Inhalt des E-Mail-Textkörpers. Wenn null, bleibt der vorhandene Inhalt unverändert.
/// </param>
/// <param name="Subject">
/// (Optional) Der neue Betreff der E-Mail. Wenn null, bleibt der vorhandene Betreff unverändert.
/// </param>
public record UpdateEmailTemplateCommand(string? Body = null, string? Subject = null) : IRequest
public record UpdateEmailTemplateCommand : IEmailTemplateQuery, IRequest
{
/// <param>
/// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll.
/// </param>
[JsonIgnore]
public IEmailTemplateQuery? EmailTemplateQuery { get; set; }
/// <summary>
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
/// </summary>
public int? Id { get; set; }
/// <summary>
/// Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:<br/>
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
/// 7 - DocumentRejected_ADM (für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
/// 8 - DocumentRejected_REC (für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
/// </summary>
public EmailTemplateType? Type { get; set; }
/// <summary>
///
/// </summary>
[JsonIgnore]
public DateTime ChangedWhen { get; init; } = DateTime.Now;
public Expression<Func<EmailTemplate, bool>> QueryExpression => Id is int id
? temp => temp.Id == id
: temp => temp!.Name == Type.ToString();
/// <summary>
/// Die aktualisierte E-Mail-Vorlage.
/// </summary>
public EmailTemplateUpdateDto Update { get; init; } = null!;
}
/// <summary>
@@ -41,17 +60,13 @@ public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemp
{
private readonly IRepository<EmailTemplate> _repository;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
/// <param name="mapper"></param>
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository, IMapper mapper)
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository)
{
_repository = repository;
_mapper = mapper;
}
/// <summary>
@@ -62,31 +77,6 @@ public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemp
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="NotFoundException"></exception>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
{
EmailTemplateDto? tempDto;
if (request.EmailTemplateQuery?.Id is int id)
{
var temp = await _repository.ReadOnly().Where(t => t.Id == id).FirstOrDefaultAsync(cancel);
tempDto = _mapper.Map<EmailTemplateDto>(temp);
}
else if (request!.EmailTemplateQuery!.Type is EmailTemplateType type)
{
var temp = await _repository.ReadOnly().Where(t => t.Name == type.ToString()).FirstOrDefaultAsync(cancel);
tempDto = _mapper.Map<EmailTemplateDto>(temp);
}
else
{
throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id + ". Type: " + request.EmailTemplateQuery.Type.ToString());
}
if (tempDto == null)
{
throw new NotFoundException();
}
await _repository.UpdateAsync(tempDto, t => t.Id == tempDto.Id, cancel);
}
public Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
=> _repository.UpdateAsync(request.Update, request.QueryExpression, cancel);
}

View File

@@ -17,8 +17,7 @@ public class MappingProfile : Profile
{
CreateMap<EmailTemplate, EmailTemplateDto>();
CreateMap<UpdateEmailTemplateCommand, EmailTemplate>()
.ForMember(dest => dest.Id, opt => opt.Ignore())
.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.Now));
CreateMap<EmailTemplateUpdateDto, EmailTemplate>()
.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
}
}