🔍 Code Extractor

function archive_document_v1

Maturity: 73

Archives a controlled document by changing its status to ARCHIVED, ensuring a PDF version exists and logging the action with audit trail and notifications.

File:
/tf/active/vicechatdev/document_controller_backup.py
Lines:
1442 - 1542
Complexity:
moderate

Purpose

This function manages the document archiving workflow in a controlled document management system. It validates that documents can only be archived from PUBLISHED or EFFECTIVE status, ensures PDF versions exist for compliance, updates document metadata with archive information, logs the lifecycle event, and notifies stakeholders. It enforces business rules around document lifecycle management and maintains audit trails for regulatory compliance.

Source Code

def archive_document(
    user: DocUser,
    document_uid: str,
    archive_reason: str,
    archive_comment: Optional[str] = None
) -> Dict[str, Any]:
    """
    Archive a document, changing its status to ARCHIVED.
    Ensures the document is available in PDF format.
    
    Args:
        user: User archiving the document
        document_uid: UID of document to archive
        archive_reason: Reason for archiving
        archive_comment: Optional comment about archiving
        
    Returns:
        Dictionary with archive status
        
    Raises:
        ResourceNotFoundError: If document not found
        ValidationError: If validation fails
        PermissionError: If user doesn't have permission
        BusinessRuleError: If archiving 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 archived
        if document.status not in [STATUS_PUBLISHED, STATUS_EFFECTIVE]:
            raise BusinessRuleError(f"Cannot archive document with status {document.status}")
            
        # Validate archive reason
        if not archive_reason:
            raise ValidationError("Archive reason is required")
            
        # Check if current version has a PDF version
        current_version = document.current_version
        if not current_version:
            raise BusinessRuleError("Document has no current version")
            
        if not current_version.pdf_file_path:
            raise BusinessRuleError("Document must have a PDF version before archiving")
            
        # Store previous status for audit
        previous_status = document.status
        
        # Update document
        document.status = STATUS_ARCHIVED
        
        # Add archive info to metadata
        document_metadata = {
            'archived_by': user.username,
            'archived_date': datetime.now().isoformat(),
            'archive_reason': archive_reason,
            'archive_comment': archive_comment
        }
        
        # Update document in database
        db.update_node(document_uid, {
            'status': STATUS_ARCHIVED,
            'modifiedDate': datetime.now(),
            'metadata': document_metadata
        })
        
        # Log archive event
        audit_trail.log_document_lifecycle_event(
            event_type="DOCUMENT_ARCHIVED",
            user=user,
            document_uid=document_uid,
            details={
                "previous_status": previous_status,
                "archive_reason": archive_reason,
                "archive_comment": archive_comment
            }
        )
        
        # Notify about archiving
        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": STATUS_ARCHIVED,
            "archive_reason": archive_reason,
            "archive_comment": archive_comment,
            "message": f"Document {document.doc_number} archived successfully"
        }
        
    except (ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError) as e:
        # Re-raise known errors
        raise
    except Exception as e:
        logger.error(f"Error archiving document {document_uid}: {e}")
        raise BusinessRuleError(f"Failed to archive document: {e}")

Parameters

Name Type Default Kind
user DocUser - positional_or_keyword
document_uid str - positional_or_keyword
archive_reason str - positional_or_keyword
archive_comment Optional[str] None positional_or_keyword

Parameter Details

user: DocUser object representing the authenticated user performing the archive action. Used for permission checks, audit logging, and tracking who archived the document.

document_uid: String containing the unique identifier (UID) of the document to be archived. Must correspond to an existing ControlledDocument in the database.

archive_reason: Required string explaining why the document is being archived. Cannot be empty. Used for audit trail and compliance documentation.

archive_comment: Optional string providing additional context or notes about the archiving decision. Can be None if no additional comments are needed.

Return Value

Type: Dict[str, Any]

Returns a dictionary containing archive operation results with keys: 'success' (bool indicating operation success), 'document_uid' (str), 'document_number' (str), 'title' (str), 'previous_status' (str showing status before archiving), 'new_status' (str, always STATUS_ARCHIVED), 'archive_reason' (str), 'archive_comment' (str or None), and 'message' (str with success message). On error, raises one of the documented exceptions instead of returning.

Dependencies

  • logging
  • uuid
  • os
  • tempfile
  • typing
  • datetime
  • io
  • panel
  • shutil
  • traceback

Required Imports

from typing import Dict, Any, Optional
from datetime import datetime
from CDocs import db
from CDocs.models.document import ControlledDocument
from CDocs.models.user_extensions import DocUser
from CDocs.utils import notifications
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.models.document_status import STATUS_PUBLISHED, STATUS_EFFECTIVE, STATUS_ARCHIVED
import logging

Usage Example

from CDocs.models.user_extensions import DocUser
from CDocs.controllers.document_controller import archive_document
from CDocs.controllers import ResourceNotFoundError, BusinessRuleError

# Assuming user and document_uid are already available
user = DocUser(username='john.doe')
document_uid = 'doc-12345-abcde'

try:
    result = archive_document(
        user=user,
        document_uid=document_uid,
        archive_reason='Document superseded by newer version',
        archive_comment='Replaced by document v2.0 effective 2024-01-01'
    )
    
    if result['success']:
        print(f"Document {result['document_number']} archived successfully")
        print(f"Previous status: {result['previous_status']}")
        print(f"Archive reason: {result['archive_reason']}")
except ResourceNotFoundError as e:
    print(f"Document not found: {e}")
except BusinessRuleError as e:
    print(f"Cannot archive document: {e}")
except PermissionError as e:
    print(f"Permission denied: {e}")

Best Practices

  • Always ensure the document is in PUBLISHED or EFFECTIVE status before attempting to archive
  • Provide meaningful archive_reason values for audit compliance and future reference
  • Handle all documented exceptions (ResourceNotFoundError, ValidationError, PermissionError, BusinessRuleError) in calling code
  • Verify that documents have PDF versions before archiving to meet compliance requirements
  • The function is decorated with @transaction, so database changes are atomic and will rollback on error
  • The function is decorated with @require_permission(['ARCHIVE_DOCUMENT'], 'document_uid'), so permission checks are automatic
  • The function is decorated with @log_controller_action('archive_document'), so all calls are automatically logged
  • Archive operations trigger notifications to stakeholders, so ensure notification system is properly configured
  • Archive metadata is stored in the document's metadata field with timestamp, user, reason, and comment
  • The function validates that a current version with PDF exists before allowing archiving

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function archive_document 96.7% similar

    Archives a controlled document by changing its status and all versions to ARCHIVED, moving the published PDF to an archived location with metadata, and logging the archival event.

    From: /tf/active/vicechatdev/CDocs/controllers/document_controller.py
  • function delete_document 71.8% similar

    Deletes a controlled document from the system with permission checks, status validation, and audit logging.

    From: /tf/active/vicechatdev/document_controller_backup.py
  • function publish_document 70.7% similar

    Publishes an approved controlled document by converting it to PDF with signatures and audit trail, uploading to FileCloud, and updating the document status to PUBLISHED.

    From: /tf/active/vicechatdev/document_controller_backup.py
  • function publish_document_v1 69.8% similar

    Publishes a controlled document by incrementing its version to the next major revision, converting it to a signed PDF, and updating its status to PUBLISHED.

    From: /tf/active/vicechatdev/CDocs/controllers/document_controller.py
  • function update_document_v1 64.5% similar

    Updates a controlled document's properties (title, description, status, owner, metadata) with validation, audit logging, and special handling for status transitions that require PDF publishing or training resets.

    From: /tf/active/vicechatdev/CDocs/controllers/document_controller.py
← Back to Browse