🔍 Code Extractor

function notify_approval_v1

Maturity: 65

Sends approval notifications to designated approvers for a document version, supporting multiple notification types (requested, reminder, overdue, completed, rejected, signed) with email and in-app notifications.

File:
/tf/active/vicechatdev/CDocs single class/utils/notifications.py
Lines:
1125 - 1223
Complexity:
moderate

Purpose

This function orchestrates the notification process for document approval workflows. It retrieves document and version details from an approval instance, prepares notification content based on the notification type, and dispatches notifications to specified approvers or all approvers associated with the approval. It handles various approval lifecycle events including initial requests, reminders, overdue notices, completion, rejection, and document signing notifications. The function integrates with both in-app notification systems and email templates.

Source Code

def notify_approval(approval, 
                   notification_type: str,
                   step: Optional[str] = None,
                   approver_uids: Optional[List[str]] = None) -> List[str]:
    """
    Send approval notifications to approvers.
    
    Args:
        approval: Approval instance
        notification_type: Type of notification
        approver_uids: Optional specific approvers to notify (default: all)
        
    Returns:
        List of created notification UIDs
    """
    try:
        # Get document and version details
        version = approval.document_version
        if not version:
            logger.error(f"Could not find document version for approval {approval.uid}")
            return []
            
        document = version.document
        if not document:
            logger.error(f"Could not find document for approval {approval.uid}")
            return []
            
        # Get approvers to notify
        if approver_uids is None:
            approver_uids = approval.approver_uids
            
        if not approver_uids:
            logger.warning(f"No approvers to notify for approval {approval.uid}")
            return []
            
        # Prepare notification details
        details = {
            'approval_uid': approval.uid,
            'version_uid': version.uid,
            'doc_uid': document.uid,
            'doc_number': document.doc_number,
            'doc_type': document.doc_type,
            'title': document.title,
            'step': step,
            'version_number': version.version_number,
            'due_date': approval.due_date.strftime('%Y-%m-%d') if approval.due_date else None
        }
        
        # Create message based on notification type
        message = None
        if notification_type == 'APPROVAL_REQUESTED':
            message = f"Please approve {document.doc_number} - {document.title} (v{version.version_number})"
        elif notification_type == 'APPROVAL_REMINDER':
            message = f"Reminder: Your approval of {document.doc_number} (v{version.version_number}) is due soon"
        elif notification_type == 'APPROVAL_OVERDUE':
            message = f"Your approval of {document.doc_number} (v{version.version_number}) is overdue"
        elif notification_type == 'APPROVAL_COMPLETED':
            message = f"The approval process for {document.doc_number} (v{version.version_number}) has been completed"
        elif notification_type == 'APPROVAL_REJECTED':
            message = f"The approval for {document.doc_number} (v{version.version_number}) has been rejected"
        elif notification_type == 'DOCUMENT_SIGNED':
            message = f"Document {document.doc_number} (v{version.version_number}) has been signed"
            
        # Determine email template based on notification type
        email_template = None
        if notification_type == 'APPROVAL_REQUESTED':
            email_template = 'approval_requested'
        elif notification_type == 'APPROVAL_REMINDER':
            email_template = 'approval_reminder'
        elif notification_type == 'APPROVAL_OVERDUE':
            email_template = 'approval_overdue'
        elif notification_type == 'APPROVAL_COMPLETED':
            email_template = 'approval_completed'
        elif notification_type == 'APPROVAL_REJECTED':
            email_template = 'approval_rejected'
        elif notification_type == 'DOCUMENT_SIGNED':
            email_template = 'document_signed'
            
        # Add approval instructions to email data if available
        email_data = {}
        if approval.instructions:
            email_data['instructions'] = approval.instructions
            
        # Send notification
        return send_notification(
            notification_type=notification_type,
            users=approver_uids,
            resource_uid=approval.uid,
            resource_type='Approval',
            message=message,
            details=details,
            send_email=True,
            email_template=email_template,
            email_data=email_data
        )
        
    except Exception as e:
        logger.error(f"Error sending approval notification: {e}")
        return []

Parameters

Name Type Default Kind
approval - - positional_or_keyword
notification_type str - positional_or_keyword
step Optional[str] None positional_or_keyword
approver_uids Optional[List[str]] None positional_or_keyword

Parameter Details

approval: An Approval model instance containing approval details. Must have attributes: uid (unique identifier), document_version (related DocumentVersion object), approver_uids (list of approver user IDs), due_date (optional datetime), and instructions (optional string). The approval object serves as the primary data source for notification content.

notification_type: String specifying the type of notification to send. Valid values: 'APPROVAL_REQUESTED' (initial approval request), 'APPROVAL_REMINDER' (reminder before due date), 'APPROVAL_OVERDUE' (past due date), 'APPROVAL_COMPLETED' (approval process finished), 'APPROVAL_REJECTED' (approval was rejected), 'DOCUMENT_SIGNED' (document has been signed). This determines the message content and email template used.

step: Optional string indicating the current step or stage in the approval workflow. This is included in the notification details dictionary and can be used for tracking multi-step approval processes. Defaults to None if not provided.

approver_uids: Optional list of user ID strings to notify. If None (default), notifications are sent to all approvers listed in approval.approver_uids. Use this parameter to target specific approvers in multi-stage approval workflows or for selective notifications.

Return Value

Type: List[str]

Returns a list of strings containing the unique identifiers (UIDs) of successfully created notifications. Each UID corresponds to a notification record created by the send_notification function. Returns an empty list if no approvers are found, if document/version retrieval fails, or if an exception occurs during notification creation.

Dependencies

  • logging
  • typing
  • datetime
  • CDocs
  • CDocs.config
  • CDocs.models.user_extensions
  • CDocs.utils
  • models.review
  • models.approval

Required Imports

import logging
from typing import List, Optional
from datetime import datetime
from CDocs import db
from CDocs.config import settings
from CDocs.models.user_extensions import DocUser
from CDocs.utils import audit_trail
from models.approval import Approval
from models.review import ReviewCycle

Usage Example

from models.approval import Approval
from typing import List

# Assuming approval object is retrieved from database
approval = Approval.query.filter_by(uid='approval-123').first()

# Send initial approval request to all approvers
notification_uids = notify_approval(
    approval=approval,
    notification_type='APPROVAL_REQUESTED',
    step='Technical Review'
)
print(f"Created {len(notification_uids)} notifications")

# Send reminder to specific approvers
specific_approvers = ['user-456', 'user-789']
reminder_uids = notify_approval(
    approval=approval,
    notification_type='APPROVAL_REMINDER',
    step='Technical Review',
    approver_uids=specific_approvers
)

# Send overdue notification
overdue_uids = notify_approval(
    approval=approval,
    notification_type='APPROVAL_OVERDUE',
    step='Final Approval'
)

# Notify completion
completion_uids = notify_approval(
    approval=approval,
    notification_type='APPROVAL_COMPLETED'
)

Best Practices

  • Always ensure the approval object has valid document_version and document relationships before calling this function
  • Handle the returned list of notification UIDs to track notification success and implement retry logic if needed
  • Use the step parameter in multi-stage approval workflows to provide context about which approval stage triggered the notification
  • The function logs errors but returns empty list on failure - implement additional error handling in calling code if needed
  • Consider implementing rate limiting or batching when sending notifications to large numbers of approvers
  • Ensure email templates are properly configured before using notification types that trigger emails
  • Use approver_uids parameter to target specific approvers in parallel approval workflows where not all approvers need every notification
  • The function catches all exceptions and returns empty list - monitor logs for notification failures
  • Due dates are formatted as 'YYYY-MM-DD' strings in notification details - ensure consuming code handles this format
  • The send_notification function must be available in scope - ensure proper module organization or imports

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function notify_approval 98.6% similar

    Sends approval notifications to designated approvers for a document version, supporting multiple notification types (requested, reminder, overdue, completed, rejected, signed) with email and in-app notifications.

    From: /tf/active/vicechatdev/CDocs/utils/notifications.py
  • function complete_approval_v1 70.0% similar

    Records a user's approval decision (APPROVED or REJECTED) for a document in an approval cycle, updating the approval status and document state accordingly.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function add_approver_to_active_approval_v1 69.3% similar

    Adds a new approver to an active approval cycle with permission checks, validation, audit logging, and email notifications.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function create_approval_cycle 68.8% similar

    Creates a new approval cycle for a document, assigning approvers with configurable workflow options (sequential/parallel), instructions, and due dates.

    From: /tf/active/vicechatdev/CDocs/controllers/approval_controller_bis.py
  • function send_notification 68.5% similar

    Sends in-app notifications to one or more users and optionally sends corresponding email notifications using templates.

    From: /tf/active/vicechatdev/CDocs/utils/notifications.py
← Back to Browse