🔍 Code Extractor

function get_approval_cycle

Maturity: 62

Retrieves detailed information about an approval cycle by its UID, with optional inclusion of comments and associated document details.

File:
/tf/active/vicechatdev/CDocs/controllers/approval_controller.py
Lines:
195 - 284
Complexity:
complex

Purpose

This function fetches comprehensive approval cycle data from a document management system. It supports flexible data retrieval by allowing callers to optionally include approval comments and document metadata. The function handles complex relationships between approval cycles, document versions, and controlled documents, with fallback mechanisms for data retrieval. It's designed for use in document approval workflows where detailed approval status and history need to be displayed or processed.

Source Code

def get_approval_cycle(approval_uid: str, include_comments: bool = False, include_document: bool = False) -> Dict[str, Any]:
    """
    Get detailed information about a approval cycle.
    
    Args:
        approval_uid: UID of the approval cycle
        include_comments: Whether to include approval comments
        include_document: Whether to include document details
        
    Returns:
        Dictionary with approval cycle information
    """
    try:
        # Get ApprovalCycle instance
        from CDocs.models.approval import ApprovalCycle
        approval_cycle = ApprovalCycle(uid=approval_uid)
        
        if not approval_cycle:
            raise ResourceNotFoundError(f"Approval cycle not found: {approval_uid}")
            
        # Get basic approval data
        result = approval_cycle.to_dict()
        result['on_version'] = approval_cycle.document_version_number
        
        # Add document information if requested
        if include_document:
            # First get the document version this approval is for
            document_version_uid = approval_cycle.document_version_uid
            
            if document_version_uid:
                from CDocs.models.document import DocumentVersion, ControlledDocument
                doc_version = DocumentVersion(uid=document_version_uid)
                
                # Now get the document from the version
                if doc_version and doc_version.document:
                    document = doc_version.document
                    result['document'] = {
                        'uid': document.uid,
                        'doc_number': document.doc_number,
                        'title': document.title,
                        'department': document.department,
                        'status': document.status,
                        'doc_type': document.doc_type,
                        'revision': doc_version.version_number
                    }
                    # Store document_uid for use elsewhere
                    result['document_uid'] = document.uid
            
            # Fallback if we couldn't get the document through normal relationships
            if 'document' not in result:
                # Try to find the document directly from the database
                from CDocs import db
                doc_query = """
                MATCH (d:ControlledDocument)-[:HAS_VERSION]->(v:DocumentVersion)<-[:FOR_APPROVE]-(r:ApprovalCycle)
                WHERE r.UID = $approval_uid
                RETURN d.UID as doc_uid, d.docNumber as doc_number, d.title as title
                LIMIT 1
                """
                doc_result = db.run_query(doc_query, {"approval_uid": approval_uid})
                
                if doc_result and doc_result[0].get('doc_uid'):
                    result['document'] = {
                        'uid': doc_result[0].get('doc_uid'),
                        'doc_number': doc_result[0].get('doc_number'),
                        'title': doc_result[0].get('title')
                    }
                    # Store document_uid for use elsewhere
                    result['document_uid'] = doc_result[0].get('doc_uid')
        
        # Add approver assignments if they exist
        approver_assignments = approval_cycle.get_approver_assignments()
        if approver_assignments:
            result['approver_assignments'] = [
                assignment.to_dict() for assignment in approver_assignments
            ]
        
        # Add comments if requested
        if include_comments:
            comments = approval_cycle.comments
            if comments:
                result['comments'] = [
                    comment.to_dict() for comment in comments
                ]
                
        return result
        
    except Exception as e:
        logger.error(f"Error retrieving approval cycle: {e}")
        logger.error(traceback.format_exc())
        raise BusinessRuleError(f"Failed to retrieve approval cycle: {e}")

Parameters

Name Type Default Kind
approval_uid str - positional_or_keyword
include_comments bool False positional_or_keyword
include_document bool False positional_or_keyword

Parameter Details

approval_uid: Unique identifier (UID) string for the approval cycle to retrieve. This is the primary key used to locate the specific approval cycle in the database.

include_comments: Boolean flag (default: False) that determines whether to include all approval comments associated with this approval cycle in the returned data. When True, adds a 'comments' array to the result containing comment dictionaries.

include_document: Boolean flag (default: False) that determines whether to include detailed information about the document being approved. When True, adds a 'document' object with metadata like doc_number, title, department, status, doc_type, and revision number. Uses fallback query if normal relationship traversal fails.

Return Value

Type: Dict[str, Any]

Returns a dictionary containing approval cycle information. Base structure includes all fields from ApprovalCycle.to_dict() plus 'on_version' (document version number). If include_document=True, adds 'document' dict with uid, doc_number, title, department, status, doc_type, revision, and 'document_uid' field. If include_comments=True, adds 'comments' list of comment dictionaries. Always includes 'approver_assignments' list if assignments exist. Raises ResourceNotFoundError if approval cycle not found, or BusinessRuleError for other failures.

Dependencies

  • CDocs.models.approval
  • CDocs.models.document
  • CDocs.controllers
  • CDocs.db
  • logging
  • traceback
  • typing

Required Imports

from typing import Dict, Any
import logging
import traceback
from CDocs.controllers import log_controller_action, ResourceNotFoundError, BusinessRuleError

Conditional/Optional Imports

These imports are only needed under specific conditions:

from CDocs.models.approval import ApprovalCycle

Condition: always required, imported inside function body

Required (conditional)
from CDocs.models.document import DocumentVersion, ControlledDocument

Condition: only when include_document=True

Optional
from CDocs import db

Condition: only when include_document=True and fallback query is needed

Optional

Usage Example

# Basic usage - get approval cycle without extras
approval_data = get_approval_cycle('approval-uid-12345')
print(f"Approval status: {approval_data.get('status')}")

# Get approval with comments
approval_with_comments = get_approval_cycle(
    approval_uid='approval-uid-12345',
    include_comments=True
)
for comment in approval_with_comments.get('comments', []):
    print(f"Comment: {comment.get('text')}")

# Get full approval details with document info
full_approval = get_approval_cycle(
    approval_uid='approval-uid-12345',
    include_comments=True,
    include_document=True
)
print(f"Document: {full_approval['document']['doc_number']}")
print(f"Title: {full_approval['document']['title']}")
print(f"Approvers: {len(full_approval.get('approver_assignments', []))}")

Best Practices

  • Always wrap calls in try-except blocks to handle ResourceNotFoundError and BusinessRuleError exceptions
  • Use include_comments and include_document flags judiciously as they add database queries and increase response size
  • Validate approval_uid format before calling to avoid unnecessary database queries
  • The function uses lazy imports for performance - models are only imported when needed
  • Be aware of the fallback mechanism for document retrieval - it uses a direct Cypher query if relationship traversal fails
  • Check for existence of optional keys ('document', 'comments', 'approver_assignments') before accessing them in the returned dictionary
  • The function is decorated with log_controller_action, so all calls are automatically logged for audit purposes
  • Consider caching results if the same approval cycle is queried multiple times, as the function performs multiple database operations

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function get_approval_cycle_v1 92.6% similar

    Retrieves an approval cycle by its unique identifier (UID) and optionally includes associated comments and document information.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function get_approval_v1 88.2% similar

    A convenience wrapper function that retrieves approval cycle details by delegating to get_approval_cycle with the same parameters.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function get_approval 87.8% similar

    Retrieves a specific approval cycle by its unique identifier (UID) with optional inclusion of associated document details and approval comments.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller.py
  • function get_document_approvals 86.1% similar

    Retrieves all approval cycles associated with a specific document, with optional filtering for active cycles only.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function get_document_approval_cycles 84.5% similar

    Retrieves all approval cycles associated with a specific document, with optional filtering for active cycles only.

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