diff --git a/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs new file mode 100644 index 00000000..b812ea31 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IDocumentReceiverElementService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs b/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs new file mode 100644 index 00000000..337c1d68 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IDocumentStatusService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs b/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs new file mode 100644 index 00000000..8151916e --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEmailTemplateService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs new file mode 100644 index 00000000..52d547a0 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEnvelopeCertificateService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs new file mode 100644 index 00000000..9192756f --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEnvelopeHistoryService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs new file mode 100644 index 00000000..348257e0 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs @@ -0,0 +1,12 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEnvelopeReceiverService : IBasicCRUDService + { + Task VerifyAccessCode(string envelopeUuid, string accessCode); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs new file mode 100644 index 00000000..6ce6d9e3 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEnvelopeService : IBasicCRUDService + { + Task>> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = false); + + Task> ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs new file mode 100644 index 00000000..0a480c0a --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IEnvelopeTypeService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IReceiverService.cs new file mode 100644 index 00000000..9480eec8 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IReceiverService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IReceiverService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs new file mode 100644 index 00000000..caf0fea0 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Contracts.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Contracts +{ + public interface IUserReceiverService : IBasicCRUDService + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs index b728de31..751ab329 100644 --- a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs +++ b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs @@ -1,15 +1,12 @@ namespace EnvelopeGenerator.Application.DTOs { - public record ConfigDto - { - public string DocumentPath { get; init; } - public int SendingProfile { get; init; } - public string SignatureHost { get; init; } - public string ExternalProgramName { get; init; } - public string ExportPath { get; init; } - public string DocumentPathDmz { get; init; } - public string ExportPathDmz { get; init; } - public string SignedMailPath { get; init; } - public string DocumentPathMoveAftsend { get; init; } - } + public record ConfigDto( + string DocumentPath, + int SendingProfile, + string SignatureHost, + string ExternalProgramName, + string ExportPath, + string DocumentPathDmz, + string ExportPathDmz, + string DocumentPathMoveAftsend); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs new file mode 100644 index 00000000..06e700b1 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs @@ -0,0 +1,22 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record DocumentReceiverElementDto( + int Id, + int DocumentId, + int ReceiverId, + int ElementType, + double PositionX, + double PositionY, + double Width, + double Height, + int Page, + bool Required, + string? Tooltip, + bool ReadOnly, + int AnnotationIndex, + DateTime AddedWhen, + DateTime? ChangedWhen, + double Top, + double Left + ); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs new file mode 100644 index 00000000..4037c064 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs @@ -0,0 +1,12 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record DocumentStatusDto( + int Id, + int EnvelopeId, + int ReceiverId, + int Status, + DateTime? StatusChangedWhen, + string Value, + DateTime AddedWhen, + DateTime? ChangedWhen); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs new file mode 100644 index 00000000..5ec688ab --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs @@ -0,0 +1,8 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record EmailTemplateDto( + int Id, + string Name, + string Body, + string Subject); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs new file mode 100644 index 00000000..44547d1e --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs @@ -0,0 +1,12 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record EnvelopeCertificateDto( + int Id, + int EnvelopeId, + string EnvelopeUuid, + string EnvelopeSubject, + int CreatorId, + string CreatorName, + string CreatorEmail, + int EnvelopeStatus); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs index c5ea7402..6f1d816c 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs @@ -1,12 +1,13 @@ namespace EnvelopeGenerator.Application.DTOs { public record EnvelopeDocumentDto - { - public int Guid { get; init; } - public int EnvelopeId { get; init; } - public string Filename { get; init; } - public string Filepath { get; init; } - public DateTime AddedWhen { get; init; } - public string FilenameOriginal { get; init; } - } + ( + int Id, + int EnvelopeId, + string Filename, + string Filepath, + DateTime AddedWhen, + string FilenameOriginal, + IEnumerable? Elements + ); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs new file mode 100644 index 00000000..0a352d7f --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs @@ -0,0 +1,38 @@ +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.DTOs +{ + public record EnvelopeDto( + int Id, + int UserId, + int Status, + string Uuid, + string Message, + DateTime? ExpiresWhen, + DateTime? ExpiresWarningWhen, + DateTime AddedWhen, + DateTime? ChangedWhen, + string Title, + int? ContractType, + string Language, + bool? SendReminderEmails, + int? FirstReminderDays, + int? ReminderIntervalDays, + int? EnvelopeTypeId, + int? CertificationType, + bool? UseAccessCode, + int? FinalEmailToCreator, + int? FinalEmailToReceivers, + int? ExpiresWhenDays, + int? ExpiresWarningWhenDays, + bool DmzMoved, + ReceiverDto? User, + EnvelopeType? EnvelopeType, + string? EnvelopeTypeTitle, + bool IsAlreadySent, + string? StatusTranslated, + string? ContractTypeTranslated, + IEnumerable? Documents, + IEnumerable? Receivers, + IEnumerable? History); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeHistoryDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeHistoryDto.cs new file mode 100644 index 00000000..8efd12e1 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeHistoryDto.cs @@ -0,0 +1,10 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record EnvelopeHistoryDto( + long Id, + int EnvelopeId, + string UserReference, + int Status, + DateTime AddedWhen, + DateTime? ActionDate); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs new file mode 100644 index 00000000..02404c47 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs @@ -0,0 +1,17 @@ +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.DTOs +{ + public record EnvelopeReceiverDto( + int EnvelopeId, + int ReceiverId, + int Sequence, + string Name, + string JobTitle, + string CompanyName, + string PrivateMessage, + DateTime AddedWhen, + DateTime? ChangedWhen, + Envelope? Envelope, + Receiver? Receiver); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs new file mode 100644 index 00000000..2342784d --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs @@ -0,0 +1,19 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record EnvelopeTypeDto( + int Id, + string Title, + string Language, + int? ExpiresDays, + int? CertificationType, + bool? UseAccessCode, + int? FinalEmailToCreator, + int? FinalEmailToReceivers, + DateTime AddedWhen, + DateTime? ChangedWhen, + int? ExpiresWarningDays, + bool? SendReminderEmails, + int? FirstReminderDays, + int? ReminderIntervalDays, + int? ContractType); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/ReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/ReceiverDto.cs new file mode 100644 index 00000000..8e3a3f96 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/ReceiverDto.cs @@ -0,0 +1,9 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record ReceiverDto( + int Id, + string EmailAddress, + string Signature, + DateTime AddedWhen, + IEnumerable? EnvelopeReceivers); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs new file mode 100644 index 00000000..8c80ecd8 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs @@ -0,0 +1,11 @@ +namespace EnvelopeGenerator.Application.DTOs +{ + public record UserReceiverDto( + int Id, + int UserId, + int ReceiverId, + string Name, + string CompanyName, + string JobTitle, + DateTime AddedWhen); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs b/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs index 2a4dc6d3..3dbe14a5 100644 --- a/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs +++ b/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs @@ -8,11 +8,33 @@ namespace EnvelopeGenerator.Application.MappingProfiles { public BasicDtoMappingProfile() { + // Entity to DTO mappings CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + // DTO to Entity mappings CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs new file mode 100644 index 00000000..5fd3b4c6 --- /dev/null +++ b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class DocumentReceiverElementService : BasicCRUDService, IDocumentReceiverElementService + { + public DocumentReceiverElementService(IDocumentReceiverElementRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/DocumentStatusService.cs b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs new file mode 100644 index 00000000..7c6f6306 --- /dev/null +++ b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class DocumentStatusService : BasicCRUDService, IDocumentStatusService + { + public DocumentStatusService(IDocumentStatusRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EmailTemplateService.cs b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs new file mode 100644 index 00000000..653ef99c --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class EmailTemplateService : BasicCRUDService, IEmailTemplateService + { + public EmailTemplateService(IEmailTemplateRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs b/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs new file mode 100644 index 00000000..9752a0d3 --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class EnvelopeCertificateService : BasicCRUDService, IEnvelopeCertificateService + { + public EnvelopeCertificateService(IEnvelopeCertificateRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeGeneratorExtensions.cs b/EnvelopeGenerator.Application/Services/EnvelopeGeneratorExtensions.cs new file mode 100644 index 00000000..d111202b --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeGeneratorExtensions.cs @@ -0,0 +1,39 @@ +namespace EnvelopeGenerator.Application.Services +{ + /// + /// Provides extension methods for decoding and extracting information from an envelope receiver ID. + /// + public static class EnvelopeGeneratorExtensions + { + /// + /// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature. + /// + /// The base64 encoded string containing the envelope UUID and receiver signature. + /// A tuple containing the envelope UUID and receiver signature. + public static (string EnvelopeUuid, string ReceiverSignature) DecodeEnvelopeReceiverId(this string envelopeReceiverId) + { + byte[] bytes = Convert.FromBase64String(envelopeReceiverId); + string decodedString = System.Text.Encoding.UTF8.GetString(bytes); + string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None); + + if (parts.Length > 1) + return (EnvelopeUuid: parts[0], ReceiverSignature: parts[1]); + else + return (string.Empty, string.Empty); + } + + /// + /// Gets the envelope UUID from the decoded envelope receiver ID. + /// + /// The base64 encoded string to decode. + /// The envelope UUID. + public static string GetEnvelopeUuid(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().EnvelopeUuid; + + /// + /// Gets the receiver signature from the decoded envelope receiver ID. + /// + /// The base64 encoded string to decode. + /// The receiver signature. + public static string GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature; + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs new file mode 100644 index 00000000..67784a0f --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class EnvelopeHistoryService : BasicCRUDService, IEnvelopeHistoryService + { + public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs new file mode 100644 index 00000000..787ed26f --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs @@ -0,0 +1,26 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; +using Microsoft.EntityFrameworkCore; + +namespace EnvelopeGenerator.Application.Services +{ + public class EnvelopeReceiverService : BasicCRUDService, IEnvelopeReceiverService + { + public EnvelopeReceiverService(IEnvelopeReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + + public async Task VerifyAccessCode(string envelopeUuid, string accessCode) + { + var envelopeAccessCode = await _repository.ReadAccessCodeByEnvelopeUuid(envelopeUuid); + return CreateMessage(isSuccess: accessCode == envelopeAccessCode) ; + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeService.cs new file mode 100644 index 00000000..efd6055f --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeService.cs @@ -0,0 +1,37 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class EnvelopeService : BasicCRUDService, IEnvelopeService + { + public EnvelopeService(IEnvelopeRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + + public async Task>> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = false) + { + var envelopes = await _repository.ReadAllWithAsync(documents: documents, receivers: receivers, history: history, documentReceiverElement: documentReceiverElement); + var readDto = _mapper.MapOrThrow>(envelopes); + return Successful(readDto); + } + + public async Task> ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false) + { + var envelope = await _repository.ReadByUuidAsync(uuid: uuid, signature: signature, withDocuments: withDocuments, withReceivers: withReceivers, withHistory: withHistory, withDocumentReceiverElement: withDocumentReceiverElement, withAll:withAll); + + if (envelope is null) + return Failed(); + + var readDto = _mapper.MapOrThrow(envelope); + return Successful(readDto); + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs new file mode 100644 index 00000000..c48e8a62 --- /dev/null +++ b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class EnvelopeTypeService : BasicCRUDService, IEnvelopeTypeService + { + public EnvelopeTypeService(IEnvelopeTypeRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/ReceiverService.cs b/EnvelopeGenerator.Application/Services/ReceiverService.cs new file mode 100644 index 00000000..301772a5 --- /dev/null +++ b/EnvelopeGenerator.Application/Services/ReceiverService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class ReceiverService : BasicCRUDService, IReceiverService + { + public ReceiverService(IReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/UserReceiverService.cs b/EnvelopeGenerator.Application/Services/UserReceiverService.cs new file mode 100644 index 00000000..57d9c1aa --- /dev/null +++ b/EnvelopeGenerator.Application/Services/UserReceiverService.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DigitalData.Core.Application; +using DigitalData.Core.Contracts.CultureServices; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Application.Services +{ + public class UserReceiverService : BasicCRUDService, IUserReceiverService + { + public UserReceiverService(IUserReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper) + : base(repository, translationService, mapper) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Constants.cs b/EnvelopeGenerator.Domain/Constants.cs new file mode 100644 index 00000000..eeccbea2 --- /dev/null +++ b/EnvelopeGenerator.Domain/Constants.cs @@ -0,0 +1,119 @@ +namespace EnvelopeGenerator.Domain +{ + public class Constants + { + #region Status Fields + public enum EnvelopeStatus + { + Invalid = 0, + EnvelopeCreated = 1001, + EnvelopeSaved = 1002, + EnvelopeQueued = 1003, + EnvelopeSent = 1004, // Not used + EnvelopePartlySigned = 1005, + EnvelopeCompletelySigned = 1006, + EnvelopeReportCreated = 1007, + EnvelopeArchived = 1008, + EnvelopeDeleted = 1009, + AccessCodeRequested = 2001, + AccessCodeCorrect = 2002, + AccessCodeIncorrect = 2003, + DocumentOpened = 2004, + DocumentSigned = 2005, + SignatureConfirmed = 2006, + MessageInvitationSent = 3001, // Used by Trigger + MessageAccessCodeSent = 3002, + MessageConfirmationSent = 3003, + MessageDeletionSent = 3004, + MessageCompletionSent = 3005 + } + + public enum ElementStatus + { + Created = 0 + } + + public enum DocumentStatus + { + Created = 0, + Signed = 1 + } + + public enum ReceiverStatus + { + Unsigned = 0, + Signed = 1 + } + + #endregion + + #region Type Fields + + public enum ElementType + { + Signature = 1 + } + + public enum ContractType + { + Contract = 1, + ReadAndSign = 2 + } + + public enum ColorType + { + ReceiverColor1 = 1, + ReceiverColor2 = 2, + ReceiverColor3 = 3, + ReceiverColor4 = 4, + ReceiverColor5 = 5, + ReceiverColor6 = 6, + ReceiverColor7 = 7, + ReceiverColor8 = 8, + ReceiverColor9 = 9, + ReceiverColor10 = 10 + } + + public enum CertificationType + { + ElectronicSignature = 1, + QualifiedSignature = 2 + } + + public enum FinalEmailType + { + No = 0, + Yes = 1, + YesWithAttachment = 2 + } + + public enum PageOrientation + { + Portrait = 0, + Landscape = 1 + } + + public enum EmailTemplateType + { + DocumentReceived, + DocumentSigned, + DocumentDeleted, + DocumentCompleted, + DocumentAccessCodeReceived + } + + #endregion + + #region Constants + + public const string DATABASE = "DATABASE"; + public const string LOGCONFIG = "LOGCONFIG"; + public const string GDPICTURE = "GDPICTURE"; + + public const string GREEN_300 = "#bbf7d0"; + public const string RED_300 = "#fecaca"; + public const string ORANGE_300 = "#fed7aa"; + + #endregion + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/Config.cs b/EnvelopeGenerator.Domain/Entities/Config.cs index ff689bf4..6c91262c 100644 --- a/EnvelopeGenerator.Domain/Entities/Config.cs +++ b/EnvelopeGenerator.Domain/Entities/Config.cs @@ -40,4 +40,4 @@ namespace EnvelopeGenerator.Domain.Entities [DefaultValue("")] // This sets the default value for DOCUMENT_PATH_MOVE_AFTSEND public string DocumentPathMoveAftsend { get; set; } } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs b/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs new file mode 100644 index 00000000..537f215c --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs @@ -0,0 +1,91 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")] + public class DocumentReceiverElement + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("DOCUMENT_ID")] + public int DocumentId { get; set; } + + [Required] + [Column("RECEIVER_ID")] + public int ReceiverId { get; set; } + + [Required] + [Column("ELEMENT_TYPE")] + [DefaultValue(0)] + public int ElementType { get; set; } + + [Required] + [Column("POSITION_X")] + [DefaultValue(0)] + public double PositionX { get; set; } + + [Required] + [Column("POSITION_Y")] + [DefaultValue(0)] + public double PositionY { get; set; } + + [Required] + [Column("WIDTH")] + [DefaultValue(0)] + public double Width { get; set; } + + [Required] + [Column("HEIGHT")] + [DefaultValue(0)] + public double Height { get; set; } + + [Required] + [Column("PAGE")] + [DefaultValue(1)] + public int Page { get; set; } + + [Required] + [Column("REQUIRED")] + [DefaultValue(false)] + public bool Required { get; set; } + + [Column("TOOLTIP")] + public string? Tooltip { get; set; } + + [Required] + [Column("READ_ONLY")] + [DefaultValue(false)] + public bool ReadOnly { get; set; } + + [Required] + [Column("ANNOTATION_INDEX")] + [DefaultValue(0)] + public int AnnotationIndex { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + [DefaultValue("GETDATE()")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + [ForeignKey("DocumentId")] + public virtual EnvelopeDocument? Document { get; set; } + + [ForeignKey("ReceiverId")] + public virtual Receiver? Receiver { get; set; } + + [NotMapped] + public double Top => Math.Round(PositionY, 5); + + [NotMapped] + public double Left => Math.Round(PositionX, 5); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs new file mode 100644 index 00000000..7ee87a27 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs @@ -0,0 +1,45 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_DOCUMENT_STATUS", Schema = "dbo")] + public class DocumentStatus + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("ENVELOPE_ID")] + public int EnvelopeId { get; set; } + + [Required] + [Column("RECEIVER_ID")] + public int ReceiverId { get; set; } + + [Required] + [Column("STATUS")] + public int Status { get; set; } + + [Column("STATUS_CHANGED_WHEN", TypeName = "datetime")] + public DateTime? StatusChangedWhen { get; set; } + + [Column("VALUE", TypeName = "nvarchar(max)")] + public string Value { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + [ForeignKey("EnvelopeId")] + public virtual Envelope? Envelope { get; set; } + + [ForeignKey("ReceiverId")] + public virtual Receiver? Receiver { get; set; } + } +} diff --git a/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs b/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs new file mode 100644 index 00000000..c82f3d4e --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_EMAIL_TEMPLATE", Schema = "dbo")] + public class EmailTemplate + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Column("NAME", TypeName = "nvarchar(64)")] + public string Name { get; set; } + + [Column("BODY", TypeName = "nvarchar(max)")] + public string Body { get; set; } + + [Column("SUBJECT", TypeName = "nvarchar(512)")] + public string Subject { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/Envelope.cs b/EnvelopeGenerator.Domain/Entities/Envelope.cs new file mode 100644 index 00000000..95e17c12 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/Envelope.cs @@ -0,0 +1,118 @@ +using EnvelopeGenerator.Common.My.Resources; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE", Schema = "dbo")] + public class Envelope + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("USER_ID")] + public int UserId { get; set; } + + [Required] + [Column("STATUS")] + public int Status { get; set; } + + [Required] + [Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")] + public string Uuid { get; set; } + + [Required] + [Column("MESSAGE", TypeName = "nvarchar(max)")] + public string Message { get; set; } + + [Column("EXPIRES_WHEN", TypeName = "datetime")] + public DateTime? ExpiresWhen { get; set; } + + [Column("EXPIRES_WARNING_WHEN", TypeName = "datetime")] + public DateTime? ExpiresWarningWhen { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + [Column("TITLE", TypeName = "nvarchar(128)")] + public string Title { get; set; } + + [Column("CONTRACT_TYPE")] + public int? ContractType { get; set; } + + [Column("LANGUAGE", TypeName = "nvarchar(5)")] + public string Language { get; set; } + + [Column("SEND_REMINDER_EMAILS")] + public bool? SendReminderEmails { get; set; } + + [Column("FIRST_REMINDER_DAYS")] + public int? FirstReminderDays { get; set; } + + [Column("REMINDER_INTERVAL_DAYS")] + public int? ReminderIntervalDays { get; set; } + + [Column("ENVELOPE_TYPE")] + public int? EnvelopeTypeId { get; set; } + + [Column("CERTIFICATION_TYPE")] + public int? CertificationType { get; set; } + + [Column("USE_ACCESS_CODE")] + public bool? UseAccessCode { get; set; } + + [Column("FINAL_EMAIL_TO_CREATOR")] + public int? FinalEmailToCreator { get; set; } + + [Column("FINAL_EMAIL_TO_RECEIVERS")] + public int? FinalEmailToReceivers { get; set; } + + [Column("EXPIRES_WHEN_DAYS")] + public int? ExpiresWhenDays { get; set; } + + [Column("EXPIRES_WARNING_WHEN_DAYS")] + public int? ExpiresWarningWhenDays { get; set; } + + [Required] + [Column("DMZ_MOVED")] + public bool DmzMoved { get; set; } + + [ForeignKey("UserId")] + public Receiver? User { get; set; } + + [ForeignKey("EnvelopeTypeId")] + public EnvelopeType? EnvelopeType { get; set; } + + [NotMapped] + public string? EnvelopeTypeTitle => EnvelopeType?.Title; + + [NotMapped] + public bool IsAlreadySent => Status > (int) Constants.EnvelopeStatus.EnvelopeSaved; + + [NotMapped] + public string? StatusTranslated => Model.ResourceManager.GetString(Status.ToString()); + + [NotMapped] + public string? ContractTypeTranslated + { + get + { + string? oContractType = ContractType.ToString(); + return oContractType is null ? default : Model.ResourceManager.GetString(oContractType); + } + } + + public IEnumerable? Documents { get; set; } + + public IEnumerable? Receivers { get; set; } + + public IEnumerable? History { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs new file mode 100644 index 00000000..c8bd8c6e --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs @@ -0,0 +1,42 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE_CERTIFICATE", Schema = "dbo")] + public class EnvelopeCertificate + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("ENVELOPE_ID")] + public int EnvelopeId { get; set; } + + [Required] + [Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")] + public string EnvelopeUuid { get; set; } + + [Required] + [Column("ENVELOPE_SUBJECT", TypeName = "nvarchar(512)")] + public string EnvelopeSubject { get; set; } + + [Required] + [Column("CREATOR_ID")] + public int CreatorId { get; set; } + + [Required] + [Column("CREATOR_NAME", TypeName = "nvarchar(128)")] + public string CreatorName { get; set; } + + [Required] + [Column("CREATOR_EMAIL", TypeName = "nvarchar(128)")] + public string CreatorEmail { get; set; } + + [Required] + [Column("ENVELOPE_STATUS")] + public int EnvelopeStatus { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs index a70efdc4..b5e64977 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs @@ -8,26 +8,28 @@ namespace EnvelopeGenerator.Domain.Entities { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - [Column("GUID", TypeName = "int")] - public int Guid { get; set; } + [Column("GUID")] + public int Id { get; set; } - [Column("ENVELOPE_ID", TypeName = "int")] [Required] + [Column("ENVELOPE_ID")] public int EnvelopeId { get; set; } - [Column("FILENAME", TypeName = "nvarchar(256)")] [Required] + [Column("FILENAME", TypeName = "nvarchar(256)")] public string Filename { get; set; } - [Column("FILEPATH", TypeName = "nvarchar(256)")] [Required] + [Column("FILEPATH", TypeName = "nvarchar(256)")] public string Filepath { get; set; } - [Column("ADDED_WHEN", TypeName = "datetime")] [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] public DateTime AddedWhen { get; set; } [Column("FILENAME_ORIGINAL", TypeName = "nvarchar(256)")] public string FilenameOriginal { get; set; } + + public IEnumerable? Elements { get; set; } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs new file mode 100644 index 00000000..20ee71bc --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs @@ -0,0 +1,33 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE_HISTORY", Schema = "dbo")] + public class EnvelopeHistory + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public long Id { get; set; } + + [Required] + [Column("ENVELOPE_ID")] + public int EnvelopeId { get; set; } + + [Required] + [Column("USER_REFERENCE", TypeName = "nvarchar(128)")] + public string UserReference { get; set; } + + [Required] + [Column("STATUS")] + public int Status { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("ACTION_DATE", TypeName = "datetime")] + public DateTime? ActionDate { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs new file mode 100644 index 00000000..6c78bfa5 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs @@ -0,0 +1,49 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")] + public class EnvelopeReceiver + { + [Key] + [Column("ENVELOPE_ID")] + public int EnvelopeId { get; set; } + + [Key] + [Column("RECEIVER_ID")] + public int ReceiverId { get; set; } + + [Required] + [Column("SEQUENCE")] + public int Sequence { get; set; } + + [Column("NAME", TypeName = "nvarchar(128)")] + public string Name { get; set; } + + [Column("JOB_TITLE", TypeName = "nvarchar(128)")] + public string JobTitle { get; set; } + + [Column("COMPANY_NAME", TypeName = "nvarchar(128)")] + public string CompanyName { get; set; } + + [Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")] + public string PrivateMessage { get; set; } + + [Column("ACCESS_CODE", TypeName = "nvarchar(64)")] + public string AccessCode { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + [ForeignKey("EnvelopeId")] + public Envelope? Envelope { get; set; } + + [ForeignKey("ReceiverId")] + public Receiver? Receiver { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs new file mode 100644 index 00000000..c1684672 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE_TYPE", Schema = "dbo")] + public class EnvelopeType + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("TITLE", TypeName = "nvarchar(128)")] + public string Title { get; set; } + + [Column("LANGUAGE", TypeName = "nvarchar(5)")] + public string Language { get; set; } + + [Column("EXPIRES_DAYS")] + public int? ExpiresDays { get; set; } + + [Column("CERTIFICATION_TYPE")] + public int? CertificationType { get; set; } + + [Column("USE_ACCESS_CODE")] + public bool? UseAccessCode { get; set; } + + [Column("FINAL_EMAIL_TO_CREATOR")] + public int? FinalEmailToCreator { get; set; } + + [Column("FINAL_EMAIL_TO_RECEIVERS")] + public int? FinalEmailToReceivers { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + [Column("EXPIRES_WARNING_DAYS")] + public int? ExpiresWarningDays { get; set; } + + [Column("SEND_REMINDER_EMAILS")] + public bool? SendReminderEmails { get; set; } + + [Column("FIRST_REMINDER_DAYS")] + public int? FirstReminderDays { get; set; } + + [Column("REMINDER_INTERVAL_DAYS")] + public int? ReminderIntervalDays { get; set; } + + [Column("CONTRACT_TYPE")] + public int? ContractType { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/Receiver.cs b/EnvelopeGenerator.Domain/Entities/Receiver.cs new file mode 100644 index 00000000..a447e770 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/Receiver.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_RECEIVER", Schema = "dbo")] + public class Receiver + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("EMAIL_ADDRESS", TypeName = "nvarchar(128)")] + public string EmailAddress { get; set; } + + [Required] + [Column("SIGNATURE", TypeName = "nvarchar(64)")] + public string Signature { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + public IEnumerable? EnvelopeReceivers { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/UserReceiver.cs b/EnvelopeGenerator.Domain/Entities/UserReceiver.cs new file mode 100644 index 00000000..9b221297 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/UserReceiver.cs @@ -0,0 +1,36 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_USER_RECEIVER", Schema = "dbo")] + public class UserReceiver + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Column("GUID")] + public int Id { get; set; } + + [Required] + [Column("USER_ID")] + public int UserId { get; set; } + + [Required] + [Column("RECEIVER_ID")] + public int ReceiverId { get; set; } + + [Required] + [Column("NAME", TypeName = "nvarchar(128)")] + public string Name { get; set; } + + [Column("COMPANY_NAME", TypeName = "nvarchar(128)")] + public string CompanyName { get; set; } + + [Column("JOB_TITLE", TypeName = "nvarchar(128)")] + public string JobTitle { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index cfadb03d..49f45937 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs index a4fb4812..120b3096 100644 --- a/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs @@ -1,5 +1,4 @@ -using DigitalData.Core.Contracts.Application; -using DigitalData.Core.Contracts.Infrastructure; +using DigitalData.Core.Contracts.Infrastructure; using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Infrastructure.Contracts diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs new file mode 100644 index 00000000..8b0519a8 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IDocumentReceiverElementRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs new file mode 100644 index 00000000..606ebd29 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IDocumentStatusRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs new file mode 100644 index 00000000..b45c9eb3 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEmailTemplateRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs new file mode 100644 index 00000000..45e531f5 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEnvelopeCertificateRepository : ICRUDRepository + { + } +} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs new file mode 100644 index 00000000..264e31b9 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEnvelopeHistoryRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs new file mode 100644 index 00000000..816baf10 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs @@ -0,0 +1,10 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEnvelopeReceiverRepository : ICRUDRepository + { + Task ReadAccessCodeByEnvelopeUuid(string envelopeUuid); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs new file mode 100644 index 00000000..132c7d06 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs @@ -0,0 +1,12 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEnvelopeRepository : ICRUDRepository + { + Task> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = true); + + Task ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs new file mode 100644 index 00000000..8a3dd1c7 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IEnvelopeTypeRepository : ICRUDRepository + { + } +} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs new file mode 100644 index 00000000..4c5ec027 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IReceiverRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs new file mode 100644 index 00000000..ba9dce31 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Contracts.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Infrastructure.Contracts +{ + public interface IUserReceiverRepository : ICRUDRepository + { + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/EGDbContext.cs b/EnvelopeGenerator.Infrastructure/EGDbContext.cs index e361faba..eb5c053c 100644 --- a/EnvelopeGenerator.Infrastructure/EGDbContext.cs +++ b/EnvelopeGenerator.Infrastructure/EGDbContext.cs @@ -12,7 +12,51 @@ namespace DigitalData.UserManager.Infrastructure.Repositories protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasNoKey(); + + modelBuilder.Entity() + .HasKey(er => new { er.EnvelopeId, er.ReceiverId }); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + // Configure the one-to-many relationship of Envelope + modelBuilder.Entity() + .HasMany(e => e.Documents) + .WithOne() + .HasForeignKey(ed => ed.EnvelopeId); + + //modelBuilder.Entity() + // .HasMany(e => e.Receivers) + // .WithOne(er => er.Envelope) + // .HasForeignKey(er => er.EnvelopeId); + + modelBuilder.Entity() + .HasMany(e => e.History) + .WithOne() + .HasForeignKey(eh => eh.EnvelopeId); + + modelBuilder.Entity() + .HasMany(ed => ed.Elements) + .WithOne(e => e.Document) + .HasForeignKey(e => e.DocumentId); + + modelBuilder.Entity() + .HasOne(dre => dre.Document) + .WithMany(ed => ed.Elements) + .HasForeignKey(dre => dre.DocumentId); + + //modelBuilder.Entity() + // .HasMany(e => e.EnvelopeReceivers) + // .WithOne(er => er.Receiver) + // .HasForeignKey(er => er.ReceiverId); base.OnModelCreating(modelBuilder); } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs new file mode 100644 index 00000000..0c7c5b55 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class DocumentReceiverElementRepository : CRUDRepository, IDocumentReceiverElementRepository + { + public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs new file mode 100644 index 00000000..0bb95c99 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class DocumentStatusRepository : CRUDRepository, IDocumentStatusRepository + { + public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs new file mode 100644 index 00000000..9b8f29fb --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EmailTemplateRepository : CRUDRepository, IEmailTemplateRepository + { + public EmailTemplateRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs new file mode 100644 index 00000000..5cc4195e --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EnvelopeCertificateRepository : CRUDRepository, IEnvelopeCertificateRepository + { + public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs new file mode 100644 index 00000000..7c19c82a --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EnvelopeHistoryRepository : CRUDRepository, IEnvelopeHistoryRepository + { + public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs new file mode 100644 index 00000000..0c6244eb --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs @@ -0,0 +1,56 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; +using Microsoft.EntityFrameworkCore; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EnvelopeRepository : CRUDRepository, IEnvelopeRepository + { + public EnvelopeRepository(EGDbContext dbContext) : base(dbContext) + { + } + + public async Task> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = false) + { + var query = _dbSet.AsQueryable(); + + if (documents) + if (documentReceiverElement) + query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); + else + query = query.Include(e => e.Documents); + + if (receivers) + query = query.Include(e => e.Receivers); + + if (history) + query = query.Include(e => e.History); + + return await query.ToListAsync(); + } + + public async Task ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false) + { + var query = _dbSet.Where(e => e.Uuid == uuid); + + if (signature is not null) + query = query.Where(e => e.Receivers != null && e.Receivers.Any(er => er.Receiver != null && er.Receiver.Signature == signature)); + + if (withAll || withDocuments) + if (withAll || withDocumentReceiverElement) + query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); + else + query = query.Include(e => e.Documents); + + if (withAll || withReceivers) + query = query.Include(e => e.Receivers!).ThenInclude(er => er.Receiver); + + if (withAll || withHistory) + query = query.Include(e => e.History); + + return await query.FirstOrDefaultAsync(); + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs new file mode 100644 index 00000000..9b7533e3 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EnvelopeTypeRepository : CRUDRepository, IEnvelopeTypeRepository + { + public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs new file mode 100644 index 00000000..0f528f41 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs @@ -0,0 +1,25 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; +using Microsoft.EntityFrameworkCore; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class EnvelopeReceiverRepository : CRUDRepository, IEnvelopeReceiverRepository + { + public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext) + { + } + + public async Task ReadAccessCodeByEnvelopeUuid(string envelopeUuid) + { + var accessCode = await _dbSet + .Where(er => er.Envelope != null && er.Envelope.Uuid == envelopeUuid) + .Select(er => er.AccessCode) + .FirstOrDefaultAsync(); + + return accessCode; + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs new file mode 100644 index 00000000..8258c76b --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class ReceiverRepository : CRUDRepository, IReceiverRepository + { + public ReceiverRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs new file mode 100644 index 00000000..2c5800ec --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs @@ -0,0 +1,14 @@ +using DigitalData.Core.Infrastructure; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Infrastructure.Repositories +{ + public class UserReceiverRepository : CRUDRepository, IUserReceiverRepository + { + public UserReceiverRepository(EGDbContext dbContext) : base(dbContext) + { + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/BaseController.cs b/EnvelopeGenerator.Web/Controllers/BaseController.cs index bd66ea78..28f90b18 100644 --- a/EnvelopeGenerator.Web/Controllers/BaseController.cs +++ b/EnvelopeGenerator.Web/Controllers/BaseController.cs @@ -2,27 +2,29 @@ using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Mvc; +using System.Text; namespace EnvelopeGenerator.Web.Controllers { public class BaseController : Controller { internal DatabaseService database; - internal LogConfig logConfig; internal State state; - public Logger logger; - public BaseController(DatabaseService database, LoggingService logging) + internal ILogger _logger; + + public BaseController(DatabaseService database, ILogger logger) { this.database = database; - this.logConfig = logging.LogConfig; - this.logger = logging.LogConfig.GetLogger(); this.state = database.State; + _logger = logger; } internal ObjectResult ErrorResponse(Exception e) { - logger.Error(e); + // Log the detailed error message. + _logger.LogError(e, "An unexpected error occurred."); + return Problem( statusCode: 500, detail: e.Message, diff --git a/EnvelopeGenerator.Web/Controllers/DocumentController.cs b/EnvelopeGenerator.Web/Controllers/DocumentController.cs index d0ce6871..16b69867 100644 --- a/EnvelopeGenerator.Web/Controllers/DocumentController.cs +++ b/EnvelopeGenerator.Web/Controllers/DocumentController.cs @@ -1,18 +1,17 @@ using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; -using static EnvelopeGenerator.Common.Constants; using EnvelopeGenerator.Application.Contracts; namespace EnvelopeGenerator.Web.Controllers { public class DocumentController : BaseController { - private readonly EnvelopeService envelopeService; + private readonly EnvelopeOldService envelopeService; private readonly ActionService? actionService; private readonly IEnvelopeDocumentService _envDocService; - public DocumentController(DatabaseService database, LoggingService logging, EnvelopeService envelope, IEnvelopeDocumentService envDocService) : base(database, logging) + public DocumentController(DatabaseService database, EnvelopeOldService envelope, IEnvelopeDocumentService envDocService, ILogger logger) : base(database, logger) { envelopeService = envelope; actionService = database.Services?.actionService; @@ -25,15 +24,12 @@ namespace EnvelopeGenerator.Web.Controllers { try { - logger.Info("DocumentController/Get"); - // Validate Envelope Key and load envelope envelopeService.EnsureValidEnvelopeKey(envelopeKey); EnvelopeResponse response = await envelopeService.LoadEnvelope(envelopeKey); // Load document info - var Request = ControllerContext.HttpContext.Request; - var document = await envelopeService.GetDocument(Request, envelopeKey); + var document = await envelopeService.GetDocument(index, envelopeKey); // Load the document from disk var bytes = await envelopeService.GetDocumentContents(document); @@ -41,9 +37,9 @@ namespace EnvelopeGenerator.Web.Controllers // Return the document as bytes return File(bytes, "application/octet-stream"); } - catch (Exception e) + catch(Exception ex) { - return ErrorResponse(e); + return ErrorResponse(ex); } } @@ -53,19 +49,17 @@ namespace EnvelopeGenerator.Web.Controllers { try { - logger.Info("DocumentController/Open"); - // Validate Envelope Key and load envelope envelopeService.EnsureValidEnvelopeKey(envelopeKey); EnvelopeResponse response = await envelopeService.LoadEnvelope(envelopeKey); - actionService.OpenEnvelope(response.Envelope, response.Receiver); + actionService?.OpenEnvelope(response.Envelope, response.Receiver); return Ok(new object()); } - catch (Exception e) + catch(Exception ex) { - return ErrorResponse(e); + return ErrorResponse(ex); } } diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index 5b87d9d9..1b8d59f1 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -1,4 +1,6 @@ -using EnvelopeGenerator.Common; + +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Mvc; @@ -6,33 +8,33 @@ namespace EnvelopeGenerator.Web.Controllers { public class EnvelopeController : BaseController { - private readonly EnvelopeService envelopeService; - private readonly ActionService actionService; + private readonly EnvelopeOldService envelopeService; + private readonly ActionService? actionService; + private readonly IEnvelopeService _envelopeService; - public EnvelopeController(DatabaseService database, LoggingService logging, EnvelopeService envelope) : base(database, logging) + public EnvelopeController(DatabaseService database, EnvelopeOldService envelope, ILogger logger, IEnvelopeService envService) : base(database, logger) { envelopeService = envelope; - actionService = database.Services?.actionService; + actionService = database?.Services?.actionService; + _envelopeService = envService; } - [HttpGet] - [Route("api/envelope/{envelopeKey}")] - public async Task Get(string envelopeKey) + [HttpGet("api/envelope/{envelopeKey}")] + public async Task Get([FromRoute] string envelopeKey) { try { - logger.Info("EnvelopeController/Get"); - // Validate Envelope Key and load envelope envelopeService.EnsureValidEnvelopeKey(envelopeKey); - EnvelopeResponse response = await envelopeService.LoadEnvelope(envelopeKey); + EnvelopeResponse response = await envelopeService.LoadEnvelope(envelopeKey); + if (envelopeService.ReceiverAlreadySigned(response.Envelope, response.Receiver.Id) == true) { return Problem(statusCode: 403); } - logger.Debug("Loaded envelope [{0}] for receiver [{1}]", response.Envelope.Id, response.Envelope.Id); + _logger.LogInformation("Loaded envelope [{0}] for receiver [{1}]", response.Envelope.Id, response.Envelope.Id); return Json(response); } catch (Exception e) @@ -41,14 +43,11 @@ namespace EnvelopeGenerator.Web.Controllers } } - [HttpPost] - [Route("api/envelope/{envelopeKey}")] - public async Task Update(string envelopeKey) + [HttpPost("api/envelope/{envelopeKey}")] + public async Task Update(string envelopeKey, int index) { try { - logger.Info("EnvelopeController/Update"); - // Validate Envelope Key and load envelope envelopeService.EnsureValidEnvelopeKey(envelopeKey); EnvelopeResponse response = await envelopeService.LoadEnvelope(envelopeKey); @@ -59,10 +58,9 @@ namespace EnvelopeGenerator.Web.Controllers return Problem(statusCode: 403); } - var Request = ControllerContext.HttpContext.Request; - var document = envelopeService.GetDocument(Request, envelopeKey); + var document = envelopeService.GetDocument(index, envelopeKey); - string annotationData = await envelopeService.EnsureValidAnnotationData(Request); + string? annotationData = await envelopeService.EnsureValidAnnotationData(Request); envelopeService.InsertDocumentStatus(new DocumentStatus() { diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeDocumentTestController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeDocumentTestController.cs deleted file mode 100644 index c191dbf2..00000000 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeDocumentTestController.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; - -namespace EnvelopeGenerator.Web.Controllers -{ - public class EnvelopeDocumentTestController : CRUDControllerBase - { - public EnvelopeDocumentTestController(ILogger logger, IEnvelopeDocumentService service) : base(logger, service) - { - } - } -} diff --git a/EnvelopeGenerator.Web/Controllers/HomeController.cs b/EnvelopeGenerator.Web/Controllers/HomeController.cs index 7f6e1d59..edb39a69 100644 --- a/EnvelopeGenerator.Web/Controllers/HomeController.cs +++ b/EnvelopeGenerator.Web/Controllers/HomeController.cs @@ -1,4 +1,7 @@ -using EnvelopeGenerator.Common; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.Services; +using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Models; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Mvc; @@ -9,28 +12,31 @@ namespace EnvelopeGenerator.Web.Controllers { public class HomeController : BaseController { - private readonly EnvelopeService _envelopeService; + private readonly EnvelopeOldService envelopeOldService; + private readonly IConfiguration _config; + private readonly IEnvelopeReceiverService _envRcvService; + private readonly IEnvelopeService _envelopeService; - public HomeController(DatabaseService databaseService, LoggingService loggingService, EnvelopeService envelopeService): base(databaseService, loggingService) + public HomeController(DatabaseService databaseService, EnvelopeOldService envelopeOldService, ILogger logger, IConfiguration configuration, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeService envelopeService) : base(databaseService, logger) { + this.envelopeOldService = envelopeOldService; + _envRcvService = envelopeReceiverService; _envelopeService = envelopeService; + _config = configuration; } - [HttpGet] - [Route("/")] + [HttpGet("/")] public IActionResult Index() { return View(); } - [HttpPost] - [Route("/")] - public IActionResult DebugEnvelopes() + [HttpPost("/")] + public IActionResult DebugEnvelopes([FromForm] string? password) { try { - StringValues passwordFromForm = HttpContext.Request.Form["password"]; - string passwordFromConfig = database.GetAppSetting("Config:AdminPassword"); + var passwordFromConfig = _config["Config:AdminPassword"] ?? throw new InvalidOperationException("No admin password configured!"); if (passwordFromConfig == null) { @@ -38,27 +44,13 @@ namespace EnvelopeGenerator.Web.Controllers return View("Index"); } - if (passwordFromForm.Count != 1) - { - ViewData["error"] = "No admin password configured!"; - return View("Index"); - } - - string password = passwordFromForm[0]; - - if (password == null) - { - ViewData["error"] = "No password supplied!"; - return View("Index"); - } - if (password != passwordFromConfig) { ViewData["error"] = "Wrong Password!"; return View("Index"); } - List envelopes = _envelopeService.LoadEnvelopes(); + List envelopes = envelopeOldService.LoadEnvelopes(); return View(envelopes); } @@ -69,14 +61,13 @@ namespace EnvelopeGenerator.Web.Controllers } } - [HttpGet] - [Route("/EnvelopeKey/{envelopeReceiverId}")] + [HttpGet("/EnvelopeKey/{envelopeReceiverId}")] public async Task ShowEnvelope([FromRoute] string envelopeReceiverId) { - EnvelopeResponse response = await _envelopeService.LoadEnvelope(envelopeReceiverId); + EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); if (response.Envelope.UseAccessCode) - { + { bool accessCodeAlreadyRequested = database.Models.receiverModel.AccessCodeAlreadyRequested(response.Receiver.Email, response.Envelope.Id); if (!accessCodeAlreadyRequested) @@ -87,52 +78,65 @@ namespace EnvelopeGenerator.Web.Controllers } return Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked"); - } + } else { ViewData["EnvelopeKey"] = envelopeReceiverId; return View(); - } + } } - [HttpPost] - [Route("/EnvelopeKey/{envelopeReceiverId}/Locked")] - public async Task ShowEnvelopePost([FromRoute] string envelopeReceiverId, [FromForm] string access_code) + [HttpPost("/EnvelopeKey/{envelopeReceiverId}/Locked")] + public async Task ShowEnvelope([FromRoute] string envelopeReceiverId, [FromForm] string access_code) { - EnvelopeResponse response = await _envelopeService.LoadEnvelope(envelopeReceiverId); - string accessCode = response.Receiver.AccessCode; + var decodedId = envelopeReceiverId.DecodeEnvelopeReceiverId(); - if (string.IsNullOrEmpty(access_code)) - { - return Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked"); - } + _logger.LogInformation($"Envelope UUID: [{decodedId.EnvelopeUuid}]"); + _logger.LogInformation($"Receiver Signature: [{decodedId.ReceiverSignature}]"); - if (accessCode.Equals(access_code, StringComparison.Ordinal)) + var verification = await _envRcvService.VerifyAccessCode(decodedId.EnvelopeUuid, access_code); + EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); + + if (verification.IsSuccess) { - bool actionResult = database.Services.actionService.EnterCorrectAccessCode(response.Envelope, response.Receiver); + if (envelopeOldService.ReceiverAlreadySigned(response.Envelope, response.Receiver.Id) == true) + { + return Problem(statusCode: 403); + } + + var envelope = await _envelopeService.ReadByUuidAsync(uuid: decodedId.EnvelopeUuid, signature: decodedId.ReceiverSignature, withAll: true); + database.Services.actionService.EnterCorrectAccessCode(response.Envelope, response.Receiver); //for history ViewData["EnvelopeKey"] = envelopeReceiverId; - return View("ShowEnvelope"); + ViewData["EnvelopeResponse"] = response; + ViewData["EnvelopeResponse"] = response; + + if (response.Envelope.Documents.Count() > 0) + { + var document = await envelopeOldService.GetDocument(response.Envelope.Documents[0].Id, envelopeReceiverId); + byte[] bytes = await envelopeOldService.GetDocumentContents(document); + ViewData["DocumentBytes"] = bytes; + } + else + ViewData["DocumentBytes"] = null; + + return View("ShowEnvelope", envelope); } else { - bool actionResult = database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); - return Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked"); + database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); //for history + return Unauthorized(); } } - [HttpGet] - [Route("/EnvelopeKey/{envelopeReceiverId}/Locked")] - public IActionResult EnvelopeLocked([FromRoute] string envelopeReceiverId) + [HttpGet("/EnvelopeKey/{envelopeReceiverId}/Locked")] + public async Task EnvelopeLocked([FromRoute] string envelopeReceiverId) { ViewData["EnvelopeKey"] = envelopeReceiverId; return View(); } - - - [HttpGet] - [Route("/EnvelopeKey/{EnvelopeReceiverId}/Success")] + [HttpGet("/EnvelopeKey/{EnvelopeReceiverId}/Success")] public IActionResult EnvelopeSigned() { ViewData["EnvelopeKey"] = HttpContext.Request.RouteValues["EnvelopeReceiverId"]; @@ -140,7 +144,6 @@ namespace EnvelopeGenerator.Web.Controllers return View(); } - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { diff --git a/EnvelopeGenerator.Web/Controllers/ConfigTestController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs similarity index 52% rename from EnvelopeGenerator.Web/Controllers/ConfigTestController.cs rename to EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs index 8ef3a656..7981dde9 100644 --- a/EnvelopeGenerator.Web/Controllers/ConfigTestController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs @@ -4,12 +4,13 @@ using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -namespace EnvelopeGenerator.Web.Controllers +namespace EnvelopeGenerator.Web.Controllers.Test { - public class ConfigTestController : CRUDControllerBase + public class TestConfigController : TestControllerBase { - public ConfigTestController(ILogger logger, IConfigService service) : base(logger, service) + public TestConfigController(ILogger logger, IConfigService service) : base(logger, service) { + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs b/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs new file mode 100644 index 00000000..e719897a --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs @@ -0,0 +1,17 @@ +using DigitalData.Core.API; +using DigitalData.Core.Contracts.Application; +using DigitalData.Core.Contracts.Infrastructure; +using Microsoft.AspNetCore.Mvc; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + //[NonController] + [ApiController] + [Route("api/test/[controller]")] + public class TestControllerBase : BasicCRUDControllerBase where TOriginalController : CRUDControllerBase where TCRUDService : ICRUDService where TCRUDRepository : ICRUDRepository where TDto : class where TEntity : class + { + public TestControllerBase(ILogger logger, TCRUDService service) : base(logger, service) + { + } + } +} diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs new file mode 100644 index 00000000..29e3c74f --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestDocumentReceiverElementController : TestControllerBase + { + public TestDocumentReceiverElementController(ILogger logger, IDocumentReceiverElementService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs new file mode 100644 index 00000000..a8ea37bb --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestDocumentStatusController : TestControllerBase + { + public TestDocumentStatusController(ILogger logger, IDocumentStatusService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs new file mode 100644 index 00000000..8bd7016b --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs @@ -0,0 +1,15 @@ +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEmailTemplateController : TestControllerBase + { + public TestEmailTemplateController(ILogger logger, IEmailTemplateService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs new file mode 100644 index 00000000..b29981cc --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeCertificateController : TestControllerBase + { + public TestEnvelopeCertificateController(ILogger logger, IEnvelopeCertificateService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs new file mode 100644 index 00000000..e7d84eea --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs @@ -0,0 +1,49 @@ +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.Services; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; +using Microsoft.AspNetCore.Mvc; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeController : TestControllerBase + { + public TestEnvelopeController(ILogger logger, IEnvelopeService service) : base(logger, service) + { + } + + [NonAction] + public override Task GetAll() + { + return base.GetAll(); + } + + [HttpGet] + public virtual async Task GetAll([FromQuery] string? envelopeKey = default, [FromQuery] bool withDocuments = false, [FromQuery] bool withReceivers = false, [FromQuery] bool withHistory = false, [FromQuery] bool withDocumentReceiverElement = false, [FromQuery] bool withAll = true) + { + if(envelopeKey is not null) + { + var decoded = envelopeKey.DecodeEnvelopeReceiverId(); + + var envlopeServiceResult = await _service.ReadByUuidAsync( + uuid: decoded.EnvelopeUuid, + signature: decoded.ReceiverSignature, + withDocuments: withDocuments, withReceivers: withReceivers, withHistory: withHistory, withDocumentReceiverElement:withDocumentReceiverElement, withAll:withAll); + + if (envlopeServiceResult.IsSuccess) + { + return Ok(envlopeServiceResult.Data); + } + return NotFound(); + } + + var result = await _service.ReadAllWithAsync(documents: withDocuments, receivers: withReceivers, history: withHistory); + if (result.IsSuccess) + { + return Ok(result); + } + return NotFound(result); + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs new file mode 100644 index 00000000..bfbafaef --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeDocumentController : TestControllerBase + { + public TestEnvelopeDocumentController(ILogger logger, IEnvelopeDocumentService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs new file mode 100644 index 00000000..98c990f8 --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeHistoryController : TestControllerBase + { + public TestEnvelopeHistoryController(ILogger logger, IEnvelopeHistoryService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs new file mode 100644 index 00000000..073720ef --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeReceiverController : TestControllerBase + { + public TestEnvelopeReceiverController(ILogger logger, IEnvelopeReceiverService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs new file mode 100644 index 00000000..06815b29 --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestEnvelopeTypeController : TestControllerBase + { + public TestEnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs new file mode 100644 index 00000000..543d4ed5 --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestReceiverController : TestControllerBase + { + public TestReceiverController(ILogger logger, IReceiverService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs new file mode 100644 index 00000000..f8778b5e --- /dev/null +++ b/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Infrastructure.Contracts; + +namespace EnvelopeGenerator.Web.Controllers.Test +{ + public class TestUserReceiverController : TestControllerBase + { + public TestUserReceiverController(ILogger logger, IUserReceiverService service) : base(logger, service) + { + + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 7945b33d..d168af5c 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -17,6 +17,7 @@ + diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs index b272d19c..fb294e56 100644 --- a/EnvelopeGenerator.Web/Program.cs +++ b/EnvelopeGenerator.Web/Program.cs @@ -7,73 +7,108 @@ using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Repositories; using EnvelopeGenerator.Web.Services; using Microsoft.EntityFrameworkCore; +using NLog; using Quartz; +using NLog.Web; +using DigitalData.Core.API; -namespace EnvelopeGenerator.Web +var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); +logger.Info("Logging initialized!"); +try { - public class Program + var builder = WebApplication.CreateBuilder(args); + + builder.Logging.ClearProviders(); + builder.Host.UseNLog(); + + // Add base services + builder.Services.AddScoped(); + + // Add higher order services + builder.Services.AddScoped(); + + // Add services to the container. + builder.Services.AddControllersWithViews(options => { - public static void Main(string[] args) - { - var builder = WebApplication.CreateBuilder(args); + options.Conventions.Add(new RemoveIfControllerConvention() + .AndIf(c => c.ControllerName.StartsWith("Test")) + .AndIf(c => !builder.Configuration.GetValue("AddTestControllers"))); + }).AddJsonOptions(q => + { + // Prevents serialization error when serializing SvgBitmap in EnvelopeReceiver + q.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles; + }); - // Add base services - builder.Services.AddSingleton(); - builder.Services.AddScoped(); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); - // Add higher order services - builder.Services.AddScoped(); + builder.Services.AddKeyTranslationService(); - // Add services to the container. - builder.Services.AddControllersWithViews().AddJsonOptions(q => - { - // Prevents serialization error when serializing SvgBitmap in EnvelopeReceiver - q.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles; - }); + //AddEF Core dbcontext + var connStr = builder.Configuration["Config:ConnectionString"]; + builder.Services.AddDbContext(options => + options.UseSqlServer(connStr)); - builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); + //Inject CRUD Service and repositories + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); - builder.Services.AddKeyTranslationService(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); - //AddEF Core dbcontext - var connStr = builder.Configuration["Config:ConnectionString"]; - builder.Services.AddDbContext(options => - options.UseSqlServer(connStr)); + //Auto mapping profiles + builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly); + + var app = builder.Build(); - //Inject CRUD Service and repositories - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - //Auto mapping profiles - builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly); - - var app = builder.Build(); - - // Configure the HTTP request pipeline. - if (!app.Environment.IsDevelopment()) - { - app.UseExceptionHandler("/Home/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseSwagger(); - app.UseSwaggerUI(); - - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseAuthorization(); - - app.MapControllers(); - - app.Run(); - } + // Configure the HTTP request pipeline. + if (!app.Environment.IsDevelopment()) + { + app.UseExceptionHandler("/Home/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); } + + app.UseSwagger(); + app.UseSwaggerUI(); + + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); +} +catch(Exception ex) +{ + logger.Error(ex, "Stopped program because of exception"); + throw; } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Services/BaseService.cs b/EnvelopeGenerator.Web/Services/BaseService.cs deleted file mode 100644 index 0f4bb450..00000000 --- a/EnvelopeGenerator.Web/Services/BaseService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using DigitalData.Modules.Logging; - -namespace EnvelopeGenerator.Web.Services -{ - public class BaseService - { - internal readonly LogConfig logConfig; - internal readonly IConfiguration config; - internal Logger logger; - - public BaseService(IConfiguration Config, LoggingService Logging) - { - logConfig = Logging.LogConfig; - logger = Logging.LogConfig.GetLogger(); - config = Config; - } - } -} diff --git a/EnvelopeGenerator.Web/Services/DatabaseService.cs b/EnvelopeGenerator.Web/Services/DatabaseService.cs index 2d2e8de2..da97a486 100644 --- a/EnvelopeGenerator.Web/Services/DatabaseService.cs +++ b/EnvelopeGenerator.Web/Services/DatabaseService.cs @@ -1,14 +1,16 @@ using DigitalData.Modules.Database; +using DigitalData.Modules.Logging; using EnvelopeGenerator.Common; namespace EnvelopeGenerator.Web.Services { - public class DatabaseService: BaseService + public class DatabaseService { public MSSQLServer MSSQL { get; set; } - public IConfiguration Config { get; set; } - public State State { get; set; } + ILogger _logger; + + public State? State { get; set; } public class ServiceContainer { @@ -48,62 +50,43 @@ namespace EnvelopeGenerator.Web.Services public readonly ModelContainer? Models; public readonly ServiceContainer? Services; - public DatabaseService(IConfiguration pConfig, LoggingService pLogging) : base(pConfig, pLogging) + public DatabaseService(ILogger logger, IConfiguration config) { - logger = pLogging.LogConfig.GetLogger(); - Config = pConfig; + LogConfig logConfig = new LogConfig(LogConfig.PathType.CustomPath, config["Config:LogPath"], null, "Digital Data", "ECM.EnvelopeGenerator.Web"); + _logger = logger; - logger.Debug("Establishing MSSQL Database connection.."); - MSSQL = new MSSQLServer(logConfig, pConfig["Config:ConnectionString"]); + _logger.LogInformation("Establishing MSSQL Database connection.."); + MSSQL = new MSSQLServer(logConfig, config["Config:ConnectionString"]); if (MSSQL.DBInitialized == true) { - logger.Debug("MSSQL Connection established: [{0}]", MSSQL.MaskedConnectionString); - - var state = GetState(); + _logger.LogInformation("MSSQL Connection established: [{0}]", MSSQL.MaskedConnectionString); - Models = new(state); - Services = new(state); + /// + /// There is a circular dependency between state and models + /// All models need a state object, including the config Model + /// The state object needs to be filled with the DbConfig property, + /// which is obtained by the config Model. + /// So first, the config model is initialized with an incomplete state object, + /// then all the other models with the DbConfig property filled. + /// + State = new State + { + Database = MSSQL, + LogConfig = logConfig, + UserId = 0, + DbConfig = null + }; + var configModel = new ConfigModel(State); + State.DbConfig = configModel.LoadConfiguration(); - State = state; + Models = new(State); + Services = new(State); } else { - logger.Error("Connection could not be established!"); + _logger.LogInformation("Connection could not be established!"); } } - - public string? GetAppSetting(string key) - { - return Config[key]; - } - - /// - /// There is a circular dependency between state and models - /// All models need a state object, including the config Model - /// The state object needs to be filled with the DbConfig property, - /// which is obtained by the config Model. - /// So first, the config model is initialized with an incomplete state object, - /// then all the other models with the DbConfig property filled. - /// - private State GetState() - { - var state = GetInitialState(); - var configModel = new ConfigModel(state); - state.DbConfig = configModel.LoadConfiguration(); - - return state; - } - - private State GetInitialState() - { - return new State - { - Database = MSSQL, - LogConfig = logConfig, - UserId = 0, - DbConfig = null - }; - } } } diff --git a/EnvelopeGenerator.Web/Services/EnvelopeService.cs b/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs similarity index 65% rename from EnvelopeGenerator.Web/Services/EnvelopeService.cs rename to EnvelopeGenerator.Web/Services/EnvelopeOldService.cs index a27049e6..42ec596e 100644 --- a/EnvelopeGenerator.Web/Services/EnvelopeService.cs +++ b/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs @@ -1,11 +1,10 @@ using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Common; -using Microsoft.Extensions.Primitives; using System.Text; namespace EnvelopeGenerator.Web.Services { - public class EnvelopeService : BaseService + public class EnvelopeOldService { private readonly ReceiverModel receiverModel; private readonly EnvelopeModel envelopeModel; @@ -13,16 +12,15 @@ namespace EnvelopeGenerator.Web.Services private readonly DocumentStatusModel documentStatusModel; - private IConfigService _configService; + private readonly IConfigService _configService; + private readonly ILogger _logger; - public EnvelopeService(IConfiguration Config, LoggingService Logging, DatabaseService database, IConfigService configService) : base(Config, Logging) + public EnvelopeOldService(DatabaseService database, IConfigService configService, ILogger logger) { - logger = Logging.LogConfig.GetLogger(); + _logger = logger; - if (database.Models == null) - { + if (database.Models is null) throw new ArgumentNullException("Models not loaded."); - } receiverModel = database.Models.receiverModel; envelopeModel = database.Models.envelopeModel; @@ -34,14 +32,14 @@ namespace EnvelopeGenerator.Web.Services public void EnsureValidEnvelopeKey(string envelopeKey) { - logger.Debug("Parsing EnvelopeKey.."); + _logger.LogInformation("Parsing EnvelopeKey.."); if (string.IsNullOrEmpty(envelopeKey)) throw new ArgumentNullException("EnvelopeKey"); Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeKey); - logger.Debug("EnvelopeUUID: [{0}]", result.Item1); - logger.Debug("ReceiverSignature: [{0}]", result.Item2); + _logger.LogInformation("EnvelopeUUID: [{0}]", result.Item1); + _logger.LogInformation("ReceiverSignature: [{0}]", result.Item2); if (string.IsNullOrEmpty(result.Item1)) throw new ArgumentNullException("EnvelopeUUID"); @@ -52,43 +50,43 @@ namespace EnvelopeGenerator.Web.Services public async Task LoadEnvelope(string pEnvelopeKey) { - logger.Debug("Loading Envelope by Key [{0}]", pEnvelopeKey); + _logger.LogInformation("Loading Envelope by Key [{0}]", pEnvelopeKey); Tuple result = Helpers.DecodeEnvelopeReceiverId(pEnvelopeKey); var envelopeUuid = result.Item1; var receiverSignature = result.Item2; var receiverId = receiverModel.GetReceiverIdBySignature(receiverSignature); - logger.Debug("Resolved receiver signature to receiverId [{0}]", receiverId); + _logger.LogInformation("Resolved receiver signature to receiverId [{0}]", receiverId); - logger.Debug("Loading envelope.."); + _logger.LogInformation("Loading envelope.."); Envelope? envelope = envelopeModel.GetByUuid(envelopeUuid); if (envelope == null) { - logger.Warn("Envelope not found"); + _logger.LogWarning("Envelope not found"); throw new NullReferenceException("Envelope not found"); } - logger.Debug("Envelope loaded"); + _logger.LogInformation("Envelope loaded"); if (envelope.Receivers == null) { - logger.Warn("Receivers for envelope not loaded"); + _logger.LogWarning("Receivers for envelope not loaded"); throw new NullReferenceException("Receivers for envelope not loaded"); } - logger.Debug("Envelope receivers found: [{0}]", envelope.Receivers.Count); + _logger.LogInformation("Envelope receivers found: [{0}]", envelope.Receivers.Count); EnvelopeReceiver? receiver = envelope.Receivers.Where(r => r.Id == receiverId).SingleOrDefault(); if (receiver == null) { - logger.Warn("Receiver [{0}] not found", receiverId); + _logger.LogWarning("Receiver [{0}] not found", receiverId); throw new NullReferenceException("Receiver not found"); } - logger.Debug("Loading documents for receiver [{0}]", receiver.Email); + _logger.LogInformation("Loading documents for receiver [{0}]", receiver.Email); // filter elements by receiver envelope.Documents = envelope.Documents.Select((document) => @@ -111,7 +109,7 @@ namespace EnvelopeGenerator.Web.Services } else { - logger.Error(configResult.Messages); + _logger.LogError(string.Join(". ", configResult.Messages)); throw new InvalidOperationException(String.Join(". ", configResult.Messages)); } @@ -150,52 +148,28 @@ namespace EnvelopeGenerator.Web.Services { try { - logger.Debug("Parsing annotation data from request.."); + _logger.LogInformation("Parsing annotation data from request.."); using MemoryStream ms = new(); await request.BodyReader.CopyToAsync(ms); var bytes = ms.ToArray(); - logger.Debug("Annotation data parsed, size: [{0}]", bytes.Length); + _logger.LogInformation("Annotation data parsed, size: [{0}]", bytes.Length); return Encoding.UTF8.GetString(bytes); } catch (Exception e) { - logger.Error(e); + _logger.LogError(e, "Inner Service Error"); throw new ArgumentNullException("AnnotationData"); } } - public int EnsureValidDocumentIndex(HttpRequest request) - { - if (!request.Query.TryGetValue("index", out StringValues documentIndexStringList)) - { - logger.Warn("There is no query parameter called index"); - throw new ArgumentNullException("DocumentIndex"); - } - - if (documentIndexStringList.FirstOrDefault() == null) - { - logger.Warn("There is no query parameter called index"); - throw new ArgumentNullException("DocumentIndex"); - } - - if (!int.TryParse(documentIndexStringList.First(), out int documentIndex)) - { - logger.Warn("Invalid document index [{0}]", documentIndexStringList.First()); - throw new ArgumentNullException("DocumentIndex"); - } - - return documentIndex; - } - - public async Task GetDocument(HttpRequest request, string envelopeKey) + public async Task GetDocument(int documentId, string envelopeKey) { EnvelopeResponse response = await LoadEnvelope(envelopeKey); - int documentId = EnsureValidDocumentIndex(request); - logger.Debug("Loading document for Id [{0}]", documentId); + _logger.LogInformation("Loading document for Id [{0}]", documentId); var document = response.Envelope.Documents. Where(d => d.Id == documentId). @@ -203,25 +177,25 @@ namespace EnvelopeGenerator.Web.Services if (document == null) throw new ArgumentException("DocumentId"); - - logger.Debug("Document [{0}] loaded!", documentId); + + _logger.LogInformation("Document [{0}] loaded!", documentId); return document; } public bool InsertDocumentStatus(Common.DocumentStatus documentStatus) { - logger.Debug("Saving annotation data.."); + _logger.LogInformation("Saving annotation data.."); return documentStatusModel.InsertOrUpdate(documentStatus); } public async Task GetDocumentContents(EnvelopeDocument document) { - logger.Debug("Loading file [{0}]", document.Filepath); + _logger.LogInformation("Loading file [{0}]", document.Filepath); var bytes = await File.ReadAllBytesAsync(document.Filepath); - logger.Info("File loaded, size: [{0}]", bytes.Length); + _logger.LogInformation("File loaded, size: [{0}]", bytes.Length); return bytes; } } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Services/LoggingService.cs b/EnvelopeGenerator.Web/Services/LoggingService.cs deleted file mode 100644 index 3d03f6cc..00000000 --- a/EnvelopeGenerator.Web/Services/LoggingService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using DigitalData.Modules.Logging; - -namespace EnvelopeGenerator.Web.Services -{ - public class LoggingService - { - public LogConfig LogConfig { get; set; } - - public LoggingService(IConfiguration Config) - { - LogConfig = new LogConfig(LogConfig.PathType.CustomPath, Config["Config:LogPath"], null, "Digital Data", "ECM.EnvelopeGenerator.Web"); - - var logger = LogConfig.GetLogger(); - logger.Info("Logging initialized!"); - - var debugLog = bool.Parse(Config["Config:LogDebug"]); - logger.Info("Setting DEBUG Logging to: [{0}]", debugLog); - LogConfig.Debug = debugLog; - - var jsonLog = bool.Parse(Config["Config:LogJson"]); - logger.Info("Setting JSON Logging to: [{0}]", jsonLog); - LogConfig.Debug = jsonLog; - } - } -} diff --git a/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml index e2c87acc..89fef304 100644 --- a/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml @@ -15,9 +15,7 @@

Sie haben das Dokument signiert. Im Anschluss erhalten Sie eine schriftliche Bestätigung.

-
- - + \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml index bd90ba66..247ae6f1 100644 --- a/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml @@ -1,12 +1,89 @@ -@{ +@using DigitalData.Core.Contracts.Application; +@using EnvelopeGenerator.Application.DTOs; +@model IServiceResult; +@{ ViewData["Title"] = "Dokument unterschreiben"; } +@if (Model.IsSuccess && Model.Data is not null) +{ + var envelope = Model.Data; + var document = envelope.Documents?.FirstOrDefault(); + var receiver = envelope.Receivers?.FirstOrDefault(); + var receiverName = receiver?.Name ?? string.Empty; + var pages = document?.Elements?.Select(e => e.Page) ?? Array.Empty(); + var stPageIndexes = string.Join(pages.Count() > 1 ? ", " : "", pages.Take(pages.Count() - 1)) + + (pages.Count() > 1 ? " und " : "") + pages.LastOrDefault(); + + +} +@if (ViewData["DocumentBytes"] is byte[] documentBytes) +{ + var envelopeResponse = ViewData["EnvelopeResponse"]; + var settings = new Newtonsoft.Json.JsonSerializerSettings + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() + }; + var envelopeResponseJson = Newtonsoft.Json.JsonConvert.SerializeObject(envelopeResponse, settings); + + var documentBase64String = Convert.ToBase64String(documentBytes); + + +}
\ No newline at end of file diff --git a/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml b/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml index d65a214d..45774e97 100644 --- a/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml +++ b/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml @@ -11,10 +11,6 @@ -
- @RenderBody() -
- @@ -24,6 +20,11 @@ @await RenderSectionAsync("Scripts", required: false) +
+ @RenderBody() +
+ + @Html.AntiForgeryToken() diff --git a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml index ac64f2b9..148aa6ad 100644 --- a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml +++ b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml @@ -1,3 +1,3 @@ @using EnvelopeGenerator.Web @using EnvelopeGenerator.Web.Models -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file diff --git a/EnvelopeGenerator.Web/appsettings.json b/EnvelopeGenerator.Web/appsettings.json index 83b8aace..4e1b460c 100644 --- a/EnvelopeGenerator.Web/appsettings.json +++ b/EnvelopeGenerator.Web/appsettings.json @@ -2,16 +2,46 @@ "DetailedErrors": true, "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Default": "Warning", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.Hosting.Diagnostics": "Warning" } }, - "Config": { - "ConnectionString": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;", - //preivous connection string without Encrypt=false and TrustServerCertificate=True -> "Server=sDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;" - "LogPath": "E:\\EnvelopeGenerator\\Logs", - "LogDebug": true, - "LogJson": true, - "AdminPassword": "dd" - } + "AdminPassword": "dd", + "NLog": { + "throwConfigExceptions": true, + "targets": { + "infoLogs": { + "type": "File", + "fileName": "E:\\EnvelopeGenerator\\Logs\\${shortdate}-ECM.EnvelopeGenerator.Web-Info.log", + "maxArchiveDays": 30 + }, + "errorLogs": { + "type": "File", + "fileName": "E:\\EnvelopeGenerator\\Logs\\${shortdate}-ECM.EnvelopeGenerator.Web-Error.log", + "maxArchiveDays": 30 + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Info", + "writeTo": "infoLogs" + }, + { + "logger": "*", + "minLevel": "Error", + "writeTo": "errorLogs" + }, + { + "logger": "Namespace.Controllers.*", + "minLevel": "Error", + "writeTo": "errorLogs", + "final": true + } + + ] + }, + "AddTestControllers": false } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/package-lock.json b/EnvelopeGenerator.Web/package-lock.json index 90966259..4a5639bb 100644 --- a/EnvelopeGenerator.Web/package-lock.json +++ b/EnvelopeGenerator.Web/package-lock.json @@ -1,8 +1,32 @@ { "name": "EnvelopeGenerator.Web", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "EnvelopeGenerator.Web", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "prettier": "^3.1.0" + } + }, + "node_modules/prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + } + }, "dependencies": { "prettier": { "version": "3.1.0", diff --git a/EnvelopeGenerator.Web/wwwroot/css/site.css b/EnvelopeGenerator.Web/wwwroot/css/site.css index e4f25b35..a2075121 100644 --- a/EnvelopeGenerator.Web/wwwroot/css/site.css +++ b/EnvelopeGenerator.Web/wwwroot/css/site.css @@ -119,4 +119,20 @@ footer#page-footer a:hover, footer#page-footer a:visited, footer#page-footer a:focus { color: #444; +} + +.sender-card { + background-color: transparent; + border: none; +} +.sender-card .row { + height: 7vh; +} +.sender-card img{ + height: 7vh; + background-color: rgb(209, 207, 207); + border-radius: 50px; +} +.envelope-message { + font-family: 'Roboto', sans-serif; } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/img/default-user.svg b/EnvelopeGenerator.Web/wwwroot/img/default-user.svg new file mode 100644 index 00000000..d39a682b --- /dev/null +++ b/EnvelopeGenerator.Web/wwwroot/img/default-user.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/img/digital_data.svg b/EnvelopeGenerator.Web/wwwroot/img/digital_data.svg new file mode 100644 index 00000000..671d90de --- /dev/null +++ b/EnvelopeGenerator.Web/wwwroot/img/digital_data.svg @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/annotation.js b/EnvelopeGenerator.Web/wwwroot/js/annotation.js index 2daa6a4b..9cd2f0d5 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/annotation.js +++ b/EnvelopeGenerator.Web/wwwroot/js/annotation.js @@ -36,7 +36,6 @@ const allAnnotations = await this.getAnnotations(instance) const pageAnnotations = allAnnotations .map((annotation) => { - console.log(annotation.toJS()) return annotation }) @@ -108,9 +107,7 @@ const canvas = document.createElement('canvas') const scale = 4 const fontSize = 10 - - console.log(receiverSignature) - + canvas.width = width * scale canvas.height = height * scale diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js b/EnvelopeGenerator.Web/wwwroot/js/app.js index 57e12e28..bd32fe6b 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js @@ -10,12 +10,10 @@ const ActionType = { } class App { - constructor(container, envelopeKey) { + constructor(container, envelopeKey, envelopeResponse, documentBytes) { this.container = container this.envelopeKey = envelopeKey - // Initialize classes - console.debug('Initializing classes..') this.UI = new UI() this.Network = new Network() this.Annotation = new Annotation() @@ -24,33 +22,16 @@ class App { this.currentDocument = null this.currentReceiver = null this.signatureCount = 0 + this.envelopeResponse = envelopeResponse; + this.documentBytes = documentBytes; } // This function will be called from the ShowEnvelope.razor page // and will trigger loading of the Editor Interface async init() { // Load the envelope from the database - console.debug('Loading envelope from database..') - const envelopeResponse = await this.Network.getEnvelope(this.envelopeKey) - - if (envelopeResponse.fatal) { - return Swal.fire({ - title: 'Fehler', - text: 'Umschlag konnte nicht geladen werden!', - icon: 'error', - }) - } - - if (envelopeResponse.error) { - return Swal.fire({ - title: 'Warnung', - text: 'Umschlag ist nicht mehr verfügbar.', - icon: 'warning', - }) - } - - this.currentDocument = envelopeResponse.data.envelope.documents[0] - this.currentReceiver = envelopeResponse.data.receiver + this.currentDocument = this.envelopeResponse.envelope.documents[0] + this.currentReceiver = this.envelopeResponse.receiver // Load the document from the filestore console.debug('Loading document from filestore') @@ -67,11 +48,12 @@ class App { icon: 'error', }) } + console.log(documentResponse.data) + console.log(this.documentBytes) - const arrayBuffer = documentResponse.data - + const arrayBuffer = this.documentBytes + console.log(arrayBuffer) // Load PSPDFKit - console.debug('Loading PSPDFKit..') this.Instance = await this.UI.loadPSPDFKit(arrayBuffer, this.container) this.UI.configurePSPDFKit(this.Instance, this.handleClick.bind(this)) @@ -219,6 +201,7 @@ class App { // Export annotation data and save to database try { const json = await this.Instance.exportInstantJSON() + console.log(json) const postEnvelopeResult = await this.Network.postEnvelope( this.envelopeKey, this.currentDocument.id, @@ -257,30 +240,11 @@ class App { .map(a => a.toJS()) .filter(a => a.isSignature) - console.log(annotations.length,"Signatures total!") - console.log(filtered.length,"Signatures signed!") - if (totalSignatures > filtered.length) { return false } else { return true } - - /*this.Instance.getFormFields().then(formFields => { - formFields.forEach(formField => { - console.log(formField.name, formField.toJS()); - }); - - // Filter form fields by type - formFields.filter(formField => ( - formField instanceof PSPDFKit.FormFields.TextFormField - )); - - // Get the total number of form fields - const totalFormFields = formFields.size; - - console.log(totalFormFields) - })*/ } async handleReset(event) { diff --git a/EnvelopeGenerator.Web/wwwroot/js/network.js b/EnvelopeGenerator.Web/wwwroot/js/network.js index e9bfc28d..c74b837a 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/network.js +++ b/EnvelopeGenerator.Web/wwwroot/js/network.js @@ -5,7 +5,6 @@ * @param {any} envelopeKey */ async getEnvelope(envelopeKey) { - console.log("getEnvelope") return this.getRequest(`/api/envelope/${envelopeKey}`) .then(this.wrapJsonResponse.bind(this)) } @@ -17,7 +16,6 @@ * @param {any} json */ async postEnvelope(envelopeKey, documentId, json) { - console.log("postEnvelope") return this.postRequest(`/api/envelope/${envelopeKey}?index=${documentId}`, json) .then(this.wrapJsonResponse.bind(this)) } @@ -28,7 +26,6 @@ * @param {any} documentId */ async getDocument(envelopeKey, documentId) { - console.log("getDocument", `/api/document/${envelopeKey}?index=${documentId}`) return this.getRequest(`/api/document/${envelopeKey}?index=${documentId}`) .then(this.wrapBinaryResponse.bind(this)) } @@ -38,7 +35,6 @@ * @param {any} envelopeKey */ async openDocument(envelopeKey) { - console.log("openDocument") return this.postRequest(`/api/document/${envelopeKey}`, {}) .then(this.wrapJsonResponse.bind(this)) } @@ -73,7 +69,7 @@ * Creates a GET HTTP request to `url` * @param {any} url */ - getRequest(url) { + getRequest(url, body) { const token = this.getCSRFToken() const options = { credentials: 'include', @@ -83,6 +79,10 @@ } } + if (body !== undefined) { + options.body = JSON.stringify(body); + } + return fetch(url, options) } @@ -138,10 +138,6 @@ async wrapResponse(response, responseHandler) { let wrappedResponse - console.log("Handling response from", response.url) - console.log("Status", response.status) - console.log(response) - if (response.status === 200) { const data = await responseHandler(response) wrappedResponse = new WrappedResponse(data, null) @@ -152,8 +148,6 @@ wrappedResponse = new WrappedResponse(null, null) } - console.log("Wrapped response", wrappedResponse) - return wrappedResponse } } diff --git a/EnvelopeGenerator.Web/wwwroot/js/ui.js b/EnvelopeGenerator.Web/wwwroot/js/ui.js index c1a2aaa9..3e1052f8 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/ui.js +++ b/EnvelopeGenerator.Web/wwwroot/js/ui.js @@ -76,7 +76,6 @@ className: 'button-reset', title: 'Zurücksetzen', onPress() { - console.log('RESET') callback('RESET') }, icon: ` @@ -90,7 +89,6 @@ className: 'button-reject', title: 'Ablehnen', onPress() { - console.log('REJECT') callback('REJECT') }, icon: ` @@ -103,7 +101,6 @@ className: 'button-finish', title: 'Abschließen', onPress() { - console.log('FINISH') callback('FINISH') }, }, diff --git a/EnvelopeGenerator.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js b/EnvelopeGenerator.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js index 12674b08..39981ff0 100644 --- a/EnvelopeGenerator.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js +++ b/EnvelopeGenerator.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js @@ -795,7 +795,7 @@ $.extend( $.validator, { } } catch ( e ) { if ( this.settings.debug && window.console ) { - console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); + console.error( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); } if ( e instanceof TypeError ) { e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";