From 5f9787902f90b31c65e2039c81820c015886e3b2 Mon Sep 17 00:00:00 2001 From: jojo aquino Date: Sun, 9 Feb 2025 09:38:56 +0000 Subject: [PATCH] Participant Registration Steps --- .../Constants/SignatoryStatus.cs | 3 +- .../Common/Extensions/StringExtensions.cs | 2 + .../IdentificationDocumentModelMapper.cs | 2 +- .../Pages/BaseTakeSelfiePageModel.cs | 137 ++++++++++++++++++ .../Registration/Steps/TakeSelfie.cshtml | 53 ++++--- .../Registration/Steps/TakeSelfie.cshtml.cs | 31 +++- .../Steps/UploadIdentification.cshtml | 2 - .../Steps/UploadIdentification.cshtml.cs | 1 - .../Participant/VideoCall/Waiting.cshtml | 28 ++++ .../Participant/VideoCall/Waiting.cshtml.cs | 15 ++ .../NotaryoSteps/ChooseNotary.cshtml | 1 - .../NotaryoSteps/TakeSelfie.cshtml.cs | 107 +------------- .../NotaryoSteps/TakeSelfie.cshtml.js | 2 +- .../NotaryoSteps/UploadDocument.cshtml | 78 +--------- .../NotaryoSteps/UploadDocument.cshtml.cs | 115 ++++----------- .../NotaryoSteps/UploadIdentification.cshtml | 60 +------- .../UploadIdentification.cshtml.cs | 2 + .../Components/TakeSelfieImage/Default.cshtml | 26 ++++ .../TakeSelfieImage/Default.cshtml.cs | 9 ++ .../TakeSelfieImage/TakeSelfieImageModel.cs | 10 ++ .../EnotaryoPH.Web/Pages/_ViewImports.cshtml | 3 + EnotaryoPH/EnotaryoPH.Web/Program.cs | 1 + 22 files changed, 335 insertions(+), 353 deletions(-) create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml.cs create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml.cs create mode 100644 EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/TakeSelfieImageModel.cs diff --git a/EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs b/EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs index bc228b3..0897dbb 100644 --- a/EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs +++ b/EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs @@ -5,6 +5,7 @@ New = 0, EmailSent = 1, Registered = 2, - FaceMatch = 3 + FaceMatch = 3, + Completed = 10 } } \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Common/Extensions/StringExtensions.cs b/EnotaryoPH/EnotaryoPH.Web/Common/Extensions/StringExtensions.cs index 45ec8ef..391a55d 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Common/Extensions/StringExtensions.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Common/Extensions/StringExtensions.cs @@ -8,6 +8,8 @@ public static string DefaultIfEmpty(this string s, string defaultValue) => !string.IsNullOrWhiteSpace(s) ? s : (defaultValue ?? string.Empty); + public static bool IsInList(this string s, params string[] list) => list.Contains(s, StringComparer.OrdinalIgnoreCase); + public static string NullIfWhiteSpace(this string s) => string.IsNullOrWhiteSpace(s) ? null : s; public static Guid ToGuidFromBase64(this string s) diff --git a/EnotaryoPH/EnotaryoPH.Web/Common/Models/IdentificationDocumentModelMapper.cs b/EnotaryoPH/EnotaryoPH.Web/Common/Models/IdentificationDocumentModelMapper.cs index 015f590..e46142b 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Common/Models/IdentificationDocumentModelMapper.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Common/Models/IdentificationDocumentModelMapper.cs @@ -20,7 +20,7 @@ namespace EnotaryoPH.Web.Common.Models internal static IdentificationDocument ToEntity(this IdentificationDocumentModel model, IdentificationDocument entity) { - ArgumentNullException.ThrowIfNull(model.File, nameof(model.File)); + ArgumentNullException.ThrowIfNull(model.File); entity.ExpirationDate = model.ExpirationDate.ToUTC(); entity.DateIssued = model.DateIssued.ToUTC(); diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs new file mode 100644 index 0000000..c645287 --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs @@ -0,0 +1,137 @@ +using EnotaryoPH.Data; +using EnotaryoPH.Data.Entities; +using Exadel.Compreface.Clients.CompreFaceClient; +using Exadel.Compreface.DTOs.FaceVerificationDTOs.FaceVerification; +using Exadel.Compreface.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace EnotaryoPH.Web.Pages +{ + public class BaseTakeSelfiePageModel : PageModel + { + protected readonly NotaryoDBContext _notaryoDBContext; + private readonly ICurrentUserService _currentUserService; + private readonly ICompreFaceClient _compreFaceClient; + private readonly IConfiguration _configuration; + + public BaseTakeSelfiePageModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration) + { + _notaryoDBContext = notaryoDBContext; + _currentUserService = currentUserService; + _compreFaceClient = compreFaceClient; + _configuration = configuration; + } + + protected async Task PostAsync() + { + var selfieImage = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]) ?? []; + var identificationDocument = _notaryoDBContext.IdentificationDocuments.First(e => e.UserID == UserID); + var faceMatches = await VerifySelfieAsync(selfieImage, identificationDocument); + + var isMatchSuccess = faceMatches.Any(); + if (isMatchSuccess) + { + var signatory = _notaryoDBContext.TransactionSignatories.First(x => x.UserID == UserID); + signatory.Status = nameof(SignatoryStatus.FaceMatch); + _notaryoDBContext.Update(signatory); + + var selfieEntity = CreateOrUpdateSelfie(selfieImage); + if (_notaryoDBContext.Entry(selfieEntity).State == EntityState.Detached) + { + _notaryoDBContext.Add(selfieEntity); + } + else + { + _notaryoDBContext.Update(selfieEntity); + } + _notaryoDBContext.SaveChanges(); + } + return isMatchSuccess; + } + + private Transaction _transactionEntity; + + private int TransactionID + { + get + { + if (_transactionEntity == null) + { + _transactionEntity = _notaryoDBContext.Transactions.AsNoTracking().First(x => x.Transaction_UID == Transaction_UID); + } + return _transactionEntity?.TransactionID ?? 0; + } + } + + private User _user; + + private int UserID + { + get + { + if (_user == null) + { + _user = _notaryoDBContext.Users.AsNoTracking().First(x => x.User_UID == _currentUserService.GetUser_UID()); + } + return _user?.UserID ?? 0; + } + } + + private async Task> VerifySelfieAsync(byte[] selfieImage, IdentificationDocument identificationDocument) + { + var selfiePath = Path.Combine(Path.GetTempPath(), "Selfies"); + if (!Directory.Exists(selfiePath)) + { + Directory.CreateDirectory(selfiePath); + } + var identificationDocumentPath = Path.Combine(selfiePath, $"{identificationDocument.IdentificationDocument_UID}.jpg"); + + var apiKey = _configuration.GetValue("CompreFaceConfig:APIKey"); + var client = _compreFaceClient.GetCompreFaceService(apiKey); + var faceVerificationRequest = new FaceVerificationRequestByBytes() + { + SourceImageInBytes = selfieImage, + TargetImageInBytes = identificationDocument.File, + DetProbThreshold = 0.81m, + Limit = 1, + Status = false, + FacePlugins = [] + }; + var result = await client.VerifyAsync(faceVerificationRequest); + var faceMatches = result.Result.SelectMany(x => x.FaceMatches); + return faceMatches; + } + + private TransactionSelfie CreateOrUpdateSelfie(byte[] selfieImage) + { + TransactionSelfie selfieEntity; + if (TransactionSelfie_UID == Guid.Empty) + { + selfieEntity = new TransactionSelfie + { + CreatedOn = DateTime.UtcNow, + TransactionSelfie_UID = Guid.CreateVersion7(DateTime.UtcNow), + UserID = UserID, + TransactionID = TransactionID + }; + TransactionSelfie_UID = selfieEntity.TransactionSelfie_UID.Value; + } + else + { + selfieEntity = _notaryoDBContext.TransactionSelfies.FirstOrDefault(e => e.TransactionSelfie_UID == TransactionSelfie_UID); + } + selfieEntity.File = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]); + return selfieEntity; + } + + [BindProperty(SupportsGet = true)] + public Guid Transaction_UID { get; set; } + + [BindProperty] + public string SelfieBase64Image { get; set; } + + [BindProperty(SupportsGet = true)] + public Guid TransactionSelfie_UID { get; set; } + } +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml index 8a6e2ed..90a53f6 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml @@ -1,37 +1,42 @@ @page "{Transaction_UID:guid}" @model EnotaryoPH.Web.Pages.Participant.Registration.Steps.TakeSelfieModel -@{ +@section Head { + + }
-

Registration Steps

-
-
-
-
-
- TAKE PICTUREAGAIN -
+

Notaryo Steps

+
+ @await Component.InvokeAsync("NotaryoSteps", new + { + NotaryoSteps = new List() { + new NotaryoStep { Name = "Upload Identification", Step = 1 }, + new NotaryoStep { Name = "Take Selfie", Step = 2, IsActive = true } + } + }) +
+
+ @await Component.InvokeAsync("TakeSelfieImage", new TakeSelfieImageModel { SelfieBase64Image = Model.SelfieBase64Image }) +
-
\ No newline at end of file + + + +@section Scripts { + + + + +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml.cs index 385032e..228cb6f 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/TakeSelfie.cshtml.cs @@ -1,15 +1,38 @@ +using EnotaryoPH.Data; +using EnotaryoPH.Web.Pages.Shared.Components.TakeSelfieImage; +using Exadel.Compreface.Clients.CompreFaceClient; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; namespace EnotaryoPH.Web.Pages.Participant.Registration.Steps { - public class TakeSelfieModel : PageModel + public class TakeSelfieModel : BaseTakeSelfiePageModel { + public TakeSelfieModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration) + : base(notaryoDBContext, currentUserService, compreFaceClient, configuration) + { + } + public void OnGet() { } - [BindProperty(SupportsGet = true)] - public Guid Transaction_UID { get; set; } + public async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + var isMatchSuccess = await PostAsync(); + if (isMatchSuccess) + { + return Redirect($"/Participant/VideoCall/Waiting/{Transaction_UID}"); + } + ModelState.AddModelError("", "Face Verification Failed"); + + return Page(); + } + + [BindProperty] + public TakeSelfieImageModel TakeSelfieImage { get; set; } } } \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml index 8615fa2..e46e863 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml @@ -1,6 +1,4 @@ @page "{Transaction_UID:guid}" -@using EnotaryoPH.Web.Pages.Shared.Components.NotaryoSteps -@using EnotaryoPH.Web.Pages.Shared.Components.UploadOrChooseIdentificationDocument @model EnotaryoPH.Web.Pages.Participant.Registration.Steps.UploadIdentificationModel @section Head { diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml.cs index 05f5159..1d247a8 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/Registration/Steps/UploadIdentification.cshtml.cs @@ -18,7 +18,6 @@ namespace EnotaryoPH.Web.Pages.Participant.Registration.Steps { if (UploadNewIdentification) { - if (!ModelState.IsValid) { return Page(); diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml new file mode 100644 index 0000000..cde6dde --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml @@ -0,0 +1,28 @@ +@page "{Transaction_UID:guid}" +@model EnotaryoPH.Web.Pages.Participant.VideoCall.WaitingModel +@{ +} + +@section Head { + +} + +
+
+

Waiting for participants

+
    +
  • +
    notary1@example.com - host
    +
  • +
  • +
    principal1@example.com - principal
    +
  • +
  • +
    principal2@example.com - principal
    +
  • +
  • +
    witness1@example.com - witness
    +
  • +
+
+
\ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml.cs new file mode 100644 index 0000000..56dcbc4 --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Participant/VideoCall/Waiting.cshtml.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace EnotaryoPH.Web.Pages.Participant.VideoCall +{ + public class WaitingModel : PageModel + { + public void OnGet() + { + } + + [BindProperty(SupportsGet = true)] + public Guid Transaction_UID { get; set; } + } +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/ChooseNotary.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/ChooseNotary.cshtml index 6bcaba5..0f80412 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/ChooseNotary.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/ChooseNotary.cshtml @@ -1,5 +1,4 @@ @page "{Transaction_UID}" -@using EnotaryoPH.Web.Pages.Shared.Components.NotaryoSteps @model EnotaryoPH.Web.Pages.Principal.NotaryoSteps.ChooseNotaryModel @{ } diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.cs index e5a3b1b..ce1ad1e 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.cs @@ -1,29 +1,15 @@ -using System.ComponentModel.DataAnnotations; using EnotaryoPH.Data; -using EnotaryoPH.Data.Entities; using Exadel.Compreface.Clients.CompreFaceClient; -using Exadel.Compreface.DTOs.FaceVerificationDTOs.FaceVerification; -using Exadel.Compreface.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps { - public class TakeSelfieModel : PageModel + public class TakeSelfieModel : BaseTakeSelfiePageModel { - private readonly NotaryoDBContext _notaryoDBContext; - private readonly ICurrentUserService _currentUserService; - private readonly ICompreFaceClient _compreFaceClient; - private readonly IConfiguration _configuration; - public TakeSelfieModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration) - { - _notaryoDBContext = notaryoDBContext; - _currentUserService = currentUserService; - _compreFaceClient = compreFaceClient; - _configuration = configuration; - } + : base(notaryoDBContext, currentUserService, compreFaceClient, configuration) + { } public void OnGet() { @@ -35,86 +21,13 @@ namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps { return Page(); } - - var user = _notaryoDBContext.Users.FirstOrDefault(u => u.User_UID == _currentUserService.GetUser_UID()); - - TransactionSelfie selfieEntity; - if (TransactionSelfie_UID == Guid.Empty) + var isMatchSuccess = await PostAsync(); + if (isMatchSuccess) { - selfieEntity = new TransactionSelfie - { - CreatedOn = DateTime.UtcNow, - TransactionSelfie_UID = Guid.CreateVersion7(DateTime.UtcNow), - UserID = user.UserID - }; - TransactionSelfie_UID = selfieEntity.TransactionSelfie_UID.Value; + return Redirect($"/Principal/NotaryoSteps/UploadDocument/{Transaction_UID}"); } - else - { - selfieEntity = _notaryoDBContext.TransactionSelfies.FirstOrDefault(e => e.TransactionSelfie_UID == TransactionSelfie_UID); - } - selfieEntity.File = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]); + ModelState.AddModelError("", "Face Verification Failed"); - if (selfieEntity.TransactionID > 0) - { - _notaryoDBContext.TransactionSelfies.Update(selfieEntity); - } - else - { - _notaryoDBContext.TransactionSelfies.Add(selfieEntity); - } - _notaryoDBContext.SaveChanges(); - - var identificationDocuments = _notaryoDBContext.IdentificationDocuments.Where(e => e.UserID == user.UserID); - var identificationDocument = identificationDocuments.First(); - - var selfiePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Selfies"); - if (!System.IO.Directory.Exists(selfiePath)) - { - System.IO.Directory.CreateDirectory(selfiePath); - } - var identificationDocumentPath = System.IO.Path.Combine(selfiePath, $"{identificationDocument.IdentificationDocument_UID}.jpg"); - var selfieImagePath = System.IO.Path.Combine(selfiePath, $"{TransactionSelfie_UID}.png"); - - var apiKey = _configuration.GetValue("CompreFaceConfig:APIKey"); - var client = _compreFaceClient.GetCompreFaceService(apiKey); - var faceVerificationRequest = new FaceVerificationRequestByBytes() - { - SourceImageInBytes = selfieEntity.File, - TargetImageInBytes = identificationDocument.File, - DetProbThreshold = 0.81m, - Limit = 1, - Status = false, - FacePlugins = [] - }; - try - { - var result = await client.VerifyAsync(faceVerificationRequest); - var faceMatches = result.Result.SelectMany(x => x.FaceMatches); - - if (faceMatches.Any()) - { - var newTransaction = new Transaction - { - TransactionDate = DateTime.UtcNow, - CreatedOn = DateTime.UtcNow, - PrincipalID = user.UserID, - Status = nameof(TransactionState.New), - Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow) - }; - _notaryoDBContext.Transactions.Add(newTransaction); - selfieEntity.Transaction = newTransaction; - _notaryoDBContext.SaveChanges(); - - return Redirect($"/Principal/NotaryoSteps/UploadDocument/{newTransaction.Transaction_UID}"); - } - ModelState.AddModelError("", "Face Verification Failed"); - } - catch (Exception ex) - { - // capture error here - ModelState.AddModelError("", ex.Message); - } return Page(); } @@ -156,11 +69,5 @@ namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps return File(selfie.File, "image/png"); } - - [BindProperty, Required] - public string SelfieBase64Image { get; set; } - - [BindProperty(SupportsGet = true)] - public Guid TransactionSelfie_UID { get; set; } } } \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.js b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.js index ba98b28..4c1d7c2 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.js +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/TakeSelfie.cshtml.js @@ -86,7 +86,7 @@ const data = control_canvas.toDataURL('image/jpg'); control_photo.setAttribute('src', data); - + debugger; control_selfieBase64Image.value = data; _showPhoto(); diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml index 852b7c5..d00a163 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml @@ -1,6 +1,5 @@ @page "{Transaction_UID}" -@using EnotaryoPH.Web.Pages.Shared.Components.NotaryoSteps -@model EnotaryoPH.Web.Pages.Principal.NotaryoSteps.UploadDocumentModel +@model UploadDocumentModel @{ } @@ -25,79 +24,12 @@ })
-
-
-
-
- - - @Html.ValidationMessageFor(x => x.DocumentFile) -
+ -
- -
-
- -
- @Html.ValidationMessageFor(x => x.DocumentType) -
-
-
-
-
- Email - - -
-
- -
-
    -
-
-
-
- Email - - -
-
- -
-
    -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
- @Html.ValidationMessageFor(x => x.IsConfirmed) -
-
- - -
+ @await Component.InvokeAsync("UploadOrChooseIdentificationDocument", Model.Transaction_UID) +
- +
diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml.cs index d71a0d2..39ec09c 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadDocument.cshtml.cs @@ -1,124 +1,67 @@ using System.ComponentModel.DataAnnotations; -using System.Text.Json; using Coravel.Queuing.Interfaces; using EnotaryoPH.Data; -using EnotaryoPH.Data.Entities; using EnotaryoPH.Web.Common.Jobs; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.Rendering; namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps { - public class UploadDocumentModel : PageModel + public class UploadDocumentModel : BaseIdentificationDocumentPageModel { private readonly ICurrentUserService _currentUserService; - private readonly NotaryoDBContext _notaryoDBContext; private readonly IQueue _queue; public UploadDocumentModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, IQueue queue) + : base(notaryoDBContext) { - _notaryoDBContext = notaryoDBContext; _currentUserService = currentUserService; _queue = queue; } - public IActionResult OnGet(Guid transaction_UID) + public void OnGet() { - var _transaction = _notaryoDBContext.Transactions - .Include(t => t.TransactionDocument) - .Include(t => t.TransactionSignatories) - .AsNoTracking().FirstOrDefault(e => e.Transaction_UID == transaction_UID); - DocumentTypes = GetDocumentTypes(); - CurrentUserEmail = _currentUserService.GetEmail(); - var signatories = _transaction.TransactionSignatories.Select(ts => new SignatoryViewModel - { - Email = ts.Email, - Type = ts.Type, - UID = ts.TransactionSignatory_UID.GetValueOrDefault() - }).ToList(); - ParticipantsJson = JsonSerializer.Serialize(signatories); - - return Page(); } public async Task OnPostAsync() { - if (!ModelState.IsValid) + if (UploadNewIdentification) { - DocumentTypes = GetDocumentTypes(); - return Page(); - } - - if (!IsConfirmed) - { - ModelState.AddModelError(nameof(IsConfirmed), "You must tick this box to continue."); - DocumentTypes = GetDocumentTypes(); - return Page(); - } - - var transaction = _notaryoDBContext.Transactions - .Include(t => t.TransactionSignatories) - .Include(t => t.TransactionDocument) - .FirstOrDefault(t => t.Transaction_UID == Transaction_UID); - if (transaction == null) - { - return NotFound(); - } - - transaction.Status = nameof(TransactionState.DocumentUploaded); - transaction.IsRecorded = IsVideoConferenceRecorded; - - if (transaction.TransactionDocument == null) - { - transaction.TransactionDocument = new TransactionDocument + if (!ModelState.IsValid) { - CreatedOn = DateTime.UtcNow, - Transaction = transaction, - TransactionDocument_UID = Guid.CreateVersion7(DateTime.UtcNow), - }; + return Page(); + } + + CreateIdentificationDocument(_currentUserService.GetUser_UID()); } - var stream = new MemoryStream((int)DocumentFile.Length); - DocumentFile.CopyTo(stream); - transaction.TransactionDocument.File = stream.ToArray(); - transaction.TransactionDocument.Filename = DocumentFile.FileName; - transaction.TransactionDocument.DocumentType = DocumentType; - transaction.TransactionDocument.UploadedOn = DateTime.UtcNow; - - var participants = JsonSerializer.Deserialize>(ParticipantsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? []; - transaction.TransactionSignatories = participants.Select(p => new TransactionSignatory - { - CreatedOn = DateTime.UtcNow, - Email = p.Email, - Status = nameof(SignatoryStatus.New), - TransactionSignatory_UID = Guid.CreateVersion7(DateTime.UtcNow), - Type = p.Type, - InvitationCode = Guid.CreateVersion7(DateTime.UtcNow).ToString() - }).ToList(); - - _notaryoDBContext.Update(transaction); - _notaryoDBContext.SaveChanges(); - - foreach (var signatory in transaction.TransactionSignatories) - { - _queue.QueueInvocableWithPayload(signatory.TransactionSignatory_UID.GetValueOrDefault()); - } + SendSignatoryInvitations(); return Redirect($"/Principal/NotaryoSteps/ChooseNotary/{Transaction_UID}"); } - private List GetDocumentTypes() + private void SendSignatoryInvitations() { - var lookupIdentificationTypes = _notaryoDBContext.LookupData.AsNoTracking().Include(e => e.LookupDataValues).FirstOrDefault(e => e.Name == "Document Types"); - return lookupIdentificationTypes.LookupDataValues - .ConvertAll(m => new SelectListItem - { - Text = m.Title.DefaultIfEmpty(m.Value), - Value = m.Value - }); + var transaction = _notaryoDBContext.Transactions + .Include(e => e.TransactionSignatories) + .FirstOrDefault(e => e.Transaction_UID == Transaction_UID); + foreach (var signatory in transaction.TransactionSignatories) + { + _queue.QueueInvocableWithPayload(signatory.TransactionSignatory_UID.GetValueOrDefault()); + } } + //private List GetDocumentTypes() + //{ + // var lookupIdentificationTypes = _notaryoDBContext.LookupData.AsNoTracking().Include(e => e.LookupDataValues).FirstOrDefault(e => e.Name == "Document Types"); + // return lookupIdentificationTypes.LookupDataValues + // .ConvertAll(m => new SelectListItem + // { + // Text = m.Title.DefaultIfEmpty(m.Value), + // Value = m.Value + // }); + //} + public string CurrentUserEmail { get; private set; } [BindProperty, Required] diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml index d613eb2..b7b6130 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml @@ -1,9 +1,5 @@ @page -@using EnotaryoPH.Web.Pages.Shared.Components.NotaryoSteps - @model UploadIdentificationModel -@{ -} @section Head { @@ -24,61 +20,7 @@
- - @if (Model.ExistingIdentificationDocuments.Count > 0) - { -
-
-
-
-
-
-
-
- } - else { - - } - -
- @Html.EditorFor(m => m.NewIdentificationDocument) -
- @if (Model.ExistingIdentificationDocuments.Count > 0) - { -
-
-
-

Existing Identification Documents

-
- - - - - - - - - - @foreach(var id in Model.ExistingIdentificationDocuments) - { - - - - - - } - -
Identification Document TypeExpiration
@id.IdentificationType@id.ExpirationDate.Value.ToShortDateString() - -
-
-
-
-
- } + @await Component.InvokeAsync("UploadOrChooseIdentificationDocument", Model.Transaction_UID)
diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml.cs index 0c97b6b..95a8039 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Principal/NotaryoSteps/UploadIdentification.cshtml.cs @@ -81,5 +81,7 @@ namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps [BindProperty] public bool UploadNewIdentification { get; set; } + + public Guid Transaction_UID { get; private set; } } } \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml new file mode 100644 index 0000000..c45a58a --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml @@ -0,0 +1,26 @@ +@model TakeSelfieImageModel + +@Html.ValidationSummary() + +
+ +
+ +
+ +
+ +
+
+ The screen capture will appear in this box. +
+
+ +
+ + +
+ +
+ + \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml.cs new file mode 100644 index 0000000..df9bfbc --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/Default.cshtml.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Mvc; + +namespace EnotaryoPH.Web.Pages.Shared.Components.TakeSelfieImage +{ + public class TakeSelfieImageViewComponent : ViewComponent + { + public async Task InvokeAsync(TakeSelfieImageModel model) => View(model); + } +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/TakeSelfieImageModel.cs b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/TakeSelfieImageModel.cs new file mode 100644 index 0000000..a74e25d --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/Shared/Components/TakeSelfieImage/TakeSelfieImageModel.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Mvc; + +namespace EnotaryoPH.Web.Pages.Shared.Components.TakeSelfieImage +{ + public class TakeSelfieImageModel + { + [BindProperty] + public string SelfieBase64Image { get; set; } + } +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Pages/_ViewImports.cshtml b/EnotaryoPH/EnotaryoPH.Web/Pages/_ViewImports.cshtml index 1931202..29e1d95 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Pages/_ViewImports.cshtml +++ b/EnotaryoPH/EnotaryoPH.Web/Pages/_ViewImports.cshtml @@ -1,5 +1,8 @@ @using EnotaryoPH.Web @using Microsoft.AspNetCore.Http.Extensions +@using EnotaryoPH.Web.Pages.Shared.Components.NotaryoSteps +@using EnotaryoPH.Web.Pages.Shared.Components.UploadOrChooseIdentificationDocument +@using EnotaryoPH.Web.Pages.Shared.Components.TakeSelfieImage @namespace EnotaryoPH.Web.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, EnotaryoPH \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Program.cs b/EnotaryoPH/EnotaryoPH.Web/Program.cs index 04739ff..f5e29f2 100644 --- a/EnotaryoPH/EnotaryoPH.Web/Program.cs +++ b/EnotaryoPH/EnotaryoPH.Web/Program.cs @@ -24,6 +24,7 @@ namespace EnotaryoPH.Web { options.Conventions.AuthorizeFolder("/Principal", "PrincipalPolicy"); options.Conventions.AuthorizeFolder("/Participant/Registration/Steps", "ParticipantPolicy"); + options.Conventions.AuthorizeFolder("/Participant/VideoCall"); }); #if DEBUG razorBuilder.AddRazorRuntimeCompilation();