Workflow: Contract Approval + Digital Signature
Modules involved: Contracts · Document Management · Workflow Automation · Proposals
Who uses it: Legal, Account manager, Sales manager, Clients
Typical duration: 1 day – 2 weeks (depends on number of approvers)
Overview
The complete signing flow for a contractual document: from drafting from a template, through multi-level internal approval, to sending for the client's digital signature and archiving the signed contract. Unsigned or expired contracts generate automatic reminders.
Flow Diagram
[CONTRACT TEMPLATE]
│ template library with merge fields
│ ↓ Create contract (manual / from proposal / from opportunity)
│
[CONTRACT — Draft]
│ fields: subject, client, type, value, start/end date
│ content: HTML with automatically populated merge fields
│
├── [INTERNAL APPROVAL — optional]
│ │ multi-level flow configured in Document Management
│ │ wh_approval_setting → approvers notified
│ │ approval status: pending → approved / rejected
│ │ ↓ Internally approved → sent to client
│
├── [SENT TO CLIENT]
│ │ email with unique link (hash URL) + PDF attached
│ │ client accesses portal with the received link
│
└── [CLIENT SIGNATURE]
│ Method A: Digital signature in portal
│ → signed = 1, signature = PNG file
│ → dmg_approval_detail_eids: IP, timestamp, name
│ Method B: Manual marking by agent
│ → marked_as_signed = 1
│
↓
[CONTRACT SIGNED ✓]
│ locked for editing
│ expiry alerts: isexpirynotified → email reminder
│
[EXPIRY / RENEWAL]
│ renew() → new contract with same clauses
│ signature: retained (renew_keep_signature) or reset
Step by Step
1. Templates and Contract Types
Where: /admin/contracts/templates and /admin/contracts/types
Contract Types (`/admin/contracts/types`)
Classify contracts organizationally: NDA, Master Agreement, Service Agreement, Addendum, etc.
Each type can have a default content template.
Templates (`/admin/contracts/templates`)
Pre-drafted HTML documents with merge fields that are automatically populated when the contract is created:
| Merge field | Value |
|---|---|
{client_name} |
Client name |
{client_email} |
Client email |
{client_phone} |
Client phone |
{contract_subject} |
Contract subject |
{contract_value} |
Contract value |
{contract_nr} |
Contract number |
{datestart} |
Start date |
{dateend} |
Expiry date |
{staff_name} |
Responsible agent |
{current_date} |
Current date |
2. Creating the Contract
Where: /admin/contracts
Creation sources:
- From accepted proposal → Create Contract button carries over the client and value
- From opportunity → via
Contracts_opportunity_model - Directly →
/admin/contracts→ Add Contract - Vendor Documents →
/admin/contracts_vendor(separate flow for vendors)
Key fields (tblcontracts):
| Field | Notes |
|---|---|
subject |
Contract title |
client |
Associated client (required) |
contract_type |
Type (NDA, services, etc.) |
datestart / dateend |
Validity period |
contract_value |
Monetary value |
nr |
Contract number (manual or auto) |
content |
HTML content of the contract |
project_id |
Associated project (optional) |
not_visible_to_client |
Whether hidden in the client portal |
hash |
Unique 32-character token for the signing URL |
At creation: signed = 0, marked_as_signed = 0, isexpirynotified = 0
3. Internal Approval (optional, via Document Management)
Where: /admin/document_management
If the organization requires internal review before sending to the client, the contract can be submitted to an approval flow configured in Document Management.
Flow configuration (dmg_approval_setting):
| Field | Notes |
|---|---|
notification_recipient |
JSON with approvers (staff IDs, departments) |
number_day_approval |
Approval deadline in days |
choose_when_approving |
Whether the approver can choose the action |
departments / job_positions |
Restrictions on who can approve |
Approval process (dmg_approval_details):
| Field | Values |
|---|---|
approve |
pending → approved / rejected |
staff_approve |
Approver's ID |
date |
Approval timestamp |
note |
Approver's comment |
Outcomes:
- Approved → contract is ready to send to the client
- Rejected → returned to the drafter with a note; edit + resubmit
4. Sending to the Client
Where: From the open contract → Send button
What happens:
- Email generated from the
contract_send_to_customertemplate with populated merge fields - If
document_attachment_on_email = 1→ the contract PDF is attached to the email - Email contains a unique link:
https://company.com/contract/{hash}— each contract has a distinct hash - Client accesses the link without authentication (hash = implicit authentication)
5. Client's Digital Signature
Where: Client portal (URL with unique hash)
Method A — Digital Signature:
- Client reads the contract in the browser (HTML or PDF)
- Draws their signature in the dedicated field (touchscreen/mouse canvas)
- Clicks Accept & Sign
- The system records in
dmg_approval_detail_eids:
| Field | Value |
|---|---|
firstname / lastname |
Signer's name |
email |
Signer's email |
ip_address |
IP address from which it was signed |
date_of_signing |
Exact signing timestamp |
approve |
signed |
- On the contract in the CRM:
signed = 1,signature = {filename.png}(signature image) - Automatic notification sent to the responsible agent: "Contract X has been signed by the client"
Method B — Manual Marking:
The agent marks the contract as manually signed (e.g. received the physically signed contract):
- Mark as Signed button →
marked_as_signed = 1 - Does not generate a digital signature file
Editing lock after signing:
If signed = 1 OR marked_as_signed = 1 → contract fields are locked and can no longer be modified. Any changes require an addendum (new contract or amendment).
6. Monitoring and Contract Expiry
Expiry reminders:
The system checks dateend daily on active contracts:
- If the deadline is approaching → email
contract_expiration_reminder_to_customersent to the client isexpirynotified = 1set after sending (to avoid re-sending)
Renewal (renew()):
- A new contract is created with the same clauses, start date = current day
- The
renew_keep_signatureoption:1→ signature is retained on the new contract0→ signature is reset:signed = 0,marked_as_signed = 0,signature = null
Client portal visibility:
- If
not_visible_to_client = 0→ the client sees the contract in the portal - The client can download the PDF and view the signing status
Contract Types in CRMConnect
| Type | URL | Description |
|---|---|---|
| Client Documents | /admin/contracts |
Contracts with clients |
| Vendor Documents | /admin/contracts_vendor |
Contracts with vendors |
| Opportunity Documents | /admin/contracts_opportunity |
Attached to opportunities |
Each type has its own model but the signing structure is identical.
Workflow Automation — Useful Automations
Combined with the Workflow Automation module, you can automate:
Trigger: Contract signed (signed = 1)
→ Action: Create implementation Project
→ Action: Send welcome email to client
→ Action: Notify delivery team
Trigger: dateend − 30 days
→ Action: Task "Contact client for renewal" → responsible agent
→ Action: Reminder email to client
Trigger: Contract rejected at internal approval
→ Action: Notify drafter + note with rejection reason
What Is Created Automatically
| Event | Created automatically |
|---|---|
| Contract created from proposal | Client and value carried over; hash generated |
| Internal approval initiated | Notifications sent to approvers from configuration |
| Contract sent to client | Email with hash link + PDF (if enabled) |
| Client signs digitally | signed=1; PNG signature file; dmg_approval_detail_eids log |
| Contract signed | Agent notification; activity log on client record |
| Expiry date approaching | Client reminder email; isexpirynotified=1 |
Points Where the Flow Can Block
| Problem | Likely cause | Solution |
|---|---|---|
| Client cannot open link | Incorrect hash or expired session | Resend the contract — a new email is generated with the same hash |
| Cannot edit signed contract | signed=1 or marked_as_signed=1 blocks editing |
Create an addendum (new contract) or manually reset in DB |
| Merge fields not replaced | Missing fields on client record (e.g. empty email) | Complete the client record before creating the contract |
| Client does not receive the email | SMTP not set or invalid client email | Check SMTP and email address in the client record |
| Expiry reminders resent daily | isexpirynotified not set |
Check expiry verification function (CRON active?) |
| Internal approval blocked | Approver did not receive notification | Check wh_approval_setting and approver's email |
Reports and Visibility
- Contract list —
/admin/contracts— filter by type, client, signed status, period - Expired contracts — filter by
dateend< today - Client activity — client record → Contracts tab — complete history
Modules Involved — Detailed Documentation
Use Document Management's approval workflow before sending any contract for signature — route the draft through legal review first so the signed version has a complete internal approval audit trail that predates the signature.
Digital signature confirmation links sent to clients expire after a configurable period. If a client reports the link is expired, regenerate and resend from the contract record — the original draft terms are preserved.