Compare commits
8 Commits
bugfix/wro
...
b8c00884a9
| Author | SHA1 | Date | |
|---|---|---|---|
| b8c00884a9 | |||
| 51d49d68ba | |||
| 4d5ee2b461 | |||
| 8a79ee4126 | |||
| cde9896c01 | |||
| c7d26a87b0 | |||
| 17ceb1f72a | |||
| b2c396c3b2 |
@@ -54,7 +54,7 @@ public class MappingProfile : Profile
|
|||||||
CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
||||||
CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>();
|
CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>();
|
||||||
CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>();
|
CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>();
|
||||||
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverBasicDto>();
|
||||||
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||||
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ private readonly IAuthenticator _authenticator;
|
|||||||
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, IAuthenticator authenticator) : base(repository, mapper)
|
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, IAuthenticator authenticator) : base(repository, mapper)
|
||||||
{
|
{
|
||||||
_tempService = tempService;
|
_tempService = tempService;
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
_dConfig = dispatcherConfigOptions.Value;
|
_dConfig = dispatcherConfigOptions.Value;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_placeholders = mailConfig.Value.Placeholders;
|
_placeholders = new Dictionary<string, string>(mailConfig.Value.Placeholders);
|
||||||
_authenticator = authenticator;
|
_authenticator = authenticator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
||||||
|
|||||||
@@ -138,12 +138,15 @@ namespace EnvelopeGenerator.Domain.Entities
|
|||||||
public byte[] DOC_RESULT { get; set; }
|
public byte[] DOC_RESULT { get; set; }
|
||||||
|
|
||||||
// TODO: * Check the Form App and remove the default value
|
// TODO: * Check the Form App and remove the default value
|
||||||
|
[NotMapped]
|
||||||
public List<EnvelopeDocument> Documents { get; set; } = new List<EnvelopeDocument>();
|
public List<EnvelopeDocument> Documents { get; set; } = new List<EnvelopeDocument>();
|
||||||
|
|
||||||
// TODO: * Check the Form App and remove the default value
|
// TODO: * Check the Form App and remove the default value
|
||||||
|
[NotMapped]
|
||||||
public List<EnvelopeHistory> History { get; set; } = new List<EnvelopeHistory>();
|
public List<EnvelopeHistory> History { get; set; } = new List<EnvelopeHistory>();
|
||||||
|
|
||||||
// TODO: * Check the Form App and remove the default value
|
// TODO: * Check the Form App and remove the default value
|
||||||
|
[NotMapped]
|
||||||
public List<Receiver> Receivers { get; set; } = new List<Receiver>();
|
public List<Receiver> Receivers { get; set; } = new List<Receiver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,10 +1,59 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
#if NETFRAMEWORK
|
||||||
|
using System;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Domain.Entities
|
namespace EnvelopeGenerator.Domain.Entities
|
||||||
{
|
{
|
||||||
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
|
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
|
||||||
public class EnvelopeReceiver : EnvelopeReceiverBase
|
public class EnvelopeReceiver
|
||||||
{
|
{
|
||||||
|
[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; }
|
||||||
|
|
||||||
|
[Column("PHONE_NUMBER")]
|
||||||
|
[StringLength(20)]
|
||||||
|
[RegularExpression(@"^\+[0-9]+$", ErrorMessage = "Phone number must start with '+' followed by digits.")]
|
||||||
|
public string PhoneNumber { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Tuple<int, int> Id => Tuple.Create(EnvelopeId, ReceiverId);
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool HasPhoneNumber => !string.IsNullOrWhiteSpace(PhoneNumber);
|
||||||
|
|
||||||
[ForeignKey("EnvelopeId")]
|
[ForeignKey("EnvelopeId")]
|
||||||
public Envelope Envelope { get; set; }
|
public Envelope Envelope { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
#if NETFRAMEWORK
|
|
||||||
using System;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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; }
|
|
||||||
|
|
||||||
[Column("PHONE_NUMBER")]
|
|
||||||
[StringLength(20)]
|
|
||||||
[RegularExpression(@"^\+[0-9]+$", ErrorMessage = "Phone number must start with '+' followed by digits.")]
|
|
||||||
public string PhoneNumber { get; set; }
|
|
||||||
|
|
||||||
[NotMapped]
|
|
||||||
public Tuple<int, int> Id => Tuple.Create(EnvelopeId, ReceiverId);
|
|
||||||
|
|
||||||
[NotMapped]
|
|
||||||
public bool HasPhoneNumber => !string.IsNullOrWhiteSpace(PhoneNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
using EnvelopeGenerator.Web.Services;
|
using EnvelopeGenerator.Web.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers;
|
||||||
|
|
||||||
|
public class BaseController : Controller
|
||||||
{
|
{
|
||||||
public class BaseController : Controller
|
protected readonly DatabaseService database;
|
||||||
|
|
||||||
|
protected readonly ILogger _logger;
|
||||||
|
|
||||||
|
public BaseController(DatabaseService database, ILogger logger)
|
||||||
{
|
{
|
||||||
protected readonly DatabaseService database;
|
this.database = database;
|
||||||
|
_logger = logger;
|
||||||
protected readonly ILogger _logger;
|
|
||||||
|
|
||||||
public BaseController(DatabaseService database, ILogger logger)
|
|
||||||
{
|
|
||||||
this.database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
74
EnvelopeGenerator.Web/wwwroot/README.md
Normal file
74
EnvelopeGenerator.Web/wwwroot/README.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# 📄 PSPDFKit-Integration – Vanilla JavaScript
|
||||||
|
|
||||||
|
Dieses Projekt zeigt, wie die PDF-Anzeige- und Signaturbibliothek [PSPDFKit](https://www.nutrient.io/sdk/web/getting-started/other-frameworks/javascript/) mithilfe von **Vanilla JavaScript** integriert werden kann.
|
||||||
|
|
||||||
|
## 🚀 Verwendungszweck
|
||||||
|
|
||||||
|
PSPDFKit wurde in der Webanwendung verwendet, um PDF-Dokumente:
|
||||||
|
- anzuzeigen,
|
||||||
|
- zu signieren,
|
||||||
|
- mit Anmerkungen zu versehen,
|
||||||
|
- Formularfelder auszufüllen.
|
||||||
|
|
||||||
|
Benutzer können Dokumente **direkt über den Browser signieren und versenden**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Wo und wie wurde PSPDFKit verwendet?
|
||||||
|
|
||||||
|
### 1. PSPDFKit laden
|
||||||
|
|
||||||
|
PSPDFKit wurde mit der Funktion `loadPSPDFKit` in `UI.js` gestartet:
|
||||||
|
|
||||||
|
```js
|
||||||
|
PSPDFKit.load({
|
||||||
|
container: ‚#app‘,
|
||||||
|
document: arrayBuffer,
|
||||||
|
licenseKey: ‚YOUR_LICENSE_KEY‘,
|
||||||
|
...
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Anmerkungen und Formularfelder
|
||||||
|
|
||||||
|
In `annotation.js` werden die folgenden Felder dynamisch zu PDF-Dokumenten hinzugefügt:
|
||||||
|
|
||||||
|
- **Signaturfeld** (`SignatureFormField`)
|
||||||
|
- **Position** (`TextFormField`)
|
||||||
|
- **Stadt** (`TextFormField`)
|
||||||
|
- **Datum** (`TextFormField`, wird automatisch mit dem heutigen Datum ausgefüllt)
|
||||||
|
- **Bezeichnungen** (`Ort`, `Position`, `Date`) – dies sind nur lesbare Textfelder.
|
||||||
|
- **Rahmen für Signaturbild** – wird dynamisch erstellt und platziert, wenn der Benutzer unterschreibt.
|
||||||
|
|
||||||
|
Die Felder werden entsprechend ihrer Position auf dem PDF berechnet und für jedes Feld wird eine eindeutige ID erstellt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Anpassungen der Symbolleiste
|
||||||
|
|
||||||
|
In `UI.js` ist die Standard-Symbolleiste (`toolbarItems`) von PSPDFKit konfiguriert:
|
||||||
|
|
||||||
|
- Es werden nur zulässige Elemente (`sidebar`, `zoom`, `pager`, `search` usw.) angezeigt.
|
||||||
|
- Je nach Benutzerberechtigung (z. B. schreibgeschützt oder beschreibbar) werden die folgenden speziellen Schaltflächen dynamisch hinzugefügt:
|
||||||
|
|
||||||
|
**Beschreibbarer Modus:**
|
||||||
|
- `Teilen` (SHARE)
|
||||||
|
- `Logout` (LOGOUT)
|
||||||
|
- `Zurücksetzen` (RESET)
|
||||||
|
- `Ablehnen` (REJECT)
|
||||||
|
- `Finalisieren` (FINISH)
|
||||||
|
|
||||||
|
**Nur-Lesemodus:**
|
||||||
|
- Die Schaltfläche `Teilen` kopiert nur den Link in die Zwischenablage (COPY_URL)
|
||||||
|
|
||||||
|
Für mobile Geräte werden zusätzlich vereinfachte Schaltflächen angezeigt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📁 Wichtige Dateien
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------------------|-----------------------------------------------|
|
||||||
|
| `app.js` | Hauptanwendungsklasse, Dokumentladen und -steuerung |
|
||||||
|
| `ui.js` | PSPDFKit-UI-Einrichtung und Symbolleistenverwaltung |
|
||||||
|
| `annotation.js` | Erstellen und Löschen von Anmerkungsfeldern |
|
||||||
Reference in New Issue
Block a user