Compare commits

...

7 Commits

Author SHA1 Message Date
Developer 02
6e3bb6c3a0 feat: Enhance receiver input and table components
- Updated `ReceiverInputComponent` to support optional index parameter in the `filter` function to manage email input logic more effectively.
- Added `last_used_name` functionality in `ReceiverTableComponent` to auto-fill names based on the last used email name.
- Implemented email duplication prevention logic in `ReceiverTableComponent` to ensure unique email inputs.
- Refactored component lifecycle methods and data handling for improved performance and user experience.
2024-08-30 22:25:13 +02:00
Developer 02
d347ec420c feat: ReadAllAsync-Methode zur ReceiverRepository hinzugefügt
- `ReadAllAsync`-Methode hinzugefügt, um alle `Receiver`-Entitäten asynchron zurückzugeben.
- Stellt sicher, dass alle Empfänger abgerufen werden, während die vorhandene Abfragelogik mit `ReadBy` erhalten bleibt.
2024-08-30 11:58:00 +02:00
Developer 02
a011b677ea refactor: EnvelopeReceiver-Klasse refaktoriert, um eine Endlosschleife zu verhindern und die Datenabfrage zu verbessern
- `EnvelopeReceiver` in `EnvelopeReceiver` und `EnvelopeReceiverBase` aufgeteilt, um zirkuläre Abhängigkeiten zu vermeiden.
- `EnvelopeReceiverBasicDto` für vereinfachte Datenübertragungsobjekte erstellt.
- `ReceiverRepository` aktualisiert, um den zuletzt verwendeten Empfängernamen durch das Laden aktueller `EnvelopeReceiver`-Daten einzubeziehen.
- `ReceiverReadDto` angepasst, um `LastUsedName` zu erhalten und `EnvelopeReceivers` für die JSON-Serialisierung zu ignorieren.
2024-08-30 11:27:36 +02:00
Developer 02
8831436809 feat(controller): add endpoint to retrieve last used receiver name by email
- Implemented `Get` endpoint in `EnvelopeReceiverController` to fetch the last used receiver's name by email.
- Added handling for successful and failed responses, including proper status codes and logging.
2024-08-29 17:15:00 +02:00
Developer 02
1ededc1f64 feat(service): add ReadLastUsedReceiverNameByMail method to IEnvelopeReceiverService and EnvelopeReceiverService
- Added `ReadLastUsedReceiverNameByMail` method to `IEnvelopeReceiverService` interface.
- Implemented `ReadLastUsedReceiverNameByMail` method in `EnvelopeReceiverService` to retrieve the last used receiver's name by email and handle results with `DataResult`.
2024-08-29 16:57:45 +02:00
Developer 02
183c94fd0a Merge branch 'master' into feat/signFlow-gen 2024-08-29 16:49:30 +02:00
Developer 02
a0a5568d93 feat(repository): Methode ReadLastByReceiver zu IEnvelopeReceiverRepository und EnvelopeReceiverRepository hinzugefügt
- Methode `ReadLastByReceiver` zum Interface `IEnvelopeReceiverRepository` hinzugefügt.
- Methode `ReadLastByReceiver` in `EnvelopeReceiverRepository` implementiert, um den letzten `EnvelopeReceiver` anhand der E-Mail-Adresse abzurufen.
2024-08-29 16:04:19 +02:00
25 changed files with 192 additions and 105 deletions

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Common; using EnvelopeGenerator.Common;
namespace EnvelopeGenerator.Application.Contracts namespace EnvelopeGenerator.Application.Contracts

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.Abstractions.Application; using DigitalData.Core.Abstractions.Application;
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts namespace EnvelopeGenerator.Application.Contracts
@@ -25,5 +25,7 @@ namespace EnvelopeGenerator.Application.Contracts
Task<DataResult<bool>> IsExisting(string envelopeReceiverId); Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
Task<DataResult<string?>> ReadLastUsedReceiverNameByMail(string mail);
} }
} }

View File

@@ -0,0 +1,26 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
{
public record EnvelopeReceiverBasicDto()
{
public int EnvelopeId { get; init; }
public int ReceiverId { get; init; }
public int Sequence { get; init; }
[TemplatePlaceholder("[NAME_RECEIVER]")]
public string? Name { get; init; }
public string? JobTitle { get; init; }
public string? CompanyName { get; init; }
public string? PrivateMessage { get; init; }
public DateTime AddedWhen { get; init; }
public DateTime? ChangedWhen { get; init; }
}
}

View File

@@ -0,0 +1,11 @@
using EnvelopeGenerator.Application.DTOs.Receiver;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
{
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
{
public EnvelopeDto? Envelope { get; set; }
public ReceiverReadDto? Receiver { get; set; }
}
}

View File

@@ -1,31 +0,0 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using EnvelopeGenerator.Application.DTOs.Receiver;
namespace EnvelopeGenerator.Application.DTOs
{
public record EnvelopeReceiverDto()
{
public int EnvelopeId { get; set; }
public int ReceiverId { get; set; }
public int Sequence { get; set; }
[TemplatePlaceholder("[NAME_RECEIVER]")]
public string? Name { get; set; }
public string? JobTitle { get; set; }
public string? CompanyName { get; set; }
public string? PrivateMessage { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime? ChangedWhen { get; set; }
public EnvelopeDto? Envelope { get; set; }
public ReceiverReadDto? Receiver { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs.Receiver namespace EnvelopeGenerator.Application.DTOs.Receiver
{ {
@@ -6,6 +8,12 @@ namespace EnvelopeGenerator.Application.DTOs.Receiver
int Id, int Id,
string EmailAddress, string EmailAddress,
string Signature, string Signature,
DateTime AddedWhen DateTime AddedWhen
) : BaseDTO<int>(Id); ) : BaseDTO<int>(Id)
{
[JsonIgnore]
public IEnumerable<EnvelopeReceiverBasicDto>? EnvelopeReceivers { get; init; }
public string? LastUsedName => EnvelopeReceivers?.LastOrDefault()?.Name;
};
} }

View File

@@ -14,7 +14,7 @@
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="1.0.1.1" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="1.0.1.1" />
<PackageReference Include="DigitalData.Core.Application" Version="1.0.0" /> <PackageReference Include="DigitalData.Core.Application" Version="1.0.0" />
<PackageReference Include="DigitalData.Core.DTO" Version="1.0.0" /> <PackageReference Include="DigitalData.Core.DTO" Version="1.0.0.1" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="1.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
<PackageReference Include="UserManager.Application" Version="1.0.0" /> <PackageReference Include="UserManager.Application" Version="1.0.0" />

View File

@@ -1,6 +1,7 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
@@ -43,6 +44,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles
CreateMap<ReceiverCreateDto, Receiver>(); CreateMap<ReceiverCreateDto, Receiver>();
CreateMap<ReceiverUpdateDto, Receiver>(); CreateMap<ReceiverUpdateDto, Receiver>();
CreateMap<UserReceiverDto, UserReceiver>(); CreateMap<UserReceiverDto, UserReceiver>();
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
} }
} }
} }

View File

@@ -5,7 +5,7 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Abstraction.Services; using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
using DigitalData.UserManager.Application; using DigitalData.UserManager.Application;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Common; using EnvelopeGenerator.Common;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -14,7 +14,7 @@ using static EnvelopeGenerator.Common.Constants;
namespace EnvelopeGenerator.Application.Services namespace EnvelopeGenerator.Application.Services
{ {
public class EnvelopeMailService : EmailOutService, IEnvelopeMailService public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
{ {
private readonly IEmailTemplateService _tempService; private readonly IEmailTemplateService _tempService;
private readonly IEnvelopeReceiverService _envRcvService; private readonly IEnvelopeReceiverService _envRcvService;

View File

@@ -2,7 +2,7 @@
using DigitalData.Core.Application; using DigitalData.Core.Application;
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Contracts;
@@ -122,5 +122,11 @@ namespace EnvelopeGenerator.Application.Services
var dto_list = _mapper.MapOrThrow<IEnumerable<EnvelopeReceiverDto>>(er_list); var dto_list = _mapper.MapOrThrow<IEnumerable<EnvelopeReceiverDto>>(er_list);
return Result.Success(dto_list); return Result.Success(dto_list);
} }
public async Task<DataResult<string?>> ReadLastUsedReceiverNameByMail(string mail)
{
var er = await _repository.ReadLastByReceiver(mail);
return er is null ? Result.Fail<string?>().Notice(LogLevel.None, Flag.NotFound) : Result.Success(er.Name);
}
} }
} }

View File

@@ -1,45 +1,10 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations.Schema;
namespace EnvelopeGenerator.Domain.Entities namespace EnvelopeGenerator.Domain.Entities
{ {
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")] [Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
public class EnvelopeReceiver public class EnvelopeReceiver : EnvelopeReceiverBase
{ {
[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")] [ForeignKey("EnvelopeId")]
public Envelope? Envelope { get; set; } public Envelope? Envelope { get; set; }

View File

@@ -0,0 +1,43 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EnvelopeGenerator.Domain.Entities
{
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
public class EnvelopeReceiverBase
{
[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; }
}
}

View File

@@ -22,5 +22,7 @@ namespace EnvelopeGenerator.Domain.Entities
[Required] [Required]
[Column("ADDED_WHEN", TypeName = "datetime")] [Column("ADDED_WHEN", TypeName = "datetime")]
public DateTime AddedWhen { get; set; } public DateTime AddedWhen { get; set; }
public IEnumerable<EnvelopeReceiver>? EnvelopeReceivers { get; init; }
} }
} }

View File

@@ -37,19 +37,19 @@ export class ReceiverInputComponent implements OnInit, OnChanges {
private setupFiltering(): void { private setupFiltering(): void {
this.filteredOptions = this.control.valueChanges.pipe( this.filteredOptions = this.control.valueChanges.pipe(
startWith(''), startWith(''),
map(value => this.filter(value || '', this.options)), map(value => this.filter(value || '', this.options, this.index)),
); );
} }
control = new FormControl(''); control = new FormControl('');
filteredOptions!: Observable<string[]>; filteredOptions!: Observable<string[]>;
@Input() options: string[] = []; @Input() options: string[] = [];
@Input() filter: (value: string, options: string[]) => string[] = value => { @Input() filter: (value: string, options: string[], index?: number) => string[] = value => {
const filterValue = value.toLowerCase(); const filterValue = value.toLowerCase();
return this.options.filter(option => option.toLowerCase().includes(filterValue)); return this.options.filter(option => option.toLowerCase().includes(filterValue));
} }
@Input() index?: number;
public get text(): string { public get text(): string {
return this.control.value || ''; return this.control.value || '';

View File

@@ -1,8 +1,8 @@
<table mat-table [dataSource]="receiverData" class="mat-elevation-z8"> <table mat-table [dataSource]="receiverData" class="mat-elevation-z8">
<ng-container matColumnDef="email"> <ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef> Email </th> <th mat-header-cell *matHeaderCellDef> Email </th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element; let i = index">
<receiver-input [options]="receiver_mails" [filter]="receiver_filter"></receiver-input> <receiver-input [options]="receiver_mails" [filter]="receiver_filter" [index]="i"></receiver-input>
</td> </td>
</ng-container> </ng-container>

View File

@@ -34,24 +34,39 @@ export class ReceiverTableComponent implements OnInit {
constructor(private receiverService: ReceiverService) { } constructor(private receiverService: ReceiverService) { }
async ngOnInit() { async ngOnInit() {
this.receiver_mails = await this.receiverService.getReceiverAsync().then((receivers: any[]) => receivers.map(r => r.emailAddress)); const receivers = await this.receiverService.getReceiverAsync();
this.receiver_mails = receivers.map((r: any) => r.emailAddress);
this.last_used_name = receivers.reduce((acc: any, r: any) => {
acc[r.emailAddress] = r.lastUsedName;
return acc;
}, {} as { [key: string]: string | null });
} }
receiver_filter: (value: string, options: string[]) => string[] = (value, options) => { receiver_filter: (value: string, options: string[], index?: number) => string[] = (value, options, index) => {
const filterValue = value.toLowerCase(); const filterValue = value.toLowerCase();
// set the name if it is used befor
const name = this.last_used_name[value];
if (name && index)
this.receiverData.at(index)!.name = name
// !!! do not allow email duplication !!!
var similarMails = this.receiver_mails.filter(m => m.toLocaleLowerCase() === value.toLocaleLowerCase() && m !== value)
if (similarMails.length > 0 && index != undefined) {
this.receiverInputs[index].text = similarMails[0];
}
console.log(this.receiverInputs.length + " - " + index)
// if added into last row // if added into last row
if (value.length > 0 && (this.receiverInputs.at(-1)?.lenght ?? 0) > 0) { if (value.length > 0 && (this.receiverInputs.at(-1)?.lenght ?? 0) > 0) {
this.receiverData.at(-1)!.accessCode = generateAccessCode(); this.receiverData.at(-1)!.accessCode = generateAccessCode();
this.receiverData.push({ email: "", name: "", accessCode: "" }); this.receiverData.push({ email: "", name: "", accessCode: "" });
this.update(); this.update();
} }
else if (value.length == 0) { // delete the row with out mail
for (var i = 0; i < this.receiverInputs.length - 1; i++) { else if (value.length === 0 && this.receiverInputs.length - 1 !== index) {
if (this.receiverInputs[i].lenght === 0) { if ( this.receiverInputs.length > 1 && this.receiverInputs[index!]?.lenght === 0) {
this.receiverData.splice(i, 1); this.receiverData.splice(index!, 1);
this.update(); this.update();
}
} }
} }
@@ -59,6 +74,7 @@ export class ReceiverTableComponent implements OnInit {
} }
receiver_mails: string[] = []; receiver_mails: string[] = [];
last_used_name: { [key: string]: string | null } = {};
@ViewChildren(ReceiverInputComponent) receiverInputsQueryList!: QueryList<ReceiverInputComponent>; @ViewChildren(ReceiverInputComponent) receiverInputsQueryList!: QueryList<ReceiverInputComponent>;
get receiverInputs(): ReceiverInputComponent[] { get receiverInputs(): ReceiverInputComponent[] {

View File

@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.GeneratorAPI.Controllers namespace EnvelopeGenerator.GeneratorAPI.Controllers
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[Authorize]
[ApiController] [ApiController]
public class EnvelopeReceiverController : ControllerBase public class EnvelopeReceiverController : ControllerBase
{ {
@@ -17,8 +18,7 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
_logger = logger; _logger = logger;
_erService = envelopeReceiverService; _erService = envelopeReceiverService;
} }
[Authorize]
[HttpGet] [HttpGet]
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] int? min_status = null, [FromQuery] int? max_status = null, [FromQuery] int[]? ignore_status = null) public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] int? min_status = null, [FromQuery] int? max_status = null, [FromQuery] int[]? ignore_status = null)
{ {
@@ -49,5 +49,28 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
return new StatusCodeResult(StatusCodes.Status500InternalServerError); return new StatusCodeResult(StatusCodes.Status500InternalServerError);
} }
} }
[HttpGet("receiver-name/{mail}")]
public async Task<IActionResult> GetReceiverName([FromRoute] string mail)
{
try
{
return await _erService.ReadLastUsedReceiverNameByMail(mail).ThenAsync(
Success: res => res is null ? Ok(string.Empty) : Ok(res),
Fail: IActionResult (msg, ntc) =>
{
if (ntc.HasFlag(Flag.NotFound))
return NotFound();
_logger.LogNotice(ntc);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
} }
} }

View File

@@ -20,5 +20,7 @@ namespace EnvelopeGenerator.Infrastructure.Contracts
Task<string?> ReadAccessCodeByIdAsync(int envelopeId, int receiverId); Task<string?> ReadAccessCodeByIdAsync(int envelopeId, int receiverId);
Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
Task<EnvelopeReceiver?> ReadLastByReceiver(string email);
} }
} }

View File

@@ -1,5 +1,4 @@
using DigitalData.Core.Infrastructure; using DigitalData.Core.Infrastructure;
using DigitalData.UserManager.Infrastructure.Repositories;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Contracts;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -76,5 +75,10 @@ namespace EnvelopeGenerator.Infrastructure.Repositories
return await query.Include(er => er.Envelope).Include(er => er.Receiver).ToListAsync(); return await query.Include(er => er.Envelope).Include(er => er.Receiver).ToListAsync();
} }
public async Task<EnvelopeReceiver?> ReadLastByReceiver(string email)
{
return await _dbSet.Where(er => er.Receiver!.EmailAddress == email).OrderBy(er => er.EnvelopeId).LastOrDefaultAsync();
}
} }
} }

View File

@@ -11,7 +11,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories
{ {
} }
protected IQueryable<Receiver> ReadBy(string? emailAddress = null, string? signature = null) protected IQueryable<Receiver> ReadBy(string? emailAddress = null, string? signature = null, bool withLastUsedName = true)
{ {
IQueryable<Receiver> query = _dbSet.AsNoTracking(); IQueryable<Receiver> query = _dbSet.AsNoTracking();
@@ -21,9 +21,17 @@ namespace EnvelopeGenerator.Infrastructure.Repositories
if(signature is not null) if(signature is not null)
query = query.Where(r => r.Signature == signature); query = query.Where(r => r.Signature == signature);
// envelope receivers are ignored (with '[JsonIgnore]' attribute). The reson to add them is to get the las used receiver name
if (withLastUsedName)
{
query = query.Include(r => r.EnvelopeReceivers!.OrderByDescending(er => er.EnvelopeId).Take(1));
}
return query; return query;
} }
public async Task<Receiver?> ReadByAsync(string? emailAddress = null, string? signature = null) => await ReadBy(emailAddress, signature).FirstOrDefaultAsync(); public async Task<Receiver?> ReadByAsync(string? emailAddress = null, string? signature = null) => await ReadBy(emailAddress, signature).FirstOrDefaultAsync();
public async override Task<IEnumerable<Receiver>> ReadAllAsync() => await ReadBy().ToListAsync();
} }
} }

View File

@@ -10,11 +10,11 @@ using DigitalData.Core.API;
using EnvelopeGenerator.Application; using EnvelopeGenerator.Application;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using EnvelopeGenerator.Web.Models; using EnvelopeGenerator.Web.Models;
using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {

View File

@@ -1,12 +1,12 @@
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Net; using System.Net;
namespace EnvelopeGenerator.Web.Controllers.Test namespace EnvelopeGenerator.Web.Controllers.Test
{ {
[ApiController] [ApiController]
[Route("api/test/[controller]")] [Route("api/test/[controller]")]
public class TestEnvelopeMailController : ControllerBase public class TestEnvelopeMailController : ControllerBase
{ {

View File

@@ -1,10 +1,10 @@
using DigitalData.Core.API; using DigitalData.Core.API;
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application; using EnvelopeGenerator.Application;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
namespace EnvelopeGenerator.Web.Controllers.Test namespace EnvelopeGenerator.Web.Controllers.Test
{ {

View File

@@ -4,10 +4,10 @@
@{ @{
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
} }
@using DigitalData.Core.DTO; @ using DigitalData.Core.DTO;
@using EnvelopeGenerator.Application.DTOs; @ using EnvelopeGenerator.Application.DTOs;
@using Newtonsoft.Json @ using Newtonsoft.Json
@using Newtonsoft.Json.Serialization @ using Newtonsoft.Json.Serialization
@model EnvelopeReceiverDto; @model EnvelopeReceiverDto;
<partial name="_CookieConsentPartial" /> <partial name="_CookieConsentPartial" />
@{ @{

View File

@@ -1,10 +1,10 @@
@{ @{
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
} }
@using DigitalData.Core.DTO; @ using DigitalData.Core.DTO;
@using EnvelopeGenerator.Application.DTOs; @ using EnvelopeGenerator.Application.DTOs;
@using Newtonsoft.Json @ using Newtonsoft.Json
@using Newtonsoft.Json.Serialization @ using Newtonsoft.Json.Serialization
@model EnvelopeReceiverDto; @model EnvelopeReceiverDto;
@{ @{
ViewData["Title"] = _localizer[WebKey.SignDoc]; ViewData["Title"] = _localizer[WebKey.SignDoc];