From 3fd2f90f65046f51c949b79cefe2a10ca528f584 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 6 Jun 2024 10:02:56 +0200 Subject: [PATCH] =?UTF-8?q?Die=20Ansicht=20EnvelopeRejected=20(EnvelopeRej?= =?UTF-8?q?ected.cshtml)=20wurde=20so=20entwickelt,=20dass=20sie=20nach=20?= =?UTF-8?q?Ablehnung=20eines=20Umschlags=20angezeigt=20wird.=20Logik=20hin?= =?UTF-8?q?zugef=C3=BCgt,=20um=20eine=20Umleitung=20zu=20aktivieren,=20nac?= =?UTF-8?q?hdem=20ein=20Umschlag=20abgelehnt=20wurde.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contracts/IEnvelopeHistoryService.cs | 2 + .../DTOs/EnvelopeDto.cs | 3 +- .../Resources/Resource.de-DE.resx | 12 ++++ .../Resources/Resource.en-US.resx | 12 ++++ .../Controllers/EnvelopeController.cs | 3 +- .../Controllers/HomeController.cs | 44 ++++++++++++ .../Views/Home/EnvelopeRejected.cshtml | 72 +++++++++++++++++++ .../Views/Home/EnvelopeSigned.cshtml | 2 +- .../Views/Shared/_Layout.cshtml | 6 +- EnvelopeGenerator.Web/WebKey.cs | 4 ++ EnvelopeGenerator.Web/wwwroot/css/site.css | 5 ++ .../wwwroot/js/api-service.js | 14 +++- .../wwwroot/js/event-binder.js | 4 +- 13 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs index 9f4d5ce7..1d7ffa73 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs @@ -15,6 +15,8 @@ namespace EnvelopeGenerator.Application.Contracts Task IsSigned(int envelopeId, string userReference); + Task IsRejected(int envelopeId, string? userReference = null); + Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null); Task> ReadRejectedAsync(int envelopeId, string? userReference = null); diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs index 3b1cc6db..ced6f7f3 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs @@ -34,6 +34,5 @@ namespace EnvelopeGenerator.Application.DTOs bool IsAlreadySent, string? StatusTranslated, string? ContractTypeTranslated, - IEnumerable? Documents, - IEnumerable? History); + IEnumerable? Documents); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx index f1816694..4e6ce44e 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx @@ -135,6 +135,12 @@ Dokument geschützt + + Dokument abgelehnt + + + Dokument unterschrieben + Englisch @@ -144,6 +150,9 @@ Erstellt am {0} von {1}. Sie können den Absender über <a href="mailto:{2}?subject={3}&body=Sehr%20geehrter%20{4}%20{5},%0A%0A%0A">{6}</a> kontaktieren. + + Ihr Einspruch wurde weitergeleitet! + Abschließen @@ -174,6 +183,9 @@ Ablehnung + + Ihr Einspruch wurde an {0} weitergeleitet. Sie können über <a href="mailto:{1}?subject={2}&body=Dear%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen. + Warum lehnen Sie den Vertrag ab? diff --git a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx index 5fe14156..4f2862c8 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx @@ -135,6 +135,12 @@ Document protected + + Document rejected + + + Document signed + English @@ -144,6 +150,9 @@ Created on {0} by {1}. You can contact the sender via <a href="mailto:{2}?subject={3}&body=Dear%20{4}%20{5},%0A%0A%0A">{6}</a>. + + Your objection has been forwarded! + Finalize @@ -174,6 +183,9 @@ Rejection + + Your objection has been forwarded to {0}. You can contact via <a href="mailto:{1}?subject={2}&body=Dear%20{0},%0A%0A%0A">{1}</a>. + Why do you reject the contract? diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index 444440e6..1353c8b1 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -1,7 +1,6 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application; using EnvelopeGenerator.Application.Contracts; -using DigitalData.Core.DTO; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Authorization; @@ -134,7 +133,7 @@ namespace EnvelopeGenerator.Web.Controllers if (envRcvRes.IsFailed) { _logger.LogNotice(envRcvRes.Notices); - return Unauthorized(); + return Unauthorized("you are not authirized"); } return await _histService.RecordAsync(envRcvRes.Data.EnvelopeId, userReference: mail, EnvelopeStatus.DocumentRejected, comment: reason).ThenAsync( diff --git a/EnvelopeGenerator.Web/Controllers/HomeController.cs b/EnvelopeGenerator.Web/Controllers/HomeController.cs index 898bd470..f9968d9b 100644 --- a/EnvelopeGenerator.Web/Controllers/HomeController.cs +++ b/EnvelopeGenerator.Web/Controllers/HomeController.cs @@ -16,6 +16,9 @@ using Microsoft.AspNetCore.Localization; using System.Text.Encodings.Web; using EnvelopeGenerator.Web.Models; using EnvelopeGenerator.Application.Resources; +using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; +using System.Text.RegularExpressions; +using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Web.Controllers { @@ -209,6 +212,7 @@ namespace EnvelopeGenerator.Web.Controllers } } + [Authorize] [HttpGet("EnvelopeKey/{envelopeReceiverId}/Success")] public async Task EnvelopeSigned(string envelopeReceiverId) { @@ -242,6 +246,46 @@ namespace EnvelopeGenerator.Web.Controllers } } + [Authorize] + [HttpGet("EnvelopeKey/{envelopeReceiverId}/Rejected")] + public async Task EnvelopeRejected(string envelopeReceiverId) + { + try + { + envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId); + + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId).ThenAsync( + SuccessAsync: async (er) => + { + ViewData["UserCulture"] = _cultures[UserLanguage]; + return await _historyService.IsRejected(envelopeId: er.EnvelopeId) + ? View(er) + : Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked"); + + }, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return this.ViewEnvelopeNotFound(); + }); + } + catch (Exception ex) + { + _logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex); + return this.ViewInnerServiceError(); + } + } + + [HttpGet("EnvelopeRejected")] + public async Task Dev() + { + var eKey = "ZGI5M2VjOTQtY2JkNS00YWQyLTg2NDEtZTU0ZjUyMjMwOTNlOjpFREZFNDk3QjZGRENEMjUyMkZCRTdFRDg0OTQ3RUQyNDE1RTAyOUM4QkQ1RTdDOUU3RTk1MkY1MzhBNkRGRTM1"; + var er = await _envRcvService.ReadByEnvelopeReceiverIdAsync(eKey); + ViewData["UserCulture"] = _cultures[UserLanguage]; + return View("EnvelopeRejected", er.Data); + } + [Authorize] [HttpGet("IsAuthenticated")] public IActionResult IsAuthenticated() diff --git a/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml b/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml new file mode 100644 index 00000000..243398a2 --- /dev/null +++ b/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml @@ -0,0 +1,72 @@ +@{ + ViewData["Title"] = _localizer[WebKey.DocRejected]; +} +@{ + var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; +} +@using DigitalData.Core.DTO; +@using EnvelopeGenerator.Application.DTOs; +@using Newtonsoft.Json +@using Newtonsoft.Json.Serialization +@model EnvelopeReceiverDto; + +@{ + var userCulture = ViewData["UserCulture"] as Culture; + var envelope = Model.Envelope; + var document = Model.Envelope?.Documents?.FirstOrDefault(); + var sender = Model.Envelope?.User; +} +
+
+
+ + + + + + + + + +
+

@_localizer[WebKey.EnvelopeObjectionTitle].TrySanitize(_sanitizer)

+
+
+
+

+ + @Html.Raw(string.Format(_localizer[WebKey.RejectionInfo2], + $"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer), + sender?.Email.TryEncode(_encoder), + envelope?.Title.TryEncode(_encoder))) + +

+
+
+
+ \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml b/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml index 82ac9bc1..5d0d7379 100644 --- a/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/EnvelopeSigned.cshtml @@ -1,5 +1,5 @@ @{ - ViewData["Title"] = "Dokument unterschrieben"; + ViewData["Title"] = _localizer[WebKey.DocSigned]; }
diff --git a/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml b/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml index 7064942a..8f921b12 100644 --- a/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml +++ b/EnvelopeGenerator.Web/Views/Shared/_Layout.cshtml @@ -8,7 +8,7 @@ - + @ViewData["Title"] @@ -17,6 +17,10 @@ + @if (ViewData["EnvelopeKey"] is string envelopeKey) + { + + } diff --git a/EnvelopeGenerator.Web/WebKey.cs b/EnvelopeGenerator.Web/WebKey.cs index 270efcc7..4b179d2f 100644 --- a/EnvelopeGenerator.Web/WebKey.cs +++ b/EnvelopeGenerator.Web/WebKey.cs @@ -18,6 +18,8 @@ public static readonly string LockedFooterBody = nameof(LockedFooterBody); public static readonly string WrongAccessCode = nameof(WrongAccessCode); public static readonly string SignDoc = nameof(SignDoc); + public static readonly string DocRejected = nameof(DocRejected); + public static readonly string DocSigned = nameof(DocSigned); public static readonly string DocProtected = nameof(DocProtected); public static readonly string Complete = nameof(Complete); public static readonly string EnvelopeInfo1 = nameof(EnvelopeInfo1); @@ -26,5 +28,7 @@ public static readonly string Reject = nameof(Reject); public static readonly string and = nameof(and); public static readonly string Hello = nameof(Hello); + public static readonly string EnvelopeObjectionTitle = nameof(EnvelopeObjectionTitle); + public static readonly string RejectionInfo2 = nameof(RejectionInfo2); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/css/site.css b/EnvelopeGenerator.Web/wwwroot/css/site.css index 1803152c..edeaa86c 100644 --- a/EnvelopeGenerator.Web/wwwroot/css/site.css +++ b/EnvelopeGenerator.Web/wwwroot/css/site.css @@ -103,6 +103,11 @@ body { color: #fff; } + .page header .icon.rejected { + background-color: #e4d8d5; + color: #fff; + } + .page .form { max-width: 30rem; margin: 2rem auto; diff --git a/EnvelopeGenerator.Web/wwwroot/js/api-service.js b/EnvelopeGenerator.Web/wwwroot/js/api-service.js index c35804a5..70a05a70 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/api-service.js +++ b/EnvelopeGenerator.Web/wwwroot/js/api-service.js @@ -9,11 +9,19 @@ class API { return `/api/envelope/reject`; } + static get REJECT_REDIR_URL(){ + return `/envelopekey/${API.ENV_KEY}/rejected`; + } + static __XSRF_TOKEN static get XSRF_TOKEN() { API.__XSRF_TOKEN ??= document.getElementsByName('__RequestVerificationToken')[0].value; return API.__XSRF_TOKEN; } + + static get ENV_KEY(){ + return ENV_KEY ?? document.querySelector('meta[name="env-key"]').getAttribute('content'); + } } const submitForm = async form => await fetch(form.action, { @@ -38,4 +46,8 @@ const createRequest = async (method, url, body, contentType) => { const createPost = (url, body, contentType) => createRequest('POST', url, body, contentType); -const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JSON); \ No newline at end of file +const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JSON); + +const redirect = (url) => window.location.href = url; + +const redirRejected = () => redirect(API.REJECT_REDIR_URL); \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/event-binder.js b/EnvelopeGenerator.Web/wwwroot/js/event-binder.js index 7c44420b..72ef8694 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/event-binder.js +++ b/EnvelopeGenerator.Web/wwwroot/js/event-binder.js @@ -30,8 +30,8 @@ $('.btn_reject').click(_ => const res = result.value; console.log(res) if (res.ok) { - alert('rejected') + redirRejected() } else - alert('fail') + Swal.showValidationMessage(`Request failed: ${res.message}`); })); \ No newline at end of file