# 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)