diff --git a/EnvelopeGenerator.sln b/EnvelopeGenerator.sln index 45a720f9..1158a000 100644 --- a/EnvelopeGenerator.sln +++ b/EnvelopeGenerator.sln @@ -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 + FORM_APPLICATION_CONTEXT.md = FORM_APPLICATION_CONTEXT.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0CBC2432-A561-4440-89BC-671B66A24146}" diff --git a/FORM_APPLICATION_CONTEXT.md b/FORM_APPLICATION_CONTEXT.md new file mode 100644 index 00000000..948290e6 --- /dev/null +++ b/FORM_APPLICATION_CONTEXT.md @@ -0,0 +1,788 @@ +# EnvelopeGenerator.Form – VB.NET Desktop Application Context + +## Purpose +**Legacy Windows Forms application** for envelope creation, management, and signature field placement. Built with **DevExpress components** and **GdPicture14** for PDF manipulation. This application is being **migrated to ReceiverUI + API** architecture. + +**Primary Libraries:** DevExpress XtraGrid/XtraEditors, GdPicture14, VB.NET (.NET Framework 4.6.2) + +--- + +## Application Architecture + +### Projects Structure +| Project | Purpose | +|---|---| +| **EnvelopeGenerator.Form** | Main WinForms UI (VB.NET) | +| **EnvelopeGenerator.CommonServices** | Shared services/helpers | +| **EnvelopeGenerator.Service** | Windows Service (legacy) | +| **EnvelopeGenerator.BBTests** | Tests | + +### Key Forms (Pages) + +#### 1. **frmMain.vb** - Envelope Overview (Dashboard) +**Route Equivalent:** `/sender` (EnvelopeSenderPage.razor) + +**Purpose:** Main dashboard showing all envelopes with status filtering. + +**Key Features:** +- **Tab-based layout** with 2+2 tabs: + - **Tab 0:** Active Envelopes (not sent/partially signed) + - **Tab 1:** Completed Envelopes (signed/rejected/deleted) + - **Tab 2:** Reports (Admin only) + - **Tab 3:** Additional Reports (Admin only) + +**Envelope Status Colors:** +| Status | Color | Hex Code | Description | +|---|---|---|---| +| `EnvelopePartlySigned` | Green | `#81C784` (GREEN_300) | At least one receiver signed | +| `EnvelopeQueued` / `EnvelopeSent` | Orange | `#FFB74D` (ORANGE_300) | Sent to receivers, awaiting signatures | +| `EnvelopeCompletelySigned` | Green | `#81C784` (GREEN_300) | All receivers signed | +| `EnvelopeDeleted` / `EnvelopeWithdrawn` / `EnvelopeRejected` | Red | `#E57373` (RED_300) | Envelope cancelled/rejected | + +**Receiver Status Colors (in detail grids):** +| Status | Color | Hex Code | +|---|---|---| +| `Signed` | Green | `#81C784` (GREEN_300) | +| `Not Signed` | Red | `#E57373` (RED_300) | + +**Grid Layouts:** + +1. **GridEnvelopes** (Active): + - Columns: ID, Title, Status, Created Date, Creator + - **Master-Detail:** Expands to show: + - **ViewReceivers:** Receiver list with status colors + - **ViewHistory:** Envelope history (status changes, emails sent) + +2. **GridCompleted** (Completed): + - Same structure as GridEnvelopes + - **ViewReceiversCompleted** and **ViewHistoryCompleted** detail grids + +**Toolbar Actions:** +| Button | Action | Enabled When | +|---|---|---| +| **Create Envelope** | Opens `frmEnvelopeEditor` | Always | +| **Edit Envelope** | Opens `frmEnvelopeEditor` with selected envelope | Envelope selected & not sent | +| **Delete Envelope** | Shows `frmRueckruf` (reason dialog) ? deletes | Envelope selected | +| **Show Document** | Opens PDF in temp folder | Envelope & document selected | +| **Contact Receiver** | Opens mailto link | Receiver selected | +| **Resend Invitation** | Resends email to receiver | Receiver selected | +| **Send Access Code** | Manually sends access code email | Receiver selected & UseAccessCode=true | +| **Info Mail** | Opens mailto to support team | Receiver selected (for issues) | +| **2FA Properties** | Shows `frm2Factor_Properties` dialog | Receiver selected & TFA enabled | +| **Export Report (EB)** | Exports completed envelope result PDF | Completed envelope selected | +| **Refresh** | Reloads data | Always | +| **Export to Excel** | Exports current grid to XLSX | Always | + +**Auto-Refresh:** Timer refreshes every N seconds (configurable), but **only when `frmEnvelopeEditor` is not open**. + +**Persistence:** Grid layouts saved to `{GridViewName}_UserLayout.xml` in user AppData folder. + +--- + +#### 2. **frmEnvelopeEditor.vb** - Envelope Creation/Edit +**Route Equivalent:** `/sender/envelope/{id}` (future) + +**Purpose:** Create or edit envelope details, add documents, manage receivers. + +**Workflow:** +1. **On New Envelope:** Opens `frmEnvelopeMainData` popup **first** (title, type, settings) +2. **After popup OK:** Main editor loads +3. **Add Document:** Single PDF file (via Open Dialog or Drag & Drop) +4. **Add Receivers:** Grid with auto-complete from previous emails +5. **Edit Fields:** Opens `frmFieldEditor` for signature field placement +6. **Send Envelope:** Validates and sends invitations + +**UI Layout:** +- **Top Ribbon:** DevExpress ribbon with actions +- **Left Panel:** Document list (thumbnail + details) +- **Right Panel:** Receiver list (name, email, access code, phone) +- **Bottom Bar:** Envelope ID, Creator Email, Info messages + +**Ribbon Actions:** +| Button | Action | Enabled When | +|---|---|---| +| **Add File** | Opens file dialog | No document added | +| **Merge Files** | Opens `frmOrderFiles` to concatenate PDFs | No document added | +| **Delete File** | Removes document | Document selected | +| **Show File** | Opens PDF in default viewer | Document selected | +| **Edit Fields** | Opens `frmFieldEditor` | Document + receivers exist | +| **Edit Data** | Opens `frmEnvelopeMainData` | Always | +| **Save** | Saves envelope without validation | Always | +| **Send Envelope** | Validates & sends invitations | Document + receivers exist | +| **Cancel** | Closes with save prompt | Always | +| **Delete Receiver** | Removes receiver from list | Receiver selected | + +**Receiver Grid:** +- **Columns:** Name, Email, Access Code, Phone (if TFA enabled) +- **Auto-complete:** Email field suggests previous receivers +- **Validation:** Email format, Phone format (+49... for TFA) +- **Access Code:** Auto-generated on email entry (if UseAccessCode=true) +- **Color Assignment:** Each receiver gets a unique color (for signature fields) + +**Document Grid:** +- **Single file only** (currently limited to 1 PDF) +- **Thumbnail:** Generated via GdPicture14 +- **Page Count:** Displayed + +**Drag & Drop:** +- Drop PDF files directly onto form +- Only 1 file allowed +- Visual feedback (red bar if >1 file) + +**Validation:** +- Title required +- Message required +- At least 1 document +- At least 1 receiver +- Valid email addresses +- Valid phone numbers (if TFA enabled) +- Signature fields exist for each receiver (before sending) + +--- + +#### 3. **frmEnvelopeMainData.vb** - Envelope Settings Popup +**Route Equivalent:** Part of `/sender/envelope/{id}` (inline in ReceiverUI) + +**Purpose:** Configure envelope metadata and behavior. **Shown as modal popup** before main editor. + +**Fields:** + +| Field | Type | Description | +|---|---|---| +| **Title** | Text | Envelope title (required) | +| **Envelope Type** | Dropdown | Template (ContractType, Language, defaults) | +| **Language** | Dropdown | de/en | +| **Use Access Code** | Checkbox | Require 6-digit code for signing | +| **2FA Enabled** | Checkbox | Require SMS verification (forces Access Code ON) | +| **Certification Type** | Dropdown | Basic / Advanced / Qualified | +| **Final Email to Creator** | Dropdown | No / OnComplete / OnCompleteOrReject | +| **Final Email to Receivers** | Dropdown | No / OnComplete / OnCompleteOrReject | +| **Send Reminder Emails** | Checkbox | Auto-send reminders | +| **First Reminder Days** | Number | Days before first reminder | +| **Reminder Interval Days** | Number | Days between reminders | +| **Expires When Days** | Number | Days until envelope expires | +| **Expires Warning Days** | Number | Days before expiry to warn | + +**Layout:** +- **Compact mode:** Only Title, Type, Language visible +- **Expanded mode:** Click "All Options" to show reminder/expiry settings + +**Behavior:** +- **On Type Selection:** Auto-fills all settings from template +- **On 2FA Enable:** Forces "Use Access Code" ON and disables checkbox +- **On New Envelope:** Shows before main editor +- **On Edit Envelope:** Opens as separate dialog, Type field read-only + +**Validation:** Title is required (red border via Adorner). + +--- + +#### 4. **frmFieldEditor.vb** - Signature Field Placement +**Route Equivalent:** `/sender/envelope/{id}/fields` (future, or inline in editor) + +**Purpose:** Place signature fields on PDF pages using **GdPicture14** viewer with annotations. + +**UI Layout:** +- **Left:** PDF Viewer (GdViewer) with annotation tools +- **Right:** Thumbnail navigator (ThumbnailEx2) +- **Top:** Toolbar with receiver selector and actions + +**Toolbar:** +| Button | Action | +|---|---| +| **Receiver Selector** | Popup menu with receiver names (colored circles) | +| **Add Signature** | Draws new signature annotation | +| **Delete** | Removes selected annotation | +| **Save** | Saves signature fields to database | + +**Signature Field Details:** +- **Size:** 1.77" × 1.96" (4.5cm × 5cm) - **FIXED SIZE** +- **Color:** Matches receiver color (from grid assignment) +- **Label:** "SIGNATUR" (or localized "Signature") +- **Position:** Draggable on PDF canvas +- **Database Format:** Coordinates stored in **INCHES** (GdPicture native) + +**Coordinate System:** +- **Origin:** Top-left corner +- **Units:** Inches (not points or pixels) +- **Axes:** X right, Y down +- **Storage:** Direct INCHES values (no conversion) + +**Evidence from Code:** +```vb +Private Const SIGNATURE_WIDTH As Single = 1.77 ' inches +Private Const SIGNATURE_HEIGHT As Single = 1.96 ' inches + +Sub LoadAnnotation(pElement As DocReceiverElement, ...) + oAnnotation.Left = CSng(pElement.X) ' Direct INCHES assignment + oAnnotation.Top = CSng(pElement.Y) +End Sub +``` + +**Multi-Receiver Support:** +- **Receiver switcher:** Click receiver name in popup menu +- **Current receiver:** Highlighted in toolbar (name + colored circle) +- **Other receivers' fields:** Shown semi-transparent (30% opacity), not selectable +- **Save:** Saves current receiver's fields, switches receiver, reloads all annotations + +**Annotation Behavior:** +- **New annotation:** User clicks "Add Signature" ? draws interactive annotation ? auto-sized to 1.77×1.96 +- **Existing annotation:** Loaded from database, locked size (can move but not resize) +- **Styling:** Filled rectangle with centered text "SIGNATUR" +- **Validation:** No resize, no text edit, no rotation + +**Unsaved Changes Prompt:** +- On form close: "There are unsaved changes. Save? Yes/No/Cancel" +- Yes ? Saves ? Closes +- No ? Discards ? Closes +- Cancel ? Stays open + +--- + +#### 5. **frmRueckruf.vb** - Delete Reason Dialog +**Route Equivalent:** Inline confirmation in ReceiverUI + +**Purpose:** Capture reason for envelope deletion/withdrawal. + +**Fields:** +- **Envelope ID** (display only) +- **Envelope Title** (display only) +- **Reason** (required text box) + +**Buttons:** +- **OK:** Confirms deletion with reason +- **Cancel:** Cancels operation + +**Global Variables:** +```vb +Public CurrentEnvelopID As Long +Public CurrentEnvelopetitle As String +Public Shared Continue_Reject As Boolean = False +Public Shared Reject_reason As String = "" +``` + +--- + +#### 6. **frm2Factor_Properties.vb** - 2FA Management +**Route Equivalent:** `/admin/2fa/{email}` (future admin panel) + +**Purpose:** View/manage 2FA settings for a receiver. + +**Fields:** +- **Email Address** (display only) +- **TOTP Secret Key** (display only) +- **Registration Deadline** (display only) + +**Usage:** Admin tool to debug 2FA issues or reset TOTP secrets. + +--- + +#### 7. **frmOrderFiles.vb** - PDF Merge Tool +**Route Equivalent:** Inline in ReceiverUI (future) + +**Purpose:** Select multiple PDFs and merge them into a single document. + +**UI:** +- **File list:** Selected PDFs +- **Up/Down buttons:** Reorder files +- **Add/Remove buttons:** Manage list + +**Merge Logic:** +- Uses GdPicture14 `MergeDocuments()` +- Output: Single PDF in temp folder +- Auto-loaded as envelope document + +--- + +## Data Models (Controllers) + +### EnvelopeListController +**Purpose:** Load envelope lists for dashboard grids. + +**Methods:** +- `ListEnvelopes()` ? Active envelopes (not completed) +- `ListCompleted()` ? Completed envelopes (signed/rejected/deleted) +- `DeleteEnvelope(envelope, reason)` ? Soft delete with reason +- `GetPieChart()` ? DevExpress ChartControl (not used) +- `GetEnvelopeReceiverAddresses(userId)` ? List of previous receiver emails (for auto-complete) + +--- + +### EnvelopeEditorController +**Purpose:** Manage envelope CRUD and document/receiver operations. + +**Key Methods:** + +| Method | Purpose | +|---|---| +| `CreateDocument(filePath)` | Imports PDF, extracts pages/thumbnail, saves to DB | +| `DeleteDocument(document)` | Removes document from envelope | +| `SaveReceivers(envelope, receivers)` | Saves/updates receivers with access codes | +| `DeleteReceiver(receiver)` | Removes receiver (checks if fields exist) | +| `ElementsExist(receiverId)` | Checks if signature fields exist for receiver | +| `SaveEnvelope()` | Persists envelope to database | +| `SendEnvelope()` | Validates, queues emails, sends invitations | +| `ValidateEnvelopeForSending(errors)` | Checks all receivers have signature fields | +| `GetLastNameByEmailAdress(email)` | Returns previous name for email (auto-fill) | +| `GetLastPhoneByEmailAdress(email)` | Returns previous phone for email (auto-fill) | +| `DeleteEnvelopeFromDisk(envelope)` | Cleans up temp files | + +**ActionService Methods:** +- `ResendReceiver(envelope, receiver)` ? Resends invitation email +- `ManuallySendAccessCode(envelope, receiver)` ? Sends access code email + +--- + +### FieldEditorController +**Purpose:** Manage signature field annotations (DocReceiverElement). + +**Key Methods:** + +| Method | Purpose | +|---|---| +| `LoadElements()` | Loads all signature fields from database | +| `AddOrUpdateElement(annotation, orientation)` | Converts GdPicture annotation ? DocReceiverElement | +| `SaveElements(receiverId)` | Persists signature fields for receiver | +| `DeleteElement(element)` | Removes signature field | +| `GetElement(annotation)` | Finds element by annotation tag | +| `GetElementInfo(tag)` | Parses annotation tag (receiverId\|page\|guid) | + +**Annotation Tag Format:** +``` +"{receiverId}|{page}|{elementId}" +Example: "42|1|-1" (receiver 42, page 1, unsaved) +Example: "42|1|137" (receiver 42, page 1, element ID 137) +``` + +**Element Coordinate Conversion:** +```vb +' Database stores INCHES directly (GdPicture native) +Sub AddOrUpdateElement(annotation, orientation) + element.X = annotation.Left ' INCHES + element.Y = annotation.Top ' INCHES + element.Width = annotation.Width ' INCHES + element.Height = annotation.Height ' INCHES + element.Page = currentPage +End Sub +``` + +--- + +## Migration to ReceiverUI + API + +### Mapping Table + +| Form Feature | ReceiverUI Equivalent | Status | +|---|---|---| +| **frmMain** (Envelope list) | `/sender` (EnvelopeSenderPage.razor) | ? Exists | +| Tab 0: Active Envelopes | `/sender` default view | ? Grid with filters | +| Tab 1: Completed Envelopes | `/sender` with status filter | ? Same grid | +| Status colors (Green/Orange/Red) | CSS classes `.status-signed`, `.status-pending`, etc. | ?? **Needs implementation** | +| Master-detail grids (Receivers/History) | Expandable rows or modal dialogs | ?? **Needs implementation** | +| Toolbar: Create Envelope | Button ? `/sender/envelope/new` | ?? **Needs implementation** | +| Toolbar: Edit Envelope | Button ? `/sender/envelope/{id}` | ?? **Needs implementation** | +| Toolbar: Delete Envelope | Button ? Shows delete reason modal | ?? **Needs implementation** | +| Toolbar: Show Document | Downloads PDF | ?? **Needs implementation** | +| Toolbar: Contact Receiver | `mailto:` link | ?? **Needs implementation** | +| Toolbar: Resend Invitation | API call ? refresh grid | ?? **Needs implementation** | +| Toolbar: Export Excel | Download XLSX | ?? **Needs implementation** | +| Auto-refresh timer | SignalR or polling | ?? **Needs implementation** | +| Grid layout persistence | LocalStorage | ?? **Needs implementation** | +| **frmEnvelopeEditor** | `/sender/envelope/{id}` | ? **Not implemented** | +| ? **frmEnvelopeMainData** popup | Inline form section or stepper | ? **Not implemented** | +| Document upload (Drag & Drop) | Blazor InputFile with drag zone | ?? **Needs implementation** | +| Receiver grid (auto-complete) | DevExpress Blazor Grid with lookup | ?? **Needs implementation** | +| Merge PDFs (frmOrderFiles) | Client-side PDF.js or server-side | ?? **Needs implementation** | +| **frmFieldEditor** | `/sender/envelope/{id}/fields` or inline | ? **Not implemented** | +| GdPicture PDF viewer | PDF.js + canvas overlay (like EnvelopeReceiverPage) | ?? **Partial (receiver side only)** | +| Signature field placement | Drag & drop signature boxes on canvas | ? **Not implemented** | +| Receiver color coding | CSS variables + signature field borders | ? **Not implemented** | +| Multi-receiver switcher | Dropdown or tabs | ? **Not implemented** | +| Thumbnail navigator | PDF.js thumbnail sidebar (like receiver) | ?? **Exists for receiver** | +| Save signature fields | API POST `/api/Envelope/{id}/Elements` | ? **Not implemented** | +| **frm2Factor_Properties** | Admin panel `/admin/2fa/{email}` | ? **Not implemented** | +| **frmRueckruf** (Delete reason) | Modal dialog in EnvelopeSenderPage | ?? **Needs implementation** | + +--- + +## Critical Implementation Notes + +### 1. **Coordinate System Consistency** +**Database (Form App):** INCHES (GdPicture native) +**ReceiverUI (PDF.js):** Pixels on canvas +**Conversion Required:** +```csharp +// Sender side (placing fields): +float xInches = canvasPixelX / (canvasWidth / pageWidthInches); +float yInches = canvasPixelY / (canvasHeight / pageHeightInches); + +// Receiver side (displaying fields): +float canvasX = (xInches / pageWidthInches) * canvasWidth; +float canvasY = (yInches / pageHeightInches) * canvasHeight; +``` + +**A4 Page Dimensions:** +- Width: 8.27" = 595pt +- Height: 11.69" = 842pt + +--- + +### 2. **Status Color System** +Form app uses **DevExpress CustomDrawCell** event for row coloring. ReceiverUI should use: + +```css +/* Envelope status colors */ +.envelope-row.status-partly-signed { background-color: #81C784; } /* GREEN_300 */ +.envelope-row.status-queued, +.envelope-row.status-sent { background-color: #FFB74D; } /* ORANGE_300 */ +.envelope-row.status-completed { background-color: #81C784; } /* GREEN_300 */ +.envelope-row.status-deleted, +.envelope-row.status-rejected { background-color: #E57373; } /* RED_300 */ + +/* Receiver status colors */ +.receiver-row.signed { background-color: #81C784; } +.receiver-row.unsigned { background-color: #E57373; } +``` + +--- + +### 3. **Master-Detail Grid Pattern** +Form app uses **nested GridViews** (ViewReceivers, ViewHistory). ReceiverUI options: + +**Option A:** DevExpress Blazor Grid with master-detail template +```razor + + + + + + + + + +``` + +**Option B:** Click row ? show modal with receivers/history +```razor + +... + + + + + ... + + +``` + +--- + +### 4. **Signature Field Editor Architecture** + +**Form App:** +- GdPicture14 native annotations +- Fixed size (1.77×1.96 inches) +- Color-coded per receiver +- Draggable, non-resizable + +**ReceiverUI Equivalent:** +- PDF.js canvas + HTML overlay (like receiver signature buttons) +- `
` positioned absolutely +- Drag & drop with JS (`onmousedown`, `onmousemove`, `onmouseup`) +- Snap to grid (optional) +- Store coordinates in INCHES (convert from pixels) + +**Example HTML Overlay:** +```html +
+
+ Receiver: John Doe +
+
+``` + +**JS Dragging Logic:** +```javascript +function makeSignatureFieldDraggable(element) { + let offsetX, offsetY; + element.onmousedown = (e) => { + offsetX = e.clientX - element.offsetLeft; + offsetY = e.clientY - element.offsetTop; + document.onmousemove = (e) => { + element.style.left = (e.clientX - offsetX) + 'px'; + element.style.top = (e.clientY - offsetY) + 'px'; + }; + document.onmouseup = () => { + document.onmousemove = null; + saveFieldPosition(element); // Convert px ? inches ? API + }; + }; +} +``` + +--- + +### 5. **Auto-Complete Receiver Email** +Form app uses **DevExpress ComboBox** with `AllReceiverEmails` list. ReceiverUI options: + +**Option A:** DevExpress Blazor TagBox with remote data +```razor + + +``` + +**Option B:** HTML5 datalist +```razor + + + @foreach (var email in previousEmails) { + +``` + +--- + +### 6. **Drag & Drop File Upload** +Form app uses **WinForms DragDrop** events. ReceiverUI equivalent: + +```razor +
+

Drop PDF here or click to browse

+ +
+ +@code { + async Task HandleDrop(DragEventArgs e) { + var files = e.DataTransfer.Files; + if (files.Length > 1) { + errorMessage = "Only one file allowed"; + return; + } + await UploadDocument(files[0]); + } +} +``` + +--- + +### 7. **PDF Merge (frmOrderFiles)** +Form app uses **GdPicture14 MergeDocuments**. ReceiverUI options: + +**Option A:** Server-side merge (iText7 or PDFSharp) +```csharp +[HttpPost("api/Document/Merge")] +public async Task MergePDFs([FromForm] List files) { + using var outputStream = new MemoryStream(); + using var pdfDocument = new PdfDocument(new PdfWriter(outputStream)); + + foreach (var file in files) { + using var inputStream = file.OpenReadStream(); + using var sourcePdf = new PdfDocument(new PdfReader(inputStream)); + sourcePdf.CopyPagesTo(1, sourcePdf.GetNumberOfPages(), pdfDocument); + } + + pdfDocument.Close(); + return File(outputStream.ToArray(), "application/pdf", "merged.pdf"); +} +``` + +**Option B:** Client-side merge (PDF-lib.js in Blazor JS interop) +```javascript +async function mergePDFs(fileDataUrls) { + const pdfDoc = await PDFDocument.create(); + for (const dataUrl of fileDataUrls) { + const existingPdfBytes = await fetch(dataUrl).then(res => res.arrayBuffer()); + const pdf = await PDFDocument.load(existingPdfBytes); + const copiedPages = await pdfDoc.copyPages(pdf, pdf.getPageIndices()); + copiedPages.forEach(page => pdfDoc.addPage(page)); + } + const pdfBytes = await pdfDoc.save(); + return pdfBytes; +} +``` + +--- + +## Form App Workflow Summary + +### New Envelope Workflow (Sender) +``` +1. Click "Create Envelope" in frmMain + ? +2. frmEnvelopeMainData popup opens + - Enter Title (required) + - Select Envelope Type (loads defaults) + - Configure settings (Access Code, 2FA, Language, etc.) + - Click OK + ? +3. frmEnvelopeEditor opens + - Add PDF document (drag & drop or browse) + - Add receivers (email auto-complete, access code auto-gen) + - Click "Edit Fields" + ? +4. frmFieldEditor opens + - Select receiver from dropdown (colored circles) + - Click "Add Signature" ? draw box on PDF + - Drag to position (1.77×1.96 inches, fixed size) + - Repeat for each receiver + - Click "Save" + ? +5. Back to frmEnvelopeEditor + - Click "Send Envelope" + - Validation: + * Title exists + * Message exists + * Document exists + * Receivers exist + * All receivers have signature fields + - Confirmation: "Do you want to start the signature process now?" + - Click Yes ? Envelope status = EnvelopeSent + ? +6. Emails sent to receivers with invitation links + ? +7. frmMain refreshes, envelope moves to "Sent" (orange color) +``` + +### Receiver Signing Workflow (External) +``` +1. Receiver clicks link in email + ? +2. Web browser opens (EnvelopeGenerator.Web or ReceiverUI) + - If UseAccessCode=true: Enter 6-digit code + - If TFA=true: Enter SMS code + ? +3. PDF viewer loads with signature fields highlighted + - Click "Sign" button on each field + - Draw/type/upload signature + - Enter name, position, place + ? +4. Submit ? Backend stamps signature on PDF + ? +5. Envelope status updates: + - First signature ? EnvelopePartlySigned (green) + - Last signature ? EnvelopeCompletelySigned (green) + ? +6. Final emails sent (if configured): + - To creator: "All receivers signed" + - To receivers: "Envelope completed, download PDF" +``` + +--- + +## Missing Features in ReceiverUI (To Implement) + +### High Priority +1. ? **Envelope list grid** (`/sender`) with status colors +2. ? **Master-detail grids** (receivers/history) +3. ? **Create/Edit envelope form** (`/sender/envelope/{id}`) +4. ? **Envelope settings popup/stepper** (title, type, options) +5. ? **Document upload** (drag & drop, single PDF) +6. ? **Receiver management** (add/edit/delete with auto-complete) +7. ? **Signature field editor** (PDF.js + draggable overlays) +8. ? **Send envelope** (validation + API call) + +### Medium Priority +9. ? **Delete envelope** (with reason modal) +10. ? **Resend invitation** (per receiver) +11. ? **Show document** (PDF preview) +12. ? **Contact receiver** (mailto link) +13. ? **Export to Excel** (grid data) +14. ? **PDF merge tool** (multi-file select + merge) +15. ? **Grid layout persistence** (LocalStorage) + +### Low Priority +16. ? **2FA management** (admin panel) +17. ? **Reports tab** (statistics, admin only) +18. ? **Auto-refresh** (SignalR or polling) +19. ? **Ghost mode** (impersonate user, admin only) +20. ? **Log file export** (debug tool) + +--- + +## Data Flow Diagram + +``` +???????????????????????? +? frmMain ? ? Envelope list (Active/Completed tabs) +? (Dashboard) ? ? Status colors (Green/Orange/Red) +???????????????????????? ? Master-detail grids (Receivers/History) + ? ? Toolbar actions (Create/Edit/Delete/Send) + ? Click "Create" + ? +???????????????????????? +? frmEnvelopeMainData ? ? Popup: Title, Type, Settings +? (Settings Popup) ? ? Dropdowns: Language, Certification, Final Emails +???????????????????????? ? Checkboxes: Access Code, 2FA, Reminders + ? Click OK + ? +???????????????????????? +? frmEnvelopeEditor ? ? Document upload (drag & drop) +? (Main Editor) ? ? Receiver grid (email auto-complete) +???????????????????????? ? Merge PDFs button + ? Click "Edit Fields" + ? +???????????????????????? +? frmFieldEditor ? ? GdPicture PDF viewer +? (Signature Placer) ? ? Receiver selector (colored circles) +???????????????????????? ? Draggable signature boxes (1.77×1.96") + ? Click "Save" + ? +???????????????????????? +? Database ? ? DocReceiverElement (X, Y, Width, Height in INCHES) +? (TBSIG_ELEMENT) ? ? EnvelopeReceiver (Name, Email, Access Code, Phone) +???????????????????????? ? Envelope (Title, Status, Settings) + ? Click "Send Envelope" + ? +???????????????????????? +? Email Service ? ? Send invitation emails to receivers +? ? ? Template: Link + Access Code (if enabled) +???????????????????????? + ? + ? +???????????????????????? +? Receiver Web Page ? ? PDF.js viewer with signature buttons +? (EnvelopeReceiverPage)? ? Click button ? Signature popup (draw/type/image) +???????????????????????? ? Submit ? API stamps signature on PDF + ? + ? +???????????????????????? +? Database Update ? ? EnvelopeHistory (Signed, Timestamp) +? ? ? Envelope Status ? PartlySigned / CompletelySigned +???????????????????????? + ? All signed? + ? +???????????????????????? +? Final Email Service ? ? Send "Completed" email to creator/receivers +? ? ? Attach signed PDF +???????????????????????? +``` + +--- + +## Key Takeaways for Migration + +1. **Tab-based layout** ? Single grid with status filter dropdown +2. **Status colors** ? CSS classes or inline styles +3. **Master-detail grids** ? Expandable rows or modal dialogs +4. **Popup settings form** ? Inline form or stepper UI +5. **GdPicture PDF viewer** ? PDF.js with canvas overlay +6. **Signature field dragging** ? HTML5 drag & drop + absolute positioning +7. **Coordinate system** ? **ALWAYS INCHES** in database, convert to/from pixels for UI +8. **Receiver colors** ? CSS variables or inline styles +9. **Auto-complete emails** ? DevExpress TagBox or HTML5 datalist +10. **PDF merge** ? Server-side (iText7) or client-side (PDF-lib.js) + +--- + +**Last Updated:** Session 20 (Form Application Analysis)