This commit is contained in:
2024-04-15 14:09:06 +02:00
108 changed files with 2225 additions and 434 deletions

View File

@@ -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<IDocumentReceiverElementRepository, DocumentReceiverElementDto, DocumentReceiverElement, int>
{
}
}

View File

@@ -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<IDocumentStatusRepository, DocumentStatusDto, DocumentStatus, int>
{
}
}

View File

@@ -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<IEmailTemplateRepository, EmailTemplateDto, EmailTemplate, int>
{
}
}

View File

@@ -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<IEnvelopeCertificateRepository, EnvelopeCertificateDto, EnvelopeCertificate, int>
{
}
}

View File

@@ -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<IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long>
{
}
}

View File

@@ -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<IEnvelopeReceiverRepository, EnvelopeReceiverDto, EnvelopeReceiver, int>
{
Task<IServiceMessage> VerifyAccessCode(string envelopeUuid, string accessCode);
}
}

View File

@@ -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<IEnvelopeRepository, EnvelopeDto, Envelope, int>
{
Task<IServiceResult<IEnumerable<EnvelopeDto>>> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = false);
Task<IServiceResult<EnvelopeDto>> ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false);
}
}

View File

@@ -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<IEnvelopeTypeRepository, EnvelopeTypeDto, EnvelopeType, int>
{
}
}

View File

@@ -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<IReceiverRepository, ReceiverDto, Receiver, int>
{
}
}

View File

@@ -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<IUserReceiverRepository, UserReceiverDto, UserReceiver, int>
{
}
}

View File

@@ -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);
}

View File

@@ -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
);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,8 @@
namespace EnvelopeGenerator.Application.DTOs
{
public record EmailTemplateDto(
int Id,
string Name,
string Body,
string Subject);
}

View File

@@ -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);
}

View File

@@ -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<DocumentReceiverElementDto>? Elements
);
}

View File

@@ -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<EnvelopeDocumentDto>? Documents,
IEnumerable<EnvelopeReceiverDto>? Receivers,
IEnumerable<EnvelopeHistoryDto>? History);
}

View File

@@ -0,0 +1,10 @@
namespace EnvelopeGenerator.Application.DTOs
{
public record EnvelopeHistoryDto(
long Id,
int EnvelopeId,
string UserReference,
int Status,
DateTime AddedWhen,
DateTime? ActionDate);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,9 @@
namespace EnvelopeGenerator.Application.DTOs
{
public record ReceiverDto(
int Id,
string EmailAddress,
string Signature,
DateTime AddedWhen,
IEnumerable<EnvelopeReceiverDto>? EnvelopeReceivers);
}

View File

@@ -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);
}

View File

@@ -8,11 +8,33 @@ namespace EnvelopeGenerator.Application.MappingProfiles
{
public BasicDtoMappingProfile()
{
// Entity to DTO mappings
CreateMap<Config, ConfigDto>();
CreateMap<DocumentReceiverElement, DocumentReceiverElementDto>();
CreateMap<DocumentStatus, DocumentStatusDto>();
CreateMap<EmailTemplate, EmailTemplateDto>();
CreateMap<Envelope, EnvelopeDto>();
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
CreateMap<EnvelopeHistory, EnvelopeHistoryDto>();
CreateMap<EnvelopeReceiver, EnvelopeReceiverDto>();
CreateMap<EnvelopeType, EnvelopeTypeDto>();
CreateMap<Receiver, ReceiverDto>();
CreateMap<UserReceiver, UserReceiverDto>();
// DTO to Entity mappings
CreateMap<ConfigDto, Config>();
CreateMap<DocumentReceiverElementDto, DocumentReceiverElement>();
CreateMap<DocumentStatusDto, DocumentStatus>();
CreateMap<EmailTemplateDto, EmailTemplate>();
CreateMap<EnvelopeDto, Envelope>();
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
CreateMap<EnvelopeHistoryDto, EnvelopeHistory>();
CreateMap<EnvelopeReceiverDto, EnvelopeReceiver>();
CreateMap<EnvelopeTypeDto, EnvelopeType>();
CreateMap<ReceiverDto, Receiver>();
CreateMap<UserReceiverDto, UserReceiver>();
}
}
}
}

View File

@@ -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<IDocumentReceiverElementRepository, DocumentReceiverElementDto, DocumentReceiverElement, int>, IDocumentReceiverElementService
{
public DocumentReceiverElementService(IDocumentReceiverElementRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IDocumentStatusRepository, DocumentStatusDto, DocumentStatus, int>, IDocumentStatusService
{
public DocumentStatusService(IDocumentStatusRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IEmailTemplateRepository, EmailTemplateDto, EmailTemplate, int>, IEmailTemplateService
{
public EmailTemplateService(IEmailTemplateRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IEnvelopeCertificateRepository, EnvelopeCertificateDto, EnvelopeCertificate, int>, IEnvelopeCertificateService
{
public EnvelopeCertificateService(IEnvelopeCertificateRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -0,0 +1,39 @@
namespace EnvelopeGenerator.Application.Services
{
/// <summary>
/// Provides extension methods for decoding and extracting information from an envelope receiver ID.
/// </summary>
public static class EnvelopeGeneratorExtensions
{
/// <summary>
/// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature.
/// </summary>
/// <param name="envelopeReceiverId">The base64 encoded string containing the envelope UUID and receiver signature.</param>
/// <returns>A tuple containing the envelope UUID and receiver signature.</returns>
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);
}
/// <summary>
/// Gets the envelope UUID from the decoded envelope receiver ID.
/// </summary>
/// <param name="envelopeReceiverId">The base64 encoded string to decode.</param>
/// <returns>The envelope UUID.</returns>
public static string GetEnvelopeUuid(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().EnvelopeUuid;
/// <summary>
/// Gets the receiver signature from the decoded envelope receiver ID.
/// </summary>
/// <param name="envelopeReceiverId">The base64 encoded string to decode.</param>
/// <returns>The receiver signature.</returns>
public static string GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
}
}

View File

@@ -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<IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
{
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IEnvelopeReceiverRepository, EnvelopeReceiverDto, EnvelopeReceiver, int>, IEnvelopeReceiverService
{
public EnvelopeReceiverService(IEnvelopeReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
public async Task<IServiceMessage> VerifyAccessCode(string envelopeUuid, string accessCode)
{
var envelopeAccessCode = await _repository.ReadAccessCodeByEnvelopeUuid(envelopeUuid);
return CreateMessage(isSuccess: accessCode == envelopeAccessCode) ;
}
}
}

View File

@@ -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<IEnvelopeRepository, EnvelopeDto, Envelope, int>, IEnvelopeService
{
public EnvelopeService(IEnvelopeRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
public async Task<IServiceResult<IEnumerable<EnvelopeDto>>> 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<IEnumerable<EnvelopeDto>>(envelopes);
return Successful(readDto);
}
public async Task<IServiceResult<EnvelopeDto>> 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<EnvelopeDto>();
var readDto = _mapper.MapOrThrow<EnvelopeDto>(envelope);
return Successful(readDto);
}
}
}

View File

@@ -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<IEnvelopeTypeRepository, EnvelopeTypeDto, EnvelopeType, int>, IEnvelopeTypeService
{
public EnvelopeTypeService(IEnvelopeTypeRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IReceiverRepository, ReceiverDto, Receiver, int>, IReceiverService
{
public ReceiverService(IReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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<IUserReceiverRepository, UserReceiverDto, UserReceiver, int>, IUserReceiverService
{
public UserReceiverService(IUserReceiverRepository repository, IKeyTranslationService translationService, IMapper mapper)
: base(repository, translationService, mapper)
{
}
}
}

View File

@@ -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
}
}

View File

@@ -40,4 +40,4 @@ namespace EnvelopeGenerator.Domain.Entities
[DefaultValue("")] // This sets the default value for DOCUMENT_PATH_MOVE_AFTSEND
public string DocumentPathMoveAftsend { get; set; }
}
}
}

View File

@@ -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);
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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<EnvelopeDocument>? Documents { get; set; }
public IEnumerable<EnvelopeReceiver>? Receivers { get; set; }
public IEnumerable<EnvelopeHistory>? History { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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<DocumentReceiverElement>? Elements { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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<EnvelopeReceiver>? EnvelopeReceivers { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
</ItemGroup>
</Project>

View File

@@ -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

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IDocumentReceiverElementRepository : ICRUDRepository<DocumentReceiverElement, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IDocumentStatusRepository : ICRUDRepository<DocumentStatus, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEmailTemplateRepository : ICRUDRepository<EmailTemplate, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEnvelopeCertificateRepository : ICRUDRepository<EnvelopeCertificate, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEnvelopeHistoryRepository : ICRUDRepository<EnvelopeHistory, long>
{
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEnvelopeReceiverRepository : ICRUDRepository<EnvelopeReceiver, int>
{
Task<string?> ReadAccessCodeByEnvelopeUuid(string envelopeUuid);
}
}

View File

@@ -0,0 +1,12 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEnvelopeRepository : ICRUDRepository<Envelope, int>
{
Task<IEnumerable<Envelope>> ReadAllWithAsync(bool documents = false, bool receivers = false, bool history = false, bool documentReceiverElement = true);
Task<Envelope?> ReadByUuidAsync(string uuid, string? signature = null, bool withDocuments = false, bool withReceivers = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withAll = false);
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IEnvelopeTypeRepository : ICRUDRepository<EnvelopeType, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IReceiverRepository : ICRUDRepository<Receiver, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Contracts.Infrastructure;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Infrastructure.Contracts
{
public interface IUserReceiverRepository : ICRUDRepository<UserReceiver, int>
{
}
}

View File

@@ -12,7 +12,51 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Config>().HasNoKey();
modelBuilder.Entity<EnvelopeReceiver>()
.HasKey(er => new { er.EnvelopeId, er.ReceiverId });
modelBuilder.Entity<EnvelopeDocument>();
modelBuilder.Entity<DocumentReceiverElement>();
modelBuilder.Entity<DocumentStatus>();
modelBuilder.Entity<EmailTemplate>();
modelBuilder.Entity<Envelope>();
modelBuilder.Entity<EnvelopeCertificate>();
modelBuilder.Entity<EnvelopeHistory>();
modelBuilder.Entity<EnvelopeType>();
modelBuilder.Entity<Receiver>();
modelBuilder.Entity<UserReceiver>();
// Configure the one-to-many relationship of Envelope
modelBuilder.Entity<Envelope>()
.HasMany(e => e.Documents)
.WithOne()
.HasForeignKey(ed => ed.EnvelopeId);
//modelBuilder.Entity<Envelope>()
// .HasMany(e => e.Receivers)
// .WithOne(er => er.Envelope)
// .HasForeignKey(er => er.EnvelopeId);
modelBuilder.Entity<Envelope>()
.HasMany(e => e.History)
.WithOne()
.HasForeignKey(eh => eh.EnvelopeId);
modelBuilder.Entity<EnvelopeDocument>()
.HasMany(ed => ed.Elements)
.WithOne(e => e.Document)
.HasForeignKey(e => e.DocumentId);
modelBuilder.Entity<DocumentReceiverElement>()
.HasOne(dre => dre.Document)
.WithMany(ed => ed.Elements)
.HasForeignKey(dre => dre.DocumentId);
//modelBuilder.Entity<Receiver>()
// .HasMany(e => e.EnvelopeReceivers)
// .WithOne(er => er.Receiver)
// .HasForeignKey(er => er.ReceiverId);
base.OnModelCreating(modelBuilder);
}

View File

@@ -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<DocumentReceiverElement, int, EGDbContext>, IDocumentReceiverElementRepository
{
public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<DocumentStatus, int, EGDbContext>, IDocumentStatusRepository
{
public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<EmailTemplate, int, EGDbContext>, IEmailTemplateRepository
{
public EmailTemplateRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<EnvelopeCertificate, int, EGDbContext>, IEnvelopeCertificateRepository
{
public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<EnvelopeHistory, long, EGDbContext>, IEnvelopeHistoryRepository
{
public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<Envelope, int, EGDbContext>, IEnvelopeRepository
{
public EnvelopeRepository(EGDbContext dbContext) : base(dbContext)
{
}
public async Task<IEnumerable<Envelope>> 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<Envelope?> 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();
}
}
}

View File

@@ -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<EnvelopeType, int, EGDbContext>, IEnvelopeTypeRepository
{
public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<EnvelopeReceiver, int, EGDbContext>, IEnvelopeReceiverRepository
{
public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext)
{
}
public async Task<string?> ReadAccessCodeByEnvelopeUuid(string envelopeUuid)
{
var accessCode = await _dbSet
.Where(er => er.Envelope != null && er.Envelope.Uuid == envelopeUuid)
.Select(er => er.AccessCode)
.FirstOrDefaultAsync();
return accessCode;
}
}
}

View File

@@ -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<Receiver, int, EGDbContext>, IReceiverRepository
{
public ReceiverRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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<UserReceiver, int, EGDbContext>, IUserReceiverRepository
{
public UserReceiverRepository(EGDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -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,

View File

@@ -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<DocumentController> 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);
}
}

View File

@@ -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<EnvelopeController> 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<IActionResult> Get(string envelopeKey)
[HttpGet("api/envelope/{envelopeKey}")]
public async Task<IActionResult> 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<IActionResult> Update(string envelopeKey)
[HttpPost("api/envelope/{envelopeKey}")]
public async Task<IActionResult> 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()
{

View File

@@ -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<EnvelopeDocumentTestController, IEnvelopeDocumentService, IEnvelopeDocumentRepository, EnvelopeDocumentDto, EnvelopeDocumentDto, EnvelopeDocumentDto, EnvelopeDocument, int>
{
public EnvelopeDocumentTestController(ILogger<EnvelopeDocumentTestController> logger, IEnvelopeDocumentService service) : base(logger, service)
{
}
}
}

View File

@@ -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<HomeController> 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<Envelope> envelopes = _envelopeService.LoadEnvelopes();
List<Envelope> envelopes = envelopeOldService.LoadEnvelopes();
return View(envelopes);
}
@@ -69,14 +61,13 @@ namespace EnvelopeGenerator.Web.Controllers
}
}
[HttpGet]
[Route("/EnvelopeKey/{envelopeReceiverId}")]
[HttpGet("/EnvelopeKey/{envelopeReceiverId}")]
public async Task<IActionResult> 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<IActionResult> ShowEnvelopePost([FromRoute] string envelopeReceiverId, [FromForm] string access_code)
[HttpPost("/EnvelopeKey/{envelopeReceiverId}/Locked")]
public async Task<IActionResult> 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<IActionResult> 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()
{

View File

@@ -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<ConfigTestController, IConfigService, IConfigRepository, ConfigDto, ConfigDto, ConfigDto, Config, int>
public class TestConfigController : TestControllerBase<TestConfigController, IConfigService, IConfigRepository, ConfigDto, Config, int>
{
public ConfigTestController(ILogger<ConfigTestController> logger, IConfigService service) : base(logger, service)
public TestConfigController(ILogger<TestConfigController> logger, IConfigService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TOriginalController, TCRUDService, TCRUDRepository, TDto, TEntity, TId> : BasicCRUDControllerBase<TOriginalController, TCRUDService, TCRUDRepository, TDto, TEntity, TId> where TOriginalController : CRUDControllerBase<TOriginalController, TCRUDService, TCRUDRepository, TDto, TDto, TDto, TEntity, TId> where TCRUDService : ICRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId> where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class
{
public TestControllerBase(ILogger<TOriginalController> logger, TCRUDService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestDocumentReceiverElementController, IDocumentReceiverElementService, IDocumentReceiverElementRepository, DocumentReceiverElementDto, DocumentReceiverElement, int>
{
public TestDocumentReceiverElementController(ILogger<TestDocumentReceiverElementController> logger, IDocumentReceiverElementService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestDocumentStatusController, IDocumentStatusService, IDocumentStatusRepository, DocumentStatusDto, DocumentStatus, int>
{
public TestDocumentStatusController(ILogger<TestDocumentStatusController> logger, IDocumentStatusService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEmailTemplateController, IEmailTemplateService, IEmailTemplateRepository, EmailTemplateDto, EmailTemplate, int>
{
public TestEmailTemplateController(ILogger<TestEmailTemplateController> logger, IEmailTemplateService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEnvelopeCertificateController, IEnvelopeCertificateService, IEnvelopeCertificateRepository, EnvelopeCertificateDto, EnvelopeCertificate, int>
{
public TestEnvelopeCertificateController(ILogger<TestEnvelopeCertificateController> logger, IEnvelopeCertificateService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEnvelopeController, IEnvelopeService, IEnvelopeRepository, EnvelopeDto, Envelope, int>
{
public TestEnvelopeController(ILogger<TestEnvelopeController> logger, IEnvelopeService service) : base(logger, service)
{
}
[NonAction]
public override Task<IActionResult> GetAll()
{
return base.GetAll();
}
[HttpGet]
public virtual async Task<IActionResult> 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);
}
}
}

View File

@@ -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<TestEnvelopeDocumentController, IEnvelopeDocumentService, IEnvelopeDocumentRepository, EnvelopeDocumentDto, EnvelopeDocument, int>
{
public TestEnvelopeDocumentController(ILogger<TestEnvelopeDocumentController> logger, IEnvelopeDocumentService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEnvelopeHistoryController, IEnvelopeHistoryService, IEnvelopeHistoryRepository, EnvelopeHistoryDto, EnvelopeHistory, long>
{
public TestEnvelopeHistoryController(ILogger<TestEnvelopeHistoryController> logger, IEnvelopeHistoryService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEnvelopeReceiverController, IEnvelopeReceiverService, IEnvelopeReceiverRepository, EnvelopeReceiverDto, EnvelopeReceiver, int>
{
public TestEnvelopeReceiverController(ILogger<TestEnvelopeReceiverController> logger, IEnvelopeReceiverService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestEnvelopeTypeController, IEnvelopeTypeService, IEnvelopeTypeRepository, EnvelopeTypeDto, EnvelopeType, int>
{
public TestEnvelopeTypeController(ILogger<TestEnvelopeTypeController> logger, IEnvelopeTypeService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestReceiverController, IReceiverService, IReceiverRepository, ReceiverDto, Receiver, int>
{
public TestReceiverController(ILogger<TestReceiverController> logger, IReceiverService service) : base(logger, service)
{
}
}
}

View File

@@ -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<TestUserReceiverController, IUserReceiverService, IUserReceiverRepository, UserReceiverDto, UserReceiver, int>
{
public TestUserReceiverController(ILogger<TestUserReceiverController> logger, IUserReceiverService service) : base(logger, service)
{
}
}
}

View File

@@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
<PackageReference Include="Quartz" Version="3.8.0" />
<PackageReference Include="Quartz.AspNetCore" Version="3.8.0" />
<PackageReference Include="Quartz.Plugins" Version="3.8.0" />

View File

@@ -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<DatabaseService>();
// Add higher order services
builder.Services.AddScoped<EnvelopeOldService>();
// 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<bool>("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<LoggingService>();
builder.Services.AddScoped<DatabaseService>();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Add higher order services
builder.Services.AddScoped<EnvelopeService>();
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<EGDbContext>(options =>
options.UseSqlServer(connStr));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//Inject CRUD Service and repositories
builder.Services.AddScoped<IConfigRepository, ConfigRepository>();
builder.Services.AddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
builder.Services.AddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
builder.Services.AddScoped<IConfigRepository, ConfigRepository>();
builder.Services.AddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
builder.Services.AddScoped<IDocumentStatusRepository, DocumentStatusRepository>();
builder.Services.AddScoped<IEmailTemplateRepository, EmailTemplateRepository>();
builder.Services.AddScoped<IEnvelopeRepository, EnvelopeRepository>();
builder.Services.AddScoped<IEnvelopeCertificateRepository, EnvelopeCertificateRepository>();
builder.Services.AddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
builder.Services.AddScoped<IEnvelopeHistoryRepository, EnvelopeHistoryRepository>();
builder.Services.AddScoped<IEnvelopeReceiverRepository, EnvelopeReceiverRepository>();
builder.Services.AddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
builder.Services.AddScoped<IReceiverRepository, ReceiverRepository>();
builder.Services.AddScoped<IUserReceiverRepository, UserReceiverRepository>();
builder.Services.AddKeyTranslationService();
builder.Services.AddScoped<IConfigService, ConfigService>();
builder.Services.AddScoped<IDocumentReceiverElementService, DocumentReceiverElementService>();
builder.Services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
builder.Services.AddScoped<IDocumentStatusService, DocumentStatusService>();
builder.Services.AddScoped<IEmailTemplateService, EmailTemplateService>();
builder.Services.AddScoped<IEnvelopeService, EnvelopeService>();
builder.Services.AddScoped<IEnvelopeCertificateService, EnvelopeCertificateService>();
builder.Services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
builder.Services.AddScoped<IEnvelopeHistoryService, EnvelopeHistoryService>();
builder.Services.AddScoped<IEnvelopeReceiverService, EnvelopeReceiverService>();
builder.Services.AddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
builder.Services.AddScoped<IReceiverService, ReceiverService>();
builder.Services.AddScoped<IUserReceiverService, UserReceiverService>();
//AddEF Core dbcontext
var connStr = builder.Configuration["Config:ConnectionString"];
builder.Services.AddDbContext<EGDbContext>(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<IConfigRepository, ConfigRepository>();
builder.Services.AddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
builder.Services.AddScoped<IConfigService, ConfigService>();
builder.Services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
//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;
}

View File

@@ -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;
}
}
}

View File

@@ -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<DatabaseService> _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<DatabaseService> 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);
/// <summary>
/// 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.
/// </summary>
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];
}
/// <summary>
/// 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.
/// </summary>
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
};
}
}
}

View File

@@ -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<EnvelopeOldService> _logger;
public EnvelopeService(IConfiguration Config, LoggingService Logging, DatabaseService database, IConfigService configService) : base(Config, Logging)
public EnvelopeOldService(DatabaseService database, IConfigService configService, ILogger<EnvelopeOldService> 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<string, string> 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<EnvelopeResponse> LoadEnvelope(string pEnvelopeKey)
{
logger.Debug("Loading Envelope by Key [{0}]", pEnvelopeKey);
_logger.LogInformation("Loading Envelope by Key [{0}]", pEnvelopeKey);
Tuple<string, string> 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<EnvelopeDocument> GetDocument(HttpRequest request, string envelopeKey)
public async Task<EnvelopeDocument> 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<byte[]> 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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -15,9 +15,7 @@
<section class="text-center">
<p>Sie haben das Dokument signiert. Im Anschluss erhalten Sie eine schriftliche Bestätigung.</p>
</section>
</section>
</div>
<footer class="container" id="page-footer">&copy; SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>

View File

@@ -1,12 +1,89 @@
@{
@using DigitalData.Core.Contracts.Application;
@using EnvelopeGenerator.Application.DTOs;
@model IServiceResult<EnvelopeDto>;
@{
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<int>();
var stPageIndexes = string.Join(pages.Count() > 1 ? ", " : "", pages.Take(pages.Count() - 1))
+ (pages.Count() > 1 ? " und " : "") + pages.LastOrDefault();
<nav class="navbar navbar-light bg-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-brand me-auto ms-5 envelope-message">@($"Hallo {receiverName}, {@envelope.Message}")</div>
<div class="col-1 p-0 m-0 me-3 d-flex">
<img src="~/img/digital_data.svg" alt="...">
</div>
</div>
</nav>
<div class="collapse show" id="navbarToggleExternalContent" data-bs-theme="light">
<div class="bg-light p-1">
<div class="card sender-card mb-3">
<div class="row g-0">
<div class="col-1 p-0 m-0 ps-4 mx-auto">
<img src="~/img/default-user.svg" class="img-fluid p-0 m-0" alt="...">
</div>
<div class="col p-0 m-0">
<div class="card-body p-0 m-0">
<h5 class="card-title p-0 m-0">@($"{envelope.Title}")</h5>
<p class="card-text p-0 m-0">@($"Sie haben {(pages.Count())} Briefe zu unterschreiben. Bitte prüfen Sie die Seiten {stPageIndexes}.")</p>
<p class="card-text p-0 m-0"><small class="text-body-secondary">Erstellt am @envelope.AddedWhen</small></p>
</div>
</div>
</div>
</div>
</div>
</div>
}
<script>
document.addEventListener("DOMContentLoaded", async () => {
const app = new App("#app", "@ViewData["EnvelopeKey"]");
await app.init();
})
const collapseNav = () => {
document.addEventListener('click', function (event) {
var navbarToggle = document.getElementById('navbarToggleExternalContent');
var navbarButton = document.querySelector('[data-bs-target="#navbarToggleExternalContent"]');
var isCollapsed = new bootstrap.Collapse(navbarToggle)._isTransitioning;
if (!navbarToggle.contains(event.target) && !navbarButton.contains(event.target) && !isCollapsed) {
new bootstrap.Collapse(navbarToggle).hide();
}
});
}
</script>
@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);
<script>
var base64String = "@Html.Raw(documentBase64String)";
var byteCharacters = atob(base64String);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var documentArrayBuffer = byteArray.buffer;
var envelopeResponse = @Html.Raw(envelopeResponseJson);
document.addEventListener("DOMContentLoaded", async () => {
const app = new App("#app", "@ViewData["EnvelopeKey"]", envelopeResponse, documentArrayBuffer);
await app.init();
})
</script>
}
<div id='app' style='background: gray; width: 100vw; height: 100vh; margin: 0 auto;'></div>

View File

@@ -11,10 +11,6 @@
<link rel="stylesheet" href="~/EnvelopeGenerator.Web.styles.css" asp-append-version="true" />
</head>
<body>
<main role="main">
@RenderBody()
</main>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/sweetalert2/sweetalert2.min.js"></script>
@@ -24,6 +20,11 @@
<script src="~/js/app.js" asp-append-version="true"></script>
<script src="~/lib/pspdfkit/pspdfkit.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
<main role="main">
@RenderBody()
</main>
@Html.AntiForgeryToken()
</body>

View File

@@ -1,3 +1,3 @@
@using EnvelopeGenerator.Web
@using EnvelopeGenerator.Web.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@@ -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
}

View File

@@ -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",

Some files were not shown because too many files have changed in this diff Show More