function process_document_signing_v1
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/controllers/filecloud_controller.py
1205 - 1301
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 controller action for initiating electronic signature workflows in a document management system integrated with FileCloud.
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.gen_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 name in notifications.
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
loggingosjsonuuidtempfiletypingtimeCDocs.dbCDocs.config.settingsCDocs.config.permissionsCDocs.models.documentCDocs.models.user_extensionsCDocs.utils.document_processorCDocs.utils.audit_trailCDocs.utils.notificationsCDocs.controllersCDocs.utils.metadata_catalogCDocs.utils.FC_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, notifications
from CDocs.controllers import require_permission, log_controller_action, ResourceNotFoundError, FileCloudError
Conditional/Optional Imports
These imports are only needed under specific conditions:
import logging
Condition: Required for logger.error() and logger.warning() calls throughout the function
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'
}
]
# Initiate signing process
try:
result = process_document_signing(
user=user,
document_uid='DOC-12345-ABCD',
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 verified in calling code)
- Always wrap calls in try-except blocks to handle ResourceNotFoundError, PermissionError, and FileCloudError exceptions
- Validate signers list is not empty and each signer has required 'email' field before calling
- The function logs audit events automatically; do not duplicate audit logging in calling code
- Email notifications are sent asynchronously; failures are logged but do not stop the signing process
- The signing_url returned should be provided to signers through the automated email or alternative communication channel
- Monitor logger output for warnings about failed email notifications to signers
- Ensure FileCloud API endpoint 'core/createsigningrequest' is compatible with your FileCloud version
- The function expects get_filecloud_client() and get_filecloud_document_path() helper functions to be available in scope
- Consider implementing retry logic in calling code for transient FileCloud API failures
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function process_document_signing 99.5% similar
-
function start_document_approval_workflow 66.5% similar
-
function set_document_permissions_in_filecloud 62.8% similar
-
function delete_document_from_filecloud 59.3% similar
-
function publish_document_v1 59.2% similar