Compare commits

...

3 Commits

Author SHA1 Message Date
Jonathan Jenne
ff5536d3ea Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2023-10-11 12:35:36 +02:00
Jonathan Jenne
e69dccb2e1 improve finish handling 2023-10-11 12:35:30 +02:00
Jonathan Jenne
8d5e24c6a7 Add documentstatus 2023-10-11 11:10:38 +02:00
10 changed files with 195 additions and 42 deletions

View File

@@ -14,6 +14,11 @@
Created = 0
End Enum
Public Enum DocumentStatus
Created = 0
Signed = 1
End Enum
Public Enum EnvelopeHistoryActionType
Created = 0
Saved = 1

View File

@@ -0,0 +1,10 @@
Public Class DocumentStatus
Public Property Id As Integer
Public Property EnvelopeId As Integer
Public Property ReceiverId As Integer
Public Property Value As String
Public Property Status As Constants.DocumentStatus = Constants.DocumentStatus.Created
Public Property StatusChangedWhen As Date
End Class

View File

@@ -95,6 +95,7 @@
<Compile Include="Constants.vb" />
<Compile Include="Entities\DbConfig.vb" />
<Compile Include="Entities\ElementMetadata.vb" />
<Compile Include="Entities\DocumentStatus.vb" />
<Compile Include="Entities\ElementStatus.vb" />
<Compile Include="Entities\EmailData.vb" />
<Compile Include="Entities\EmailTemplate.vb" />
@@ -112,6 +113,7 @@
<Compile Include="Models\ConfigModel.vb" />
<Compile Include="Models\DocumentModel.vb" />
<Compile Include="Models\ElementModel.vb" />
<Compile Include="Models\DocumentStatusModel.vb" />
<Compile Include="Models\ElementStatusModel.vb" />
<Compile Include="Models\EmailModel.vb" />
<Compile Include="Models\EnvelopeModel.vb" />

View File

@@ -0,0 +1,89 @@
Imports System.Data.SqlClient
Public Class DocumentStatusModel
Inherits BaseModel
Public Sub New(pState As State)
MyBase.New(pState)
End Sub
Public Function InsertOrUpdate(pDocumentStatus As DocumentStatus) As Boolean
If pDocumentStatus.Id = 0 Then
Return Insert(pDocumentStatus)
Else
Return Update(pDocumentStatus)
End If
End Function
Public Function Insert(pDocumentStatus As DocumentStatus) As Boolean
Try
Dim oSql = "INSERT INTO [dbo].[TBSIG_DOCUMENT_STATUS]
([ENVELOPE_ID]
,[RECEIVER_ID]
,[STATUS]
,[STATUS_CHANGED_WHEN]
,[VALUE])
VALUES
(@ENVELOPE_ID
,@RECEIVER_ID
,@STATUS
,@STATUS_CHANGED_WHEN
,@VALUE)"
Dim oCommand As New SqlCommand(oSql)
oCommand.Parameters.Add("ENVELOPE_ID", SqlDbType.Int).Value = pDocumentStatus.EnvelopeId
oCommand.Parameters.Add("RECEIVER_ID", SqlDbType.Int).Value = pDocumentStatus.ReceiverId
oCommand.Parameters.Add("STATUS", SqlDbType.NVarChar).Value = pDocumentStatus.Status.ToString()
oCommand.Parameters.Add("STATUS_CHANGED_WHEN", SqlDbType.DateTime).Value = Now()
oCommand.Parameters.Add("VALUE", SqlDbType.NVarChar).Value = pDocumentStatus.Value
If Database.ExecuteNonQuery(oCommand) Then
pDocumentStatus.Id = GetElementId(pDocumentStatus)
Return True
Else
Return False
End If
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Public Function Update(pDocumentStatus As DocumentStatus) As Boolean
Try
Dim oSql = "UPDATE [dbo].[TBSIG_DOCUMENT_STATUS]
SET [STATUS] = @STATUS
,[STATUS_CHANGED_WHEN] = @STATUS_CHANGED_WHEN
,[CHANGED_WHEN] = @CHANGED_WHEN
,[VALUE] = @VALUE
WHERE GUID = @GUID"
Dim oCommand As New SqlCommand(oSql)
oCommand.Parameters.Add("GUID", SqlDbType.Int).Value = pDocumentStatus.Id
oCommand.Parameters.Add("STATUS", SqlDbType.NVarChar).Value = pDocumentStatus.Status.ToString()
oCommand.Parameters.Add("STATUS_CHANGED_WHEN", SqlDbType.DateTime).Value = Now()
oCommand.Parameters.Add("CHANGED_WHEN", SqlDbType.DateTime).Value = Now()
oCommand.Parameters.Add("VALUE", SqlDbType.NVarChar).Value = pDocumentStatus.Value
If Database.ExecuteNonQuery(oCommand) Then
Return True
Else
Return False
End If
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Private Function GetElementId(pDocument As DocumentStatus) As Integer
Try
Return Database.GetScalarValue($"SELECT MAX(GUID) FROM TBSIG_DOCUMENT_STATUS
WHERE ENVELOPE_ID = {pDocument.EnvelopeId} AND RECEIVER_ID = {pDocument.ReceiverId}")
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
End Class

View File

@@ -1,4 +1,5 @@
using DigitalData.Modules.Logging;
using DigitalData.Modules.Database;
using DigitalData.Modules.Logging;
using EnvelopeGenerator.Common;
using EnvelopeGenerator.Common.My.Resources;
using EnvelopeGenerator.Web.Services;
@@ -9,7 +10,7 @@ using System.Text;
namespace EnvelopeGenerator.Web.Handler
{
public class FileHandler
public class FileHandler
{
/// <summary>
/// URL: GET /api/envelope/{envelopeKey}
@@ -17,7 +18,7 @@ namespace EnvelopeGenerator.Web.Handler
/// Returns a
/// </summary>
/// <returns></returns>
public static IResult HandleGetEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
public IResult HandleGetEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
@@ -48,7 +49,7 @@ namespace EnvelopeGenerator.Web.Handler
/// Returns a document for the supplied EnvelopeKey and Document Id / Index
/// </summary>
/// <returns>file buffer of the requested document</returns>
public async static Task<IResult> HandleGetDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
public async Task<IResult> HandleGetDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
@@ -80,7 +81,7 @@ namespace EnvelopeGenerator.Web.Handler
}
}
public async static Task<IResult> HandlePostDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
public async Task<IResult> HandlePostDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
@@ -110,10 +111,7 @@ namespace EnvelopeGenerator.Web.Handler
}
}
public async static Task<IResult> HandlePostEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
public async Task<IResult> HandlePostEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
@@ -129,14 +127,23 @@ namespace EnvelopeGenerator.Web.Handler
int documentId = EnsureValidDocumentIndex(logger, ctx.Request);
var document = GetDocument(r.Envelope, documentId);
var annotationData = EnsureValidAnnotationData(logger, ctx.Request);
string? annotationData = await EnsureValidAnnotationData(logger, ctx.Request);
if (annotationData == null)
{
throw new ArgumentNullException("AnnotationData");
}
// TODO: Save annotations to database
State state = GetState(logging.LogConfig, database.MSSQL);
DocumentStatusModel model = new(state);
model.InsertOrUpdate(new DocumentStatus()
{
EnvelopeId = r.Envelope.Id,
ReceiverId = r.ReceiverId,
Value = annotationData,
Status = Common.Constants.DocumentStatus.Signed
});
return Results.Ok();
}
@@ -145,12 +152,19 @@ namespace EnvelopeGenerator.Web.Handler
// Better error handling & reporting
logger.Error(e);
return Results.Problem();
}
}
}
private static int EnsureValidDocumentIndex(Logger logger, HttpRequest request)
private State GetState(LogConfig LogConfig, MSSQLServer Database)
{
return new State
{
LogConfig = LogConfig,
Database = Database,
};
}
private int EnsureValidDocumentIndex(Logger logger, HttpRequest request)
{
if (request.Query.TryGetValue("index", out StringValues documentIndexString))
{
@@ -169,7 +183,7 @@ namespace EnvelopeGenerator.Web.Handler
}
}
private static string EnsureValidEnvelopeKey(Logger logger, HttpRequest request)
private string EnsureValidEnvelopeKey(Logger logger, HttpRequest request)
{
logger.Debug("Parsing EnvelopeKey..");
var envelopeKey = request.RouteValues["envelopeKey"] as string;
@@ -190,7 +204,7 @@ namespace EnvelopeGenerator.Web.Handler
return envelopeKey;
}
private static async Task<string> EnsureValidAnnotationData(Logger logger, HttpRequest request)
private async Task<string?> EnsureValidAnnotationData(Logger logger, HttpRequest request)
{
logger.Debug("Parsing AnnotationData..");
@@ -210,7 +224,7 @@ namespace EnvelopeGenerator.Web.Handler
}
private static EnvelopeDocument GetDocument(Common.Envelope envelope, int documentId)
private EnvelopeDocument GetDocument(Common.Envelope envelope, int documentId)
{
var document = envelope.Documents.
Where(d => d.Id == documentId).

View File

@@ -0,0 +1,5 @@
@page "/EnvelopeKey/Finish"
<h3>Dokumente signiert</h3>
<p>Sie haben den Umschlag erfolgreich signiert!</p>

View File

@@ -1,5 +1,6 @@
using EnvelopeGenerator.Web.Handler;
using EnvelopeGenerator.Web.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@@ -35,10 +36,12 @@ app.UseStaticFiles();
app.UseRouting();
// Add file download endpoint
app.MapGet("/api/document/{envelopeKey}", FileHandler.HandleGetDocument);
app.MapPost("/api/document/{envelopeKey}", FileHandler.HandlePostDocument);
app.MapGet("/api/envelope/{envelopeKey}", FileHandler.HandleGetEnvelope);
app.MapPost("/api/envelope/{envelopeKey}", FileHandler.HandlePostEnvelope);
FileHandler handler = new();
app.MapGet("/api/document/{envelopeKey}", handler.HandleGetDocument);
app.MapPost("/api/document/{envelopeKey}", handler.HandlePostDocument);
app.MapGet("/api/envelope/{envelopeKey}", handler.HandleGetEnvelope);
app.MapPost("/api/envelope/{envelopeKey}", handler.HandlePostEnvelope);
// Blazor plumbing
app.MapBlazorHub();

View File

@@ -50,7 +50,7 @@ export class App {
// Load PSPDFKit
console.debug("Loading PSPDFKit..")
App.Instance = await App.UI.loadPSPDFKit(arrayBuffer, container)
App.UI.configurePSPDFKit(this.Instance, App.handleClick)
App.UI.configurePSPDFKit(this.Instance, App.handleClick)
// Load annotations into PSPDFKit
console.debug("Loading annotations..")
@@ -71,14 +71,18 @@ export class App {
}
public static async handleFinish(event: any) {
await App.Instance.save();
// Export annotation data and save to database
const json = await App.Instance.exportInstantJSON()
console.log(json);
console.log(JSON.stringify(json));
const result = await App.Network.postEnvelope(App.envelopeKey, App.currentDocument.id, JSON.stringify(json))
const result: boolean = await App.Network.postEnvelope(App.envelopeKey, App.currentDocument.id, JSON.stringify(json))
if (result == true) {
alert("Dokument erfolgreich signiert!")
}
// Flatten the annotations and save the document to disk
/*
@@ -91,7 +95,7 @@ export class App {
public static async handleReset(event: any) {
if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) {
const result = App.Annotation.deleteAnnotations(App.Instance)
}
}
}
private static async downloadDocument() {
@@ -202,7 +206,7 @@ class Network {
.then(res => res.json());
}
public postEnvelope(envelopeKey: string, documentId: number, jsonString: string): Promise<any> {
public postEnvelope(envelopeKey: string, documentId: number, jsonString: string): Promise<boolean> {
const options: RequestInit = {
credentials: "include",
method: "POST",
@@ -210,11 +214,23 @@ class Network {
}
return fetch(`/api/envelope/${envelopeKey}?index=${documentId}`, options)
.then(res => {
console.log(res)
res.json()
.then(this.handleResponse)
.then((res: Response) => {
if (!res.ok) {
return false;
};
return true;
});
}
private handleResponse(res: Response) {
if (!res.ok) {
console.log(`Request failed with status ${res.status}`)
return res
} else {
return res
}
}
}
@@ -230,7 +246,7 @@ class UI {
"zoom-mode",
"spacer",
"search"
]
]
// Load the PSPDFKit UI by setting a target element as the container to render in
// and a arraybuffer which represents the document that should be displayed.

View File

@@ -133,16 +133,12 @@ var App = /** @class */ (function () {
json = _a.sent();
console.log(json);
console.log(JSON.stringify(json));
return [4 /*yield*/, App.Network.postEnvelope(App.envelopeKey, App.currentDocument.id, JSON.stringify(json))
// Flatten the annotations and save the document to disk
/*
const buffer = await App.Instance.exportPDF({ flatten: true });
const result = await App.Network.postDocument(App.envelopeKey, App.currentDocument.id, buffer);
console.log(result)
*/
];
return [4 /*yield*/, App.Network.postEnvelope(App.envelopeKey, App.currentDocument.id, JSON.stringify(json))];
case 3:
result = _a.sent();
if (result == true) {
alert("Dokument erfolgreich signiert!");
}
return [2 /*return*/];
}
});
@@ -286,11 +282,24 @@ var Network = /** @class */ (function () {
body: jsonString
};
return fetch("/api/envelope/".concat(envelopeKey, "?index=").concat(documentId), options)
.then(this.handleResponse)
.then(function (res) {
console.log(res);
res.json();
if (!res.ok) {
return false;
}
;
return true;
});
};
Network.prototype.handleResponse = function (res) {
if (!res.ok) {
console.log("Request failed with status ".concat(res.status));
return res;
}
else {
return res;
}
};
return Network;
}());
var UI = /** @class */ (function () {

File diff suppressed because one or more lines are too long