DTO für EnvelopeHistory-Erstellung hinzugefügt, asynchrone Record-Methode implementiert und Datenbank-Trigger für Envelope- und EnvelopeHistory-Entitäten konfiguriert.

This commit is contained in:
Developer 02 2024-05-16 16:40:38 +02:00
parent 81220ac9b4
commit 2e66129485
11 changed files with 39 additions and 22 deletions

View File

@ -1,17 +1,20 @@
using DigitalData.Core.Contracts.Application; using DigitalData.Core.Contracts.Application;
using EnvelopeGenerator.Application.DTOs; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Contracts;
using static EnvelopeGenerator.Common.Constants; using static EnvelopeGenerator.Common.Constants;
namespace EnvelopeGenerator.Application.Contracts namespace EnvelopeGenerator.Application.Contracts
{ {
public interface IEnvelopeHistoryService : IBasicCRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long> public interface IEnvelopeHistoryService : ICRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>
{ {
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null); Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null);
Task<bool> AccessCodeAlreadyRequested(int envelopeId, string userReference); Task<bool> AccessCodeAlreadyRequested(int envelopeId, string userReference);
Task<bool> IsSigned(int envelopeId, string userReference); Task<bool> IsSigned(int envelopeId, string userReference);
Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status);
} }
} }

View File

@ -1,4 +1,5 @@
using DigitalData.UserManager.Domain.Entities; using DigitalData.UserManager.Domain.Entities;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.DTOs namespace EnvelopeGenerator.Application.DTOs

View File

@ -0,0 +1,8 @@
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
{
public record EnvelopeHistoryCreateDto(
int EnvelopeId,
string UserReference,
int Status,
DateTime? ActionDate);
}

View File

@ -1,4 +1,4 @@
namespace EnvelopeGenerator.Application.DTOs namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
{ {
public record EnvelopeHistoryDto( public record EnvelopeHistoryDto(
long Id, long Id,

View File

@ -1,5 +1,6 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.MappingProfiles namespace EnvelopeGenerator.Application.MappingProfiles
@ -17,6 +18,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>(); CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>(); CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
CreateMap<EnvelopeHistory, EnvelopeHistoryDto>(); CreateMap<EnvelopeHistory, EnvelopeHistoryDto>();
CreateMap<EnvelopeHistory, EnvelopeHistoryCreateDto>();
CreateMap<EnvelopeReceiver, EnvelopeReceiverDto>(); CreateMap<EnvelopeReceiver, EnvelopeReceiverDto>();
CreateMap<EnvelopeType, EnvelopeTypeDto>(); CreateMap<EnvelopeType, EnvelopeTypeDto>();
CreateMap<Receiver, ReceiverDto>(); CreateMap<Receiver, ReceiverDto>();
@ -32,6 +34,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>(); CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>(); CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
CreateMap<EnvelopeHistoryDto, EnvelopeHistory>(); CreateMap<EnvelopeHistoryDto, EnvelopeHistory>();
CreateMap<EnvelopeHistoryCreateDto, EnvelopeHistory>();
CreateMap<EnvelopeReceiverDto, EnvelopeReceiver>(); CreateMap<EnvelopeReceiverDto, EnvelopeReceiver>();
CreateMap<EnvelopeTypeDto, EnvelopeType>(); CreateMap<EnvelopeTypeDto, EnvelopeType>();
CreateMap<ReceiverDto, Receiver>(); CreateMap<ReceiverDto, Receiver>();

View File

@ -2,15 +2,16 @@
using DigitalData.Core.Application; using DigitalData.Core.Application;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Contracts;
using static EnvelopeGenerator.Common.Constants; using static EnvelopeGenerator.Common.Constants;
using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Resources;
using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
namespace EnvelopeGenerator.Application.Services namespace EnvelopeGenerator.Application.Services
{ {
public class EnvelopeHistoryService : BasicCRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
{ {
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper) public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper)
: base(repository, localizer, mapper) : base(repository, localizer, mapper)
@ -33,5 +34,12 @@ namespace EnvelopeGenerator.Application.Services
envelopeId: envelopeId, envelopeId: envelopeId,
userReference: userReference, userReference: userReference,
status: (int) EnvelopeStatus.DocumentSigned) > 0; status: (int) EnvelopeStatus.DocumentSigned) > 0;
public async Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status) =>
await CreateAsync(new (EnvelopeId: envelopeId, UserReference: userReference, Status: (int)status, ActionDate: DateTime.Now))
.ThenAsync(
Success: id => Result.Success(id),
Fail: (mssg, ntc) => Result.Fail<long>().Message(mssg).Notice(ntc)
);
} }
} }

View File

@ -25,6 +25,7 @@ namespace EnvelopeGenerator.Domain.Entities
[Required] [Required]
[Column("ADDED_WHEN", TypeName = "datetime")] [Column("ADDED_WHEN", TypeName = "datetime")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime AddedWhen { get; set; } public DateTime AddedWhen { get; set; }
[Column("ACTION_DATE", TypeName = "datetime")] [Column("ACTION_DATE", TypeName = "datetime")]

View File

@ -33,11 +33,6 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
.WithOne() .WithOne()
.HasForeignKey(ed => ed.EnvelopeId); .HasForeignKey(ed => ed.EnvelopeId);
//modelBuilder.Entity<Envelope>()
// .HasMany(e => e.Receivers)
// .WithOne(er => er.Envelope)
// .HasForeignKey(er => er.EnvelopeId);
modelBuilder.Entity<Envelope>() modelBuilder.Entity<Envelope>()
.HasMany(e => e.History) .HasMany(e => e.History)
.WithOne() .WithOne()
@ -53,10 +48,9 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
.WithMany(ed => ed.Elements) .WithMany(ed => ed.Elements)
.HasForeignKey(dre => dre.DocumentId); .HasForeignKey(dre => dre.DocumentId);
//modelBuilder.Entity<Receiver>() // Configure entities to handle database triggers
// .HasMany(e => e.EnvelopeReceivers) modelBuilder.Entity<Envelope>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
// .WithOne(er => er.Receiver) modelBuilder.Entity<EnvelopeHistory>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
// .HasForeignKey(er => er.ReceiverId);
base.OnModelCreating(modelBuilder); base.OnModelCreating(modelBuilder);
} }

View File

@ -56,8 +56,8 @@ namespace EnvelopeGenerator.Web.Controllers
bool accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress); bool accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress);
if (!accessCodeAlreadyRequested) if (!accessCodeAlreadyRequested)
{ {
// Send email with password await _historyService.RecordAsync(er.EnvelopeId, er.Receiver.EmailAddress, Constants.EnvelopeStatus.AccessCodeRequested);
bool actionResult = database.Services.actionService.RequestAccessCode(response.Envelope, response.Receiver);
bool result = database.Services.emailService.SendDocumentAccessCodeReceivedEmail(response.Envelope, response.Receiver); bool result = database.Services.emailService.SendDocumentAccessCodeReceivedEmail(response.Envelope, response.Receiver);
} }
@ -89,13 +89,12 @@ namespace EnvelopeGenerator.Web.Controllers
UserLanguage = _cultures.Default.Language; UserLanguage = _cultures.Default.Language;
return Redirect($"{Request.Headers["Referer"]}?culture={_cultures.Default.Language}"); return Redirect($"{Request.Headers["Referer"]}?culture={_cultures.Default.Language}");
} }
else if (UserLanguage is not null && culture is not null)
if (UserLanguage is not null && culture is not null)
{ {
return Redirect($"Locked"); return Redirect($"Locked");
} }
ViewData["UserLanguage"] = UserLanguage; ViewData["UserLanguage"] = UserLanguage ?? culture;
return await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId).ThenAsync( return await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId).ThenAsync(
Success: isExisting => isExisting ? View().WithData("EnvelopeKey", envelopeReceiverId) : this.ViewEnvelopeNotFound(), Success: isExisting => isExisting ? View().WithData("EnvelopeKey", envelopeReceiverId) : this.ViewEnvelopeNotFound(),

View File

@ -1,13 +1,13 @@
using DigitalData.Core.API; using DigitalData.Core.API;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Contracts;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Web.Controllers.Test namespace EnvelopeGenerator.Web.Controllers.Test
{ {
public class TestEnvelopeHistoryController : TestControllerBase<IEnvelopeHistoryService, IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long> public class TestEnvelopeHistoryController : CRUDControllerBase<IEnvelopeHistoryService, IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>
{ {
public TestEnvelopeHistoryController(ILogger<TestEnvelopeHistoryController> logger, IEnvelopeHistoryService service) : base(logger, service) public TestEnvelopeHistoryController(ILogger<TestEnvelopeHistoryController> logger, IEnvelopeHistoryService service) : base(logger, service)
{ {

View File

@ -19,7 +19,7 @@
}, },
"PSPDFKitLicenseKey": null, "PSPDFKitLicenseKey": null,
/* The first format parameter {0} will be replaced by the nonce value. */ /* The first format parameter {0} will be replaced by the nonce value. */
"TestCSP": true, "TestCSP": false,
"Content-Security-Policy": [ "Content-Security-Policy": [
"default-src 'self'", "default-src 'self'",
"script-src 'self' 'nonce-{0}' 'unsafe-inline' 'unsafe-eval' blob: data:", "script-src 'self' 'nonce-{0}' 'unsafe-inline' 'unsafe-eval' blob: data:",