function process_document_signing
Initiates a document signing workflow through FileCloud's Signority integration, creating a signing request for specified signers and sending notification emails.
/tf/active/vicechatdev/CDocs single class/controllers/filecloud_controller.py
953 - 1049
complex
Purpose
This function orchestrates the complete document signing process by: (1) validating document existence and user permissions, (2) creating a signing request in FileCloud's Signority system, (3) logging audit trail events, and (4) notifying all signers via email. It serves as the primary entry point for initiating electronic signature workflows in a controlled document management system.
Source Code
def process_document_signing(
user: DocUser,
document_uid: str,
signers: List[Dict[str, Any]]
) -> Dict[str, Any]:
"""
Process document signing through FileCloud's Signority integration.
Args:
user: User initiating the signing process
document_uid: UID of the document to sign
signers: List of signers with their details (name, email, role)
Returns:
Dictionary with signing process information
Raises:
ResourceNotFoundError: If document not found
PermissionError: If user doesn't have permission
FileCloudError: If signing process fails
"""
# Get document instance
doc = ControlledDocument(uid=document_uid)
if not doc:
raise ResourceNotFoundError(f"Document not found: {document_uid}")
# Get file path
file_path = get_filecloud_document_path(doc)
try:
client = get_filecloud_client()
# Create signing request
signing_data = {
"filepath": file_path,
"title": f"Signing request for {doc.doc_number} - {doc.title}",
"message": f"Please sign the document: {doc.doc_number} - {doc.title}",
"signers": signers
}
# Use the FileCloud API to create a signing request
# This endpoint may vary based on FileCloud version and configuration
result = client._api_request("core/createsigningrequest", signing_data)
if not isinstance(result, dict) or not result.get('success', False):
error_msg = result.get('message', 'Unknown error') if isinstance(result, dict) else str(result)
logger.error(f"Failed to create signing request in FileCloud: {error_msg}")
raise FileCloudError(f"Failed to create signing request: {error_msg}")
# Extract signing request information
signing_request_id = result.get('request_id')
signing_url = result.get('request_url')
# Log audit event
audit_trail.log_document_lifecycle_event(
event_type="DOCUMENT_SIGNING_REQUESTED",
user=user,
document_uid=document_uid,
details={
"file_path": file_path,
"signing_request_id": signing_request_id,
"signers": signers
}
)
# Notify signers (if email notification wasn't handled by FileCloud)
for signer in signers:
if 'email' in signer:
try:
notifications.send_email(
to_addresses=signer['email'],
subject=f"Document Signing Request: {doc.doc_number} - {doc.title}",
template_name="signing_request",
template_data={
"signer_name": signer.get('name', 'Signer'),
"doc_number": doc.doc_number,
"title": doc.title,
"requester": user.name,
"signing_url": signing_url,
"doc_details": f"Document Type: {doc.doc_type}, Department: {doc.department}"
}
)
except Exception as e:
logger.warning(f"Failed to send signing notification email to {signer['email']}: {e}")
return {
"success": True,
"document_uid": document_uid,
"file_path": file_path,
"signing_request_id": signing_request_id,
"signing_url": signing_url,
"signers": signers
}
except Exception as e:
logger.error(f"Error processing document signing in FileCloud: {e}")
raise FileCloudError(f"Error processing document signing: {e}")
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
DocUser | - | positional_or_keyword |
document_uid |
str | - | positional_or_keyword |
signers |
List[Dict[str, Any]] | - | positional_or_keyword |
Parameter Details
user: DocUser object representing the authenticated user initiating the signing process. Must have SIGN_DOCUMENT permission. Used for audit logging and as the requester in notification emails.
document_uid: String containing the unique identifier (UID) of the document to be signed. Must correspond to an existing ControlledDocument in the system. Used to retrieve document metadata and file path.
signers: List of dictionaries, where each dictionary contains signer information. Expected keys: 'name' (signer's full name), 'email' (signer's email address for notifications), 'role' (optional, signer's role in the signing process). Minimum one signer required. Each signer will receive a notification email with the signing URL.
Return Value
Type: Dict[str, Any]
Returns a dictionary with keys: 'success' (boolean, always True on successful execution), 'document_uid' (string, echoes input document UID), 'file_path' (string, FileCloud path to the document), 'signing_request_id' (string/int, unique identifier for the signing request in FileCloud), 'signing_url' (string, URL where signers can access the document for signing), 'signers' (list, echoes input signers list). On error, raises exceptions instead of returning.
Dependencies
loggingosjsonuuidtempfiletypingtimeCDocsFC_api
Required Imports
from typing import Dict, List, Any
from CDocs.models.document import ControlledDocument
from CDocs.models.user_extensions import DocUser
from CDocs.utils import audit_trail
from CDocs.utils import notifications
from CDocs.controllers import require_permission, log_controller_action, ResourceNotFoundError
from CDocs.controllers import FileCloudError
import logging
Conditional/Optional Imports
These imports are only needed under specific conditions:
from FC_api import FileCloudAPI
Condition: Required for FileCloud client instantiation via get_filecloud_client()
Required (conditional)from CDocs.utils.filecloud_integration import get_filecloud_client, get_filecloud_document_path
Condition: Required helper functions for FileCloud operations (assumed to exist based on usage)
Required (conditional)Usage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers.filecloud_controller import process_document_signing
# Get authenticated user
user = DocUser.query.filter_by(username='john.doe').first()
# Define signers
signers = [
{
'name': 'Jane Smith',
'email': 'jane.smith@example.com',
'role': 'Approver'
},
{
'name': 'Bob Johnson',
'email': 'bob.johnson@example.com',
'role': 'Reviewer'
}
]
# Process signing request
try:
result = process_document_signing(
user=user,
document_uid='DOC-12345-UUID',
signers=signers
)
print(f"Signing request created: {result['signing_request_id']}")
print(f"Signing URL: {result['signing_url']}")
except ResourceNotFoundError as e:
print(f"Document not found: {e}")
except FileCloudError as e:
print(f"FileCloud error: {e}")
Best Practices
- Ensure the user has SIGN_DOCUMENT permission before calling (enforced by decorator but should be checked in UI)
- Validate signer email addresses before passing to this function to avoid notification failures
- Handle all three exception types: ResourceNotFoundError, PermissionError, and FileCloudError
- The function logs warnings for email notification failures but continues execution - monitor logs for delivery issues
- Store the returned signing_request_id for tracking and status checking purposes
- The FileCloud API endpoint 'core/createsigningrequest' may vary by FileCloud version - verify compatibility
- Email notifications are sent even if FileCloud handles its own notifications - consider disabling duplicate notifications
- Audit trail events are logged automatically - ensure audit_trail system is properly configured
- The function expects signers list to have at least 'email' key; 'name' and 'role' are optional but recommended
- Consider implementing retry logic for transient FileCloud API failures
- The signing_url returned should be shared securely with signers
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function process_document_signing_v1 99.5% similar
-
function start_document_approval_workflow 66.8% similar
-
function set_document_permissions_in_filecloud 62.5% similar
-
function delete_document_from_filecloud 59.4% similar
-
function publish_document_v1 58.9% similar