function clone_document_v1
Clones an existing controlled document by creating a new document with optional content copying, metadata inheritance, and audit trail logging.
/tf/active/vicechatdev/CDocs single class/controllers/document_controller.py
2112 - 2240
complex
Purpose
This function enables document duplication within a controlled document management system. It creates a new document based on an existing source document, optionally copying its content and version history. The function supports customization of the cloned document's title, type, and department, while maintaining audit trails and enforcing permissions. It handles the complete workflow including document creation, content transfer, version management, and error recovery with automatic cleanup on failure.
Source Code
def clone_document(
user: DocUser,
document_uid: str,
new_title: Optional[str] = None,
doc_type: Optional[str] = None,
department: Optional[str] = None,
include_content: bool = True,
clone_as_new_revision: bool = False
) -> Dict[str, Any]:
"""
Clone an existing document as a new document or new revision.
Args:
user: User cloning the document
document_uid: UID of the source document
new_title: Title for the cloned document (defaults to "Copy of [original]")
doc_type: Document type code for the new document (defaults to same as original)
department: Department code for the new document (defaults to same as original)
include_content: Whether to include the content of the original document
clone_as_new_revision: Whether to create as a new revision of the same document
Returns:
Dictionary with cloned document details
"""
try:
# Get the source document
source_document = ControlledDocument(uid=document_uid)
if not source_document:
raise ResourceNotFoundError(f"Document {document_uid} not found")
# Get current version
current_version = source_document.current_version
if not current_version and include_content:
raise BusinessRuleError("Document has no current version to clone")
# Use original title if none provided
if not new_title:
new_title = f"Copy of {source_document.title}"
# Use original document type and department if none provided
if not doc_type:
doc_type = source_document.doc_type
if not department:
department = source_document.department
# Create new document
new_document = ControlledDocument.create(
title=new_title,
doc_type=doc_type,
department=department,
owner=user,
properties={
"description": f"Cloned from {source_document.doc_number}: {source_document.title}",
"status": "DRAFT",
"revision" : "0.0"
}
)
if not new_document:
raise BusinessRuleError("Failed to create new document")
# Copy content if requested
if include_content and current_version:
# Download content from source document
content_result = download_document_version(
user=user,
document_uid=document_uid,
version_uid=current_version.uid if current_version else None
)
if not content_result or 'content' not in content_result:
raise BusinessRuleError("Failed to download source document content")
# Create initial version for new document
file_content = content_result['content']
file_name = content_result.get('file_name', 'document.pdf')
# Create version for new document
version_result = create_document_version(
user=user,
document_uid=new_document.uid,
file_content=file_content,
file_name=file_name,
comment="Initial version created from cloned document"
)
if not version_result or 'UID' not in version_result:
# If version creation fails, delete the new document to clean up
db.delete_node(new_document.uid, cascade=True)
raise BusinessRuleError("Failed to create document version")
# Log cloning event
audit_trail.log_document_lifecycle_event(
event_type="DOCUMENT_CLONED",
user=user,
document_uid=new_document.uid,
details={
"source_document_uid": document_uid,
"source_document_number": source_document.doc_number,
"include_content": include_content
}
)
# Return success with new document details
return {
"success": True,
"message": "Document cloned successfully",
"document": {
"uid": new_document.uid,
"doc_number": new_document.doc_number,
"title": new_document.title,
"version_uid" : version_result.get('UID') if version_result else None
}
}
except (ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError) as e:
logger.error(f"Error cloning document: {str(e)}")
return {
"success": False,
"message": str(e)
}
except Exception as e:
logger.error(f"Unexpected error cloning document: {str(e)}")
logger.error(traceback.format_exc())
return {
"success": False,
"message": f"An unexpected error occurred: {str(e)}"
}
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
DocUser | - | positional_or_keyword |
document_uid |
str | - | positional_or_keyword |
new_title |
Optional[str] | None | positional_or_keyword |
doc_type |
Optional[str] | None | positional_or_keyword |
department |
Optional[str] | None | positional_or_keyword |
include_content |
bool | True | positional_or_keyword |
clone_as_new_revision |
bool | False | positional_or_keyword |
Parameter Details
user: DocUser object representing the authenticated user performing the clone operation. Must have CREATE_DOCUMENT permission as enforced by the decorator.
document_uid: String containing the unique identifier (UID) of the source document to be cloned. Must reference an existing document in the system.
new_title: Optional string for the cloned document's title. If None, defaults to 'Copy of [original title]'. Used to distinguish the clone from the original.
doc_type: Optional string code representing the document type classification for the new document. If None, inherits the doc_type from the source document.
department: Optional string code representing the department ownership for the new document. If None, inherits the department from the source document.
include_content: Boolean flag (default True) indicating whether to copy the actual file content from the source document's current version to the new document. If False, only metadata is cloned.
clone_as_new_revision: Boolean flag (default False) intended to create the clone as a new revision of the same document rather than a separate document. Note: This parameter is declared but not currently implemented in the function logic.
Return Value
Type: Dict[str, Any]
Returns a dictionary with keys: 'success' (bool indicating operation success), 'message' (str with status/error message), and optionally 'document' (dict containing 'uid', 'doc_number', 'title', and 'version_uid' of the cloned document). On failure, only 'success' and 'message' keys are present.
Dependencies
logginguuidostempfiletypingdatetimeiopanelshutiltracebackjsonreCDocsconfigrandom
Required Imports
from typing import Dict, Any, Optional
import traceback
import logging
from CDocs import db
from CDocs.config import settings
from CDocs.models.document import ControlledDocument
from CDocs.models.user_extensions import DocUser
from CDocs.utils import audit_trail
from CDocs.controllers import require_permission, log_controller_action, transaction
from CDocs.controllers import ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError
from CDocs.controllers.document_controller import download_document_version, create_document_version
Usage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers.document_controller import clone_document
# Get authenticated user
user = DocUser.get_by_username('john.doe')
# Clone a document with default settings (includes content)
result = clone_document(
user=user,
document_uid='doc-12345-abcde'
)
if result['success']:
print(f"Document cloned successfully: {result['document']['doc_number']}")
print(f"New UID: {result['document']['uid']}")
else:
print(f"Clone failed: {result['message']}")
# Clone with custom title and without content
result = clone_document(
user=user,
document_uid='doc-12345-abcde',
new_title='Modified Copy of Original',
doc_type='PROCEDURE',
department='ENGINEERING',
include_content=False
)
# Access cloned document details
if result['success']:
cloned_uid = result['document']['uid']
cloned_doc_number = result['document']['doc_number']
Best Practices
- Always check the 'success' key in the returned dictionary before accessing the 'document' key to avoid KeyError exceptions
- The function is decorated with @transaction, so database operations are automatically rolled back on failure
- The function is decorated with @require_permission('CREATE_DOCUMENT'), so ensure the user has appropriate permissions before calling
- When include_content=True, ensure the source document has a current version, otherwise a BusinessRuleError will be raised
- The function automatically cleans up (deletes) the newly created document if version creation fails, preventing orphaned documents
- The clone_as_new_revision parameter is currently not implemented in the function logic despite being declared
- Audit trail events are automatically logged for successful cloning operations with source document details
- Use specific exception handling for ResourceNotFoundError, ValidationError, PermissionError, and BusinessRuleError for granular error management
- The function uses download_document_version and create_document_version helper functions which must be available in the same module
- Default title format 'Copy of [original]' helps users identify cloned documents; consider providing custom titles for clarity
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function clone_document 94.6% similar
-
function clone_document_v2 93.3% similar
-
function create_document_version_v4 70.0% similar
-
function create_document_version_v3 68.4% similar
-
function create_document_version_v5 67.6% similar