function publish_document_v2
Publishes a controlled document by changing its status to PUBLISHED or EFFECTIVE based on the effective date, with audit logging and notifications.
/tf/active/vicechatdev/CDocs copy/controllers/document_controller.py
960 - 1059
moderate
Purpose
This function manages the document publication workflow in a controlled document management system. It validates that a document is in an appropriate state for publication (DRAFT, IN_REVIEW, or APPROVED), sets the effective and expiry dates, updates the document status, logs the lifecycle event for audit purposes, and sends notifications to relevant stakeholders. The function determines whether to set status to EFFECTIVE (if effective date is now or past) or PUBLISHED (if effective date is in the future).
Source Code
def publish_document(
user: DocUser,
document_uid: str,
effective_date: Optional[datetime] = None,
expiry_date: Optional[datetime] = None,
publish_comment: Optional[str] = None
) -> Dict[str, Any]:
"""
Publish a document, changing its status to PUBLISHED or EFFECTIVE.
Args:
user: User publishing the document
document_uid: UID of document to publish
effective_date: Optional date when document becomes effective
expiry_date: Optional expiry date
publish_comment: Optional comment about publishing
Returns:
Dictionary with publish status
Raises:
ResourceNotFoundError: If document not found
ValidationError: If validation fails
PermissionError: If user doesn't have permission
BusinessRuleError: If publishing is not allowed
"""
try:
# Get document instance
document = ControlledDocument(uid=document_uid)
if not document:
raise ResourceNotFoundError(f"Document not found: {document_uid}")
# Check if document can be published
if document.status not in ["DRAFT", "IN_REVIEW", "APPROVED"]:
raise BusinessRuleError(f"Cannot publish document with status {document.status}")
# Check if document has a current version
if not document.current_version:
raise BusinessRuleError("Cannot publish document without a current version")
# Set effective date if not provided
if not effective_date:
effective_date = datetime.now()
# Determine status based on effective date
new_status = "EFFECTIVE" if effective_date <= datetime.now() else "PUBLISHED"
# Store previous status for audit
previous_status = document.status
# Update document
document.status = new_status
document.effective_date = effective_date
document.expiry_date = expiry_date
document.modified_date = datetime.now()
# Add publish info to metadata
document.metadata = document.metadata or {}
document.metadata["published_by"] = user.username
document.metadata["published_date"] = datetime.now().isoformat()
document.metadata["publish_comment"] = publish_comment
# Save changes
document.save()
# Log publish event
audit_trail.log_document_lifecycle_event(
event_type="DOCUMENT_PUBLISHED",
user=user,
document_uid=document_uid,
details={
"previous_status": previous_status,
"new_status": new_status,
"effective_date": effective_date.isoformat() if effective_date else None,
"expiry_date": expiry_date.isoformat() if expiry_date else None,
"comment": publish_comment
}
)
# Notify about publication
notifications.notify_document_update(document, "DOCUMENT_STATUS_CHANGED")
return {
"success": True,
"document_uid": document_uid,
"document_number": document.doc_number,
"title": document.title,
"previous_status": previous_status,
"new_status": new_status,
"effective_date": effective_date,
"expiry_date": expiry_date,
"message": f"Document {document.doc_number} published successfully"
}
except (ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError) as e:
# Re-raise known errors
raise
except Exception as e:
logger.error(f"Error publishing document {document_uid}: {e}")
raise BusinessRuleError(f"Failed to publish document: {e}")
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
DocUser | - | positional_or_keyword |
document_uid |
str | - | positional_or_keyword |
effective_date |
Optional[datetime] | None | positional_or_keyword |
expiry_date |
Optional[datetime] | None | positional_or_keyword |
publish_comment |
Optional[str] | None | positional_or_keyword |
Parameter Details
user: DocUser object representing the authenticated user performing the publish action. Used for permission checks, audit logging, and tracking who published the document.
document_uid: String containing the unique identifier (UID) of the document to be published. Must correspond to an existing ControlledDocument in the system.
effective_date: Optional datetime object specifying when the document becomes effective. If not provided, defaults to the current datetime. Determines whether document status becomes EFFECTIVE (date <= now) or PUBLISHED (date > now).
expiry_date: Optional datetime object specifying when the document expires and is no longer valid. Can be None for documents without expiration.
publish_comment: Optional string containing a comment or note about the publication action. Stored in document metadata for audit trail purposes.
Return Value
Type: Dict[str, Any]
Returns a dictionary containing publication results with keys: 'success' (bool, always True on successful execution), 'document_uid' (str, the published document's UID), 'document_number' (str, the document's number), 'title' (str, document title), 'previous_status' (str, status before publication), 'new_status' (str, PUBLISHED or EFFECTIVE), 'effective_date' (datetime, when document becomes effective), 'expiry_date' (datetime or None, when document expires), and 'message' (str, success message with document number).
Dependencies
loggingdatetimetypingpanelCDocs
Required Imports
from typing import Dict, Any, Optional
from datetime import datetime
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, transaction
from CDocs.controllers import ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError
import logging
Usage Example
from datetime import datetime, timedelta
from CDocs.models.user_extensions import DocUser
from your_module import publish_document
# Get authenticated user
user = DocUser.get_by_username('john.doe')
# Publish document immediately
result = publish_document(
user=user,
document_uid='doc-12345-abcde',
publish_comment='Initial release of safety procedures'
)
print(f"Published: {result['document_number']} - Status: {result['new_status']}")
# Publish document with future effective date
future_date = datetime.now() + timedelta(days=30)
expiry = datetime.now() + timedelta(days=365)
result = publish_document(
user=user,
document_uid='doc-67890-fghij',
effective_date=future_date,
expiry_date=expiry,
publish_comment='Scheduled for next quarter release'
)
print(f"Status: {result['new_status']}, Effective: {result['effective_date']}")
Best Practices
- Always ensure the user has PUBLISH_DOCUMENT permission before calling this function (handled by decorator)
- Wrap calls in try-except blocks to handle ResourceNotFoundError, ValidationError, PermissionError, and BusinessRuleError exceptions
- Provide meaningful publish_comment values for audit trail and compliance purposes
- Verify document is in DRAFT, IN_REVIEW, or APPROVED status before attempting to publish
- Set appropriate effective_date and expiry_date values based on business requirements
- The function automatically determines EFFECTIVE vs PUBLISHED status based on effective_date comparison with current time
- Function is decorated with @transaction, so database changes are atomic and will rollback on error
- Function is decorated with @log_controller_action for automatic action logging
- Document must have a current_version set before it can be published
- Previous status is preserved in audit logs for compliance and traceability
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function publish_document_v1 92.5% similar
-
function publish_document 91.3% similar
-
function publish_document_v3 91.2% similar
-
function update_document_v1 72.9% similar
-
function update_document_v3 72.3% similar