🔍 Code Extractor

class DocumentVersion_v1

Maturity: 28

Model representing a specific version of a controlled document.

File:
/tf/active/vicechatdev/CDocs/models/document.py
Lines:
43 - 696
Complexity:
moderate

Purpose

Model representing a specific version of a controlled document.

Source Code

class DocumentVersion(BaseModel):
    """Model representing a specific version of a controlled document."""
    
    def __init__(self, data: Optional[Dict[str, Any]] = None, uid: Optional[str] = None):
        """
        Initialize a document version.
        
        Args:
            data: Dictionary of version properties
            uid: Version UID to load from database (if data not provided)
        """
        if data is None and uid is not None:
            # Fetch document data from database
            data = db.get_node_by_uid(uid)
            
        super().__init__(data or {})
        self._parent_doc = None  # Cached parent document
    
    @classmethod
    def create(cls, document_uid: str, version_number: str, 
            created_by: Union[DocUser, str], 
            file_paths: Optional[Dict[str, str]] = None,
            properties: Optional[Dict[str, Any]] = None) -> Optional['DocumentVersion']:
        """
        Create a new document version.
        
        Args:
            document_uid: UID of parent document
            version_number: Version number string (e.g., "1.0")
            created_by: User creating the version or their UID
            file_paths: Dictionary containing file paths in FileCloud
                    Can include 'base', 'word', 'pdf' keys
            properties: Additional properties for the version
            
        Returns:
            New DocumentVersion instance or None if creation failed
        """
        try:
            # First fetch the document to check if it has a custom path
            doc = ControlledDocument(uid=document_uid)
            if not doc:
                logger.error(f"Document not found: {document_uid}")
                return None
                
            # Prepare properties
            props = properties or {}
            props.update({
                'versionNumber': version_number,
                'status': 'DRAFT',
                'createdDate': datetime.now(),
            })
            
            # Handle file paths based on the document's path structure
            if file_paths:
                # If base path is directly provided, use it
                if 'base' in file_paths:
                    props['fileCloudPath'] = file_paths['base']
                # Otherwise, try to derive it based on custom path or standard structure
                elif 'word' in file_paths or 'pdf' in file_paths:
                    # Get the source file path (prefer word over PDF)
                    source_path = file_paths.get('word', file_paths.get('pdf'))
                    
                    if doc.custom_path:
                        # For custom path, derive base path maintaining the custom path structure
                        document_folder = f"{doc.custom_path}/{doc.doc_number}"
                        base_name = f"{doc.doc_number}_v{version_number}"
                        props['fileCloudPath'] = f"{document_folder}/{base_name}"
                    else:
                        # For standard path, use the file path directly
                        base_path, ext = os.path.splitext(source_path)
                        props['fileCloudPath'] = base_path
                    
                    # Get file type from source path
                    _, ext = os.path.splitext(source_path)
                    if ext and ext.startswith('.'):
                        props['file_type'] = ext[1:]
                    else:
                        props['file_type'] = 'docx'  # Default to docx if extension unclear
            else:
                # No file paths provided, but we should still set fileCloudPath
                # based on document structure for future use
                if doc.custom_path:
                    document_folder = f"{doc.custom_path}/{doc.doc_number}"
                    base_name = f"{doc.doc_number}_v{version_number}"
                    props['fileCloudPath'] = f"{document_folder}/{base_name}"
                else:
                    department_folder = f"/{settings.FILECLOUD_ROOT_FOLDER}/{doc.department}"
                    doc_type_folder = f"{department_folder}/{doc.doc_type}"
                    document_folder = f"{doc_type_folder}/{doc.doc_number}"
                    base_name = f"{doc.doc_number}_v{version_number}"
                    props['fileCloudPath'] = f"{document_folder}/{base_name}"
            
            # Create node in database
            version_data = db.create_node(
                NodeLabels.DOCUMENT_VERSION,
                props,
                document_uid,
                RelTypes.HAS_VERSION
            )
            
            if not version_data:
                logger.error(f"Failed to create document version for document {document_uid}")
                return None
                
            # Create the version instance
            version = cls(version_data)
            
            # Link to author
            user_uid = created_by.uid if isinstance(created_by, DocUser) else created_by
            db.create_relationship(
                version.uid,
                user_uid,
                RelTypes.AUTHORED_BY
            )
            
            # Link to previous version if any exists
            previous_versions = db.run_query(
                """
                MATCH (d:ControlledDocument {UID: $doc_uid})-[:HAS_VERSION]->(v:DocumentVersion)
                WHERE v.UID <> $version_uid
                RETURN v
                ORDER BY v.versionNumber DESC
                LIMIT 1
                """,
                {"doc_uid": document_uid, "version_uid": version.uid}
            )
            
            if previous_versions and 'v' in previous_versions[0]:
                prev_version = previous_versions[0]['v']
                db.create_relationship(
                    version.uid,
                    prev_version['UID'],
                    RelTypes.PREVIOUS_VERSION
                )
            
            return version
            
        except Exception as e:
            logger.error(f"Error creating document version: {e}")
            return None
    
    @property
    def document_uid(self) -> Optional[str]:
        """Get the UID of the parent document."""
        if hasattr(self, '_document_uid') and self._document_uid:
            return self._document_uid
            
        result = db.run_query(
            """
            MATCH (d:ControlledDocument)-[:HAS_VERSION]->(v:DocumentVersion {UID: $uid})
            RETURN d.UID as doc_uid
            """,
            {"uid": self.uid}
        )
        
        if result and 'doc_uid' in result[0]:
            self._document_uid = result[0]['doc_uid']
            return self._document_uid
            
        return None
    
    @property
    def document(self) -> Optional['ControlledDocument']:
        """Get the parent document instance."""
        if self._parent_doc:
            return self._parent_doc
            
        doc_uid = self.document_uid
        if doc_uid:
            self._parent_doc = ControlledDocument(uid=doc_uid)
            return self._parent_doc
            
        return None
    
    @property
    def version_number(self) -> str:
        """Get version number."""
        return self._data.get('versionNumber', self._data.get('version_number', '1.0'))
    
    @property
    def share_id(self) -> str:
        """Get share ID for this version."""
        return self._data.get('share_id', '')
    
    @share_id.setter
    def share_id(self, value: str) -> None:
        """Set share ID for this version."""
        self._data['share_id'] = value
        db.update_node(self.uid, {'share_id': value})   
    
    @property
    def share_url(self) -> str:
        """Get share URL for this version."""
        return self._data.get('share_url', self.get_primary_file_path())
    
    @share_url.setter
    def share_url(self, value: str) -> None:
        """Set share URL for this version."""
        self._data['share_url'] = value
        db.update_node(self.uid, {'share_url': value})

    @property
    def status(self) -> str:
        """Get version status code."""
        return self._data.get('status', 'DRAFT')
    
    @status.setter
    def status(self, value: str) -> None:
        """Set version status using code."""
        # Convert from name to code if needed
        status_code = settings.get_document_status_code(value)
        
        # Validate status code
        if not settings.is_valid_document_status(status_code):
            logger.warning(f"Invalid status: {value}")
            return
            
        self._data['status'] = status_code
        db.update_node(self.uid, {'status': status_code})
    
    def get_status_name(self) -> str:
        """Get the full status name."""
        return settings.get_document_status_name(self.status)
    
    def get_status_color(self) -> str:
        """Get the color for displaying this status."""
        return settings.get_status_color(self.status)

    @property
    def is_published(self) -> bool:
        """
        Check if this version is published.
        
        Returns:
            bool: True if this version is published, False otherwise
        """
        return is_published_status(self.status)
    
    @property
    def is_current(self) -> bool:
        """
        Check if this version is the current version of its document.
        
        Returns:
            bool: True if this is the current version, False otherwise
        """
        try:
            # Use the document method if we have a document reference
            document = self.document
            if document:
                return document.is_current_version(self.uid)
                
            # Otherwise, query directly using the database helper
            result = db.run_query(
                """
                MATCH (d:ControlledDocument)-[:CURRENT_VERSION]->(v:DocumentVersion {UID: $version_uid})
                RETURN COUNT(d) > 0 as is_current
                """,
                {"version_uid": self.uid}
            )
            
            if result and 'is_current' in result[0]:
                return result[0]['is_current']
                
            return False
        except Exception as e:
            logger.error(f"Error checking if version is current: {e}")
            return False

    @property
    def filecloud_path(self) -> Optional[str]:
        """
        Get the base FileCloud path without extension.
        This is the central attribute for file references.
        
        Returns:
            str: Base path in FileCloud without file extension
        """
        return self._data.get('fileCloudPath')
    
    @filecloud_path.setter
    def filecloud_path(self, path: str) -> None:
        """
        Set the base FileCloud path without extension.
        
        Args:
            path: Base path in FileCloud without file extension
        """
        self._data['fileCloudPath'] = path
        db.update_node(self.uid, {'fileCloudPath': path})
    
    @property
    def word_file_path(self) -> Optional[str]:
        """
        Get path to editable file in FileCloud.
        Dynamically constructs path based on filecloud_path and file_type.
        
        Returns:
            str: Path to the editable file or None if base path is not available
        """
        # Import here to avoid circular imports
        from CDocs.controllers.filecloud_controller import get_filecloud_document_path
        
        # Use the document and version number to get the full path
        document = self.document
        if not document:
            return None
            
        try:
            # Get file path using the centralized function
            return get_filecloud_document_path(document, self.version_number)
        except Exception as e:
            logger.error(f"Error getting word file path: {e}")
            return None
    
    @property
    def pdf_file_path(self) -> Optional[str]:
        """
        Get path to PDF file in FileCloud.
        Uses centralized path function and checks if PDF exists.
        
        Returns:
            str: Path to the PDF file or None if file doesn't exist
        """
        # Import here to avoid circular imports
        from CDocs.controllers.filecloud_controller import get_filecloud_document_path
        
        # Use the document and version number to get the full path
        document = self.document
        if not document:
            return None
            
        try:
            # Get editable file path 
            file_path = get_filecloud_document_path(document, self.version_number)
            
            # If it's already a PDF, return it
            if file_path.lower().endswith('.pdf'):
                return file_path
                
            # Otherwise construct PDF path - replace extension with .pdf
            base_path = os.path.splitext(file_path)[0]
            pdf_path = f"{base_path}.pdf"
            
            # Check if PDF exists in FileCloud
            from CDocs.controllers.filecloud_controller import get_filecloud_client
            client = get_filecloud_client()
            if client.check_file_exists(pdf_path):
                return pdf_path
            
            return None
        except Exception as e:
            logger.error(f"Error getting PDF file path: {e}")
            return None
    
    
    @property
    def file_type(self) -> Optional[str]:
        """Get filetype and extension of file"""
        return self._data.get('file_type')
    
    @property
    def file_name(self) -> Optional[str]:
        """Get filetype and extension of file"""
        return self._data.get('file_name')
    
    @pdf_file_path.setter
    def pdf_file_path(self, path: str) -> None:
        """
        Set the PDF file path and extract base path if not already set.
        
        Args:
            path: Full path to the PDF file
        """
        if not path:
            return
            
        # Extract the base path by removing the extension
        base_path, ext = os.path.splitext(path)
        
        # If filecloud_path isn't set yet, set it
        if not self.filecloud_path:
            self.filecloud_path = base_path
        #db.update_node(self.uid, {'fileCloudPath': path})
    
    @property
    def created_date(self) -> Optional[datetime]:
        """Get version creation date."""
        return self._data.get('created_date')
    
    @property
    def effective_date(self) -> Optional[datetime]:
        """Get date when version becomes effective."""
        return self._data.get('effective_date')
    
    @effective_date.setter
    def effective_date(self, date: datetime) -> None:
        """Set effective date."""
        self._data['effectiveDate'] = date
        db.update_node(self.uid, {'effective_date': date})
    
    @property
    def expiry_date(self) -> Optional[datetime]:
        """Get expiry date."""
        return self._data.get('expiryDate')
    
    @expiry_date.setter
    def expiry_date(self, date: datetime) -> None:
        """Set expiry date."""
        self._data['expiryDate'] = date
        db.update_node(self.uid, {'expiryDate': date})
    
    @property
    def author(self) -> Optional[DocUser]:
        """Get author of the version."""
        result = db.run_query(
            """
            MATCH (v:DocumentVersion {UID: $uid})-[:AUTHORED_BY]->(u:User)
            RETURN u
            """,
            {"uid": self.uid}
        )
        
        if result and 'u' in result[0]:
            return DocUser(result[0]['u'])
            
        return None
    
    @property
    def change_summary(self) -> str:
        """Get summary of changes in this version."""
        return self._data.get('changeSummary', '')
    
    @change_summary.setter
    def change_summary(self, summary: str) -> None:
        """Set change summary."""
        self._data['changeSummary'] = summary
        db.update_node(self.uid, {'changeSummary': summary})
    
    @property
    def hash(self) -> Optional[str]:
        """Get document hash."""
        return self._data.get('hash')
    
    @hash.setter
    def hash(self, value: str) -> None:
        """Set document hash."""
        self._data['hash'] = value
        db.update_node(self.uid, {'hash': value})
    
    def calculate_hash(self, file_content: bytes) -> str:
        """
        Calculate SHA-256 hash for file content.
        
        Args:
            file_content: Content of the file as bytes
            
        Returns:
            Hash string
        """
        hasher = hashlib.sha256()
        hasher.update(file_content)
        hash_value = hasher.hexdigest()
        
        # Store hash in the database
        self.hash = hash_value
        
        return hash_value
    
    def get_previous_version(self) -> Optional['DocumentVersion']:
        """
        Get the previous version of the document.
        
        Returns:
            Previous DocumentVersion or None if this is the first version
        """
        result = db.run_query(
            """
            MATCH (v:DocumentVersion {UID: $uid})-[:PREVIOUS_VERSION]->(prev:DocumentVersion)
            RETURN prev
            """,
            {"uid": self.uid}
        )
        
        if result and 'prev' in result[0]:
            return DocumentVersion(result[0]['prev'])
            
        return None
    
    def start_review(self, reviewers: List[Union[DocUser, str]], 
                    due_date: Optional[datetime] = None,
                    instructions: str = '') -> Optional['ReviewCycle']:
        """
        Start a review cycle for this version.
        
        Args:
            reviewers: List of DocUser instances or UIDs of reviewers
            due_date: Date when review should be completed
            instructions: Instructions for reviewers
            
        Returns:
            ReviewCycle instance or None if creation failed
        """
        # Circular import handled by delayed import
        from .review import ReviewCycle
        
        # Generate due date if not provided
        if not due_date:
            due_date = datetime.now() + timedelta(days=settings.DEFAULT_REVIEW_DAYS)
        
        # Create review cycle
        return ReviewCycle.create(self.uid, reviewers, due_date, instructions)
    
    def get_active_review(self) -> Optional[Dict[str, Any]]:
        """
        Get the active review cycle for this version.
        
        Returns:
            Review cycle data or None if no active review
        """
        result = db.run_query(
            """
            MATCH (v:DocumentVersion {UID: $uid})-[:FOR_REVIEW]->(r:ReviewCycle)
            WHERE r.status IN ['PENDING', 'IN_PROGRESS']
            RETURN r
            ORDER BY r.startDate DESC
            LIMIT 1
            """,
            {"uid": self.uid}
        )
        
        if result and 'r' in result[0]:
            return result[0]['r']
            
        return None
    
    def get_reviews(self) -> List[Dict[str, Any]]:
        """
        Get all review cycles for this version.
        
        Returns:
            List of review cycle data
        """
        result = db.run_query(
            """
            MATCH (v:DocumentVersion {UID: $uid})-[:FOR_REVIEW]->(r:ReviewCycle)
            RETURN r
            ORDER BY r.startDate DESC
            """,
            {"uid": self.uid}
        )
        
        return [record['r'] for record in result if 'r' in record]
    
    # Add this method to the ControlledDocument class
    def save(self) -> bool:
        """Save all changes to the database."""
        try:
            # If node doesn't exist, create it
            if not db.node_exists(self.uid):
                created = db.create_node_with_uid(
                    NodeLabels.CONTROLLED_DOCUMENT,
                    self._data,
                    self.uid
                )
                return created
            
            # Otherwise update existing node
            return db.update_node(self.uid, self._data)
        except Exception as e:
            logger.error(f"Error saving document: {e}")
            import traceback
            logger.error(traceback.format_exc())
            return False
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary representation."""
        result = super().to_dict()
        
        # Add author information if available
        author = self.author
        if author:
            result['author'] = {
                'UID': author.uid,
                'name': author.name,
                'email': author.email
            }
        
        # Add document ID if available
        document = self.document
        if document:
            result['documentId'] = document.doc_number
            
        return result

    def get_primary_file_path(self) -> Optional[str]:
        """
        Get the primary file path based on document status.
        For published/non-editable documents, returns PDF path.
        For editable documents, returns editable document path.
        
        Returns:
            str: Path to the primary file or None if no files are available
        """
        if not self.is_current:
            return None
            
        if self.is_published:
            return self.pdf_file_path
        else:
            return self.word_file_path

    def has_pdf_version(self) -> bool:
        """
        Check if this version has a PDF version.
        
        Returns:
            bool: True if version has PDF file
        """
        return bool(self.pdf_file_path)

    def has_editable_version(self) -> bool:
        """
        Check if this version has an editable version.
        
        Returns:
            bool: True if version has editable file
        """
        return bool(self.word_file_path)

    def get_file_extension(self) -> str:
        """
        Get the file extension for the primary file.
        
        Returns:
            str: File extension (like '.docx', '.pdf')
        """
        if self.word_file_path:
            # Get extension from path
            return os.path.splitext(self.word_file_path)[1].lower()
        elif self.pdf_file_path:
            return '.pdf'
        else:
            return ''

    def is_editable_format(self) -> bool:
        """
        Check if the primary file is in an editable format.
        
        Returns:
            bool: True if editable format
        """
        ext = self.get_file_extension()
        return ext.lower() in ['.docx', '.doc', '.pptx', '.ppt', '.xlsx', '.xls']

Parameters

Name Type Default Kind
bases BaseModel -

Parameter Details

bases: Parameter of type BaseModel

Return Value

Returns unspecified type

Class Interface

Methods

__init__(self, data, uid)

Purpose: Initialize a document version. Args: data: Dictionary of version properties uid: Version UID to load from database (if data not provided)

Parameters:

  • data: Type: Optional[Dict[str, Any]]
  • uid: Type: Optional[str]

Returns: None

create(cls, document_uid, version_number, created_by, file_paths, properties) -> Optional['DocumentVersion']

Purpose: Create a new document version. Args: document_uid: UID of parent document version_number: Version number string (e.g., "1.0") created_by: User creating the version or their UID file_paths: Dictionary containing file paths in FileCloud Can include 'base', 'word', 'pdf' keys properties: Additional properties for the version Returns: New DocumentVersion instance or None if creation failed

Parameters:

  • cls: Parameter
  • document_uid: Type: str
  • version_number: Type: str
  • created_by: Type: Union[DocUser, str]
  • file_paths: Type: Optional[Dict[str, str]]
  • properties: Type: Optional[Dict[str, Any]]

Returns: Returns Optional['DocumentVersion']

document_uid(self) -> Optional[str] property

Purpose: Get the UID of the parent document.

Returns: Returns Optional[str]

document(self) -> Optional['ControlledDocument'] property

Purpose: Get the parent document instance.

Returns: Returns Optional['ControlledDocument']

version_number(self) -> str property

Purpose: Get version number.

Returns: Returns str

share_id(self) -> str property

Purpose: Get share ID for this version.

Returns: Returns str

share_id(self, value) -> None

Purpose: Set share ID for this version.

Parameters:

  • value: Type: str

Returns: Returns None

share_url(self) -> str property

Purpose: Get share URL for this version.

Returns: Returns str

share_url(self, value) -> None

Purpose: Set share URL for this version.

Parameters:

  • value: Type: str

Returns: Returns None

status(self) -> str property

Purpose: Get version status code.

Returns: Returns str

status(self, value) -> None

Purpose: Set version status using code.

Parameters:

  • value: Type: str

Returns: Returns None

get_status_name(self) -> str

Purpose: Get the full status name.

Returns: Returns str

get_status_color(self) -> str

Purpose: Get the color for displaying this status.

Returns: Returns str

is_published(self) -> bool property

Purpose: Check if this version is published. Returns: bool: True if this version is published, False otherwise

Returns: Returns bool

is_current(self) -> bool property

Purpose: Check if this version is the current version of its document. Returns: bool: True if this is the current version, False otherwise

Returns: Returns bool

filecloud_path(self) -> Optional[str] property

Purpose: Get the base FileCloud path without extension. This is the central attribute for file references. Returns: str: Base path in FileCloud without file extension

Returns: Returns Optional[str]

filecloud_path(self, path) -> None

Purpose: Set the base FileCloud path without extension. Args: path: Base path in FileCloud without file extension

Parameters:

  • path: Type: str

Returns: Returns None

word_file_path(self) -> Optional[str] property

Purpose: Get path to editable file in FileCloud. Dynamically constructs path based on filecloud_path and file_type. Returns: str: Path to the editable file or None if base path is not available

Returns: Returns Optional[str]

pdf_file_path(self) -> Optional[str] property

Purpose: Get path to PDF file in FileCloud. Uses centralized path function and checks if PDF exists. Returns: str: Path to the PDF file or None if file doesn't exist

Returns: Returns Optional[str]

file_type(self) -> Optional[str] property

Purpose: Get filetype and extension of file

Returns: Returns Optional[str]

file_name(self) -> Optional[str] property

Purpose: Get filetype and extension of file

Returns: Returns Optional[str]

pdf_file_path(self, path) -> None

Purpose: Set the PDF file path and extract base path if not already set. Args: path: Full path to the PDF file

Parameters:

  • path: Type: str

Returns: Returns None

created_date(self) -> Optional[datetime] property

Purpose: Get version creation date.

Returns: Returns Optional[datetime]

effective_date(self) -> Optional[datetime] property

Purpose: Get date when version becomes effective.

Returns: Returns Optional[datetime]

effective_date(self, date) -> None

Purpose: Set effective date.

Parameters:

  • date: Type: datetime

Returns: Returns None

expiry_date(self) -> Optional[datetime] property

Purpose: Get expiry date.

Returns: Returns Optional[datetime]

expiry_date(self, date) -> None

Purpose: Set expiry date.

Parameters:

  • date: Type: datetime

Returns: Returns None

author(self) -> Optional[DocUser] property

Purpose: Get author of the version.

Returns: Returns Optional[DocUser]

change_summary(self) -> str property

Purpose: Get summary of changes in this version.

Returns: Returns str

change_summary(self, summary) -> None

Purpose: Set change summary.

Parameters:

  • summary: Type: str

Returns: Returns None

hash(self) -> Optional[str] property

Purpose: Get document hash.

Returns: Returns Optional[str]

hash(self, value) -> None

Purpose: Set document hash.

Parameters:

  • value: Type: str

Returns: Returns None

calculate_hash(self, file_content) -> str

Purpose: Calculate SHA-256 hash for file content. Args: file_content: Content of the file as bytes Returns: Hash string

Parameters:

  • file_content: Type: bytes

Returns: Returns str

get_previous_version(self) -> Optional['DocumentVersion']

Purpose: Get the previous version of the document. Returns: Previous DocumentVersion or None if this is the first version

Returns: Returns Optional['DocumentVersion']

start_review(self, reviewers, due_date, instructions) -> Optional['ReviewCycle']

Purpose: Start a review cycle for this version. Args: reviewers: List of DocUser instances or UIDs of reviewers due_date: Date when review should be completed instructions: Instructions for reviewers Returns: ReviewCycle instance or None if creation failed

Parameters:

  • reviewers: Type: List[Union[DocUser, str]]
  • due_date: Type: Optional[datetime]
  • instructions: Type: str

Returns: Returns Optional['ReviewCycle']

get_active_review(self) -> Optional[Dict[str, Any]]

Purpose: Get the active review cycle for this version. Returns: Review cycle data or None if no active review

Returns: Returns Optional[Dict[str, Any]]

get_reviews(self) -> List[Dict[str, Any]]

Purpose: Get all review cycles for this version. Returns: List of review cycle data

Returns: Returns List[Dict[str, Any]]

save(self) -> bool

Purpose: Save all changes to the database.

Returns: Returns bool

to_dict(self) -> Dict[str, Any]

Purpose: Convert to dictionary representation.

Returns: Returns Dict[str, Any]

get_primary_file_path(self) -> Optional[str]

Purpose: Get the primary file path based on document status. For published/non-editable documents, returns PDF path. For editable documents, returns editable document path. Returns: str: Path to the primary file or None if no files are available

Returns: Returns Optional[str]

has_pdf_version(self) -> bool

Purpose: Check if this version has a PDF version. Returns: bool: True if version has PDF file

Returns: Returns bool

has_editable_version(self) -> bool

Purpose: Check if this version has an editable version. Returns: bool: True if version has editable file

Returns: Returns bool

get_file_extension(self) -> str

Purpose: Get the file extension for the primary file. Returns: str: File extension (like '.docx', '.pdf')

Returns: Returns str

is_editable_format(self) -> bool

Purpose: Check if the primary file is in an editable format. Returns: bool: True if editable format

Returns: Returns bool

Required Imports

import logging
import uuid
import hashlib
from typing import Dict
from typing import List

Usage Example

# Example usage:
# result = DocumentVersion(bases)

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class DocumentVersion 78.5% similar

    A dataclass that represents a versioned snapshot of a document, capturing its structure, metadata, and change history at a specific point in time.

    From: /tf/active/vicechatdev/vice_ai/models.py
  • class ControlledDocument 75.1% similar

    Model representing a controlled document.

    From: /tf/active/vicechatdev/CDocs/models/document.py
  • class Document 67.6% similar

    A dataclass representing a document with hierarchical structure, versioning, metadata, and collaboration features.

    From: /tf/active/vicechatdev/vice_ai/models.py
  • class ApprovalCycle_v1 61.9% similar

    Model representing a approval cycle for a document version.

    From: /tf/active/vicechatdev/CDocs/models/approval.py
  • class ApprovalCycle 59.9% similar

    Model representing an approval cycle for a document version.

    From: /tf/active/vicechatdev/CDocs/models/approval_bis.py
← Back to Browse