Die Ansicht EnvelopeRejected (EnvelopeRejected.cshtml) wurde so entwickelt, dass sie nach Ablehnung eines Umschlags angezeigt wird. Logik hinzugefügt, um eine Umleitung zu aktivieren, nachdem ein Umschlag abgelehnt wurde.

This commit is contained in:
Developer 02 2024-06-06 10:02:56 +02:00
parent d077a66796
commit 3fd2f90f65
13 changed files with 174 additions and 9 deletions

View File

@ -15,6 +15,8 @@ namespace EnvelopeGenerator.Application.Contracts
Task<bool> IsSigned(int envelopeId, string userReference);
Task<bool> IsRejected(int envelopeId, string? userReference = null);
Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null);
Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null);

View File

@ -34,6 +34,5 @@ namespace EnvelopeGenerator.Application.DTOs
bool IsAlreadySent,
string? StatusTranslated,
string? ContractTypeTranslated,
IEnumerable<EnvelopeDocumentDto>? Documents,
IEnumerable<EnvelopeHistoryDto>? History);
IEnumerable<EnvelopeDocumentDto>? Documents);
}

View File

@ -135,6 +135,12 @@
<data name="DocProtected" xml:space="preserve">
<value>Dokument geschützt</value>
</data>
<data name="DocRejected" xml:space="preserve">
<value>Dokument abgelehnt</value>
</data>
<data name="DocSigned" xml:space="preserve">
<value>Dokument unterschrieben</value>
</data>
<data name="en-US" xml:space="preserve">
<value>Englisch</value>
</data>
@ -144,6 +150,9 @@
<data name="EnvelopeInfo2" xml:space="preserve">
<value>Erstellt am {0} von {1}. Sie können den Absender über &lt;a href="mailto:{2}?subject={3}&amp;body=Sehr%20geehrter%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt; kontaktieren.</value>
</data>
<data name="EnvelopeObjectionTitle" xml:space="preserve">
<value>Ihr Einspruch wurde weitergeleitet!</value>
</data>
<data name="Finalize" xml:space="preserve">
<value>Abschließen</value>
</data>
@ -174,6 +183,9 @@
<data name="Rejection" xml:space="preserve">
<value>Ablehnung</value>
</data>
<data name="RejectionInfo2" xml:space="preserve">
<value>Ihr Einspruch wurde an {0} weitergeleitet. Sie können über &lt;a href="mailto:{1}?subject={2}&amp;body=Dear%20{0},%0A%0A%0A"&gt;{1}&lt;/a&gt; Kontakt aufnehmen.</value>
</data>
<data name="RejectionReasonQ" xml:space="preserve">
<value>Warum lehnen Sie den Vertrag ab?</value>
</data>

View File

@ -135,6 +135,12 @@
<data name="DocProtected" xml:space="preserve">
<value>Document protected</value>
</data>
<data name="DocRejected" xml:space="preserve">
<value>Document rejected</value>
</data>
<data name="DocSigned" xml:space="preserve">
<value>Document signed</value>
</data>
<data name="en-US" xml:space="preserve">
<value>English</value>
</data>
@ -144,6 +150,9 @@
<data name="EnvelopeInfo2" xml:space="preserve">
<value>Created on {0} by {1}. You can contact the sender via &lt;a href="mailto:{2}?subject={3}&amp;body=Dear%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt;.</value>
</data>
<data name="EnvelopeObjectionTitle" xml:space="preserve">
<value>Your objection has been forwarded!</value>
</data>
<data name="Finalize" xml:space="preserve">
<value>Finalize</value>
</data>
@ -174,6 +183,9 @@
<data name="Rejection" xml:space="preserve">
<value>Rejection</value>
</data>
<data name="RejectionInfo2" xml:space="preserve">
<value>Your objection has been forwarded to {0}. You can contact via &lt;a href="mailto:{1}?subject={2}&amp;body=Dear%20{0},%0A%0A%0A"&gt;{1}&lt;/a&gt;.</value>
</data>
<data name="RejectionReasonQ" xml:space="preserve">
<value>Why do you reject the contract?</value>
</data>

View File

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

View File

@ -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<IActionResult> EnvelopeSigned(string envelopeReceiverId)
{
@ -242,6 +246,46 @@ namespace EnvelopeGenerator.Web.Controllers
}
}
[Authorize]
[HttpGet("EnvelopeKey/{envelopeReceiverId}/Rejected")]
public async Task<IActionResult> 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<IActionResult> 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()

View File

@ -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;
<partial name="_CookieConsentPartial" />
@{
var userCulture = ViewData["UserCulture"] as Culture;
var envelope = Model.Envelope;
var document = Model.Envelope?.Documents?.FirstOrDefault();
var sender = Model.Envelope?.User;
}
<div class="page container p-5">
<header class="text-center">
<div class="icon rejected">
<svg height="100" width="100" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 500 520" xml:space="preserve">
<polygon style="fill:#F4B2B0;" points="27.959,164.583 27.959,160.534 172.263,14.827 172.263,164.583 "/>
<g>
<path style="fill:#B3404A;" d="M459.181,264.152c-5.593-5.981-14.975-6.295-20.956-0.703c-5.981,5.593-6.295,14.976-0.703,20.956
c20.435,21.854,31.69,50.379,31.69,80.317c0,64.859-52.766,117.623-117.623,117.623c-64.859,0-117.623-52.766-117.623-117.623
s52.765-117.623,117.623-117.623c8.187,0,14.827-6.638,14.827-14.827c0-8.189-6.639-14.827-14.827-14.827
c-81.208,0-147.276,66.068-147.276,147.276c0,14.953,2.248,29.389,6.41,42.997H42.786v-167.54c0-8.189-6.638-14.827-14.827-14.827
s-14.827,6.638-14.827,14.827v182.366c0,8.189,6.638,14.827,14.827,14.827h195.559c25.359,44.53,73.265,74.626,128.072,74.626
c81.208,0,147.276-66.068,147.276-147.276C498.866,327.236,484.772,291.519,459.181,264.152z"/>
<path style="fill:#B3404A;" d="M394.597,0H172.263c-0.178,0-0.353,0.021-0.529,0.027c-0.172,0.006-0.344,0.013-0.516,0.025
c-0.636,0.044-1.268,0.117-1.889,0.242c-0.021,0.004-0.04,0.012-0.061,0.015c-0.608,0.126-1.202,0.299-1.787,0.5
c-0.159,0.053-0.314,0.111-0.471,0.171c-0.577,0.219-1.143,0.463-1.689,0.752c-0.024,0.013-0.049,0.022-0.073,0.034
c-0.565,0.304-1.103,0.657-1.626,1.033c-0.135,0.098-0.268,0.197-0.4,0.299c-0.519,0.4-1.023,0.824-1.49,1.296L17.428,150.099
c-0.348,0.351-0.676,0.719-0.984,1.1c-0.212,0.261-0.399,0.534-0.59,0.805c-0.086,0.123-0.182,0.239-0.264,0.363
c-0.219,0.331-0.415,0.673-0.603,1.017c-0.042,0.076-0.09,0.147-0.13,0.222c-0.187,0.353-0.35,0.713-0.506,1.078
c-0.033,0.077-0.073,0.151-0.105,0.23c-0.141,0.345-0.259,0.697-0.374,1.048c-0.034,0.107-0.077,0.211-0.11,0.317
c-0.096,0.325-0.172,0.654-0.246,0.984c-0.033,0.142-0.073,0.28-0.101,0.424c-0.059,0.304-0.096,0.609-0.136,0.915
c-0.022,0.173-0.055,0.344-0.073,0.519c-0.028,0.302-0.034,0.605-0.044,0.907c-0.006,0.168-0.025,0.334-0.025,0.501v4.051
c0,8.189,6.638,14.827,14.827,14.827h144.304c8.189,0,14.827-6.638,14.827-14.827V29.653h192.681v143.315
c0,8.189,6.639,14.827,14.827,14.827s14.827-6.638,14.827-14.827V14.827C409.423,6.638,402.786,0,394.597,0z M59.498,149.757
l91.096-91.982l6.842-6.908v98.89H59.498z"/>
</g>
<polygon style="fill:#F4B2B0;" points="425.039,404.045 384.233,363.241 425.039,322.435 392.394,289.792 351.59,330.597
310.786,289.792 278.14,322.435 318.946,363.241 278.14,404.045 310.786,436.689 351.59,395.885 392.394,436.689 "/>
<path style="fill:#B3404A;" d="M392.395,451.515c-3.932,0-7.702-1.563-10.484-4.343l-30.32-30.322l-30.32,30.322
c-5.791,5.788-15.176,5.79-20.969,0l-32.645-32.644c-2.78-2.78-4.343-6.552-4.343-10.484s1.563-7.704,4.343-10.484l30.32-30.32
l-30.32-30.32c-2.78-2.78-4.343-6.552-4.343-10.484c0-3.932,1.563-7.704,4.343-10.484l32.645-32.644
c5.793-5.79,15.178-5.788,20.969,0l30.32,30.322l30.32-30.322c2.781-2.78,6.552-4.343,10.484-4.343s7.704,1.563,10.484,4.343
l32.644,32.644c5.79,5.79,5.79,15.178,0,20.968l-30.32,30.32l30.32,30.32c5.79,5.79,5.79,15.178,0,20.968l-32.644,32.644
C400.099,449.954,396.327,451.515,392.395,451.515z M299.11,404.045l11.676,11.676l30.32-30.322c5.791-5.79,15.176-5.79,20.969,0
l30.32,30.322l11.676-11.676l-30.322-30.32c-5.79-5.79-5.79-15.178,0-20.969l30.322-30.32l-11.676-11.676l-30.32,30.322
c-5.791,5.79-15.176,5.79-20.969,0l-30.32-30.322l-11.676,11.676l30.32,30.32c5.79,5.79,5.79,15.178,0,20.969L299.11,404.045z"/>
</svg>
</div>
<h1>@_localizer[WebKey.EnvelopeObjectionTitle].TrySanitize(_sanitizer)</h1>
</header>
<section class="text-center">
<div class="card-body p-0 m-0 ms-4">
<p class="card-text p-0 m-0">
<small class="text-body-secondary">
@Html.Raw(string.Format(_localizer[WebKey.RejectionInfo2],
$"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer),
sender?.Email.TryEncode(_encoder),
envelope?.Title.TryEncode(_encoder)))
</small>
</p>
</div>
</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,5 +1,5 @@
@{
ViewData["Title"] = "Dokument unterschrieben";
ViewData["Title"] = _localizer[WebKey.DocSigned];
}
<div class="page container p-5">
<header class="text-center">

View File

@ -8,7 +8,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"]</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/lib/sweetalert2/sweetalert2.min.css" />
@ -17,6 +17,10 @@
<link rel="stylesheet" href="~/lib/flag-icons-main/css/flag-icons.min.css" asp-append-version="true" />
</head>
<body>
@if (ViewData["EnvelopeKey"] is string envelopeKey)
{
<script>const ENV_KEY = "@envelopeKey.TrySanitize(_sanitizer)"</script>
}
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/popper/dist/umd/popper.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>

View File

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

View File

@ -103,6 +103,11 @@ body {
color: #fff;
}
.page header .icon.rejected {
background-color: #e4d8d5;
color: #fff;
}
.page .form {
max-width: 30rem;
margin: 2rem auto;

View File

@ -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);
const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JSON);
const redirect = (url) => window.location.href = url;
const redirRejected = () => redirect(API.REJECT_REDIR_URL);

View File

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