Compare commits

...

8 Commits

Author SHA1 Message Date
babd96200a Refactor and enhance PDF finalization process
- Added new imports to integrate additional services.
- Renamed `envelope` to `oEnvelopeEntity` for clarity.
- Improved envelope retrieval logic and error handling.
- Refactored `ReadOnly` envelope handling for readability.
- Reintroduced and enhanced annotation processing logic.
- Updated `BurnAnnotsToPDF` call with better logging.
- Added envelope domain model loading for report creation.
- Implemented signing certificate report generation.
- Merged burned document with signing certificate report.
- Updated output file naming and adjusted save logic.
- Improved method structure with clear steps and logging.
2026-08-24 14:33:03 +02:00
f9cfcf1f19 Fix: Add "Read and confirmed" label for RaC envelopes
Updated the Signature Certificate report to display the correct
label "Read and confirmed" for "Read and Sign" envelopes.

- Added `DocumentSignedRaC` resource key to `Model.resx` and
  `Model.en.resx` with localized values ("Gelesen und bestätigt"
  and "Read and confirmed").
- Updated `ReportItem.vb` to include conditional logic in
  `ItemStatusTranslated` for "Read and Sign" envelopes.
- Added strongly-typed property for `DocumentSignedRaC` in
  `Model.Designer.cs`.
- Updated `fix-report-label-read-and-confirmed.md` documentation
  to reflect changes, including testing steps and task completion.

These changes ensure accurate status labels in the report for
different envelope types.
2026-08-24 14:31:40 +02:00
ffb9e07466 Fix label for "Read and Sign" envelopes in reports
Addressed an issue where the Signature Certificate report incorrectly displayed "Document signed" for "Read and Sign" envelopes. Added a new resource key, `DocumentSignedRaC`, with translations ("Read and confirmed" / "Gelesen und bestätigt") to resolve this.

Updated `ItemStatusTranslated` in `ReportItem.vb` to use the new key for "Read and Sign" envelopes (`EnvelopeTypeId == 2`) while retaining existing behavior for other envelope types. Leveraged `Envelope.IsReadAndConfirm()` to determine envelope type.

Pending tasks include adding the new resource key to resource files and updating `Model.Designer.cs` with a strongly-typed property. Testing instructions provided to verify correct label behavior.
2026-08-24 13:47:28 +02:00
5384a08905 Update .gitignore to exclude specific files and directories
The .gitignore file was updated to ignore the following files and
directories:
- `FodyWeavers.xsd`
- `/EnvelopeGenerator.Tests.Application/annotations.json`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/TekH - SoftHSM Test.md`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/publish-output`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md+/ignore/EnvelopeGenerator.Form`

These changes ensure that unnecessary or sensitive files are not
tracked in version control.
2026-08-20 14:58:51 +02:00
dda5ff28e1 Update build package paths to include PreRelease folder
Updated the `DesktopBuildPackageLocation` property in
`IISProfileNet8.pubxml` and `IISProfile.pubxml` to store
build packages in the `PreRelease` directory.

- Updated `EnvelopeGenerator.API.zip` and `EnvelopeGenerator.Server.zip` paths in `IISProfileNet8.pubxml`.
- Updated `EnvelopeGenerator.ReceiverUI.zip` path in `IISProfile.pubxml`.

No other properties or configurations were modified.
2026-07-06 14:32:18 +02:00
043349a47f Update EnvelopeGenerator.Server/EnvelopeGenerator.Server/README.md 2026-07-06 10:17:10 +02:00
c36f7ccf98 Merge branch 'feat/migr-DxReportViewer' into master 2026-07-02 15:59:31 +02:00
cf3e85bcd7 Update .gitignore and add new solution items
Updated the `.gitignore` file to exclude the `MigrationBackup/`
directory. Added `publish-output` and `tekh_softHSM_test.md`
to the `EnvelopeGenerator.Server` directory.

Modified the `EnvelopeGenerator.sln` file to include a new
solution item `RECEIVER_PDF_VIEWER_CONTEXT.md` under the
`src` project section. No structural changes were made to
existing projects in the solution.
2026-07-02 15:56:46 +02:00
13 changed files with 236 additions and 45 deletions

1
.gitignore vendored
View File

@@ -369,3 +369,4 @@ FodyWeavers.xsd
/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md
/EnvelopeGenerator.Server/EnvelopeGenerator.Server/publish-output
/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md
/ignore/EnvelopeGenerator.Form

View File

@@ -11,7 +11,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>5e0e17c0-ff5a-4246-bf87-1add85376a27</ProjectGuid>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\API\net8\$(Version)\EnvelopeGenerator.API.zip</DesktopBuildPackageLocation>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\PreRelease\API\net8\$(Version)\EnvelopeGenerator.API.zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>EnvelopeGenerator</DeployIisAppPath>
<_TargetId>IISWebDeployPackage</_TargetId>

View File

@@ -1,6 +1,7 @@
Imports System.IO
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports EnvelopeGenerator.CommonServices
Imports EnvelopeGenerator.CommonServices.Jobs
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument
Imports GdPicture14
@@ -145,64 +146,91 @@ Public Class frmFinalizePDF
log.AppendLine($"Document bytes: {oBuffer.Length}")
' 3. Check what BurnAnnotsToPDF will do internally
Dim oEnvelopeEntity As Envelope = Nothing
Using scope = Factory.Shared.ScopeFactory.CreateScope()
Dim envRepo = scope.ServiceProvider.Repository(Of Envelope)()
Dim envelope = envRepo.Where(Function(env) env.Id = envelopeId).FirstOrDefault()
oEnvelopeEntity = envRepo.Where(Function(env) env.Id = envelopeId).FirstOrDefault()
If envelope Is Nothing Then
If oEnvelopeEntity Is Nothing Then
log.AppendLine("ERROR: Envelope not found in EF Core!")
txtResult.Text = log.ToString()
Return
End If
log.AppendLine($"Envelope found: Id={envelope.Id}, EnvelopeTypeId={envelope.EnvelopeTypeId}")
log.AppendLine($"ReadOnly (IsReadAndConfirm): {envelope.ReadOnly}")
log.AppendLine($"Envelope found: Id={oEnvelopeEntity.Id}, EnvelopeTypeId={oEnvelopeEntity.EnvelopeTypeId}")
log.AppendLine($"ReadOnly (IsReadAndConfirm): {oEnvelopeEntity.ReadOnly}")
If envelope.ReadOnly Then
log.AppendLine(">>> EARLY RETURN: ReadOnly=True, original PDF returned without burning")
txtResult.Text = log.ToString()
Return
End If
Dim sigRepo = scope.ServiceProvider.Repository(Of DocReceiverElement)()
Dim elements = sigRepo _
.Where(Function(sig) sig.Document.EnvelopeId = envelopeId) _
.Include(Function(sig) sig.Annotations) _
.ToList()
log.AppendLine($"Elements (Signature) count: {elements.Count}")
If elements.Any() Then
log.AppendLine(">>> PATH: BurnElementAnnotsToPDF (new element-based path)")
For Each elem In elements
Dim annotCount = If(elem.Annotations IsNot Nothing, elem.Annotations.Count(), 0)
log.AppendLine($" Element Id={elem.Id}, Page={elem.Page}, X={elem.X}, Y={elem.Y}, W={elem.Width}, H={elem.Height}, Annotations={annotCount}")
If elem.Annotations IsNot Nothing Then
For Each annot In elem.Annotations
log.AppendLine($" Annot: Name={annot.Name}, Type={annot.Type}, X={annot.X}, Y={annot.Y}, W={annot.Width}, H={annot.Height}")
Next
End If
Next
If oEnvelopeEntity.ReadOnly Then
log.AppendLine(">>> ReadOnly=True: original PDF will be used without burning (annotations skipped)")
Else
log.AppendLine(">>> PATH: BurnInstantJSONAnnotsToPDF (old JSON-based path)")
Dim sigRepo = scope.ServiceProvider.Repository(Of DocReceiverElement)()
Dim elements = sigRepo _
.Where(Function(sig) sig.Document.EnvelopeId = envelopeId) _
.Include(Function(sig) sig.Annotations) _
.ToList()
log.AppendLine($"Elements (Signature) count: {elements.Count}")
If elements.Any() Then
log.AppendLine(">>> PATH: BurnElementAnnotsToPDF (new element-based path)")
For Each elem In elements
Dim annotCount = If(elem.Annotations IsNot Nothing, elem.Annotations.Count(), 0)
log.AppendLine($" Element Id={elem.Id}, Page={elem.Page}, X={elem.X}, Y={elem.Y}, W={elem.Width}, H={elem.Height}, Annotations={annotCount}")
If elem.Annotations IsNot Nothing Then
For Each annot In elem.Annotations
log.AppendLine($" Annot: Name={annot.Name}, Type={annot.Type}, X={annot.X}, Y={annot.Y}, W={annot.Width}, H={annot.Height}")
Next
End If
Next
Else
log.AppendLine(">>> PATH: BurnInstantJSONAnnotsToPDF (old JSON-based path)")
End If
End If
End Using
' 4. Actually call BurnAnnotsToPDF (same as Service)
' 4. Burn annotations (ReadOnly envelopes return original PDF unchanged)
log.AppendLine("")
log.AppendLine("Calling BurnAnnotsToPDF...")
Dim oNewBuffer = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId)
log.AppendLine($"Result bytes: {oNewBuffer.Length}")
log.AppendLine($"Same as input: {oBuffer.Length = oNewBuffer.Length AndAlso oBuffer.SequenceEqual(oNewBuffer)}")
Dim oBurnedBuffer As Byte() = PDFBurner.BurnAnnotsToPDF(oBuffer, oJsonList, envelopeId)
log.AppendLine($"Burned bytes: {oBurnedBuffer.Length}")
log.AppendLine($"Unchanged (ReadOnly): {oBuffer.Length = oBurnedBuffer.Length AndAlso oBuffer.SequenceEqual(oBurnedBuffer)}")
' 5. Write output
' 5. Build State and load Envelope domain model for ReportCreator
log.AppendLine("")
log.AppendLine("Loading envelope domain model for report...")
Dim oState As New State() With {
.Database = Database,
.LogConfig = LogConfig
}
Dim oEnvelopeModel As New EnvelopeModel(oState)
Dim oEnvelope = oEnvelopeModel.GetById(envelopeId)
If oEnvelope Is Nothing Then
log.AppendLine("ERROR: Envelope not found via EnvelopeModel!")
txtResult.Text = log.ToString()
Return
End If
log.AppendLine($"Envelope loaded: {oEnvelope.Id}")
' 6. Create signing certificate report
log.AppendLine("Creating signing certificate report...")
Dim oReportCreator As New ReportCreator(LogConfig, oState)
Dim oReportBuffer As Byte() = oReportCreator.CreateReport(oEnvelope)
log.AppendLine($"Report bytes: {oReportBuffer.Length}")
' 7. Merge burned document + report (last page)
log.AppendLine("Merging documents...")
Dim oMerger As New PDFMerger(LogConfig, pGDPictureLicenseKey)
Dim oMergedBuffer As Byte() = oMerger.MergeDocuments(oBurnedBuffer, oReportBuffer)
log.AppendLine($"Merged bytes: {oMergedBuffer.Length}")
' 8. Save and open
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}_FullTest.burned.pdf")
File.WriteAllBytes(oNewPath, oNewBuffer)
log.AppendLine($"Output: {oNewPath}")
Dim oMergedPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}_FullTest.merged.pdf")
File.WriteAllBytes(oMergedPath, oMergedBuffer)
log.AppendLine($"Output: {oMergedPath}")
txtResult.Text = log.ToString()
Process.Start(oNewPath)
Process.Start(oMergedPath)
Catch ex As Exception
txtResult.Text = $"ERROR: {ex.Message}{vbCrLf}{vbCrLf}{ex.ToString()}"

View File

@@ -1,5 +1,6 @@
Imports EnvelopeGenerator.Domain.Constants
Imports EnvelopeGenerator.Domain.Entities
Imports EnvelopeGenerator.Domain.Interfaces
Public Class ReportItem
@@ -11,8 +12,15 @@ Public Class ReportItem
Public Property ItemStatus As EnvelopeStatus
Public ReadOnly Property ItemStatusTranslated As String
Get
Dim oStatus = ItemStatus.ToString()
Return My.Resources.Model.ResourceManager.GetString(oStatus)
Dim oStatusKey = ItemStatus.ToString()
If ItemStatus = EnvelopeStatus.DocumentSigned AndAlso
Envelope IsNot Nothing AndAlso
Envelope.IsReadAndConfirm() Then
oStatusKey = "DocumentSignedRaC"
End If
Return My.Resources.Model.ResourceManager.GetString(oStatusKey)
End Get
End Property

View File

@@ -168,6 +168,9 @@
<data name="DocumentSigned" xml:space="preserve">
<value>Document signed</value>
</data>
<data name="DocumentSignedRaC" xml:space="preserve">
<value>Read and confirmed</value>
</data>
<data name="Draft" xml:space="preserve">
<value>Draft</value>
</data>

View File

@@ -168,6 +168,9 @@
<data name="DocumentSigned" xml:space="preserve">
<value>Dokument unterzeichnet</value>
</data>
<data name="DocumentSignedRaC" xml:space="preserve">
<value>Gelesen und bestätigt</value>
</data>
<data name="Draft" xml:space="preserve">
<value>Entwurf</value>
</data>

View File

@@ -213,6 +213,15 @@ namespace My.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Gelesen und bestätigt.
/// </summary>
public static string DocumentSignedRaC {
get {
return ResourceManager.GetString("DocumentSignedRaC", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Entwurf.
/// </summary>

View File

@@ -168,6 +168,9 @@
<data name="DocumentSigned" xml:space="preserve">
<value>Dokument unterzeichnet</value>
</data>
<data name="DocumentSignedRaC" xml:space="preserve">
<value>Gelesen und bestätigt</value>
</data>
<data name="Draft" xml:space="preserve">
<value>Entwurf</value>
</data>

View File

@@ -9,7 +9,7 @@
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>fb2d306b-1042-4a70-31ed-f991a1599371</ProjectGuid>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\ReceiverUI\net8\$(Version)\EnvelopeGenerator.ReceiverUI.zip</DesktopBuildPackageLocation>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\PreRelease\ReceiverUI\net8\$(Version)\EnvelopeGenerator.ReceiverUI.zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>EnvelopeGenerator.ReceiverUI</DeployIisAppPath>
<_TargetId>IISWebDeployPackage</_TargetId>

View File

@@ -11,7 +11,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>5e0e17c0-ff5a-4246-bf87-1add85376a27</ProjectGuid>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\API\net8\$(Version)\EnvelopeGenerator.Server.zip</DesktopBuildPackageLocation>
<DesktopBuildPackageLocation>M:\App&amp;Service\0 DD - Smart UP\signFLOW\PreRelease\API\net8\$(Version)\EnvelopeGenerator.Server.zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>EnvelopeGenerator</DeployIisAppPath>
<_TargetId>IISWebDeployPackage</_TargetId>

View File

@@ -84,7 +84,7 @@ dotnet publish EnvelopeGenerator.Server\EnvelopeGenerator.Server\EnvelopeGenerat
| `--runtime win-x64` | Zielplattform: Windows 64-Bit |
| `-o .\publish-output` | Ausgabeverzeichnis |
### Doğrulama nach dem Publish
### Überprüfung nach dem Publish
Nach erfolgreichem Publish folgende Dateien im Ausgabeverzeichnis prüfen:

View File

@@ -22,6 +22,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{134D4164-B291-4E19-99B9-E4FA3AFAB62C}"
ProjectSection(SolutionItems) = preProject
COPILOT_CONTEXT.md = COPILOT_CONTEXT.md
fix-report-label-read-and-confirmed.md = fix-report-label-read-and-confirmed.md
FORM_APPLICATION_CONTEXT.md = FORM_APPLICATION_CONTEXT.md
RECEIVER_PDF_VIEWER_CONTEXT.md = RECEIVER_PDF_VIEWER_CONTEXT.md
EndProjectSection

View File

@@ -0,0 +1,135 @@
# Fix: Report Label "Read and confirmed" for Read and Sign Envelopes
## Status
✅ **COMPLETED**
## Git Branch
```
fix/report-label-read-and-confirmed
```
---
## Problem
In the **Signature Certificate report** (`Signierungszertifikat`), the history event
list always showed **"Document signed"** for status `DocumentSigned` (code `2005`) <20>
even when the envelope type was **"Read and Sign"** (`EnvelopeTypeId = 2`).
For "Read and Sign" envelopes the correct label must be **"Read and confirmed"**
(DE: **"Gelesen und best<73>tigt"**).
### Screenshot reference
The report shows a table with columns *Ereignis | Benutzer | Zeitstempel*.
The row with status 2005 displayed "Document signed" where "Read and confirmed"
was expected.
---
## Root Cause
`ReportItem.ItemStatusTranslated` in
`EnvelopeGenerator.CommonServices\Jobs\FinalizeDocument\ReportItem.vb`
resolved the display label by calling:
```vb
My.Resources.Model.ResourceManager.GetString(ItemStatus.ToString())
```
There was **no branching logic** to handle the Read and Sign envelope type.
The same `DocumentSigned` key was always used regardless of envelope type.
---
## Solution
### Convention followed
The project already uses a `RaC` (**R**ead **a**nd **C**onfirm) suffix for
Read-and-Sign label variants across all resource files:
| Existing RaC keys |
|---|
| `DocumentRejectedRaC` |
| `EnvelopeReportCreatedRaC` |
| `MessageConfirmationSentRaC` |
### New resource key added: `DocumentSignedRaC`
| Resource file | Value |
|---|---|
| `Model.resx` (DE, default) | `Gelesen und best<73>tigt` |
| `Model.en.resx` (EN) | `Read and confirmed` |
### Logic change in `ReportItem.vb`
```vb
Public ReadOnly Property ItemStatusTranslated As String
Get
Dim oStatusKey = ItemStatus.ToString()
If ItemStatus = EnvelopeStatus.DocumentSigned AndAlso
Envelope IsNot Nothing AndAlso
Envelope.IsReadAndConfirm() Then
oStatusKey = "DocumentSignedRaC"
End If
Return My.Resources.Model.ResourceManager.GetString(oStatusKey)
End Get
End Property
```
`Envelope.IsReadAndConfirm()` is defined in
`EnvelopeGenerator.Domain\Interfaces\IEnvelope.cs` and returns `true`
when `EnvelopeTypeId == 2`.
---
## Files Changed
| # | File | Change | Status |
|---|---|---|---|
| 1 | `EnvelopeGenerator.CommonServices\Jobs\FinalizeDocument\ReportItem.vb` | Added `RaC` branching logic to `ItemStatusTranslated` | ? Done |
| 2 | `EnvelopeGenerator.Domain\Resources\Model.resx` | Added `DocumentSignedRaC` = `Gelesen und bestätigt` | ✅ Done |
| 3 | `EnvelopeGenerator.CommonServices\Strings\Model.resx` | Added `DocumentSignedRaC` = `Gelesen und bestätigt` | ✅ Done |
| 4 | `EnvelopeGenerator.CommonServices\Strings\Model.en.resx` | Added `DocumentSignedRaC` = `Read and confirmed` | ✅ Done |
| 5 | `EnvelopeGenerator.Domain\Resources\Model.Designer.cs` | Added `DocumentSignedRaC` strongly-typed property | ✅ Done |
---
## How to resume (for next agent)
All pending items are **resource file additions only**.
Each file needs one new `<data>` block inserted **directly after** the existing
`DocumentSigned` entry:
```xml
<data name="DocumentSignedRaC" xml:space="preserve">
<value>Gelesen und best<73>tigt</value> <!-- DE files -->
<!-- OR -->
<value>Read and confirmed</value> <!-- EN file -->
</data>
```
`Model.Designer.cs` also needs a new strongly-typed property added after
`DocumentSigned`:
```csharp
/// <summary>
/// Looks up a localized string similar to Gelesen und best<73>tigt.
/// </summary>
public static string DocumentSignedRaC {
get {
return ResourceManager.GetString("DocumentSignedRaC", resourceCulture);
}
}
```
---
## Testing
After changes, generate a Signature Certificate report for a **Read and Sign**
envelope and verify:
- History row with status 2005 shows **"Read and confirmed"** (EN)
- History row with status 2005 shows **"Gelesen und best<73>tigt"** (DE)
- Regular (non-RaC) envelopes still show **"Document signed"** / **"Dokument unterzeichnet"**